1
0

drv_gpio.c 12 KB

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