drv_gpio.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  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-26 AisinoChip first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include <rtconfig.h>
  14. #include "board.h"
  15. #ifdef RT_USING_PIN
  16. #include <rtdevice.h>
  17. #define __ACM32_PIN(index, gpio, gpio_index) \
  18. { \
  19. index, GPIO##gpio, GPIO_PIN_##gpio_index \
  20. }
  21. #define __ACM32_PIN_RESERVE \
  22. { \
  23. -1, 0, 0 \
  24. }
  25. /* ACM32 GPIO driver */
  26. struct pin_index
  27. {
  28. int index;
  29. enum_GPIOx_t gpio;
  30. uint32_t pin;
  31. };
  32. struct pin_irq_map
  33. {
  34. rt_uint16_t line;
  35. EXTI_HandleTypeDef handle;
  36. };
  37. static const struct pin_index pins[] =
  38. {
  39. #if defined(BSP_USING_GPIO1)
  40. __ACM32_PIN(0, A, 0),
  41. __ACM32_PIN(1, A, 1),
  42. __ACM32_PIN(2, A, 2),
  43. __ACM32_PIN(3, A, 3),
  44. __ACM32_PIN(4, A, 4),
  45. __ACM32_PIN(5, A, 5),
  46. __ACM32_PIN(6, A, 6),
  47. __ACM32_PIN(7, A, 7),
  48. __ACM32_PIN(8, A, 8),
  49. __ACM32_PIN(9, A, 9),
  50. __ACM32_PIN(10, A, 10),
  51. __ACM32_PIN(11, A, 11),
  52. __ACM32_PIN(12, A, 12),
  53. __ACM32_PIN(13, A, 13),
  54. __ACM32_PIN(14, A, 14),
  55. __ACM32_PIN(15, A, 15),
  56. __ACM32_PIN(16, B, 0),
  57. __ACM32_PIN(17, B, 1),
  58. __ACM32_PIN(18, B, 2),
  59. __ACM32_PIN(19, B, 3),
  60. __ACM32_PIN(20, B, 4),
  61. __ACM32_PIN(21, B, 5),
  62. __ACM32_PIN(22, B, 6),
  63. __ACM32_PIN(23, B, 7),
  64. __ACM32_PIN(24, B, 8),
  65. __ACM32_PIN(25, B, 9),
  66. __ACM32_PIN(26, B, 10),
  67. __ACM32_PIN(27, B, 11),
  68. __ACM32_PIN(28, B, 12),
  69. __ACM32_PIN(29, B, 13),
  70. __ACM32_PIN(30, B, 14),
  71. __ACM32_PIN(31, B, 15),
  72. #if defined(BSP_USING_GPIO2)
  73. __ACM32_PIN(32, C, 0),
  74. __ACM32_PIN(33, C, 1),
  75. __ACM32_PIN(34, C, 2),
  76. __ACM32_PIN(35, C, 3),
  77. __ACM32_PIN(36, C, 4),
  78. __ACM32_PIN(37, C, 5),
  79. __ACM32_PIN(38, C, 6),
  80. __ACM32_PIN(39, C, 7),
  81. __ACM32_PIN(40, C, 8),
  82. __ACM32_PIN(41, C, 9),
  83. __ACM32_PIN(42, C, 10),
  84. __ACM32_PIN(43, C, 11),
  85. __ACM32_PIN(44, C, 12),
  86. __ACM32_PIN(45, C, 13),
  87. __ACM32_PIN(46, C, 14),
  88. __ACM32_PIN(47, C, 15),
  89. __ACM32_PIN(48, D, 0),
  90. __ACM32_PIN(49, D, 1),
  91. __ACM32_PIN(50, D, 2),
  92. __ACM32_PIN(51, D, 3),
  93. __ACM32_PIN(52, D, 4),
  94. __ACM32_PIN(53, D, 5),
  95. __ACM32_PIN(54, D, 6),
  96. __ACM32_PIN(55, D, 7),
  97. __ACM32_PIN(56, D, 8),
  98. __ACM32_PIN(57, D, 9),
  99. __ACM32_PIN(58, D, 10),
  100. __ACM32_PIN(59, D, 11),
  101. __ACM32_PIN(60, D, 12),
  102. __ACM32_PIN(61, D, 13),
  103. __ACM32_PIN(62, D, 14),
  104. __ACM32_PIN(63, D, 15),
  105. #endif /* defined(BSP_USING_GPIO2) */
  106. #endif /* defined(BSP_USING_GPIO1) */
  107. };
  108. static struct pin_irq_map pin_irq_map[] =
  109. {
  110. {EXTI_LINE_0, {0}},
  111. {EXTI_LINE_1, {0}},
  112. {EXTI_LINE_2, {0}},
  113. {EXTI_LINE_3, {0}},
  114. {EXTI_LINE_4, {0}},
  115. {EXTI_LINE_5, {0}},
  116. {EXTI_LINE_6, {0}},
  117. {EXTI_LINE_7, {0}},
  118. {EXTI_LINE_8, {0}},
  119. {EXTI_LINE_9, {0}},
  120. {EXTI_LINE_10, {0}},
  121. {EXTI_LINE_11, {0}},
  122. {EXTI_LINE_12, {0}},
  123. {EXTI_LINE_13, {0}},
  124. {EXTI_LINE_14, {0}},
  125. {EXTI_LINE_15, {0}},
  126. };
  127. static struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
  128. {
  129. {-1, 0, RT_NULL, RT_NULL},
  130. {-1, 0, RT_NULL, RT_NULL},
  131. {-1, 0, RT_NULL, RT_NULL},
  132. {-1, 0, RT_NULL, RT_NULL},
  133. {-1, 0, RT_NULL, RT_NULL},
  134. {-1, 0, RT_NULL, RT_NULL},
  135. {-1, 0, RT_NULL, RT_NULL},
  136. {-1, 0, RT_NULL, RT_NULL},
  137. {-1, 0, RT_NULL, RT_NULL},
  138. {-1, 0, RT_NULL, RT_NULL},
  139. {-1, 0, RT_NULL, RT_NULL},
  140. {-1, 0, RT_NULL, RT_NULL},
  141. {-1, 0, RT_NULL, RT_NULL},
  142. {-1, 0, RT_NULL, RT_NULL},
  143. {-1, 0, RT_NULL, RT_NULL},
  144. {-1, 0, RT_NULL, RT_NULL},
  145. };
  146. static uint32_t pin_irq_enable_mask = 0;
  147. #define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
  148. static const struct pin_index *get_pin(uint8_t pin)
  149. {
  150. const struct pin_index *index;
  151. if (pin < ITEM_NUM(pins))
  152. {
  153. index = &pins[pin];
  154. if (index->index == -1)
  155. index = RT_NULL;
  156. }
  157. else
  158. {
  159. index = RT_NULL;
  160. }
  161. return index;
  162. };
  163. static void acm32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
  164. {
  165. const struct pin_index *index;
  166. index = get_pin(pin);
  167. if (index == RT_NULL)
  168. {
  169. return;
  170. }
  171. HAL_GPIO_WritePin(index->gpio, index->pin, (enum_PinState_t)value);
  172. }
  173. static int acm32_pin_read(rt_device_t dev, rt_base_t pin)
  174. {
  175. int value;
  176. const struct pin_index *index;
  177. value = PIN_LOW;
  178. index = get_pin(pin);
  179. if (index == RT_NULL)
  180. {
  181. return value;
  182. }
  183. value = HAL_GPIO_ReadPin(index->gpio, index->pin);
  184. return value;
  185. }
  186. static void acm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
  187. {
  188. const struct pin_index *index;
  189. GPIO_InitTypeDef GPIO_InitStruct;
  190. index = get_pin(pin);
  191. if (index == RT_NULL)
  192. {
  193. return;
  194. }
  195. /* Configure GPIO_InitStructure */
  196. GPIO_InitStruct.Pin = index->pin;
  197. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  198. GPIO_InitStruct.Pull = GPIO_NOPULL;
  199. GPIO_InitStruct.Alternate = GPIO_FUNCTION_0;
  200. if (mode == PIN_MODE_OUTPUT)
  201. {
  202. /* output setting */
  203. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  204. GPIO_InitStruct.Pull = GPIO_NOPULL;
  205. }
  206. else if (mode == PIN_MODE_INPUT)
  207. {
  208. /* input setting: not pull. */
  209. GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  210. GPIO_InitStruct.Pull = GPIO_NOPULL;
  211. }
  212. else if (mode == PIN_MODE_INPUT_PULLUP)
  213. {
  214. /* input setting: pull up. */
  215. GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  216. GPIO_InitStruct.Pull = GPIO_PULLUP;
  217. }
  218. else if (mode == PIN_MODE_INPUT_PULLDOWN)
  219. {
  220. /* input setting: pull down. */
  221. GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  222. GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  223. }
  224. else if (mode == PIN_MODE_OUTPUT_OD)
  225. {
  226. /* output setting: od. */
  227. GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
  228. GPIO_InitStruct.Pull = GPIO_NOPULL;
  229. }
  230. /* special PIN process */
  231. __HAL_RTC_PC13_DIGIT();
  232. HAL_GPIO_Init(index->gpio, &GPIO_InitStruct);
  233. }
  234. #define PIN2INDEX(pin) ((pin) % 16)
  235. static rt_err_t acm32_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
  236. rt_uint32_t mode, void (*hdr)(void *args), void *args)
  237. {
  238. const struct pin_index *index;
  239. rt_base_t level;
  240. rt_int32_t irqindex = -1;
  241. index = get_pin(pin);
  242. if (index == RT_NULL)
  243. {
  244. return RT_ENOSYS;
  245. }
  246. irqindex = PIN2INDEX(pin);
  247. level = rt_hw_interrupt_disable();
  248. if (pin_irq_hdr_tab[irqindex].pin == pin &&
  249. pin_irq_hdr_tab[irqindex].hdr == hdr &&
  250. pin_irq_hdr_tab[irqindex].mode == mode &&
  251. pin_irq_hdr_tab[irqindex].args == args)
  252. {
  253. rt_hw_interrupt_enable(level);
  254. return RT_EOK;
  255. }
  256. if (pin_irq_hdr_tab[irqindex].pin != -1)
  257. {
  258. rt_hw_interrupt_enable(level);
  259. return RT_EBUSY;
  260. }
  261. pin_irq_hdr_tab[irqindex].pin = pin;
  262. pin_irq_hdr_tab[irqindex].hdr = hdr;
  263. pin_irq_hdr_tab[irqindex].mode = mode;
  264. pin_irq_hdr_tab[irqindex].args = args;
  265. rt_hw_interrupt_enable(level);
  266. return RT_EOK;
  267. }
  268. static rt_err_t acm32_pin_dettach_irq(struct rt_device *device, rt_int32_t pin)
  269. {
  270. const struct pin_index *index;
  271. rt_base_t level;
  272. rt_int32_t irqindex = -1;
  273. index = get_pin(pin);
  274. if (index == RT_NULL)
  275. {
  276. return RT_ENOSYS;
  277. }
  278. irqindex = PIN2INDEX(pin);
  279. level = rt_hw_interrupt_disable();
  280. if (pin_irq_hdr_tab[irqindex].pin == -1)
  281. {
  282. rt_hw_interrupt_enable(level);
  283. return RT_EOK;
  284. }
  285. pin_irq_hdr_tab[irqindex].pin = -1;
  286. pin_irq_hdr_tab[irqindex].hdr = RT_NULL;
  287. pin_irq_hdr_tab[irqindex].mode = 0;
  288. pin_irq_hdr_tab[irqindex].args = RT_NULL;
  289. rt_hw_interrupt_enable(level);
  290. return RT_EOK;
  291. }
  292. static rt_err_t acm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
  293. rt_uint32_t enabled)
  294. {
  295. const struct pin_index *index;
  296. struct pin_irq_map *irqmap;
  297. rt_base_t level;
  298. rt_int32_t irqindex = -1;
  299. GPIO_InitTypeDef GPIO_InitStruct;
  300. index = get_pin(pin);
  301. if (index == RT_NULL)
  302. {
  303. return RT_ENOSYS;
  304. }
  305. irqindex = PIN2INDEX(pin);
  306. irqmap = &pin_irq_map[irqindex];
  307. if (enabled == PIN_IRQ_ENABLE)
  308. {
  309. level = rt_hw_interrupt_disable();
  310. if (pin_irq_hdr_tab[irqindex].pin == -1)
  311. {
  312. rt_hw_interrupt_enable(level);
  313. return RT_ENOSYS;
  314. }
  315. /* Configure GPIO_InitStructure */
  316. GPIO_InitStruct.Pin = index->pin;
  317. GPIO_InitStruct.Alternate = GPIO_FUNCTION_0;
  318. GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
  319. irqmap->handle.u32_Line = irqmap->line;
  320. irqmap->handle.u32_Mode = EXTI_MODE_INTERRUPT;
  321. switch (pin_irq_hdr_tab[irqindex].mode)
  322. {
  323. case PIN_IRQ_MODE_RISING:
  324. GPIO_InitStruct.Pull = GPIO_PULLDOWN;
  325. irqmap->handle.u32_Trigger = EXTI_TRIGGER_RISING;
  326. break;
  327. case PIN_IRQ_MODE_FALLING:
  328. GPIO_InitStruct.Pull = GPIO_PULLUP;
  329. irqmap->handle.u32_Trigger = EXTI_TRIGGER_FALLING;
  330. break;
  331. case PIN_IRQ_MODE_RISING_FALLING:
  332. GPIO_InitStruct.Pull = GPIO_NOPULL;
  333. irqmap->handle.u32_Trigger = EXTI_TRIGGER_RISING_FALLING;
  334. break;
  335. }
  336. HAL_GPIO_Init(index->gpio, &GPIO_InitStruct);
  337. irqmap->handle.u32_GPIOSel = pin / 16;
  338. HAL_EXTI_SetConfigLine(&irqmap->handle);
  339. pin_irq_enable_mask |= 1 << irqindex;
  340. rt_hw_interrupt_enable(level);
  341. }
  342. else if (enabled == PIN_IRQ_DISABLE)
  343. {
  344. if ((pin_irq_enable_mask & (1 << irqindex)) == 0)
  345. {
  346. return RT_ENOSYS;
  347. }
  348. level = rt_hw_interrupt_disable();
  349. EXTI->IENR &= ~irqmap->line;
  350. EXTI->EENR &= ~irqmap->line;
  351. rt_hw_interrupt_enable(level);
  352. }
  353. else
  354. {
  355. return -RT_ENOSYS;
  356. }
  357. return RT_EOK;
  358. }
  359. const static struct rt_pin_ops _acm32_pin_ops =
  360. {
  361. acm32_pin_mode,
  362. acm32_pin_write,
  363. acm32_pin_read,
  364. acm32_pin_attach_irq,
  365. acm32_pin_dettach_irq,
  366. acm32_pin_irq_enable,
  367. };
  368. rt_inline void pin_irq_hdr(int irqno)
  369. {
  370. if (pin_irq_hdr_tab[irqno].hdr)
  371. {
  372. pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args);
  373. }
  374. }
  375. int rt_hw_pin_init(void)
  376. {
  377. return rt_device_pin_register("pin", &_acm32_pin_ops, RT_NULL);
  378. }
  379. INIT_BOARD_EXPORT(rt_hw_pin_init);
  380. void EXTI_IRQHandler(void)
  381. {
  382. /* enter interrupt */
  383. rt_interrupt_enter();
  384. for (int i = 0; i < 16; i++)
  385. {
  386. if (EXTI->PDR & pin_irq_map[i].line)
  387. {
  388. EXTI->PDR = pin_irq_map[i].line;
  389. pin_irq_hdr(i);
  390. break;
  391. }
  392. }
  393. /* leave interrupt */
  394. rt_interrupt_leave();
  395. }
  396. #endif /* RT_USING_PIN */