drv_gpio.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-08-20 BruceOu the first version
  9. */
  10. #include <rtdevice.h>
  11. #include <rthw.h>
  12. #include <rtconfig.h>
  13. #ifdef RT_USING_PIN
  14. #include "drv_gpio.h"
  15. static const struct pin_index pins[] =
  16. {
  17. GD32_PIN(0, A, 0),
  18. GD32_PIN(1, A, 1),
  19. GD32_PIN(2, A, 2),
  20. GD32_PIN(3, A, 3),
  21. GD32_PIN(4, A, 4),
  22. GD32_PIN(5, A, 5),
  23. GD32_PIN(6, A, 6),
  24. GD32_PIN(7, A, 7),
  25. GD32_PIN(8, A, 8),
  26. GD32_PIN(9, A, 9),
  27. GD32_PIN(10, A, 10),
  28. GD32_PIN(11, A, 11),
  29. GD32_PIN(12, A, 12),
  30. GD32_PIN(13, A, 13),
  31. GD32_PIN(14, A, 14),
  32. GD32_PIN(15, A, 15),
  33. GD32_PIN(16, B, 0),
  34. GD32_PIN(17, B, 1),
  35. GD32_PIN(18, B, 2),
  36. GD32_PIN(19, B, 3),
  37. GD32_PIN(20, B, 4),
  38. GD32_PIN(21, B, 5),
  39. GD32_PIN(22, B, 6),
  40. GD32_PIN(23, B, 7),
  41. GD32_PIN(24, B, 8),
  42. GD32_PIN(25, B, 9),
  43. GD32_PIN(26, B, 10),
  44. GD32_PIN(27, B, 11),
  45. GD32_PIN(28, B, 12),
  46. GD32_PIN(39, B, 13),
  47. GD32_PIN(30, B, 14),
  48. GD32_PIN(31, B, 15),
  49. GD32_PIN(32, C, 0),
  50. GD32_PIN(33, C, 1),
  51. GD32_PIN(34, C, 2),
  52. GD32_PIN(35, C, 3),
  53. GD32_PIN(36, C, 4),
  54. GD32_PIN(37, C, 5),
  55. GD32_PIN(38, C, 6),
  56. GD32_PIN(39, C, 7),
  57. GD32_PIN(40, C, 8),
  58. GD32_PIN(41, C, 9),
  59. GD32_PIN(42, C, 10),
  60. GD32_PIN(43, C, 11),
  61. GD32_PIN(44, C, 12),
  62. GD32_PIN(45, C, 13),
  63. GD32_PIN(46, C, 14),
  64. GD32_PIN(47, C, 15),
  65. GD32_PIN(50, D, 2),
  66. GD32_PIN_DEFAULT,
  67. GD32_PIN_DEFAULT,
  68. GD32_PIN_DEFAULT,
  69. GD32_PIN_DEFAULT,
  70. GD32_PIN_DEFAULT,
  71. GD32_PIN_DEFAULT,
  72. GD32_PIN_DEFAULT,
  73. GD32_PIN_DEFAULT,
  74. GD32_PIN_DEFAULT,
  75. GD32_PIN_DEFAULT,
  76. GD32_PIN_DEFAULT,
  77. GD32_PIN_DEFAULT,
  78. GD32_PIN_DEFAULT,
  79. GD32_PIN(64, F, 0),
  80. GD32_PIN(65, F, 1),
  81. GD32_PIN_DEFAULT,
  82. GD32_PIN_DEFAULT,
  83. GD32_PIN(68, F, 4),
  84. GD32_PIN(69, F, 5),
  85. GD32_PIN(70, F, 6),
  86. GD32_PIN(71, F, 7),
  87. GD32_PIN_DEFAULT,
  88. GD32_PIN_DEFAULT,
  89. GD32_PIN_DEFAULT,
  90. GD32_PIN_DEFAULT,
  91. GD32_PIN_DEFAULT,
  92. GD32_PIN_DEFAULT,
  93. GD32_PIN_DEFAULT,
  94. GD32_PIN_DEFAULT,
  95. };
  96. static const struct pin_irq_map pin_irq_map[] =
  97. {
  98. {GPIO_PIN_0, EXTI0_IRQn},
  99. {GPIO_PIN_1, EXTI1_IRQn},
  100. {GPIO_PIN_2, EXTI2_IRQn},
  101. {GPIO_PIN_3, EXTI3_IRQn},
  102. {GPIO_PIN_4, EXTI4_IRQn},
  103. {GPIO_PIN_5, EXTI5_9_IRQn},
  104. {GPIO_PIN_6, EXTI5_9_IRQn},
  105. {GPIO_PIN_7, EXTI5_9_IRQn},
  106. {GPIO_PIN_8, EXTI5_9_IRQn},
  107. {GPIO_PIN_9, EXTI5_9_IRQn},
  108. {GPIO_PIN_10, EXTI10_15_IRQn},
  109. {GPIO_PIN_11, EXTI10_15_IRQn},
  110. {GPIO_PIN_12, EXTI10_15_IRQn},
  111. {GPIO_PIN_13, EXTI10_15_IRQn},
  112. {GPIO_PIN_14, EXTI10_15_IRQn},
  113. {GPIO_PIN_15, EXTI10_15_IRQn},
  114. };
  115. struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
  116. {
  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. {-1, 0, RT_NULL, RT_NULL},
  132. {-1, 0, RT_NULL, RT_NULL},
  133. };
  134. #define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
  135. /**
  136. * @brief get pin
  137. * @param pin
  138. * @retval None
  139. */
  140. const struct pin_index *get_pin(rt_uint8_t pin)
  141. {
  142. const struct pin_index *index;
  143. if (pin < ITEM_NUM(pins))
  144. {
  145. index = &pins[pin];
  146. if (index->index == -1)
  147. index = RT_NULL;
  148. }
  149. else
  150. {
  151. index = RT_NULL;
  152. }
  153. return index;
  154. }
  155. /**
  156. * @brief set pin mode
  157. * @param dev, pin, mode
  158. * @retval None
  159. */
  160. static void gd32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
  161. {
  162. const struct pin_index *index = RT_NULL;
  163. rt_uint32_t pin_mode = 0;
  164. #if defined SOC_SERIES_GD32F4xx
  165. rt_uint32_t pin_pupd = 0, pin_odpp = 0;
  166. #endif
  167. index = get_pin(pin);
  168. if (index == RT_NULL)
  169. {
  170. return;
  171. }
  172. /* GPIO Periph clock enable */
  173. rcu_periph_clock_enable(index->clk);
  174. #if defined SOC_SERIES_GD32F4xx
  175. pin_mode = GPIO_MODE_OUTPUT;
  176. #else
  177. pin_mode = GPIO_MODE_OUT_PP;
  178. #endif
  179. switch(mode)
  180. {
  181. case PIN_MODE_OUTPUT:
  182. /* output setting */
  183. #if defined SOC_SERIES_GD32F4xx
  184. pin_mode = GPIO_MODE_OUTPUT;
  185. pin_pupd = GPIO_PUPD_NONE;
  186. pin_odpp = GPIO_OTYPE_PP;
  187. #else
  188. pin_mode = GPIO_MODE_OUT_PP;
  189. #endif
  190. break;
  191. case PIN_MODE_OUTPUT_OD:
  192. /* output setting: od. */
  193. #if defined SOC_SERIES_GD32F4xx
  194. pin_mode = GPIO_MODE_OUTPUT;
  195. pin_pupd = GPIO_PUPD_NONE;
  196. pin_odpp = GPIO_OTYPE_OD;
  197. #else
  198. pin_mode = GPIO_MODE_OUT_OD;
  199. #endif
  200. break;
  201. case PIN_MODE_INPUT:
  202. /* input setting: not pull. */
  203. #if defined SOC_SERIES_GD32F4xx
  204. pin_mode = GPIO_MODE_INPUT;
  205. pin_pupd = GPIO_PUPD_PULLUP | GPIO_PUPD_PULLDOWN;
  206. #else
  207. pin_mode = GPIO_MODE_IN_FLOATING;
  208. #endif
  209. break;
  210. case PIN_MODE_INPUT_PULLUP:
  211. /* input setting: pull up. */
  212. #if defined SOC_SERIES_GD32F4xx
  213. pin_mode = GPIO_MODE_INPUT;
  214. pin_pupd = GPIO_PUPD_PULLUP;
  215. #else
  216. pin_mode = GPIO_MODE_IPU;
  217. #endif
  218. break;
  219. case PIN_MODE_INPUT_PULLDOWN:
  220. /* input setting: pull down. */
  221. #if defined SOC_SERIES_GD32F4xx
  222. pin_mode = GPIO_MODE_INPUT;
  223. pin_pupd = GPIO_PUPD_PULLDOWN;
  224. #else
  225. pin_mode = GPIO_MODE_IPD;
  226. #endif
  227. break;
  228. default:
  229. break;
  230. }
  231. #if defined SOC_SERIES_GD32F4xx
  232. gpio_mode_set(index->gpio_periph, pin_mode, pin_pupd, index->pin);
  233. if(pin_mode == GPIO_MODE_OUTPUT)
  234. {
  235. gpio_output_options_set(index->gpio_periph, pin_odpp, GPIO_OSPEED_50MHZ, index->pin);
  236. }
  237. #else
  238. gpio_init(index->gpio_periph, pin_mode, GPIO_OSPEED_50MHZ, index->pin);
  239. #endif
  240. }
  241. /**
  242. * @brief pin write
  243. * @param dev, pin, valuie
  244. * @retval None
  245. */
  246. static void gd32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
  247. {
  248. const struct pin_index *index = RT_NULL;
  249. index = get_pin(pin);
  250. if (index == RT_NULL)
  251. {
  252. return;
  253. }
  254. gpio_bit_write(index->gpio_periph, index->pin, (bit_status)value);
  255. }
  256. /**
  257. * @brief pin read
  258. * @param dev, pin
  259. * @retval None
  260. */
  261. static int gd32_pin_read(rt_device_t dev, rt_base_t pin)
  262. {
  263. int value = PIN_LOW;
  264. const struct pin_index *index = RT_NULL;
  265. index = get_pin(pin);
  266. if (index == RT_NULL)
  267. {
  268. return value;
  269. }
  270. value = gpio_input_bit_get(index->gpio_periph, index->pin);
  271. return value;
  272. }
  273. /**
  274. * @brief bit2bitno
  275. * @param bit
  276. * @retval None
  277. */
  278. rt_inline rt_int32_t bit2bitno(rt_uint32_t bit)
  279. {
  280. rt_uint8_t i;
  281. for (i = 0; i < 32; i++)
  282. {
  283. if ((0x01 << i) == bit)
  284. {
  285. return i;
  286. }
  287. }
  288. return -1;
  289. }
  290. /**
  291. * @brief pin write
  292. * @param pinbit
  293. * @retval None
  294. */
  295. rt_inline const struct pin_irq_map *get_pin_irq_map(rt_uint32_t pinbit)
  296. {
  297. rt_int32_t map_index = bit2bitno(pinbit);
  298. if (map_index < 0 || map_index >= ITEM_NUM(pin_irq_map))
  299. {
  300. return RT_NULL;
  301. }
  302. return &pin_irq_map[map_index];
  303. }
  304. /**
  305. * @brief pin irq attach
  306. * @param device, pin, mode
  307. * @retval None
  308. */
  309. static rt_err_t gd32_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
  310. rt_uint32_t mode, void (*hdr)(void *args), void *args)
  311. {
  312. const struct pin_index *index = RT_NULL;
  313. rt_base_t level;
  314. rt_int32_t hdr_index = -1;
  315. index = get_pin(pin);
  316. if (index == RT_NULL)
  317. {
  318. return -RT_EINVAL;
  319. }
  320. hdr_index = bit2bitno(index->pin);
  321. if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map))
  322. {
  323. return -RT_EINVAL;
  324. }
  325. level = rt_hw_interrupt_disable();
  326. if (pin_irq_hdr_tab[hdr_index].pin == pin &&
  327. pin_irq_hdr_tab[hdr_index].hdr == hdr &&
  328. pin_irq_hdr_tab[hdr_index].mode == mode &&
  329. pin_irq_hdr_tab[hdr_index].args == args)
  330. {
  331. rt_hw_interrupt_enable(level);
  332. return RT_EOK;
  333. }
  334. if (pin_irq_hdr_tab[hdr_index].pin != -1)
  335. {
  336. rt_hw_interrupt_enable(level);
  337. return -RT_EFULL;
  338. }
  339. pin_irq_hdr_tab[hdr_index].pin = pin;
  340. pin_irq_hdr_tab[hdr_index].hdr = hdr;
  341. pin_irq_hdr_tab[hdr_index].mode = mode;
  342. pin_irq_hdr_tab[hdr_index].args = args;
  343. rt_hw_interrupt_enable(level);
  344. return RT_EOK;
  345. }
  346. /**
  347. * @brief pin irq detach
  348. * @param device, pin
  349. * @retval None
  350. */
  351. static rt_err_t gd32_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
  352. {
  353. const struct pin_index *index = RT_NULL;
  354. rt_base_t level;
  355. rt_int32_t hdr_index = -1;
  356. index = get_pin(pin);
  357. if (index == RT_NULL)
  358. {
  359. return -RT_EINVAL;
  360. }
  361. hdr_index = bit2bitno(index->pin);
  362. if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map))
  363. {
  364. return -RT_EINVAL;
  365. }
  366. level = rt_hw_interrupt_disable();
  367. if (pin_irq_hdr_tab[hdr_index].pin == -1)
  368. {
  369. rt_hw_interrupt_enable(level);
  370. return RT_EOK;
  371. }
  372. pin_irq_hdr_tab[hdr_index].pin = -1;
  373. pin_irq_hdr_tab[hdr_index].hdr = RT_NULL;
  374. pin_irq_hdr_tab[hdr_index].mode = 0;
  375. pin_irq_hdr_tab[hdr_index].args = RT_NULL;
  376. rt_hw_interrupt_enable(level);
  377. return RT_EOK;
  378. }
  379. /**
  380. * @brief pin irq enable
  381. * @param device, pin, enabled
  382. * @retval None
  383. */
  384. static rt_err_t gd32_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
  385. {
  386. const struct pin_index *index;
  387. const struct pin_irq_map *irqmap;
  388. rt_base_t level;
  389. rt_int32_t hdr_index = -1;
  390. exti_trig_type_enum trigger_mode;
  391. index = get_pin(pin);
  392. if (index == RT_NULL)
  393. {
  394. return -RT_EINVAL;
  395. }
  396. if (enabled == PIN_IRQ_ENABLE)
  397. {
  398. hdr_index = bit2bitno(index->pin);
  399. if (hdr_index < 0 || hdr_index >= ITEM_NUM(pin_irq_map))
  400. {
  401. return -RT_EINVAL;
  402. }
  403. level = rt_hw_interrupt_disable();
  404. if (pin_irq_hdr_tab[hdr_index].pin == -1)
  405. {
  406. rt_hw_interrupt_enable(level);
  407. return -RT_EINVAL;
  408. }
  409. irqmap = &pin_irq_map[hdr_index];
  410. switch (pin_irq_hdr_tab[hdr_index].mode)
  411. {
  412. case PIN_IRQ_MODE_RISING:
  413. trigger_mode = EXTI_TRIG_RISING;
  414. break;
  415. case PIN_IRQ_MODE_FALLING:
  416. trigger_mode = EXTI_TRIG_FALLING;
  417. break;
  418. case PIN_IRQ_MODE_RISING_FALLING:
  419. trigger_mode = EXTI_TRIG_BOTH;
  420. break;
  421. default:
  422. rt_hw_interrupt_enable(level);
  423. return -RT_EINVAL;
  424. }
  425. #if defined SOC_SERIES_GD32F4xx
  426. rcu_periph_clock_enable(RCU_SYSCFG);
  427. #else
  428. rcu_periph_clock_enable(RCU_AF);
  429. #endif
  430. /* enable and set interrupt priority */
  431. nvic_irq_enable(irqmap->irqno, 5U, 0U);
  432. /* connect EXTI line to GPIO pin */
  433. #if defined SOC_SERIES_GD32F4xx
  434. syscfg_exti_line_config(index->port_src, index->pin_src);
  435. #else
  436. gpio_exti_source_select(index->port_src, index->pin_src);
  437. #endif
  438. /* configure EXTI line */
  439. exti_init((exti_line_enum)(index->pin), EXTI_INTERRUPT, trigger_mode);
  440. exti_interrupt_flag_clear((exti_line_enum)(index->pin));
  441. rt_hw_interrupt_enable(level);
  442. }
  443. else if (enabled == PIN_IRQ_DISABLE)
  444. {
  445. irqmap = get_pin_irq_map(index->pin);
  446. if (irqmap == RT_NULL)
  447. {
  448. return -RT_EINVAL;
  449. }
  450. nvic_irq_disable(irqmap->irqno);
  451. }
  452. else
  453. {
  454. return -RT_EINVAL;
  455. }
  456. return RT_EOK;
  457. }
  458. const static struct rt_pin_ops gd32_pin_ops =
  459. {
  460. .pin_mode = gd32_pin_mode,
  461. .pin_write = gd32_pin_write,
  462. .pin_read = gd32_pin_read,
  463. .pin_attach_irq = gd32_pin_attach_irq,
  464. .pin_detach_irq= gd32_pin_detach_irq,
  465. .pin_irq_enable = gd32_pin_irq_enable,
  466. RT_NULL,
  467. };
  468. /**
  469. * @brief pin write
  470. * @param irqno
  471. * @retval None
  472. */
  473. rt_inline void pin_irq_hdr(int irqno)
  474. {
  475. if (pin_irq_hdr_tab[irqno].hdr)
  476. {
  477. pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args);
  478. }
  479. }
  480. /**
  481. * @brief gd32 exit interrupt
  482. * @param exti_line
  483. * @retval None
  484. */
  485. void GD32_GPIO_EXTI_IRQHandler(rt_int8_t exti_line)
  486. {
  487. if(RESET != exti_interrupt_flag_get((exti_line_enum)(1 << exti_line)))
  488. {
  489. pin_irq_hdr(exti_line);
  490. exti_interrupt_flag_clear((exti_line_enum)(1 << exti_line));
  491. }
  492. }
  493. void EXTI0_IRQHandler(void)
  494. {
  495. rt_interrupt_enter();
  496. GD32_GPIO_EXTI_IRQHandler(0);
  497. rt_interrupt_leave();
  498. }
  499. void EXTI1_IRQHandler(void)
  500. {
  501. rt_interrupt_enter();
  502. GD32_GPIO_EXTI_IRQHandler(1);
  503. rt_interrupt_leave();
  504. }
  505. void EXTI2_IRQHandler(void)
  506. {
  507. rt_interrupt_enter();
  508. GD32_GPIO_EXTI_IRQHandler(2);
  509. rt_interrupt_leave();
  510. }
  511. void EXTI3_IRQHandler(void)
  512. {
  513. rt_interrupt_enter();
  514. GD32_GPIO_EXTI_IRQHandler(3);
  515. rt_interrupt_leave();
  516. }
  517. void EXTI4_IRQHandler(void)
  518. {
  519. rt_interrupt_enter();
  520. GD32_GPIO_EXTI_IRQHandler(4);
  521. rt_interrupt_leave();
  522. }
  523. void EXTI5_9_IRQHandler(void)
  524. {
  525. rt_interrupt_enter();
  526. GD32_GPIO_EXTI_IRQHandler(5);
  527. GD32_GPIO_EXTI_IRQHandler(6);
  528. GD32_GPIO_EXTI_IRQHandler(7);
  529. GD32_GPIO_EXTI_IRQHandler(8);
  530. GD32_GPIO_EXTI_IRQHandler(9);
  531. rt_interrupt_leave();
  532. }
  533. void EXTI10_15_IRQHandler(void)
  534. {
  535. rt_interrupt_enter();
  536. GD32_GPIO_EXTI_IRQHandler(10);
  537. GD32_GPIO_EXTI_IRQHandler(11);
  538. GD32_GPIO_EXTI_IRQHandler(12);
  539. GD32_GPIO_EXTI_IRQHandler(13);
  540. GD32_GPIO_EXTI_IRQHandler(14);
  541. GD32_GPIO_EXTI_IRQHandler(15);
  542. rt_interrupt_leave();
  543. }
  544. int rt_hw_pin_init(void)
  545. {
  546. int result;
  547. result = rt_device_pin_register("pin", &gd32_pin_ops, RT_NULL);
  548. return result;
  549. }
  550. INIT_BOARD_EXPORT(rt_hw_pin_init);
  551. #endif