1 /*
2  * Copyright (c) 2020-2020, BLUETRUM Development Team
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include "ab32vg1_hal.h"
8 
9 #ifdef HAL_GPIO_MODULE_ENABLED
10 
11 #if 0
12 #define HAL_LOG(...)       hal_printf(__VA_ARGS__)
13 #else
14 #define HAL_LOG(...)
15 #endif
16 
gpio_afinit(hal_sfr_t gpiox,uint8_t pin,uint32_t alternate,uint32_t af_con)17 void gpio_afinit(hal_sfr_t gpiox, uint8_t pin, uint32_t alternate, uint32_t af_con)
18 {
19     uint32_t is_rx_map_tx = (alternate & UT1RXMAP_TX) || (alternate & UT0RXMAP_TX);
20     if ((af_con & 0xf0u) != GPIO_AFDIS) {
21         gpiox[GPIOxFEN]   |= BIT(pin);
22 
23         switch (is_rx_map_tx)
24         {
25         case UT1RXMAP_TX:
26             FUNCMCONx(GPIO_GET_AFCON(af_con)) |= GPIO_AF_MAP_CLR(UT1RXMAP_AF);
27             break;
28         case UT0RXMAP_TX:
29             FUNCMCONx(GPIO_GET_AFCON(af_con)) |= GPIO_AF_MAP_CLR(UT0RXMAP_AF);
30             break;
31         default:
32             break;
33         }
34 
35         FUNCMCONx(GPIO_GET_AFCON(af_con)) |= GPIO_AF_MAP_CLR(af_con & 0x1f);
36         FUNCMCONx(GPIO_GET_AFCON(af_con)) |= alternate;
37         HAL_LOG("af_con=0x%X AFCON=%d alternate=%d\n", af_con, GPIO_GET_AFCON(af_con), (af_con & 0x1f));
38     }
39 }
40 
41 /**
42  * @brief Initialize the gpio.
43  *
44  * @param port GPIO port(GPIOAN, GPIOBN, GPIOEN, GPIOFN).
45  * @param gpio_init the configuration of the specified GPIO peripheral.
46  */
hal_gpio_init(hal_sfr_t gpiox,gpio_init_t gpio_init)47 void hal_gpio_init(hal_sfr_t gpiox, gpio_init_t gpio_init)
48 {
49     uint8_t iocurrent = 0;
50     if (gpio_init == HAL_NULL) {
51         return;
52     }
53 
54     for (iocurrent = 0; iocurrent < 8; iocurrent++) {
55         if ((gpio_init->pin & BIT(iocurrent)) == 0) {
56             continue;
57         }
58 
59         gpio_afinit(gpiox, iocurrent, gpio_init->alternate, gpio_init->af_con);
60 
61         switch (gpio_init->dir)
62         {
63         case GPIO_DIR_INPUT:
64             /* When set to input, clear all pull-ups of the port. */
65             gpiox[GPIOxDIR]     |= BIT(iocurrent);
66             gpiox[GPIOxPU]      &= ~BIT(iocurrent);
67             gpiox[GPIOxPU200K]  &= ~BIT(iocurrent);
68             gpiox[GPIOxPD200K]  &= ~BIT(iocurrent);
69             gpiox[GPIOxPU300K]  &= ~BIT(iocurrent);
70             gpiox[GPIOxPD300K]  &= ~BIT(iocurrent);
71 
72             switch (gpio_init->pull)
73             {
74             case GPIO_PULLUP:
75                 gpiox[GPIOxPD] &= ~BIT(iocurrent);
76                 gpiox[GPIOxPU] |= BIT(iocurrent);
77                 break;
78             case GPIO_PULLDOWN:
79                 gpiox[GPIOxPU] &= ~BIT(iocurrent);
80                 gpiox[GPIOxPD] |= BIT(iocurrent);
81                 break;
82             case GPIO_NOPULL:
83                 gpiox[GPIOxPU] &= ~BIT(iocurrent);
84                 gpiox[GPIOxPD] &= ~BIT(iocurrent);
85             default:
86                 break;
87             }
88             break;
89         case GPIO_DIR_OUTPUT:
90             gpiox[GPIOxDIR] &= ~BIT(iocurrent);
91             break;
92         default:
93             break;
94         }
95 
96         switch (gpio_init->de)
97         {
98         case GPIO_DIGITAL:
99             gpiox[GPIOxDE] |= BIT(iocurrent);
100             break;
101         case GPIO_ANALOG:
102             gpiox[GPIOxDE] &= ~BIT(iocurrent);
103             break;
104         default:
105             break;
106         }
107     }
108 }
109 
110 /**
111  * @brief Read the specified input port pin.
112  *
113  * @param port GPIO port(GPIOAN, GPIOBN, GPIOEN, GPIOFN).
114  * @param pin This parameter can be GPIO_PIN_x where x can be (0.15).
115  * @return uint8_t The input port pin value.
116  */
hal_gpio_read(hal_sfr_t gpiox,uint8_t pin)117 uint8_t hal_gpio_read(hal_sfr_t gpiox, uint8_t pin)
118 {
119     return ((gpiox[GPIOx] & BIT(pin)) != GPIO_PIN_LOW) ? GPIO_PIN_HIGH : GPIO_PIN_LOW;
120 }
121 
122 /**
123  * @brief Set or clear the selected data port bit.
124  *
125  * @param port GPIO port(GPIOAN, GPIOBN, GPIOEN, GPIOFN).
126  * @param pin This parameter can be GPIO_PIN_x where x can be (0.15).
127  * @param state specifies the value to be written to the selected bit.
128  *          @arg GPIO_PIN_LOW:
129  *          @arg GPIO_PIN_HIGH:
130  */
hal_gpio_write(hal_sfr_t gpiox,uint8_t pin,uint8_t state)131 void hal_gpio_write(hal_sfr_t gpiox, uint8_t pin, uint8_t state)
132 {
133     if (state == GPIO_PIN_LOW) {
134         gpiox[GPIOx] &= ~BIT(pin);
135     } else {
136         gpiox[GPIOx] |= BIT(pin);
137     }
138 }
139 
140 /**
141  * @brief Toggle the specified GPIO pin.
142  *
143  * @param port GPIO port(GPIOAN, GPIOBN, GPIOEN, GPIOFN).
144  * @param pin This parameter can be GPIO_PIN_x where x can be (0.15).
145  */
hal_gpio_toggle(hal_sfr_t gpiox,uint8_t pin)146 void hal_gpio_toggle(hal_sfr_t gpiox, uint8_t pin)
147 {
148     gpiox[GPIOx] ^= BIT(pin);
149 }
150 
151 #endif
152