drv_gpio.c 13 KB

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