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