drv_gpio.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. /*
  2. * Copyright (c) 2022-2025, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2025-01-22 chasel first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include "drv_gpio.h"
  13. #include <board.h>
  14. #include <rthw.h>
  15. #include <hal_gpio.h>
  16. #include <hal_exti.h>
  17. #include <hal_misc.h>
  18. #include <hal_rcc.h>
  19. #define PIN_NUM(port, no) (((((port) & 0xFu) << 4) | ((no) & 0xFu)))
  20. #define PIN_PORT(pin) ((uint8_t)(((pin) >> 4) & 0xFu))
  21. #define PIN_NO(pin) ((uint8_t)((pin) & 0xFu))
  22. #define RCC_PIN_PORT(pin) ((uint32_t)(0x01u << (PIN_PORT(pin))))
  23. #define PIN_ATPORTSOURCE(pin) ((uint8_t)(((pin) & 0xF0u) >> 4))
  24. #define PIN_ATPINSOURCE(pin) ((uint8_t)((pin) & 0xFu))
  25. #define PIN_ATPORT(pin) ((GPIO_TypeDef *)(GPIOA_BASE + (0x400u * PIN_PORT(pin))))
  26. #define PIN_ATPIN(pin) ((uint16_t)(1u << PIN_NO(pin)))
  27. /* mm32f5265 pin port */
  28. #define __MM32_PORT_MAX 6u
  29. #define PIN_ATPORT_MAX __MM32_PORT_MAX
  30. struct pin_irq_map
  31. {
  32. rt_uint16_t pinbit;
  33. rt_uint32_t irqbit;
  34. enum IRQn irqno;
  35. };
  36. const struct pin_irq_map mm32_pin_irq_map[] =
  37. {
  38. {GPIO_Pin_0, EXTI_Line0, EXTI0_IRQn},
  39. {GPIO_Pin_1, EXTI_Line1, EXTI1_IRQn},
  40. {GPIO_Pin_2, EXTI_Line2, EXTI2_IRQn},
  41. {GPIO_Pin_3, EXTI_Line3, EXTI3_IRQn},
  42. {GPIO_Pin_4, EXTI_Line4, EXTI4_IRQn},
  43. {GPIO_Pin_5, EXTI_Line5, EXTI9_5_IRQn},
  44. {GPIO_Pin_6, EXTI_Line6, EXTI9_5_IRQn},
  45. {GPIO_Pin_7, EXTI_Line7, EXTI9_5_IRQn},
  46. {GPIO_Pin_8, EXTI_Line8, EXTI9_5_IRQn},
  47. {GPIO_Pin_9, EXTI_Line9, EXTI9_5_IRQn},
  48. {GPIO_Pin_10, EXTI_Line10, EXTI15_10_IRQn},
  49. {GPIO_Pin_11, EXTI_Line11, EXTI15_10_IRQn},
  50. {GPIO_Pin_12, EXTI_Line12, EXTI15_10_IRQn},
  51. {GPIO_Pin_13, EXTI_Line13, EXTI15_10_IRQn},
  52. {GPIO_Pin_14, EXTI_Line14, EXTI15_10_IRQn},
  53. {GPIO_Pin_15, EXTI_Line15, EXTI15_10_IRQn},
  54. };
  55. struct rt_pin_irq_hdr mm32_pin_irq_hdr_tab[] =
  56. {
  57. {-1, 0, RT_NULL, RT_NULL},
  58. {-1, 0, RT_NULL, RT_NULL},
  59. {-1, 0, RT_NULL, RT_NULL},
  60. {-1, 0, RT_NULL, RT_NULL},
  61. {-1, 0, RT_NULL, RT_NULL},
  62. {-1, 0, RT_NULL, RT_NULL},
  63. {-1, 0, RT_NULL, RT_NULL},
  64. {-1, 0, RT_NULL, RT_NULL},
  65. {-1, 0, RT_NULL, RT_NULL},
  66. {-1, 0, RT_NULL, RT_NULL},
  67. {-1, 0, RT_NULL, RT_NULL},
  68. {-1, 0, RT_NULL, RT_NULL},
  69. {-1, 0, RT_NULL, RT_NULL},
  70. {-1, 0, RT_NULL, RT_NULL},
  71. {-1, 0, RT_NULL, RT_NULL},
  72. {-1, 0, RT_NULL, RT_NULL},
  73. };
  74. #define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
  75. static rt_base_t mm32_pin_get(const char *name)
  76. {
  77. rt_base_t pin = 0;
  78. int hw_port_num, hw_pin_num = 0;
  79. int i, name_len;
  80. name_len = rt_strlen(name);
  81. if ((name_len < 4) || (name_len >= 6)) {
  82. return -RT_EINVAL;
  83. }
  84. if ((name[0] != 'P') || (name[2] != '.')) {
  85. return -RT_EINVAL;
  86. }
  87. if ((name[1] >= 'A') && (name[1] <= 'Z')) {
  88. hw_port_num = (int)(name[1] - 'A');
  89. } else {
  90. return -RT_EINVAL;
  91. }
  92. for (i = 3; i < name_len; i++) {
  93. hw_pin_num *= 10;
  94. hw_pin_num += name[i] - '0';
  95. }
  96. pin = PIN_NUM(hw_port_num, hw_pin_num);
  97. return pin;
  98. }
  99. void mm32_pin_write(rt_device_t dev, rt_base_t pin, rt_uint8_t value)
  100. {
  101. GPIO_TypeDef *gpio_port;
  102. uint16_t gpio_pin;
  103. if (PIN_PORT(pin) < PIN_ATPORT_MAX) {
  104. gpio_port = PIN_ATPORT(pin);
  105. gpio_pin = PIN_ATPIN(pin);
  106. } else {
  107. return;
  108. }
  109. GPIO_WriteBit(gpio_port, gpio_pin, (PIN_LOW == value) ? Bit_RESET : Bit_SET);
  110. }
  111. rt_ssize_t mm32_pin_read(rt_device_t dev, rt_base_t pin)
  112. {
  113. GPIO_TypeDef *gpio_port;
  114. uint16_t gpio_pin;
  115. int value;
  116. value = PIN_LOW;
  117. if (PIN_PORT(pin) < PIN_ATPORT_MAX) {
  118. gpio_port = PIN_ATPORT(pin);
  119. gpio_pin = PIN_ATPIN(pin);
  120. value = GPIO_ReadInputDataBit(gpio_port, gpio_pin);
  121. } else {
  122. return -RT_EINVAL;
  123. }
  124. return value;
  125. }
  126. void mm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_uint8_t mode)
  127. {
  128. GPIO_TypeDef *gpio_port;
  129. uint16_t gpio_pin;
  130. GPIO_InitTypeDef GPIO_InitStructure;
  131. if (PIN_PORT(pin) < PIN_ATPORT_MAX) {
  132. gpio_port = PIN_ATPORT(pin);
  133. gpio_pin = PIN_ATPIN(pin);
  134. } else {
  135. return;
  136. }
  137. /* GPIO Periph clock enable */
  138. RCC_AHBPeriphClockCmd(RCC_PIN_PORT(pin), ENABLE);
  139. /* Configure GPIO_InitStructure */
  140. GPIO_InitStructure.GPIO_Pin = gpio_pin;
  141. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  142. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_High;
  143. if (mode == PIN_MODE_OUTPUT) {
  144. /* output setting */
  145. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  146. } else if (mode == PIN_MODE_OUTPUT_OD) {
  147. /* output setting: od. */
  148. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
  149. } else if (mode == PIN_MODE_INPUT) {
  150. /* input setting: not pull. */
  151. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_FLOATING;
  152. } else if (mode == PIN_MODE_INPUT_PULLUP) {
  153. /* input setting: pull up. */
  154. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  155. } else {
  156. /* input setting:default. */
  157. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPD;
  158. }
  159. GPIO_Init(gpio_port, &GPIO_InitStructure);
  160. }
  161. rt_inline rt_int32_t bit2bitno(rt_uint32_t bit)
  162. {
  163. int i;
  164. for (i = 0; i < 32; i++) {
  165. if ((0x01 << i) == bit) {
  166. return i;
  167. }
  168. }
  169. return -1;
  170. }
  171. rt_inline const struct pin_irq_map *get_pin_irq_map(uint32_t pinbit)
  172. {
  173. rt_int32_t mapindex = bit2bitno(pinbit);
  174. if (mapindex < 0 || mapindex >= ITEM_NUM(mm32_pin_irq_map)) {
  175. return RT_NULL;
  176. }
  177. return &mm32_pin_irq_map[mapindex];
  178. };
  179. rt_err_t mm32_pin_attach_irq(struct rt_device *device, rt_base_t pin,
  180. rt_uint8_t mode, void (*hdr)(void *args), void *args)
  181. {
  182. uint16_t gpio_pin;
  183. rt_base_t level;
  184. rt_int32_t irqindex = -1;
  185. if (PIN_PORT(pin) < PIN_ATPORT_MAX) {
  186. gpio_pin = PIN_ATPIN(pin);
  187. } else {
  188. return -RT_EINVAL;
  189. }
  190. irqindex = bit2bitno(gpio_pin);
  191. if (irqindex < 0 || irqindex >= ITEM_NUM(mm32_pin_irq_map)) {
  192. return -RT_ENOSYS;
  193. }
  194. level = rt_hw_interrupt_disable();
  195. if (mm32_pin_irq_hdr_tab[irqindex].pin == pin &&
  196. mm32_pin_irq_hdr_tab[irqindex].hdr == hdr &&
  197. mm32_pin_irq_hdr_tab[irqindex].mode == mode &&
  198. mm32_pin_irq_hdr_tab[irqindex].args == args)
  199. {
  200. rt_hw_interrupt_enable(level);
  201. return RT_EOK;
  202. }
  203. if (mm32_pin_irq_hdr_tab[irqindex].pin != -1) {
  204. rt_hw_interrupt_enable(level);
  205. return -RT_EBUSY;
  206. }
  207. mm32_pin_irq_hdr_tab[irqindex].pin = pin;
  208. mm32_pin_irq_hdr_tab[irqindex].hdr = hdr;
  209. mm32_pin_irq_hdr_tab[irqindex].mode = mode;
  210. mm32_pin_irq_hdr_tab[irqindex].args = args;
  211. rt_hw_interrupt_enable(level);
  212. return RT_EOK;
  213. }
  214. rt_err_t mm32_pin_detach_irq(struct rt_device *device, rt_base_t pin)
  215. {
  216. uint16_t gpio_pin;
  217. rt_base_t level;
  218. rt_int32_t irqindex = -1;
  219. if (PIN_PORT(pin) < PIN_ATPORT_MAX) {
  220. gpio_pin = PIN_ATPIN(pin);
  221. } else {
  222. return -RT_EINVAL;
  223. }
  224. irqindex = bit2bitno(gpio_pin);
  225. if (irqindex < 0 || irqindex >= ITEM_NUM(mm32_pin_irq_map)) {
  226. return -RT_ENOSYS;
  227. }
  228. level = rt_hw_interrupt_disable();
  229. if (mm32_pin_irq_hdr_tab[irqindex].pin == -1) {
  230. rt_hw_interrupt_enable(level);
  231. return RT_EOK;
  232. }
  233. mm32_pin_irq_hdr_tab[irqindex].pin = -1;
  234. mm32_pin_irq_hdr_tab[irqindex].hdr = RT_NULL;
  235. mm32_pin_irq_hdr_tab[irqindex].mode = 0;
  236. mm32_pin_irq_hdr_tab[irqindex].args = RT_NULL;
  237. rt_hw_interrupt_enable(level);
  238. return RT_EOK;
  239. }
  240. rt_err_t mm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
  241. rt_uint8_t enabled)
  242. {
  243. GPIO_TypeDef *gpio_port;
  244. uint16_t gpio_pin;
  245. const struct pin_irq_map *irqmap;
  246. rt_base_t level;
  247. rt_int32_t irqindex = -1;
  248. GPIO_InitTypeDef GPIO_InitStructure;
  249. NVIC_InitTypeDef NVIC_InitStructure;
  250. EXTI_InitTypeDef EXTI_InitStructure;
  251. if (PIN_PORT(pin) < PIN_ATPORT_MAX) {
  252. gpio_port = PIN_ATPORT(pin);
  253. gpio_pin = PIN_ATPIN(pin);
  254. } else {
  255. return -RT_EINVAL;
  256. }
  257. if (enabled == PIN_IRQ_ENABLE)
  258. {
  259. irqindex = bit2bitno(gpio_pin);
  260. if (irqindex < 0 || irqindex >= ITEM_NUM(mm32_pin_irq_map)) {
  261. return -RT_ENOSYS;
  262. }
  263. level = rt_hw_interrupt_disable();
  264. if (mm32_pin_irq_hdr_tab[irqindex].pin == -1) {
  265. rt_hw_interrupt_enable(level);
  266. return -RT_ENOSYS;
  267. }
  268. irqmap = &mm32_pin_irq_map[irqindex];
  269. /* GPIO Periph clock enable */
  270. RCC_AHBPeriphClockCmd(RCC_PIN_PORT(pin), ENABLE);
  271. /* Configure GPIO_InitStructure */
  272. GPIO_InitStructure.GPIO_Pin = gpio_pin;
  273. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  274. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_High;
  275. GPIO_Init(gpio_port, &GPIO_InitStructure);
  276. NVIC_InitStructure.NVIC_IRQChannel = irqmap->irqno;
  277. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  278. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
  279. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  280. NVIC_Init(&NVIC_InitStructure);
  281. EXTI_InitStructure.EXTI_Line = irqmap->irqbit;
  282. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  283. switch (mm32_pin_irq_hdr_tab[irqindex].mode) {
  284. case PIN_IRQ_MODE_RISING:
  285. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  286. break;
  287. case PIN_IRQ_MODE_FALLING:
  288. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
  289. break;
  290. case PIN_IRQ_MODE_RISING_FALLING:
  291. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
  292. break;
  293. }
  294. EXTI_InitStructure.EXTI_LineCmd = ENABLE;
  295. EXTI_Init(&EXTI_InitStructure);
  296. rt_hw_interrupt_enable(level);
  297. } else if (enabled == PIN_IRQ_DISABLE) {
  298. irqmap = get_pin_irq_map(gpio_pin);
  299. if (irqmap == RT_NULL) {
  300. return -RT_ENOSYS;
  301. }
  302. EXTI_InitStructure.EXTI_Line = irqmap->irqbit;
  303. EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
  304. EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
  305. EXTI_InitStructure.EXTI_LineCmd = DISABLE;
  306. EXTI_Init(&EXTI_InitStructure);
  307. } else {
  308. return -RT_ENOSYS;
  309. }
  310. return RT_EOK;
  311. }
  312. const static struct rt_pin_ops _mm32_pin_ops =
  313. {
  314. mm32_pin_mode,
  315. mm32_pin_write,
  316. mm32_pin_read,
  317. mm32_pin_attach_irq,
  318. mm32_pin_detach_irq,
  319. mm32_pin_irq_enable,
  320. mm32_pin_get,
  321. };
  322. int rt_hw_pin_init(void)
  323. {
  324. int result;
  325. result = rt_device_pin_register("pin", &_mm32_pin_ops, RT_NULL);
  326. return result;
  327. }
  328. rt_inline void pin_irq_hdr(int irqno)
  329. {
  330. EXTI_ClearITPendingBit(mm32_pin_irq_map[irqno].irqbit);
  331. if (mm32_pin_irq_hdr_tab[irqno].hdr)
  332. {
  333. mm32_pin_irq_hdr_tab[irqno].hdr(mm32_pin_irq_hdr_tab[irqno].args);
  334. }
  335. }
  336. void EXTI0_IRQHandler(void)
  337. {
  338. /* enter interrupt */
  339. rt_interrupt_enter();
  340. pin_irq_hdr(0);
  341. /* leave interrupt */
  342. rt_interrupt_leave();
  343. }
  344. void EXTI1_IRQHandler(void)
  345. {
  346. /* enter interrupt */
  347. rt_interrupt_enter();
  348. pin_irq_hdr(1);
  349. /* leave interrupt */
  350. rt_interrupt_leave();
  351. }
  352. void EXTI2_IRQHandler(void)
  353. {
  354. /* enter interrupt */
  355. rt_interrupt_enter();
  356. pin_irq_hdr(2);
  357. /* leave interrupt */
  358. rt_interrupt_leave();
  359. }
  360. void EXTI3_IRQHandler(void)
  361. {
  362. /* enter interrupt */
  363. rt_interrupt_enter();
  364. pin_irq_hdr(3);
  365. /* leave interrupt */
  366. rt_interrupt_leave();
  367. }
  368. void EXTI4_IRQHandler(void)
  369. {
  370. /* enter interrupt */
  371. rt_interrupt_enter();
  372. pin_irq_hdr(4);
  373. /* leave interrupt */
  374. rt_interrupt_leave();
  375. }
  376. void EXTI9_5_IRQHandler(void)
  377. {
  378. /* enter interrupt */
  379. rt_interrupt_enter();
  380. if (EXTI_GetITStatus(EXTI_Line5) != RESET)
  381. {
  382. pin_irq_hdr(5);
  383. }
  384. if (EXTI_GetITStatus(EXTI_Line6) != RESET)
  385. {
  386. pin_irq_hdr(6);
  387. }
  388. if (EXTI_GetITStatus(EXTI_Line7) != RESET)
  389. {
  390. pin_irq_hdr(7);
  391. }
  392. if (EXTI_GetITStatus(EXTI_Line8) != RESET)
  393. {
  394. pin_irq_hdr(8);
  395. }
  396. if (EXTI_GetITStatus(EXTI_Line9) != RESET)
  397. {
  398. pin_irq_hdr(9);
  399. }
  400. /* leave interrupt */
  401. rt_interrupt_leave();
  402. }
  403. void EXTI15_10_IRQHandler(void)
  404. {
  405. /* enter interrupt */
  406. rt_interrupt_enter();
  407. if (EXTI_GetITStatus(EXTI_Line10) != RESET)
  408. {
  409. pin_irq_hdr(10);
  410. }
  411. if (EXTI_GetITStatus(EXTI_Line11) != RESET)
  412. {
  413. pin_irq_hdr(11);
  414. }
  415. if (EXTI_GetITStatus(EXTI_Line12) != RESET)
  416. {
  417. pin_irq_hdr(12);
  418. }
  419. if (EXTI_GetITStatus(EXTI_Line13) != RESET)
  420. {
  421. pin_irq_hdr(13);
  422. }
  423. if (EXTI_GetITStatus(EXTI_Line14) != RESET)
  424. {
  425. pin_irq_hdr(14);
  426. }
  427. if (EXTI_GetITStatus(EXTI_Line15) != RESET)
  428. {
  429. pin_irq_hdr(15);
  430. }
  431. /* leave interrupt */
  432. rt_interrupt_leave();
  433. }