1 /*
2  * Copyright (C) 2015-2020 Alibaba Group Holding Limited
3  */
4 
5 #include "objects.h"
6 #include "pinmap.h"
7 #include "PinNames.h"
8 #include <drv/gpio.h>
9 #include <aos/gpioc_csi.h>
10 
user_interrupt_handler(csi_gpio_t * gpio,uint32_t id)11 static void user_interrupt_handler(csi_gpio_t *gpio, uint32_t id)
12 {
13     if (gpio->callback != NULL) {
14         uint32_t pin_mask;
15 
16         pin_mask = (uint32_t)1 << ((id >> 16) & 0x1F);
17         gpio->callback(gpio, pin_mask, gpio->arg);
18     }
19 }
20 
csi_gpio_init(csi_gpio_t * gpio,uint32_t port_idx)21 csi_error_t csi_gpio_init(csi_gpio_t *gpio, uint32_t port_idx)
22 {
23     if(!gpio)
24         return CSI_ERROR;
25 
26     if (port_idx != PORT_A && port_idx != PORT_B){
27         printf("error\n");
28         return CSI_ERROR;
29     }
30 
31     gpio->dev.idx = port_idx;
32     gpio->callback = NULL;
33     gpio->arg = NULL;
34 
35     return CSI_OK;
36 }
37 
csi_gpio_uninit(csi_gpio_t * gpio)38 void csi_gpio_uninit(csi_gpio_t *gpio)
39 {
40     if (gpio->dev.idx != PORT_A && gpio->dev.idx != PORT_B) {
41         return;
42     }
43 
44     uint32_t pin_idx = 0;
45 
46     while(pin_idx < 32) {
47         GPIO_DeInit(((gpio->dev.idx)<<5)|pin_idx);
48         pin_idx++;
49     }
50 }
51 
csi_gpio_dir(csi_gpio_t * gpio,uint32_t pin_mask,csi_gpio_dir_t dir)52 csi_error_t csi_gpio_dir(csi_gpio_t *gpio, uint32_t pin_mask, csi_gpio_dir_t dir)
53 {
54     if (gpio->dev.idx != PORT_A && gpio->dev.idx != PORT_B) {
55         return CSI_ERROR;
56     }
57 
58     uint32_t pin_idx = 0;
59 
60     while(pin_idx < sizeof(pin_mask) * 8) {
61         if((pin_mask >> pin_idx) & 0x01) {
62             GPIO_InitTypeDef GPIO_InitStruct;
63             GPIO_InitStruct.GPIO_Pin = ((gpio->dev.idx)<<5)|pin_idx;
64             printf("gpio pin:%d\n",pin_idx);
65             GPIO_InitStruct.GPIO_Mode = dir;
66             GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
67             GPIO_Init(&GPIO_InitStruct);
68         }
69         pin_idx++;
70     }
71     return CSI_OK;
72 }
73 
csi_gpio_mode(csi_gpio_t * gpio,uint32_t pin_mask,csi_gpio_mode_t mode)74 csi_error_t csi_gpio_mode(csi_gpio_t *gpio, uint32_t pin_mask, csi_gpio_mode_t mode)
75 {
76     if (gpio->dev.idx != PORT_A && gpio->dev.idx != PORT_B) {
77         return CSI_ERROR;
78     }
79 
80     uint32_t GPIO_PuPd;
81     uint32_t pin_idx = 0;
82 
83     switch (mode) {
84         case GPIO_MODE_PULLNONE:/* No driver -> Input & High Impendance */
85             GPIO_PuPd = GPIO_PuPd_NOPULL;
86         break;
87 
88         case GPIO_MODE_PULLDOWN:
89             GPIO_PuPd = GPIO_PuPd_DOWN;
90         break;
91 
92         case GPIO_MODE_PULLUP:
93             GPIO_PuPd = GPIO_PuPd_UP;
94         break;
95 
96         default:
97             GPIO_PuPd = GPIO_PuPd_NOPULL;
98         break;
99     }
100 
101     while(pin_idx < sizeof(pin_mask) * 8) {
102         if((pin_mask >> pin_idx) & 0x01) {
103             PAD_PullCtrl(((gpio->dev.idx)<<5)|pin_idx, GPIO_PuPd);
104         }
105         pin_idx++;
106     }
107     return CSI_OK;
108 }
109 
110 
csi_gpio_irq_mode(csi_gpio_t * gpio,uint32_t pin_mask,csi_gpio_irq_mode_t mode)111 csi_error_t csi_gpio_irq_mode(csi_gpio_t *gpio, uint32_t pin_mask, csi_gpio_irq_mode_t mode)
112 {
113     if (gpio->dev.idx != PORT_A && gpio->dev.idx != PORT_B) {
114         return CSI_ERROR;
115     }
116 
117     uint32_t GPIO_ITTrigger;
118     uint32_t GPIO_ITPolarity;
119     uint32_t pin_idx = 0;
120 
121     if(gpio->dev.idx == PORT_A) {
122         InterruptRegister(GPIO_INTHandler, GPIOA_IRQ, (uint32_t)GPIOA_BASE, 5);
123         InterruptEn(GPIOA_IRQ, 5);
124     } else if (gpio->dev.idx == PORT_B){
125         InterruptRegister(GPIO_INTHandler, GPIOB_IRQ, (uint32_t)GPIOB_BASE, 5);
126         InterruptEn(GPIOB_IRQ, 5);
127     }
128 
129     switch(mode) {
130         case GPIO_IRQ_MODE_RISING_EDGE:
131             GPIO_ITTrigger = GPIO_INT_Trigger_EDGE;
132             GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_HIGH;
133         break;
134 
135         case GPIO_IRQ_MODE_FALLING_EDGE:
136             GPIO_ITTrigger = GPIO_INT_Trigger_EDGE;
137             GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW;
138         break;
139 
140         case GPIO_IRQ_MODE_BOTH_EDGE:
141             GPIO_ITTrigger = GPIO_INT_Trigger_BOTHEDGE;
142             GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW;
143         break;
144 
145         case GPIO_IRQ_MODE_LOW_LEVEL:
146             GPIO_ITTrigger = GPIO_INT_Trigger_LEVEL;
147             GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_LOW;
148         break;
149 
150         case GPIO_IRQ_MODE_HIGH_LEVEL:
151             GPIO_ITTrigger = GPIO_INT_Trigger_LEVEL;
152             GPIO_ITPolarity = GPIO_INT_POLARITY_ACTIVE_HIGH;
153         break;
154 
155         default:
156         break;
157     }
158 
159     while(pin_idx < sizeof(pin_mask) * 8) {
160         if((pin_mask >> pin_idx) & 0x01) {
161             GPIO_INTMode(((gpio->dev.idx)<<5)|pin_idx, ENABLE, GPIO_ITTrigger, GPIO_ITPolarity, GPIO_INT_DEBOUNCE_ENABLE);
162             if(gpio->callback != NULL) {
163                 GPIO_UserRegIrq(((gpio->dev.idx)<<5)|pin_idx, user_interrupt_handler, gpio);
164             }
165         }
166         pin_idx++;
167     }
168     return CSI_OK;
169 }
170 
csi_gpio_irq_enable(csi_gpio_t * gpio,uint32_t pin_mask,bool enable)171 csi_error_t csi_gpio_irq_enable(csi_gpio_t *gpio, uint32_t pin_mask, bool enable)
172 {
173     if (gpio->dev.idx != PORT_A && gpio->dev.idx != PORT_B) {
174         return CSI_ERROR;
175     }
176 
177     uint32_t pin_idx = 0;
178 
179     while(pin_idx < sizeof(pin_mask) * 8) {
180         if((pin_mask >> pin_idx) & 0x01) {
181             GPIO_INTConfig(((gpio->dev.idx)<<5)|pin_idx, enable);
182         }
183         pin_idx++;
184     }
185     return CSI_OK;
186 }
187 
csi_gpio_write(csi_gpio_t * gpio,uint32_t pin_mask,csi_gpio_pin_state_t value)188 void csi_gpio_write(csi_gpio_t *gpio, uint32_t pin_mask, csi_gpio_pin_state_t value)
189 {
190     if (gpio->dev.idx != PORT_A && gpio->dev.idx != PORT_B) {
191         return;
192     }
193 
194     uint32_t pin_idx = 0;
195 
196     while(pin_idx < sizeof(pin_mask) * 8) {
197         if((pin_mask >> pin_idx) & 0x01) {
198             GPIO_WriteBit(((gpio->dev.idx)<<5)|pin_idx, value);
199         }
200         pin_idx++;
201     }
202 }
203 
csi_gpio_toggle(csi_gpio_t * gpio,uint32_t pin_mask)204 void csi_gpio_toggle(csi_gpio_t *gpio, uint32_t pin_mask)
205 {
206     if (gpio->dev.idx != PORT_A && gpio->dev.idx != PORT_B) {
207         return;
208     }
209 
210     uint32_t pin_idx = 0, value;
211 
212     while(pin_idx < sizeof(pin_mask) * 8) {
213         if((pin_mask >> pin_idx) & 0x01) {
214             value = GPIO_ReadDataBit(((gpio->dev.idx)<<5)|pin_idx);
215             GPIO_WriteBit(((gpio->dev.idx)<<5)|pin_idx, !value);
216         }
217         pin_idx++;
218     }
219 }
220 
csi_gpio_read(csi_gpio_t * gpio,uint32_t pin_mask)221 uint32_t csi_gpio_read(csi_gpio_t *gpio, uint32_t pin_mask)
222 {
223     if (gpio->dev.idx != PORT_A && gpio->dev.idx != PORT_B) {
224         return CSI_ERROR;
225     }
226 
227     uint32_t pin_idx = 0, value = 0;
228 
229     while(pin_idx < sizeof(pin_mask) * 8) {
230         if((pin_mask >> pin_idx) & 0x01) {
231             value |= (GPIO_ReadDataBit(((gpio->dev.idx)<<5)|pin_idx) << pin_idx);
232         }
233         pin_idx++;
234     }
235 
236     return value;
237 }
238 
csi_gpio_attach_callback(csi_gpio_t * gpio,void * callback,void * arg)239 csi_error_t csi_gpio_attach_callback(csi_gpio_t *gpio, void *callback, void *arg)
240 {
241     gpio->callback = callback;
242     gpio->arg = arg;
243 
244     return CSI_OK;
245 }
246 
csi_gpio_detach_callback(csi_gpio_t * gpio)247 void csi_gpio_detach_callback(csi_gpio_t *gpio)
248 {
249     if (gpio->callback != NULL) {
250         gpio->callback = NULL;
251         gpio->arg = NULL;
252     }
253 }
254 
gpioc_csi_init(void)255 static int gpioc_csi_init(void)
256 {
257     static aos_gpioc_csi_t gpioc_csi[2];
258     int ret;
259 
260     gpioc_csi[0].gpioc.dev.id = 0;
261     gpioc_csi[0].gpioc.num_pins = 32;
262     gpioc_csi[0].default_input_cfg = AOS_GPIO_INPUT_CFG_HI;
263     gpioc_csi[0].default_output_cfg = AOS_GPIO_OUTPUT_CFG_PP;
264     ret = (int)aos_gpioc_csi_register(&gpioc_csi[0]);
265     if (ret)
266         return ret;
267 
268     gpioc_csi[1].gpioc.dev.id = 1;
269     gpioc_csi[1].gpioc.num_pins = 32;
270     gpioc_csi[1].default_input_cfg = AOS_GPIO_INPUT_CFG_HI;
271     gpioc_csi[1].default_output_cfg = AOS_GPIO_OUTPUT_CFG_PP;
272     ret = (int)aos_gpioc_csi_register(&gpioc_csi[1]);
273     if (ret) {
274         (void)aos_gpioc_csi_unregister(0);
275         return ret;
276     }
277 
278     return 0;
279 }
280 
281 LEVEL1_DRIVER_ENTRY(gpioc_csi_init)
282