drv_gpio.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481
  1. /*
  2. * Copyright (C) 2020, Huada Semiconductor Co., Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2020-10-30 CDT first version
  9. */
  10. #include <rtthread.h>
  11. #include "rthw.h"
  12. #ifdef RT_USING_PIN
  13. #include "drv_gpio.h"
  14. #include "drv_irq.h"
  15. #define GPIO_PIN_INDEX(pin) ((uint8_t)((pin) & 0x0F))
  16. #define GPIO_PORT(pin) ((uint8_t)(((pin) >> 4) & 0x0F))
  17. #define GPIO_PIN(pin) ((uint16_t)(0x01U << GPIO_PIN_INDEX(pin)))
  18. #define PIN_NUM(port, pin) (((((port) & 0x0F) << 4) | ((pin) & 0x0F)))
  19. #define PIN_MAX_NUM ((GPIO_PORT_I * 16) + (__CLZ(__RBIT(GPIO_PIN_13))) + 1)
  20. #define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
  21. static void exint0_irq_handler(void);
  22. static void exint1_irq_handler(void);
  23. static void exint2_irq_handler(void);
  24. static void exint3_irq_handler(void);
  25. static void exint4_irq_handler(void);
  26. static void exint5_irq_handler(void);
  27. static void exint6_irq_handler(void);
  28. static void exint7_irq_handler(void);
  29. static void exint8_irq_handler(void);
  30. static void exint9_irq_handler(void);
  31. static void exint10_irq_handler(void);
  32. static void exint11_irq_handler(void);
  33. static void exint12_irq_handler(void);
  34. static void exint13_irq_handler(void);
  35. static void exint14_irq_handler(void);
  36. static void exint15_irq_handler(void);
  37. struct hc32_pin_irq_map
  38. {
  39. rt_uint16_t pinbit;
  40. struct hc32_irq_config irq_config;
  41. func_ptr_t irq_callback;
  42. };
  43. #ifndef HC32_PIN_CONFIG
  44. #define HC32_PIN_CONFIG(pin, irq, src, irq_info) \
  45. { \
  46. .pinbit = pin, \
  47. .irq_callback = irq, \
  48. .irq_config = irq_info, \
  49. .irq_config.int_src = src, \
  50. }
  51. #endif /* HC32_PIN_CONFIG */
  52. static struct hc32_pin_irq_map pin_irq_map[] =
  53. {
  54. HC32_PIN_CONFIG(GPIO_PIN_00, exint0_irq_handler, INT_PORT_EIRQ0, EXINT0_IRQ_CONFIG),
  55. HC32_PIN_CONFIG(GPIO_PIN_01, exint1_irq_handler, INT_PORT_EIRQ1, EXINT1_IRQ_CONFIG),
  56. HC32_PIN_CONFIG(GPIO_PIN_02, exint2_irq_handler, INT_PORT_EIRQ2, EXINT2_IRQ_CONFIG),
  57. HC32_PIN_CONFIG(GPIO_PIN_03, exint3_irq_handler, INT_PORT_EIRQ3, EXINT3_IRQ_CONFIG),
  58. HC32_PIN_CONFIG(GPIO_PIN_04, exint4_irq_handler, INT_PORT_EIRQ4, EXINT4_IRQ_CONFIG),
  59. HC32_PIN_CONFIG(GPIO_PIN_05, exint5_irq_handler, INT_PORT_EIRQ5, EXINT5_IRQ_CONFIG),
  60. HC32_PIN_CONFIG(GPIO_PIN_06, exint6_irq_handler, INT_PORT_EIRQ6, EXINT6_IRQ_CONFIG),
  61. HC32_PIN_CONFIG(GPIO_PIN_07, exint7_irq_handler, INT_PORT_EIRQ7, EXINT7_IRQ_CONFIG),
  62. HC32_PIN_CONFIG(GPIO_PIN_08, exint8_irq_handler, INT_PORT_EIRQ8, EXINT8_IRQ_CONFIG),
  63. HC32_PIN_CONFIG(GPIO_PIN_09, exint9_irq_handler, INT_PORT_EIRQ9, EXINT9_IRQ_CONFIG),
  64. HC32_PIN_CONFIG(GPIO_PIN_10, exint10_irq_handler, INT_PORT_EIRQ10, EXINT10_IRQ_CONFIG),
  65. HC32_PIN_CONFIG(GPIO_PIN_11, exint11_irq_handler, INT_PORT_EIRQ11, EXINT11_IRQ_CONFIG),
  66. HC32_PIN_CONFIG(GPIO_PIN_12, exint12_irq_handler, INT_PORT_EIRQ12, EXINT12_IRQ_CONFIG),
  67. HC32_PIN_CONFIG(GPIO_PIN_13, exint13_irq_handler, INT_PORT_EIRQ13, EXINT13_IRQ_CONFIG),
  68. HC32_PIN_CONFIG(GPIO_PIN_14, exint14_irq_handler, INT_PORT_EIRQ14, EXINT14_IRQ_CONFIG),
  69. HC32_PIN_CONFIG(GPIO_PIN_15, exint15_irq_handler, INT_PORT_EIRQ15, EXINT15_IRQ_CONFIG),
  70. };
  71. struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
  72. {
  73. {-1, 0, RT_NULL, RT_NULL},
  74. {-1, 0, RT_NULL, RT_NULL},
  75. {-1, 0, RT_NULL, RT_NULL},
  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. };
  90. static void pin_irq_handler(rt_uint16_t pinbit)
  91. {
  92. rt_int32_t irqindex = -1;
  93. if (Set == EXINT_GetExIntSrc(pinbit))
  94. {
  95. EXINT_ClrExIntSrc(pinbit);
  96. irqindex = __CLZ(__RBIT(pinbit));
  97. if (pin_irq_hdr_tab[irqindex].hdr)
  98. {
  99. pin_irq_hdr_tab[irqindex].hdr(pin_irq_hdr_tab[irqindex].args);
  100. }
  101. }
  102. }
  103. static void exint0_irq_handler(void)
  104. {
  105. rt_interrupt_enter();
  106. pin_irq_handler(pin_irq_map[0].pinbit);
  107. rt_interrupt_leave();
  108. }
  109. static void exint1_irq_handler(void)
  110. {
  111. rt_interrupt_enter();
  112. pin_irq_handler(pin_irq_map[1].pinbit);
  113. rt_interrupt_leave();
  114. }
  115. static void exint2_irq_handler(void)
  116. {
  117. rt_interrupt_enter();
  118. pin_irq_handler(pin_irq_map[2].pinbit);
  119. rt_interrupt_leave();
  120. }
  121. static void exint3_irq_handler(void)
  122. {
  123. rt_interrupt_enter();
  124. pin_irq_handler(pin_irq_map[3].pinbit);
  125. rt_interrupt_leave();
  126. }
  127. static void exint4_irq_handler(void)
  128. {
  129. rt_interrupt_enter();
  130. pin_irq_handler(pin_irq_map[4].pinbit);
  131. rt_interrupt_leave();
  132. }
  133. static void exint5_irq_handler(void)
  134. {
  135. rt_interrupt_enter();
  136. pin_irq_handler(pin_irq_map[5].pinbit);
  137. rt_interrupt_leave();
  138. }
  139. static void exint6_irq_handler(void)
  140. {
  141. rt_interrupt_enter();
  142. pin_irq_handler(pin_irq_map[6].pinbit);
  143. rt_interrupt_leave();
  144. }
  145. static void exint7_irq_handler(void)
  146. {
  147. rt_interrupt_enter();
  148. pin_irq_handler(pin_irq_map[7].pinbit);
  149. rt_interrupt_leave();
  150. }
  151. static void exint8_irq_handler(void)
  152. {
  153. rt_interrupt_enter();
  154. pin_irq_handler(pin_irq_map[8].pinbit);
  155. rt_interrupt_leave();
  156. }
  157. static void exint9_irq_handler(void)
  158. {
  159. rt_interrupt_enter();
  160. pin_irq_handler(pin_irq_map[9].pinbit);
  161. rt_interrupt_leave();
  162. }
  163. static void exint10_irq_handler(void)
  164. {
  165. rt_interrupt_enter();
  166. pin_irq_handler(pin_irq_map[10].pinbit);
  167. rt_interrupt_leave();
  168. }
  169. static void exint11_irq_handler(void)
  170. {
  171. rt_interrupt_enter();
  172. pin_irq_handler(pin_irq_map[11].pinbit);
  173. rt_interrupt_leave();
  174. }
  175. static void exint12_irq_handler(void)
  176. {
  177. rt_interrupt_enter();
  178. pin_irq_handler(pin_irq_map[12].pinbit);
  179. rt_interrupt_leave();
  180. }
  181. static void exint13_irq_handler(void)
  182. {
  183. rt_interrupt_enter();
  184. pin_irq_handler(pin_irq_map[13].pinbit);
  185. rt_interrupt_leave();
  186. }
  187. static void exint14_irq_handler(void)
  188. {
  189. rt_interrupt_enter();
  190. pin_irq_handler(pin_irq_map[14].pinbit);
  191. rt_interrupt_leave();
  192. }
  193. static void exint15_irq_handler(void)
  194. {
  195. rt_interrupt_enter();
  196. pin_irq_handler(pin_irq_map[15].pinbit);
  197. rt_interrupt_leave();
  198. }
  199. static void hc32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
  200. {
  201. uint8_t gpio_port;
  202. uint16_t gpio_pin;
  203. if (pin < PIN_MAX_NUM)
  204. {
  205. gpio_port = GPIO_PORT(pin);
  206. gpio_pin = GPIO_PIN(pin);
  207. if (PIN_LOW == value)
  208. {
  209. GPIO_ResetPins(gpio_port, gpio_pin);
  210. }
  211. else
  212. {
  213. GPIO_SetPins(gpio_port, gpio_pin);
  214. }
  215. }
  216. }
  217. static int hc32_pin_read(rt_device_t dev, rt_base_t pin)
  218. {
  219. uint8_t gpio_port;
  220. uint16_t gpio_pin;
  221. int value = PIN_LOW;
  222. if (pin < PIN_MAX_NUM)
  223. {
  224. gpio_port = GPIO_PORT(pin);
  225. gpio_pin = GPIO_PIN(pin);
  226. if (Pin_Reset == GPIO_ReadInputPins(gpio_port, gpio_pin))
  227. {
  228. value = PIN_LOW;
  229. }
  230. else
  231. {
  232. value = PIN_HIGH;
  233. }
  234. }
  235. return value;
  236. }
  237. static void hc32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
  238. {
  239. uint8_t gpio_port;
  240. uint16_t gpio_pin;
  241. stc_gpio_init_t stcGpioInit;
  242. if (pin >= PIN_MAX_NUM)
  243. {
  244. return;
  245. }
  246. GPIO_StructInit(&stcGpioInit);
  247. switch (mode)
  248. {
  249. case PIN_MODE_OUTPUT:
  250. stcGpioInit.u16PinDir = PIN_DIR_OUT;
  251. stcGpioInit.u16PinOType = PIN_OTYPE_CMOS;
  252. break;
  253. case PIN_MODE_INPUT:
  254. stcGpioInit.u16PinDir = PIN_DIR_IN;
  255. break;
  256. case PIN_MODE_INPUT_PULLUP:
  257. stcGpioInit.u16PinDir = PIN_DIR_IN;
  258. stcGpioInit.u16PullUp = PIN_PU_ON;
  259. break;
  260. case PIN_MODE_INPUT_PULLDOWN:
  261. stcGpioInit.u16PinDir = PIN_DIR_IN;
  262. stcGpioInit.u16PullUp = PIN_PU_OFF;
  263. break;
  264. case PIN_MODE_OUTPUT_OD:
  265. stcGpioInit.u16PinDir = PIN_DIR_OUT;
  266. stcGpioInit.u16PinOType = PIN_OTYPE_NMOS;
  267. break;
  268. default:
  269. break;
  270. }
  271. gpio_port = GPIO_PORT(pin);
  272. gpio_pin = GPIO_PIN(pin);
  273. GPIO_Init(gpio_port, gpio_pin, &stcGpioInit);
  274. }
  275. static void gpio_irq_config(uint8_t u8Port, uint16_t u16Pin, uint16_t u16ExInt)
  276. {
  277. __IO uint16_t *PCRx;
  278. uint16_t pin_num;
  279. pin_num = __CLZ(__RBIT(u16Pin));
  280. PCRx = (__IO uint16_t *)((uint32_t)(&M4_GPIO->PCRA0) + ((uint32_t)u8Port * 0x40UL) + (pin_num * 4UL));
  281. MODIFY_REG16(*PCRx, GPIO_PCR_INTE, u16ExInt);
  282. }
  283. static rt_err_t hc32_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
  284. rt_uint32_t mode, void (*hdr)(void *args), void *args)
  285. {
  286. rt_base_t level;
  287. rt_int32_t irqindex = -1;
  288. if (pin >= PIN_MAX_NUM)
  289. {
  290. return -RT_ENOSYS;
  291. }
  292. irqindex = GPIO_PIN_INDEX(pin);
  293. if (irqindex >= ITEM_NUM(pin_irq_map))
  294. {
  295. return RT_ENOSYS;
  296. }
  297. level = rt_hw_interrupt_disable();
  298. if (pin_irq_hdr_tab[irqindex].pin == pin &&
  299. pin_irq_hdr_tab[irqindex].hdr == hdr &&
  300. pin_irq_hdr_tab[irqindex].mode == mode &&
  301. pin_irq_hdr_tab[irqindex].args == args)
  302. {
  303. rt_hw_interrupt_enable(level);
  304. return RT_EOK;
  305. }
  306. if (pin_irq_hdr_tab[irqindex].pin != -1)
  307. {
  308. rt_hw_interrupt_enable(level);
  309. return RT_EBUSY;
  310. }
  311. pin_irq_hdr_tab[irqindex].pin = pin;
  312. pin_irq_hdr_tab[irqindex].hdr = hdr;
  313. pin_irq_hdr_tab[irqindex].mode = mode;
  314. pin_irq_hdr_tab[irqindex].args = args;
  315. rt_hw_interrupt_enable(level);
  316. return RT_EOK;
  317. }
  318. static rt_err_t hc32_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
  319. {
  320. rt_base_t level;
  321. rt_int32_t irqindex = -1;
  322. if (pin >= PIN_MAX_NUM)
  323. {
  324. return -RT_ENOSYS;
  325. }
  326. irqindex = GPIO_PIN_INDEX(pin);
  327. if (irqindex >= ITEM_NUM(pin_irq_map))
  328. {
  329. return RT_ENOSYS;
  330. }
  331. level = rt_hw_interrupt_disable();
  332. if (pin_irq_hdr_tab[irqindex].pin == -1)
  333. {
  334. rt_hw_interrupt_enable(level);
  335. return RT_EOK;
  336. }
  337. pin_irq_hdr_tab[irqindex].pin = -1;
  338. pin_irq_hdr_tab[irqindex].hdr = RT_NULL;
  339. pin_irq_hdr_tab[irqindex].mode = 0;
  340. pin_irq_hdr_tab[irqindex].args = RT_NULL;
  341. rt_hw_interrupt_enable(level);
  342. return RT_EOK;
  343. }
  344. static rt_err_t hc32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
  345. {
  346. struct hc32_pin_irq_map *irq_map;
  347. rt_base_t level;
  348. rt_int32_t irqindex = -1;
  349. uint16_t gpio_pin;
  350. stc_exint_init_t stcExintInit;
  351. if ((pin >= PIN_MAX_NUM) || ((PIN_IRQ_ENABLE != enabled) && (PIN_IRQ_DISABLE != enabled)))
  352. {
  353. return -RT_ENOSYS;
  354. }
  355. irqindex = GPIO_PIN_INDEX(pin);
  356. if (irqindex >= ITEM_NUM(pin_irq_map))
  357. {
  358. return RT_ENOSYS;
  359. }
  360. irq_map = &pin_irq_map[irqindex];
  361. gpio_pin = GPIO_PIN(pin);
  362. if (enabled == PIN_IRQ_ENABLE)
  363. {
  364. level = rt_hw_interrupt_disable();
  365. if (pin_irq_hdr_tab[irqindex].pin == -1)
  366. {
  367. rt_hw_interrupt_enable(level);
  368. return RT_ENOSYS;
  369. }
  370. /* Exint config */
  371. EXINT_StructInit(&stcExintInit);
  372. switch (pin_irq_hdr_tab[irqindex].mode)
  373. {
  374. case PIN_IRQ_MODE_RISING:
  375. stcExintInit.u32ExIntLvl = EXINT_TRIGGER_RISING;
  376. break;
  377. case PIN_IRQ_MODE_FALLING:
  378. stcExintInit.u32ExIntLvl = EXINT_TRIGGER_FALLING;
  379. break;
  380. case PIN_IRQ_MODE_RISING_FALLING:
  381. stcExintInit.u32ExIntLvl = EXINT_TRIGGER_BOTH;
  382. break;
  383. case PIN_IRQ_MODE_LOW_LEVEL:
  384. stcExintInit.u32ExIntLvl = EXINT_TRIGGER_LOW;
  385. break;
  386. }
  387. stcExintInit.u32ExIntCh = gpio_pin;
  388. stcExintInit.u32ExIntFAE = EXINT_FILTER_A_ON;
  389. stcExintInit.u32ExIntFAClk = EXINT_FACLK_HCLK_DIV8;
  390. EXINT_Init(&stcExintInit);
  391. /* IRQ sign-in */
  392. hc32_install_irq_handler(&irq_map->irq_config, irq_map->irq_callback, RT_FALSE);
  393. NVIC_EnableIRQ(irq_map->irq_config.irq);
  394. gpio_irq_config(GPIO_PORT(pin), gpio_pin, PIN_EXINT_ON);
  395. rt_hw_interrupt_enable(level);
  396. }
  397. else
  398. {
  399. level = rt_hw_interrupt_disable();
  400. gpio_irq_config(GPIO_PORT(pin), gpio_pin, PIN_EXINT_OFF);
  401. NVIC_DisableIRQ(irq_map->irq_config.irq);
  402. rt_hw_interrupt_enable(level);
  403. }
  404. return RT_EOK;
  405. }
  406. static const struct rt_pin_ops pin_ops =
  407. {
  408. hc32_pin_mode,
  409. hc32_pin_write,
  410. hc32_pin_read,
  411. hc32_pin_attach_irq,
  412. hc32_pin_detach_irq,
  413. hc32_pin_irq_enable,
  414. };
  415. int rt_hw_pin_init(void)
  416. {
  417. return rt_device_pin_register("pin", &pin_ops, RT_NULL);
  418. }
  419. INIT_BOARD_EXPORT(rt_hw_pin_init);
  420. #endif /* RT_USING_PIN */