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  * 2021-08-15     Jonas        first version
9  */
10 
11 #include <board.h>
12 #include "drv_gpio.h"
13 
14 #ifdef RT_USING_PIN
15 
16 #define PIN_NUM(port, no)           (((((port) & 0xFu) << 4) | ((no) & 0xFu)))
17 #define PIN_PORT(pin)               ((uint8_t)(((pin) >> 4) & 0xFu))
18 #define PIN_NO(pin)                 ((uint8_t)((pin) & 0xFu))
19 
20 #define PIN_HKPORTSOURCE(pin)       ((uint8_t)(((pin) & 0xF0u) >> 4))
21 #define PIN_HKPINSOURCE(pin)        ((uint8_t)((pin) & 0xFu))
22 #define PIN_HKPORT(pin)             ((GPIO_TypeDef *)(GPIOA_BASE + (0x400u * PIN_PORT(pin))))
23 #define PIN_HKPIN(pin)              ((uint16_t)(1u << PIN_NO(pin)))
24 #if defined(GPIOZ)
25     #define __HK32_PORT_MAX 12u
26 #elif defined(GPIOK)
27     #define __HK32_PORT_MAX 11u
28 #elif defined(GPIOJ)
29     #define __HK32_PORT_MAX 10u
30 #elif defined(GPIOI)
31     #define __HK32_PORT_MAX 9u
32 #elif defined(GPIOH)
33     #define __HK32_PORT_MAX 8u
34 #elif defined(GPIOG)
35     #define __HK32_PORT_MAX 7u
36 #elif defined(GPIOF)
37     #define __HK32_PORT_MAX 6u
38 #elif defined(GPIOE)
39     #define __HK32_PORT_MAX 5u
40 #elif defined(GPIOD)
41     #define __HK32_PORT_MAX 4u
42 #elif defined(GPIOC)
43     #define __HK32_PORT_MAX 3u
44 #elif defined(GPIOB)
45     #define __HK32_PORT_MAX 2u
46 #elif defined(GPIOA)
47     #define __HK32_PORT_MAX 1u
48 #else
49     #define __HK32_PORT_MAX 0u
50     #error Unsupported HK32 GPIO peripheral.
51 #endif
52 #define PIN_HKPORT_MAX __HK32_PORT_MAX
53 
54 static const struct pin_irq_map pin_irq_map[] =
55 {
56     {GPIO_Pin_0,  EXTI_Line0,  EXTI0_1_IRQn},
57     {GPIO_Pin_1,  EXTI_Line1,  EXTI0_1_IRQn},
58     {GPIO_Pin_2,  EXTI_Line2,  EXTI2_3_IRQn},
59     {GPIO_Pin_3,  EXTI_Line3,  EXTI2_3_IRQn},
60     {GPIO_Pin_4,  EXTI_Line4,  EXTI4_15_IRQn},
61     {GPIO_Pin_5,  EXTI_Line5,  EXTI4_15_IRQn},
62     {GPIO_Pin_6,  EXTI_Line6,  EXTI4_15_IRQn},
63     {GPIO_Pin_7,  EXTI_Line7,  EXTI4_15_IRQn},
64     {GPIO_Pin_8,  EXTI_Line8,  EXTI4_15_IRQn},
65     {GPIO_Pin_9,  EXTI_Line9,  EXTI4_15_IRQn},
66     {GPIO_Pin_10, EXTI_Line10, EXTI4_15_IRQn},
67     {GPIO_Pin_11, EXTI_Line11, EXTI4_15_IRQn},
68     {GPIO_Pin_12, EXTI_Line12, EXTI4_15_IRQn},
69     {GPIO_Pin_13, EXTI_Line13, EXTI4_15_IRQn},
70     {GPIO_Pin_14, EXTI_Line14, EXTI4_15_IRQn},
71     {GPIO_Pin_15, EXTI_Line15, EXTI4_15_IRQn},
72 };
73 
74 static struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
75 {
76     {-1, 0, RT_NULL, RT_NULL},
77     {-1, 0, RT_NULL, RT_NULL},
78     {-1, 0, RT_NULL, RT_NULL},
79     {-1, 0, RT_NULL, RT_NULL},
80     {-1, 0, RT_NULL, RT_NULL},
81     {-1, 0, RT_NULL, RT_NULL},
82     {-1, 0, RT_NULL, RT_NULL},
83     {-1, 0, RT_NULL, RT_NULL},
84     {-1, 0, RT_NULL, RT_NULL},
85     {-1, 0, RT_NULL, RT_NULL},
86     {-1, 0, RT_NULL, RT_NULL},
87     {-1, 0, RT_NULL, RT_NULL},
88     {-1, 0, RT_NULL, RT_NULL},
89     {-1, 0, RT_NULL, RT_NULL},
90     {-1, 0, RT_NULL, RT_NULL},
91     {-1, 0, RT_NULL, RT_NULL},
92 };
93 static uint32_t pin_irq_enable_mask = 0;
94 
95 #define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
96 
hk32_pin_write(rt_device_t dev,rt_base_t pin,rt_uint8_t value)97 static void hk32_pin_write(rt_device_t dev, rt_base_t pin, rt_uint8_t value)
98 {
99     GPIO_TypeDef *gpio_port;
100     uint16_t gpio_pin;
101     if (PIN_PORT(pin) < PIN_HKPORT_MAX)
102     {
103         gpio_port    =  PIN_HKPORT(pin);
104         gpio_pin     =  PIN_HKPIN(pin);
105         GPIO_WriteBit(gpio_port, gpio_pin, (BitAction)value);
106     }
107 }
108 
hk32_pin_read(rt_device_t dev,rt_base_t pin)109 static rt_int8_t hk32_pin_read(rt_device_t dev, rt_base_t pin)
110 {
111     GPIO_TypeDef *gpio_port;
112     uint16_t gpio_pin;
113     rt_int8_t value;
114 
115     value = PIN_LOW;
116 
117     if (PIN_PORT(pin) < PIN_HKPORT_MAX)
118     {
119         gpio_port    =  PIN_HKPORT(pin);
120         gpio_pin     =  PIN_HKPIN(pin);
121         value = GPIO_ReadInputDataBit(gpio_port, gpio_pin);
122     }
123     else
124     {
125         return -RT_ENOSYS;
126     }
127 
128     return value;
129 }
130 
hk32_pin_mode(rt_device_t dev,rt_base_t pin,rt_uint8_t mode)131 static void hk32_pin_mode(rt_device_t dev, rt_base_t pin, rt_uint8_t mode)
132 {
133     GPIO_InitTypeDef GPIO_InitStruct;
134 
135     GPIO_TypeDef *gpio_port;
136     uint16_t gpio_pin;
137     if (PIN_PORT(pin) < PIN_HKPORT_MAX)
138     {
139         gpio_port    =  PIN_HKPORT(pin);
140         gpio_pin     =  PIN_HKPIN(pin);
141     }
142     else
143     {
144         return;
145     }
146 
147     /* Configure GPIO_InitStructure */
148     GPIO_StructInit(&GPIO_InitStruct);
149     GPIO_InitStruct.GPIO_Pin = gpio_pin;
150     GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
151     GPIO_InitStruct.GPIO_OType = GPIO_OType_PP;
152     GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_NOPULL;
153     GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
154 
155     if (mode == PIN_MODE_OUTPUT)
156     {
157         /* output setting */
158         GPIO_InitStruct.GPIO_Mode = GPIO_Mode_OUT;
159     }
160     else if (mode == PIN_MODE_INPUT)
161     {
162         /* input setting: not pull. */
163         GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
164     }
165     else if (mode == PIN_MODE_INPUT_PULLUP)
166     {
167         /* input setting: pull up. */
168         GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
169         GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
170     }
171     else if (mode == PIN_MODE_INPUT_PULLDOWN)
172     {
173         /* input setting: pull down. */
174         GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN;
175         GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
176     }
177     else if (mode == PIN_MODE_OUTPUT_OD)
178     {
179         /* output setting: od. */
180         GPIO_InitStruct.GPIO_OType = GPIO_OType_OD;
181     }
182 
183     GPIO_Init(gpio_port, &GPIO_InitStruct);
184 }
185 
bit2bitno(rt_uint32_t bit)186 rt_inline rt_int32_t bit2bitno(rt_uint32_t bit)
187 {
188     int i;
189     for (i = 0; i < 32; i++)
190     {
191         if ((0x01 << i) == bit)
192         {
193             return i;
194         }
195     }
196     return -1;
197 }
198 
get_pin_irq_map(uint32_t pinbit)199 rt_inline const struct pin_irq_map *get_pin_irq_map(uint32_t pinbit)
200 {
201     rt_int32_t mapindex = bit2bitno(pinbit);
202     if (mapindex < 0 || mapindex >= ITEM_NUM(pin_irq_map))
203     {
204         return RT_NULL;
205     }
206     return &pin_irq_map[mapindex];
207 };
208 
hk32_pin_attach_irq(struct rt_device * device,rt_base_t pin,rt_uint8_t mode,void (* hdr)(void * args),void * args)209 static rt_err_t hk32_pin_attach_irq(struct rt_device *device, rt_base_t pin,
210                                     rt_uint8_t mode, void (*hdr)(void *args), void *args)
211 {
212     rt_base_t level;
213     rt_int32_t irqindex = -1;
214 
215     uint16_t gpio_pin;
216     if (PIN_PORT(pin) < PIN_HKPORT_MAX)
217     {
218         gpio_pin     =  PIN_HKPIN(pin);
219     }
220     else
221     {
222         return -RT_ENOSYS;
223     }
224     irqindex = bit2bitno(gpio_pin);
225     if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
226     {
227         return -RT_ENOSYS;
228     }
229 
230     level = rt_hw_interrupt_disable();
231     if (pin_irq_hdr_tab[irqindex].pin == pin &&
232             pin_irq_hdr_tab[irqindex].hdr == hdr &&
233             pin_irq_hdr_tab[irqindex].mode == mode &&
234             pin_irq_hdr_tab[irqindex].args == args)
235     {
236         rt_hw_interrupt_enable(level);
237         return RT_EOK;
238     }
239     if (pin_irq_hdr_tab[irqindex].pin != -1)
240     {
241         rt_hw_interrupt_enable(level);
242         return -RT_EBUSY;
243     }
244     pin_irq_hdr_tab[irqindex].pin = pin;
245     pin_irq_hdr_tab[irqindex].hdr = hdr;
246     pin_irq_hdr_tab[irqindex].mode = mode;
247     pin_irq_hdr_tab[irqindex].args = args;
248     rt_hw_interrupt_enable(level);
249 
250     return RT_EOK;
251 }
252 
hk32_pin_dettach_irq(struct rt_device * device,rt_base_t pin)253 static rt_err_t hk32_pin_dettach_irq(struct rt_device *device, rt_base_t pin)
254 {
255     rt_base_t level;
256     rt_int32_t irqindex = -1;
257     uint16_t gpio_pin;
258     if (PIN_PORT(pin) < PIN_HKPORT_MAX)
259     {
260         gpio_pin     =  PIN_HKPIN(pin);
261     }
262     else
263     {
264         return -RT_ENOSYS;
265     }
266     irqindex = bit2bitno(gpio_pin);
267     if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
268     {
269         return -RT_ENOSYS;
270     }
271 
272     level = rt_hw_interrupt_disable();
273     if (pin_irq_hdr_tab[irqindex].pin == -1)
274     {
275         rt_hw_interrupt_enable(level);
276         return RT_EOK;
277     }
278     pin_irq_hdr_tab[irqindex].pin = -1;
279     pin_irq_hdr_tab[irqindex].hdr = RT_NULL;
280     pin_irq_hdr_tab[irqindex].mode = 0;
281     pin_irq_hdr_tab[irqindex].args = RT_NULL;
282     rt_hw_interrupt_enable(level);
283 
284     return RT_EOK;
285 }
286 
hk32_pin_irq_enable(struct rt_device * device,rt_base_t pin,rt_uint8_t enabled)287 static rt_err_t hk32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
288                                     rt_uint8_t enabled)
289 {
290     GPIO_InitTypeDef GPIO_InitStruct;
291     EXTI_InitTypeDef EXTI_InitStruct;
292     NVIC_InitTypeDef NVIC_InitStruct;
293     const struct pin_irq_map *irqmap;
294     rt_base_t level;
295     rt_int32_t irqindex = -1;
296 
297     GPIO_TypeDef *gpio_port;
298     uint16_t gpio_pin;
299     if (PIN_PORT(pin) < PIN_HKPORT_MAX)
300     {
301         gpio_port    =  PIN_HKPORT(pin);
302         gpio_pin     =  PIN_HKPIN(pin);
303     }
304     else
305     {
306         return -RT_ENOSYS;
307     }
308 
309     if (enabled == PIN_IRQ_ENABLE)
310     {
311         irqindex = bit2bitno(gpio_pin);
312         if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
313         {
314             return -RT_ENOSYS;
315         }
316 
317         level = rt_hw_interrupt_disable();
318 
319         if (pin_irq_hdr_tab[irqindex].pin == -1)
320         {
321             rt_hw_interrupt_enable(level);
322             return -RT_ENOSYS;
323         }
324 
325         irqmap = &pin_irq_map[irqindex];
326 
327         /* Configure GPIO_InitStructure */
328         GPIO_StructInit(&GPIO_InitStruct);
329         EXTI_StructInit(&EXTI_InitStruct);
330         GPIO_InitStruct.GPIO_Pin = irqmap->pinbit;
331         GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
332         EXTI_InitStruct.EXTI_Line = irqmap->pinbit;
333         EXTI_InitStruct.EXTI_Mode = EXTI_Mode_Interrupt;
334         EXTI_InitStruct.EXTI_LineCmd = ENABLE;
335         switch (pin_irq_hdr_tab[irqindex].mode)
336         {
337         case PIN_IRQ_MODE_RISING:
338             GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_DOWN;
339             EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising;
340             break;
341         case PIN_IRQ_MODE_FALLING:
342             GPIO_InitStruct.GPIO_PuPd = GPIO_PuPd_UP;
343             EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Falling;
344             break;
345         case PIN_IRQ_MODE_RISING_FALLING:
346             EXTI_InitStruct.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
347             break;
348         }
349         GPIO_Init(gpio_port, &GPIO_InitStruct);
350         SYSCFG_EXTILineConfig(PIN_HKPORTSOURCE(pin), PIN_HKPINSOURCE(pin));
351         EXTI_Init(&EXTI_InitStruct);
352         NVIC_InitStruct.NVIC_IRQChannel = irqmap->irqno;
353         NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
354         NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
355         NVIC_Init(&NVIC_InitStruct);
356         pin_irq_enable_mask |= irqmap->pinbit;
357 
358         rt_hw_interrupt_enable(level);
359     }
360     else if (enabled == PIN_IRQ_DISABLE)
361     {
362         irqmap = get_pin_irq_map(gpio_pin);
363         if (irqmap == RT_NULL)
364         {
365             return -RT_ENOSYS;
366         }
367 
368         level = rt_hw_interrupt_disable();
369 
370         pin_irq_enable_mask &= ~irqmap->pinbit;
371 
372         NVIC_InitStruct.NVIC_IRQChannelCmd = DISABLE;
373         NVIC_InitStruct.NVIC_IRQChannelPriority = 3;
374 
375         if ((irqmap->pinbit >= GPIO_Pin_0) && (irqmap->pinbit <= GPIO_Pin_1))
376         {
377             if (!(pin_irq_enable_mask & (GPIO_Pin_0 | GPIO_Pin_1)))
378             {
379                 NVIC_InitStruct.NVIC_IRQChannel = irqmap->irqno;
380             }
381         }
382         else if ((irqmap->pinbit >= GPIO_Pin_2) && \
383                  (irqmap->pinbit <= GPIO_Pin_3))
384         {
385             if (!(pin_irq_enable_mask & (GPIO_Pin_2 | GPIO_Pin_3)))
386             {
387                 NVIC_InitStruct.NVIC_IRQChannel = irqmap->irqno;
388             }
389         }
390         else if ((irqmap->pinbit >= GPIO_Pin_4) && \
391                  (irqmap->pinbit <= GPIO_Pin_15))
392         {
393             if (!(pin_irq_enable_mask & (GPIO_Pin_4  | GPIO_Pin_5  | GPIO_Pin_6  | \
394                                          GPIO_Pin_7  | GPIO_Pin_8  | GPIO_Pin_9  | \
395                                          GPIO_Pin_10 | GPIO_Pin_11 | GPIO_Pin_12 | \
396                                          GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15)))
397             {
398                 NVIC_InitStruct.NVIC_IRQChannel = irqmap->irqno;
399             }
400         }
401         else
402         {
403             NVIC_InitStruct.NVIC_IRQChannel = irqmap->irqno;
404         }
405 
406         NVIC_Init(&NVIC_InitStruct);
407         rt_hw_interrupt_enable(level);
408     }
409     else
410     {
411         return -RT_ENOSYS;
412     }
413 
414     return RT_EOK;
415 }
416 const static struct rt_pin_ops _hk32_pin_ops =
417 {
418     hk32_pin_mode,
419     hk32_pin_write,
420     hk32_pin_read,
421     hk32_pin_attach_irq,
422     hk32_pin_dettach_irq,
423     hk32_pin_irq_enable,
424     RT_NULL,
425 };
426 
pin_irq_hdr(int irqno)427 rt_inline void pin_irq_hdr(int irqno)
428 {
429     EXTI_ClearITPendingBit(pin_irq_map[irqno].lineno);
430     if (pin_irq_hdr_tab[irqno].hdr)
431     {
432         pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args);
433     }
434 }
435 
GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)436 void GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
437 {
438     pin_irq_hdr(bit2bitno(GPIO_Pin));
439 }
440 
EXTI0_1_IRQHandler(void)441 void EXTI0_1_IRQHandler(void)
442 {
443     rt_interrupt_enter();
444     if (RESET != EXTI_GetITStatus(EXTI_Line0))
445     {
446         GPIO_EXTI_IRQHandler(GPIO_Pin_0);
447     }
448     if (RESET != EXTI_GetITStatus(EXTI_Line1))
449     {
450         GPIO_EXTI_IRQHandler(GPIO_Pin_1);
451     }
452     rt_interrupt_leave();
453 }
454 
EXTI2_3_IRQHandler(void)455 void EXTI2_3_IRQHandler(void)
456 {
457     rt_interrupt_enter();
458     if (RESET != EXTI_GetITStatus(EXTI_Line2))
459     {
460         GPIO_EXTI_IRQHandler(GPIO_Pin_2);
461     }
462     if (RESET != EXTI_GetITStatus(EXTI_Line3))
463     {
464         GPIO_EXTI_IRQHandler(GPIO_Pin_3);
465     }
466     rt_interrupt_leave();
467 }
468 
EXTI4_15_IRQHandler(void)469 void EXTI4_15_IRQHandler(void)
470 {
471     rt_interrupt_enter();
472     if (RESET != EXTI_GetITStatus(EXTI_Line4))
473     {
474         GPIO_EXTI_IRQHandler(GPIO_Pin_4);
475     }
476     if (RESET != EXTI_GetITStatus(EXTI_Line5))
477     {
478         GPIO_EXTI_IRQHandler(GPIO_Pin_5);
479     }
480     if (RESET != EXTI_GetITStatus(EXTI_Line6))
481     {
482         GPIO_EXTI_IRQHandler(GPIO_Pin_6);
483     }
484     if (RESET != EXTI_GetITStatus(EXTI_Line7))
485     {
486         GPIO_EXTI_IRQHandler(GPIO_Pin_7);
487     }
488     if (RESET != EXTI_GetITStatus(EXTI_Line8))
489     {
490         GPIO_EXTI_IRQHandler(GPIO_Pin_8);
491     }
492     if (RESET != EXTI_GetITStatus(EXTI_Line9))
493     {
494         GPIO_EXTI_IRQHandler(GPIO_Pin_9);
495     }
496     if (RESET != EXTI_GetITStatus(EXTI_Line10))
497     {
498         GPIO_EXTI_IRQHandler(GPIO_Pin_10);
499     }
500     if (RESET != EXTI_GetITStatus(EXTI_Line11))
501     {
502         GPIO_EXTI_IRQHandler(GPIO_Pin_11);
503     }
504     if (RESET != EXTI_GetITStatus(EXTI_Line12))
505     {
506         GPIO_EXTI_IRQHandler(GPIO_Pin_12);
507     }
508     if (RESET != EXTI_GetITStatus(EXTI_Line13))
509     {
510         GPIO_EXTI_IRQHandler(GPIO_Pin_13);
511     }
512     if (RESET != EXTI_GetITStatus(EXTI_Line14))
513     {
514         GPIO_EXTI_IRQHandler(GPIO_Pin_14);
515     }
516     if (RESET != EXTI_GetITStatus(EXTI_Line15))
517     {
518         GPIO_EXTI_IRQHandler(GPIO_Pin_15);
519     }
520     rt_interrupt_leave();
521 }
522 
rt_hw_pin_init(void)523 int rt_hw_pin_init(void)
524 {
525     RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
526 #ifdef GPIOA
527     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA, ENABLE);
528 #endif
529 #ifdef GPIOB
530     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
531 #endif
532 #ifdef GPIOC
533     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
534 #endif
535 #ifdef GPIOD
536     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOD, ENABLE);
537 #endif
538 #ifdef GPIOE
539     RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOE, ENABLE);
540 #endif
541 #ifdef GPIOF
542     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOF, ENABLE);
543 #endif
544 #ifdef GPIOG
545     RCC_APB2PeriphClockCmd(RCC_APB2PERIPH_GPIOG, ENABLE);
546 #endif
547 
548     return rt_device_pin_register("pin", &_hk32_pin_ops, RT_NULL);
549 }
550 
551 INIT_BOARD_EXPORT(rt_hw_pin_init);
552 
553 #endif /* RT_USING_PIN */
554