drv_gpio.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538
  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-05 mazhiyuan first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <board.h>
  13. #include <rthw.h>
  14. #include <hal_gpio.h>
  15. #include <hal_exti.h>
  16. #include <hal_misc.h>
  17. #include <hal_rcc.h>
  18. #define MM32_PIN(index, rcc, gpio, gpio_index) \
  19. { \
  20. 0, RCC_##rcc##Periph_GPIO##gpio, GPIO##gpio, GPIO_Pin_##gpio_index, GPIO_PortSourceGPIO##gpio, GPIO_PinSource##gpio_index \
  21. }
  22. #define MM32_PIN_DEFAULT \
  23. { \
  24. -1, 0, 0, 0, 0, 0 \
  25. }
  26. /* MM32 GPIO driver */
  27. struct pin_index
  28. {
  29. int index;
  30. uint32_t rcc;
  31. GPIO_TypeDef *gpio;
  32. uint32_t pin;
  33. uint8_t port_source;
  34. uint8_t pin_source;
  35. };
  36. static const struct pin_index mm32_pin_map[] =
  37. {
  38. MM32_PIN_DEFAULT,
  39. MM32_PIN_DEFAULT,
  40. MM32_PIN(2, AHB, C, 13),
  41. MM32_PIN(3, AHB, C, 14),
  42. MM32_PIN(4, AHB, C, 15),
  43. MM32_PIN_DEFAULT,
  44. MM32_PIN_DEFAULT,
  45. MM32_PIN_DEFAULT,
  46. MM32_PIN_DEFAULT,
  47. MM32_PIN_DEFAULT,
  48. MM32_PIN(10, AHB, A, 0),
  49. MM32_PIN(11, AHB, A, 1),
  50. MM32_PIN(12, AHB, A, 2),
  51. MM32_PIN(13, AHB, A, 3),
  52. MM32_PIN(14, AHB, A, 4),
  53. MM32_PIN(15, AHB, A, 5),
  54. MM32_PIN(16, AHB, A, 6),
  55. MM32_PIN(17, AHB, A, 7),
  56. MM32_PIN(18, AHB, B, 0),
  57. MM32_PIN(19, AHB, B, 1),
  58. MM32_PIN(20, AHB, B, 2),
  59. MM32_PIN(21, AHB, B, 10),
  60. MM32_PIN(22, AHB, B, 11),
  61. MM32_PIN_DEFAULT,
  62. MM32_PIN_DEFAULT,
  63. MM32_PIN(25, AHB, B, 12),
  64. MM32_PIN(26, AHB, B, 13),
  65. MM32_PIN(27, AHB, B, 14),
  66. MM32_PIN(28, AHB, B, 15),
  67. MM32_PIN(29, AHB, A, 8),
  68. MM32_PIN(30, AHB, A, 9),
  69. MM32_PIN(31, AHB, A, 10),
  70. MM32_PIN(32, AHB, A, 11),
  71. MM32_PIN(33, AHB, A, 12),
  72. MM32_PIN(34, AHB, A, 13),
  73. MM32_PIN_DEFAULT,
  74. MM32_PIN_DEFAULT,
  75. MM32_PIN(37, AHB, A, 14),
  76. MM32_PIN(38, AHB, A, 15),
  77. MM32_PIN(39, AHB, B, 3),
  78. MM32_PIN(40, AHB, B, 4),
  79. MM32_PIN(41, AHB, B, 5),
  80. MM32_PIN(42, AHB, B, 6),
  81. MM32_PIN(43, AHB, B, 7),
  82. MM32_PIN_DEFAULT,
  83. MM32_PIN(45, AHB, B, 8),
  84. MM32_PIN(46, AHB, B, 9),
  85. MM32_PIN_DEFAULT,
  86. MM32_PIN_DEFAULT,
  87. };
  88. struct pin_irq_map
  89. {
  90. rt_uint16_t pinbit;
  91. rt_uint32_t irqbit;
  92. enum IRQn irqno;
  93. };
  94. const struct pin_irq_map mm32_pin_irq_map[] =
  95. {
  96. {GPIO_Pin_0, EXTI_Line0, EXTI0_IRQn},
  97. {GPIO_Pin_1, EXTI_Line1, EXTI1_IRQn},
  98. {GPIO_Pin_2, EXTI_Line2, EXTI2_IRQn},
  99. {GPIO_Pin_3, EXTI_Line3, EXTI3_IRQn},
  100. {GPIO_Pin_4, EXTI_Line4, EXTI4_IRQn},
  101. {GPIO_Pin_5, EXTI_Line5, EXTI9_5_IRQn},
  102. {GPIO_Pin_6, EXTI_Line6, EXTI9_5_IRQn},
  103. {GPIO_Pin_7, EXTI_Line7, EXTI9_5_IRQn},
  104. {GPIO_Pin_8, EXTI_Line8, EXTI9_5_IRQn},
  105. {GPIO_Pin_9, EXTI_Line9, EXTI9_5_IRQn},
  106. {GPIO_Pin_10, EXTI_Line10, EXTI15_10_IRQn},
  107. {GPIO_Pin_11, EXTI_Line11, EXTI15_10_IRQn},
  108. {GPIO_Pin_12, EXTI_Line12, EXTI15_10_IRQn},
  109. {GPIO_Pin_13, EXTI_Line13, EXTI15_10_IRQn},
  110. {GPIO_Pin_14, EXTI_Line14, EXTI15_10_IRQn},
  111. {GPIO_Pin_15, EXTI_Line15, EXTI15_10_IRQn},
  112. };
  113. struct rt_pin_irq_hdr mm32_pin_irq_hdr_tab[] =
  114. {
  115. {-1, 0, RT_NULL, RT_NULL},
  116. {-1, 0, RT_NULL, RT_NULL},
  117. {-1, 0, RT_NULL, RT_NULL},
  118. {-1, 0, RT_NULL, RT_NULL},
  119. {-1, 0, RT_NULL, RT_NULL},
  120. {-1, 0, RT_NULL, RT_NULL},
  121. {-1, 0, RT_NULL, RT_NULL},
  122. {-1, 0, RT_NULL, RT_NULL},
  123. {-1, 0, RT_NULL, RT_NULL},
  124. {-1, 0, RT_NULL, RT_NULL},
  125. {-1, 0, RT_NULL, RT_NULL},
  126. {-1, 0, RT_NULL, RT_NULL},
  127. {-1, 0, RT_NULL, RT_NULL},
  128. {-1, 0, RT_NULL, RT_NULL},
  129. {-1, 0, RT_NULL, RT_NULL},
  130. {-1, 0, RT_NULL, RT_NULL},
  131. };
  132. #define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
  133. const struct pin_index *get_pin(uint8_t pin)
  134. {
  135. const struct pin_index *index;
  136. if (pin < ITEM_NUM(mm32_pin_map))
  137. {
  138. index = &mm32_pin_map[pin];
  139. if (index->gpio == 0)
  140. index = RT_NULL;
  141. }
  142. else
  143. {
  144. index = RT_NULL;
  145. }
  146. return index;
  147. };
  148. void mm32_pin_write(rt_device_t dev, rt_base_t pin, rt_uint8_t value)
  149. {
  150. const struct pin_index *index;
  151. index = get_pin(pin);
  152. if (index == RT_NULL)
  153. {
  154. return;
  155. }
  156. if (value == PIN_LOW)
  157. {
  158. GPIO_ResetBits(index->gpio, index->pin);
  159. }
  160. else
  161. {
  162. GPIO_SetBits(index->gpio, index->pin);
  163. }
  164. }
  165. rt_ssize_t mm32_pin_read(rt_device_t dev, rt_base_t pin)
  166. {
  167. rt_ssize_t value;
  168. const struct pin_index *index;
  169. value = PIN_LOW;
  170. index = get_pin(pin);
  171. if (index == RT_NULL)
  172. {
  173. return PIN_LOW;
  174. }
  175. if (GPIO_ReadInputDataBit(index->gpio, index->pin) == Bit_RESET)
  176. {
  177. value = PIN_LOW;
  178. }
  179. else
  180. {
  181. value = PIN_HIGH;
  182. }
  183. return value;
  184. }
  185. void mm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_uint8_t mode)
  186. {
  187. const struct pin_index *index;
  188. GPIO_InitTypeDef GPIO_InitStructure;
  189. index = get_pin(pin);
  190. if (index == RT_NULL)
  191. {
  192. return;
  193. }
  194. /* GPIO Periph clock enable */
  195. RCC_AHBPeriphClockCmd(index->rcc, ENABLE);
  196. /* Configure GPIO_InitStructure */
  197. GPIO_InitStructure.GPIO_Pin = index->pin;
  198. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  199. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  200. if (mode == PIN_MODE_OUTPUT)
  201. {
  202. /* output setting */
  203. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  204. }
  205. else if (mode == PIN_MODE_OUTPUT_OD)
  206. {
  207. /* output setting: od. */
  208. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  209. }
  210. else if (mode == PIN_MODE_INPUT)
  211. {
  212. /* input setting: not pull. */
  213. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
  214. }
  215. else if (mode == PIN_MODE_INPUT_PULLUP)
  216. {
  217. /* input setting: pull up. */
  218. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  219. }
  220. else
  221. {
  222. /* input setting:default. */
  223. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  224. }
  225. GPIO_Init(index->gpio, &GPIO_InitStructure);
  226. }
  227. rt_inline rt_int32_t bit2bitno(rt_uint32_t bit)
  228. {
  229. int i;
  230. for (i = 0; i < 32; i++)
  231. {
  232. if ((0x01 << i) == bit)
  233. {
  234. return i;
  235. }
  236. }
  237. return -1;
  238. }
  239. rt_inline const struct pin_irq_map *get_pin_irq_map(uint32_t pinbit)
  240. {
  241. rt_int32_t mapindex = bit2bitno(pinbit);
  242. if (mapindex < 0 || mapindex >= ITEM_NUM(mm32_pin_irq_map))
  243. {
  244. return RT_NULL;
  245. }
  246. return &mm32_pin_irq_map[mapindex];
  247. };
  248. rt_err_t mm32_pin_attach_irq(struct rt_device *device, rt_base_t pin,
  249. rt_uint8_t mode, void (*hdr)(void *args), void *args)
  250. {
  251. const struct pin_index *index;
  252. rt_base_t level;
  253. rt_int32_t irqindex = -1;
  254. index = get_pin(pin);
  255. if (index == RT_NULL)
  256. {
  257. return -RT_ENOSYS;
  258. }
  259. irqindex = bit2bitno(index->pin);
  260. if (irqindex < 0 || irqindex >= ITEM_NUM(mm32_pin_irq_map))
  261. {
  262. return -RT_ENOSYS;
  263. }
  264. level = rt_hw_interrupt_disable();
  265. if (mm32_pin_irq_hdr_tab[irqindex].pin == pin &&
  266. mm32_pin_irq_hdr_tab[irqindex].hdr == hdr &&
  267. mm32_pin_irq_hdr_tab[irqindex].mode == mode &&
  268. mm32_pin_irq_hdr_tab[irqindex].args == args)
  269. {
  270. rt_hw_interrupt_enable(level);
  271. return RT_EOK;
  272. }
  273. if (mm32_pin_irq_hdr_tab[irqindex].pin != -1)
  274. {
  275. rt_hw_interrupt_enable(level);
  276. return -RT_EBUSY;
  277. }
  278. mm32_pin_irq_hdr_tab[irqindex].pin = pin;
  279. mm32_pin_irq_hdr_tab[irqindex].hdr = hdr;
  280. mm32_pin_irq_hdr_tab[irqindex].mode = mode;
  281. mm32_pin_irq_hdr_tab[irqindex].args = args;
  282. rt_hw_interrupt_enable(level);
  283. return RT_EOK;
  284. }
  285. rt_err_t mm32_pin_detach_irq(struct rt_device *device, rt_base_t pin)
  286. {
  287. const struct pin_index *index;
  288. rt_base_t level;
  289. rt_int32_t irqindex = -1;
  290. index = get_pin(pin);
  291. if (index == RT_NULL)
  292. {
  293. return -RT_ENOSYS;
  294. }
  295. irqindex = bit2bitno(index->pin);
  296. if (irqindex < 0 || irqindex >= ITEM_NUM(mm32_pin_irq_map))
  297. {
  298. return -RT_ENOSYS;
  299. }
  300. level = rt_hw_interrupt_disable();
  301. if (mm32_pin_irq_hdr_tab[irqindex].pin == -1)
  302. {
  303. rt_hw_interrupt_enable(level);
  304. return RT_EOK;
  305. }
  306. mm32_pin_irq_hdr_tab[irqindex].pin = -1;
  307. mm32_pin_irq_hdr_tab[irqindex].hdr = RT_NULL;
  308. mm32_pin_irq_hdr_tab[irqindex].mode = 0;
  309. mm32_pin_irq_hdr_tab[irqindex].args = RT_NULL;
  310. rt_hw_interrupt_enable(level);
  311. return RT_EOK;
  312. }
  313. rt_err_t mm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
  314. rt_uint8_t enabled)
  315. {
  316. const struct pin_index *index;
  317. const struct pin_irq_map *irqmap;
  318. rt_base_t level;
  319. rt_int32_t irqindex = -1;
  320. GPIO_InitTypeDef GPIO_InitStructure;
  321. NVIC_InitTypeDef NVIC_InitStructure;
  322. EXTI_InitTypeDef EXTI_InitStructure;
  323. index = get_pin(pin);
  324. if (index == RT_NULL)
  325. {
  326. return -RT_ENOSYS;
  327. }
  328. if (enabled == PIN_IRQ_ENABLE)
  329. {
  330. irqindex = bit2bitno(index->pin);
  331. if (irqindex < 0 || irqindex >= ITEM_NUM(mm32_pin_irq_map))
  332. {
  333. return -RT_ENOSYS;
  334. }
  335. level = rt_hw_interrupt_disable();
  336. if (mm32_pin_irq_hdr_tab[irqindex].pin == -1)
  337. {
  338. rt_hw_interrupt_enable(level);
  339. return -RT_ENOSYS;
  340. }
  341. irqmap = &mm32_pin_irq_map[irqindex];
  342. /* GPIO Periph clock enable */
  343. RCC_APB2PeriphClockCmd(index->rcc, ENABLE);
  344. /* Configure GPIO_InitStructure */
  345. GPIO_InitStructure.GPIO_Pin = index->pin;
  346. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  347. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  348. GPIO_Init(index->gpio, &GPIO_InitStructure);
  349. NVIC_InitStructure.NVIC_IRQChannel = irqmap->irqno;
  350. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  351. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  352. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  353. NVIC_Init(&NVIC_InitStructure);
  354. EXTI_InitStructure.EXTI_Line = irqmap->irqbit;
  355. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  356. switch (mm32_pin_irq_hdr_tab[irqindex].mode)
  357. {
  358. case PIN_IRQ_MODE_RISING:
  359. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  360. break;
  361. case PIN_IRQ_MODE_FALLING:
  362. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  363. break;
  364. case PIN_IRQ_MODE_RISING_FALLING:
  365. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
  366. break;
  367. }
  368. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  369. EXTI_Init(&EXTI_InitStructure);
  370. rt_hw_interrupt_enable(level);
  371. }
  372. else if (enabled == PIN_IRQ_DISABLE)
  373. {
  374. irqmap = get_pin_irq_map(index->pin);
  375. if (irqmap == RT_NULL)
  376. {
  377. return -RT_ENOSYS;
  378. }
  379. EXTI_InitStructure.EXTI_Line = irqmap->irqbit;
  380. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  381. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  382. EXTI_InitStructure.EXTI_LineCmd = DISABLE;
  383. EXTI_Init(&EXTI_InitStructure);
  384. }
  385. else
  386. {
  387. return -RT_ENOSYS;
  388. }
  389. return RT_EOK;
  390. }
  391. const static struct rt_pin_ops _mm32_pin_ops =
  392. {
  393. mm32_pin_mode,
  394. mm32_pin_write,
  395. mm32_pin_read,
  396. mm32_pin_attach_irq,
  397. mm32_pin_detach_irq,
  398. mm32_pin_irq_enable,
  399. RT_NULL,
  400. };
  401. int rt_hw_pin_init(void)
  402. {
  403. int result;
  404. result = rt_device_pin_register("pin", &_mm32_pin_ops, RT_NULL);
  405. return result;
  406. }
  407. INIT_BOARD_EXPORT(rt_hw_pin_init);
  408. rt_inline void pin_irq_hdr(int irqno)
  409. {
  410. EXTI_ClearITPendingBit(mm32_pin_irq_map[irqno].irqbit);
  411. if (mm32_pin_irq_hdr_tab[irqno].hdr)
  412. {
  413. mm32_pin_irq_hdr_tab[irqno].hdr(mm32_pin_irq_hdr_tab[irqno].args);
  414. }
  415. }
  416. void EXTI0_IRQHandler(void)
  417. {
  418. /* enter interrupt */
  419. rt_interrupt_enter();
  420. pin_irq_hdr(0);
  421. /* leave interrupt */
  422. rt_interrupt_leave();
  423. }
  424. void EXTI1_IRQHandler(void)
  425. {
  426. /* enter interrupt */
  427. rt_interrupt_enter();
  428. pin_irq_hdr(1);
  429. /* leave interrupt */
  430. rt_interrupt_leave();
  431. }
  432. void EXTI2_IRQHandler(void)
  433. {
  434. /* enter interrupt */
  435. rt_interrupt_enter();
  436. pin_irq_hdr(2);
  437. /* leave interrupt */
  438. rt_interrupt_leave();
  439. }
  440. void EXTI3_IRQHandler(void)
  441. {
  442. /* enter interrupt */
  443. rt_interrupt_enter();
  444. pin_irq_hdr(3);
  445. /* leave interrupt */
  446. rt_interrupt_leave();
  447. }
  448. void EXTI4_IRQHandler(void)
  449. {
  450. /* enter interrupt */
  451. rt_interrupt_enter();
  452. pin_irq_hdr(4);
  453. /* leave interrupt */
  454. rt_interrupt_leave();
  455. }
  456. void EXTI9_5_IRQHandler(void)
  457. {
  458. /* enter interrupt */
  459. rt_interrupt_enter();
  460. if (EXTI_GetITStatus(EXTI_Line5) != RESET)
  461. {
  462. pin_irq_hdr(5);
  463. }
  464. if (EXTI_GetITStatus(EXTI_Line6) != RESET)
  465. {
  466. pin_irq_hdr(6);
  467. }
  468. if (EXTI_GetITStatus(EXTI_Line7) != RESET)
  469. {
  470. pin_irq_hdr(7);
  471. }
  472. if (EXTI_GetITStatus(EXTI_Line8) != RESET)
  473. {
  474. pin_irq_hdr(8);
  475. }
  476. if (EXTI_GetITStatus(EXTI_Line9) != RESET)
  477. {
  478. pin_irq_hdr(9);
  479. }
  480. /* leave interrupt */
  481. rt_interrupt_leave();
  482. }
  483. void EXTI15_10_IRQHandler(void)
  484. {
  485. /* enter interrupt */
  486. rt_interrupt_enter();
  487. if (EXTI_GetITStatus(EXTI_Line10) != RESET)
  488. {
  489. pin_irq_hdr(10);
  490. }
  491. if (EXTI_GetITStatus(EXTI_Line11) != RESET)
  492. {
  493. pin_irq_hdr(11);
  494. }
  495. if (EXTI_GetITStatus(EXTI_Line12) != RESET)
  496. {
  497. pin_irq_hdr(12);
  498. }
  499. if (EXTI_GetITStatus(EXTI_Line13) != RESET)
  500. {
  501. pin_irq_hdr(13);
  502. }
  503. if (EXTI_GetITStatus(EXTI_Line14) != RESET)
  504. {
  505. pin_irq_hdr(14);
  506. }
  507. if (EXTI_GetITStatus(EXTI_Line15) != RESET)
  508. {
  509. pin_irq_hdr(15);
  510. }
  511. /* leave interrupt */
  512. rt_interrupt_leave();
  513. }