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