1 /*
2 * Copyright (c) 2006-2021, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2018-02-08 RT-Thread the first version
9 */
10 #include <rtthread.h>
11 #include <rthw.h>
12
13 #include "drv_gpio.h"
14 #include "interrupt.h"
15
16 #define DBG_TAG "GPIO"
17 #define DBG_LVL DBG_WARNING
18 #include <rtdbg.h>
19
20 #define readl(addr) (*(volatile unsigned int *)(addr))
21 #define writel(value,addr) (*(volatile unsigned int *)(addr) = (value))
22
23 // Todo: add RT_ASSERT.
24
25 /*********************************************************
26 ** IO
27 *********************************************************/
gpio_set_func(enum gpio_port port,enum gpio_pin pin,rt_uint8_t func)28 rt_err_t gpio_set_func(enum gpio_port port, enum gpio_pin pin, rt_uint8_t func)
29 {
30 rt_uint32_t addr;
31 rt_uint32_t offset;
32 rt_uint32_t data;
33
34 RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
35 RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
36
37 if (func & 0x8)
38 {
39 LOG_W("[line]:%d There is a warning with parameter input", __LINE__);
40 return -RT_EINVAL;
41 }
42
43 addr = GPIOn_CFG_ADDR(port) + (pin / 8) * 4;
44 offset = (pin % 8) * 4;
45
46 data = readl(addr);
47 data &= ~(0x7 << offset);
48 data |= func << offset;
49 writel(data, addr);
50
51 LOG_D("[line]:%d offset:%d addr:%08x data:%08x", __LINE__, offset, addr, *((rt_uint32_t *)addr));
52 return RT_EOK;
53 }
54
gpio_set_value(enum gpio_port port,enum gpio_pin pin,rt_uint8_t value)55 int gpio_set_value(enum gpio_port port, enum gpio_pin pin, rt_uint8_t value)
56 {
57 rt_uint32_t addr;
58 rt_uint32_t offset;
59 rt_uint32_t data;
60
61 RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
62 RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
63
64 if (value & 0xE)
65 {
66 LOG_W("[line]:%d There is a warning with parameter input", __LINE__);
67 return -RT_EINVAL;
68 }
69
70 addr = GPIOn_DATA_ADDR(port);
71 offset = pin;
72
73 data = readl(addr);
74 data &= ~(0x1 << offset);
75 data |= value << offset;
76 writel(data, addr);
77
78 LOG_D("[line]:%d offset:%d addr:%08x data:%08x", __LINE__, offset, addr, *((rt_uint32_t *)addr));
79 return RT_EOK;
80 }
81
gpio_get_value(enum gpio_port port,enum gpio_pin pin)82 int gpio_get_value(enum gpio_port port, enum gpio_pin pin)
83 {
84 rt_uint32_t addr;
85 rt_uint32_t offset;
86 rt_uint32_t data;
87
88 RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
89 RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
90
91 addr = GPIOn_DATA_ADDR(port);
92 offset = pin;
93
94 data = readl(addr);
95
96 LOG_D("[line]:%d offset:%d addr:%08x data:%08x", __LINE__, offset, addr, *((rt_uint32_t *)addr));
97 return (data >> offset) & 0x01;
98 }
99
gpio_set_pull_mode(enum gpio_port port,enum gpio_pin pin,enum gpio_pull pull)100 int gpio_set_pull_mode(enum gpio_port port, enum gpio_pin pin, enum gpio_pull pull)
101 {
102 rt_uint32_t addr;
103 rt_uint32_t offset;
104 rt_uint32_t data;
105
106 RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
107 RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
108
109 if (pull & 0xC)
110 {
111 LOG_W("[line]:%d There is a warning with parameter input", __LINE__);
112 return -RT_EINVAL;
113 }
114
115 addr = GPIOn_PUL_ADDR(port);
116 addr += pin > GPIO_PIN_15 ? 0x4 : 0x0;
117 offset = (pin & 0xf) << 1;
118
119 data = readl(addr);
120 data &= ~(0x3 << offset);
121 data |= pull << offset;
122 writel(data, addr);
123
124 LOG_D("[line]:%d offset:%d addr:%08x data:%08x", __LINE__, offset, addr, *((rt_uint32_t *)addr));
125 return RT_EOK;
126 }
127
gpio_set_drive_level(enum gpio_port port,enum gpio_pin pin,enum gpio_drv_level level)128 int gpio_set_drive_level(enum gpio_port port, enum gpio_pin pin, enum gpio_drv_level level)
129 {
130 volatile rt_uint32_t addr;
131 rt_uint32_t offset;
132 rt_uint32_t data;
133
134 RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
135 RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
136
137 if (level & 0xC)
138 {
139 LOG_W("[line]:%d There is a warning with parameter input", __LINE__);
140 return -RT_EINVAL;
141 }
142
143 addr = GPIOn_DRV_ADDR(port);
144 addr += pin > GPIO_PIN_15 ? 0x4 : 0x0;
145 offset = (pin & 0xf) << 1;
146
147 data = readl(addr);
148 data &= ~(0x3 << offset);
149 data |= level << offset;
150 writel(data, addr);
151
152 LOG_D("[line]:%d offset:%d addr:%08x data:%08x", __LINE__, offset, addr, *((rt_uint32_t *)addr));
153 return RT_EOK;
154 }
155
gpio_direction_input(enum gpio_port port,enum gpio_pin pin)156 void gpio_direction_input(enum gpio_port port, enum gpio_pin pin)
157 {
158 volatile rt_uint32_t addr;
159 rt_uint32_t offset;
160 rt_uint32_t data;
161
162 RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
163 RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
164
165 addr = GPIOn_CFG_ADDR(port) + (pin / 8) * 4;
166 offset = (pin % 8) * 4;
167
168 data = readl(addr);
169 data &= ~(0x7 << offset);
170 data |= IO_INPUT << offset;
171 writel(data, addr);
172
173 LOG_D("[line]:%d offset:%d addr:%08x data:%08x", __LINE__, offset, addr, *((rt_uint32_t *)addr));
174 }
175
gpio_direction_output(enum gpio_port port,enum gpio_pin pin,int value)176 void gpio_direction_output(enum gpio_port port, enum gpio_pin pin, int value)
177 {
178 volatile rt_uint32_t addr;
179 rt_uint32_t offset;
180 rt_uint32_t data;
181
182 RT_ASSERT((GPIO_PORT_A <= port) && (port < GPIO_PORT_NUM));
183 RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
184
185 gpio_set_value(port, pin, value);
186 addr = GPIOn_CFG_ADDR(port) + (pin / 8) * 4;
187 offset = (pin % 8) * 4;
188
189 data = readl(addr);
190 data &= ~(0x7 << offset);
191 data |= IO_OUTPUT << offset;
192 writel(data, addr);
193
194 LOG_D("[line]:%d offset:%d addr:%08x data:%08x", __LINE__, offset, addr, *((rt_uint32_t *)addr));
195 }
196 /*********************************************************
197 ** IRQ
198 *********************************************************/
gpio_ack_irq(enum gpio_port port,enum gpio_pin pin)199 static void gpio_ack_irq(enum gpio_port port, enum gpio_pin pin)
200 {
201 rt_uint32_t addr;
202 rt_uint32_t data;
203
204 addr = GPIOn_INT_STA_ADDR(port);
205 data = readl(addr);
206 data |= 0x1 << pin;
207 writel(data, addr);
208 }
209
gpio_select_irq_clock(enum gpio_port port,enum gpio_irq_clock clock)210 void gpio_select_irq_clock(enum gpio_port port, enum gpio_irq_clock clock)
211 {
212 rt_uint32_t addr;
213 rt_uint32_t data;
214
215 RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
216
217 addr = GPIOn_INT_DEB_ADDR(port - GPIO_PORT_D);
218
219 data = readl(addr);
220 data &= ~0x01;
221 data |= clock;
222 writel(data, addr);
223 LOG_D("[line]:%d addr:%08x data:%08x", __LINE__, addr, *((rt_uint32_t *)addr));
224 }
225
gpio_set_debounce(enum gpio_port port,enum gpio_direction_type prescaler)226 void gpio_set_debounce(enum gpio_port port, enum gpio_direction_type prescaler)
227 {
228 rt_uint32_t addr;
229 rt_uint32_t data;
230
231 RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
232
233 addr = GPIOn_INT_DEB_ADDR(port - GPIO_PORT_D);
234
235 data = readl(addr);
236 data &= ~(0x07 << 4);
237 data |= prescaler << 4;
238 writel(data, addr);
239 LOG_D("[line]:%d addr:%08x data:%08x", __LINE__, addr, *((rt_uint32_t *)addr));
240 }
241
gpio_irq_enable(enum gpio_port port,enum gpio_pin pin)242 void gpio_irq_enable(enum gpio_port port, enum gpio_pin pin)
243 {
244 rt_uint32_t addr;
245 rt_uint32_t offset;
246 rt_uint32_t data;
247
248 RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
249 RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
250
251 addr = GPIOn_INT_CTRL_ADDR(port - GPIO_PORT_D);
252 offset = pin;
253
254 data = readl(addr);
255 data |= 0x1 << offset;
256 writel(data, addr);
257 gpio_select_irq_clock(port, GPIO_IRQ_HOSC_24MHZ);
258 LOG_D("[line]:%d offset:%d addr:%08x data:%08x", __LINE__, offset, addr, *((rt_uint32_t *)addr));
259 }
260
gpio_irq_disable(enum gpio_port port,enum gpio_pin pin)261 void gpio_irq_disable(enum gpio_port port, enum gpio_pin pin)
262 {
263 rt_uint32_t addr;
264 rt_uint32_t offset;
265 rt_uint32_t data;
266
267 RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
268 RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
269
270 gpio_ack_irq(port - GPIO_PORT_D, pin);
271 addr = GPIOn_INT_CTRL_ADDR(port - GPIO_PORT_D);
272 offset = pin;
273
274 data = readl(addr);
275 data &= ~(0x1 << offset);
276
277 writel(data, addr);
278 LOG_D("[line]:%d offset:%d addr:%08x data:%08x", __LINE__, offset, addr, *((rt_uint32_t *)addr));
279 }
280
gpio_set_irq_type(enum gpio_port port,enum gpio_pin pin,enum gpio_irq_type irq_type)281 void gpio_set_irq_type(enum gpio_port port, enum gpio_pin pin, enum gpio_irq_type irq_type)
282 {
283 rt_uint32_t addr;
284 rt_uint32_t offset;
285 rt_uint32_t data;
286
287 RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
288 RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
289
290 addr = GPIOn_INT_CFG_ADDR(port - GPIO_PORT_D) + (pin / 8) * 4;
291 offset = (pin % 8) * 4;
292
293 data = readl(addr);
294 data &= ~(0x7 << offset);
295 data |= irq_type << offset;
296 writel(data, addr);
297
298 LOG_D("[line]:%d offset:%d addr:%08x data:%08x", __LINE__, offset, addr, *((rt_uint32_t *)addr));
299 }
300
301 static struct gpio_irq_def _g_gpio_irq_tbl[GPIO_PORT_NUM];
302
gpio_set_irq_callback(enum gpio_port port,enum gpio_pin pin,void (* irq_cb)(void *),void * irq_arg)303 void gpio_set_irq_callback(enum gpio_port port, enum gpio_pin pin, void (*irq_cb)(void *), void *irq_arg)
304 {
305 RT_ASSERT((GPIO_PORT_C < port) && (port < GPIO_PORT_NUM));
306 RT_ASSERT((GPIO_PIN_0 <= pin) && (pin < GPIO_PIN_NUM));
307
308 _g_gpio_irq_tbl[port].irq_cb[pin] = irq_cb;
309 _g_gpio_irq_tbl[port].irq_arg[pin] = irq_arg;
310 }
311
gpio_clear_irq_callback(enum gpio_port port,enum gpio_pin pin)312 void gpio_clear_irq_callback(enum gpio_port port, enum gpio_pin pin)
313 {
314 gpio_irq_disable(port, pin);
315
316 _g_gpio_irq_tbl[port].irq_cb[pin] = RT_NULL;
317 _g_gpio_irq_tbl[port].irq_arg[pin] = RT_NULL;
318 }
319
gpio_irq_handler(int irq,void * param)320 static void gpio_irq_handler(int irq, void *param)
321 {
322 struct gpio_irq_def *irq_def = (struct gpio_irq_def *)param;
323 rt_uint32_t pend, enable;
324 int port, pin;
325 rt_uint32_t addr;
326
327 pin = 0;
328 port = irq - PIOD_INTERRUPT;
329 addr = GPIOn_INT_STA_ADDR(port);
330 pend = readl(addr);
331 addr = GPIOn_INT_CTRL_ADDR(port);
332 enable = readl(addr);
333 pend &= enable;
334
335 while (pend)
336 {
337 if ((pend & 0x1) && (irq_def->irq_cb[pin] != RT_NULL))
338 {
339 LOG_D("do irq callback...", port, pin);
340 irq_def->irq_cb[pin](irq_def->irq_arg[pin]);
341 }
342 pin++;
343 pend = pend >> 1;
344 gpio_ack_irq(port, pin);
345 }
346 }
347
348
349 #ifdef RT_USING_PIN
350 #include <rtdevice.h>
351
352 #define PIN_MAGIC (0x5A)
353 #define PIN_NUM(_N) (sizeof(_N) / sizeof(_N[0]))
354
355 struct _pin_index
356 {
357 rt_uint8_t id;
358 rt_uint8_t pin_port;
359 rt_uint8_t pin;
360 rt_uint8_t magic;
361 };
362
363 static struct _pin_index pin_index[] =
364 {
365 {0, 0, 0, 0},
366 {1, 0, 0, 0},
367 {2, 0, 0, 0},
368 {3, 0, 0, 0},
369 {4, 0, 0, 0},
370 {5, 0, 0, 0},
371 {6, GPIO_PORT_D, GPIO_PIN_0, PIN_MAGIC},
372 {7, GPIO_PORT_D, GPIO_PIN_1, PIN_MAGIC},
373 {8, GPIO_PORT_D, GPIO_PIN_2, PIN_MAGIC},
374 {9, GPIO_PORT_D, GPIO_PIN_3, PIN_MAGIC},
375 {10, GPIO_PORT_D, GPIO_PIN_4, PIN_MAGIC},
376 {11, GPIO_PORT_D, GPIO_PIN_5, PIN_MAGIC},
377 {12, GPIO_PORT_D, GPIO_PIN_6, PIN_MAGIC},
378 {13, GPIO_PORT_D, GPIO_PIN_7, PIN_MAGIC},
379 {14, GPIO_PORT_D, GPIO_PIN_8, PIN_MAGIC},
380 {15, GPIO_PORT_D, GPIO_PIN_9, PIN_MAGIC},
381 {16, GPIO_PORT_D, GPIO_PIN_10, PIN_MAGIC},
382 {17, GPIO_PORT_D, GPIO_PIN_11, PIN_MAGIC},
383 {18, GPIO_PORT_D, GPIO_PIN_12, PIN_MAGIC},
384 {19, GPIO_PORT_D, GPIO_PIN_13, PIN_MAGIC},
385 {20, 0, 0, 0},
386 {21, GPIO_PORT_D, GPIO_PIN_14, PIN_MAGIC},
387 {22, 0, 0, 0},
388 {23, GPIO_PORT_D, GPIO_PIN_15, PIN_MAGIC},
389 {24, GPIO_PORT_D, GPIO_PIN_16, PIN_MAGIC},
390 {25, GPIO_PORT_D, GPIO_PIN_17, PIN_MAGIC},
391 {26, GPIO_PORT_D, GPIO_PIN_18, PIN_MAGIC},
392 {27, GPIO_PORT_D, GPIO_PIN_19, PIN_MAGIC},
393 {28, GPIO_PORT_D, GPIO_PIN_20, PIN_MAGIC},
394 {29, GPIO_PORT_D, GPIO_PIN_21, PIN_MAGIC},
395 {30, 0, 0, 0},
396 {31, 0, 0, 0},
397 {32, 0, 0, 0},
398 {33, 0, 0, 0},
399 {34, 0, 0, 0},
400 {35, 0, 0, 0},
401 {36, 0, 0, 0},
402 {37, GPIO_PORT_E, GPIO_PIN_12, PIN_MAGIC},
403 {38, GPIO_PORT_E, GPIO_PIN_11, PIN_MAGIC},
404 {39, GPIO_PORT_E, GPIO_PIN_10, PIN_MAGIC},
405 {40, GPIO_PORT_E, GPIO_PIN_9, PIN_MAGIC},
406 {41, GPIO_PORT_E, GPIO_PIN_8, PIN_MAGIC},
407 {42, GPIO_PORT_E, GPIO_PIN_7, PIN_MAGIC},
408 {43, GPIO_PORT_E, GPIO_PIN_6, PIN_MAGIC},
409 {44, GPIO_PORT_E, GPIO_PIN_5, PIN_MAGIC},
410 {45, GPIO_PORT_E, GPIO_PIN_4, PIN_MAGIC},
411 {46, GPIO_PORT_E, GPIO_PIN_3, PIN_MAGIC},
412 {47, GPIO_PORT_E, GPIO_PIN_2, PIN_MAGIC},
413 {48, GPIO_PORT_E, GPIO_PIN_1, PIN_MAGIC},
414 {49, GPIO_PORT_E, GPIO_PIN_0, PIN_MAGIC},
415 {50, 0, 0, 0},
416 {51, 0, 0, 0},
417 {52, 0, 0, 0},
418 {53, GPIO_PORT_F, GPIO_PIN_5, PIN_MAGIC},
419 {54, GPIO_PORT_F, GPIO_PIN_4, PIN_MAGIC},
420 {55, GPIO_PORT_F, GPIO_PIN_3, PIN_MAGIC},
421 {56, GPIO_PORT_F, GPIO_PIN_2, PIN_MAGIC},
422 {57, GPIO_PORT_F, GPIO_PIN_1, PIN_MAGIC},
423 {58, GPIO_PORT_F, GPIO_PIN_0, PIN_MAGIC},
424 {59, GPIO_PORT_C, GPIO_PIN_0, PIN_MAGIC},
425 {60, GPIO_PORT_C, GPIO_PIN_1, PIN_MAGIC},
426 {61, GPIO_PORT_C, GPIO_PIN_2, PIN_MAGIC},
427 {62, GPIO_PORT_C, GPIO_PIN_3, PIN_MAGIC},
428 {63, GPIO_PORT_A, GPIO_PIN_3, PIN_MAGIC},
429 {64, GPIO_PORT_A, GPIO_PIN_2, PIN_MAGIC},
430 {65, GPIO_PORT_A, GPIO_PIN_1, PIN_MAGIC},
431 {66, GPIO_PORT_A, GPIO_PIN_0, PIN_MAGIC},
432 };
433
pin_mode(struct rt_device * dev,rt_base_t pin,rt_uint8_t mode)434 static void pin_mode(struct rt_device *dev, rt_base_t pin, rt_uint8_t mode)
435 {
436 if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
437 {
438 LOG_E("pin:%d value wrongful", pin);
439 return;
440 }
441
442 gpio_set_func(pin_index[pin].pin_port, pin_index[pin].pin, mode);
443 }
444
pin_write(struct rt_device * dev,rt_base_t pin,rt_uint8_t value)445 static void pin_write(struct rt_device *dev, rt_base_t pin, rt_uint8_t value)
446 {
447 if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
448 {
449 LOG_E("pin:%d value wrongful", pin);
450 return;
451 }
452
453 gpio_set_value(pin_index[pin].pin_port, pin_index[pin].pin, value);
454 }
455
pin_read(struct rt_device * device,rt_base_t pin)456 static rt_ssize_t pin_read(struct rt_device *device, rt_base_t pin)
457 {
458 if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
459 {
460 LOG_E("pin:%d value wrongful", pin);
461 return -RT_EINVAL;
462 }
463
464 return gpio_get_value(pin_index[pin].pin_port, pin_index[pin].pin);
465 }
466
pin_attach_irq(struct rt_device * device,rt_base_t pin,rt_uint8_t mode,void (* hdr)(void * args),void * args)467 static rt_err_t pin_attach_irq(struct rt_device *device, rt_base_t pin, rt_uint8_t mode, void (*hdr)(void *args), void *args)
468 {
469 if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
470 {
471 LOG_E("pin:%d value wrongful", pin);
472 return -RT_ERROR;
473 }
474
475 gpio_set_irq_callback(pin_index[pin].pin_port, pin_index[pin].pin, hdr, args);
476 gpio_set_irq_type(pin_index[pin].pin_port, pin_index[pin].pin, mode);
477 return RT_EOK;
478 }
pin_detach_irq(struct rt_device * device,rt_base_t pin)479 static rt_err_t pin_detach_irq(struct rt_device *device, rt_base_t pin)
480 {
481 if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
482 {
483 LOG_E("pin:%d value wrongful", pin);
484 return -RT_ERROR;
485 }
486
487 gpio_clear_irq_callback(pin_index[pin].pin_port, pin_index[pin].pin);
488
489 return RT_EOK;
490 }
491
pin_irq_enable(struct rt_device * device,rt_base_t pin,rt_uint8_t enabled)492 rt_err_t pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled)
493 {
494 if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC))
495 {
496 LOG_E("pin:%d value wrongful", pin);
497 return -RT_ERROR;
498 }
499
500 if (enabled)
501 gpio_irq_enable(pin_index[pin].pin_port, pin_index[pin].pin);
502 else
503 gpio_irq_disable(pin_index[pin].pin_port, pin_index[pin].pin);
504
505 return RT_EOK;
506 }
507
508 /*
509 ID GPIO ID GPIO ID GPIO ID GPIO ID GPIO ID GPIO ID GPIO
510 6 PD0 13 PD7 21 PD14 29 PD21 43 PE6 53 PF5 60 PC1
511 7 PD1 14 PD8 23 PD15 37 PE12 44 PE5 54 PF4 61 PC2
512 8 PD2 15 PD9 24 PD16 38 PE11 45 PE4 55 PF3 62 PC3
513 9 PD3 16 PD10 25 PD17 39 PE10 46 PE3 56 PF2 63 PA3
514 10 PD4 17 PD11 26 PD18 40 PE9 47 PE2 57 PF1 64 PA2
515 11 PD5 18 PD12 27 PD19 41 PE8 48 PE1 58 PF0 65 PA1
516 12 PD6 19 PD13 28 PD20 42 PE7 49 PE0 59 PC0 66 PA0
517 */
518
519 static const struct rt_pin_ops ops =
520 {
521 pin_mode,
522 pin_write,
523 pin_read,
524 pin_attach_irq,
525 pin_detach_irq,
526 pin_irq_enable,
527 RT_NULL,
528 };
529 #endif
530
rt_hw_gpio_init(void)531 int rt_hw_gpio_init(void)
532 {
533 #ifdef RT_USING_PIN
534 rt_device_pin_register("gpio", &ops, RT_NULL);
535 #endif
536 /* install ISR */
537 rt_hw_interrupt_install(PIOD_INTERRUPT, gpio_irq_handler, &_g_gpio_irq_tbl[GPIO_PORT_D], "gpiod_irq");
538 rt_hw_interrupt_umask(PIOD_INTERRUPT);
539
540 rt_hw_interrupt_install(PIOE_INTERRUPT, gpio_irq_handler, &_g_gpio_irq_tbl[GPIO_PORT_E], "gpioe_irq");
541 rt_hw_interrupt_umask(PIOE_INTERRUPT);
542
543 rt_hw_interrupt_install(PIOF_INTERRUPT, gpio_irq_handler, &_g_gpio_irq_tbl[GPIO_PORT_F], "gpiof_irq");
544 rt_hw_interrupt_umask(PIOF_INTERRUPT);
545
546 return 0;
547 }
548 INIT_DEVICE_EXPORT(rt_hw_gpio_init);
549