drv_gpio.c 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  1. /*
  2. * Copyright (c) 2021 hpm
  3. *
  4. * SPDX-License-Identifier: BSD-3-Clause
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-01-11 hpmicro First version
  9. * 2022-07-28 hpmicro Fixed compiling warnings
  10. */
  11. #include <rtthread.h>
  12. #ifdef BSP_USING_GPIO
  13. #include <rthw.h>
  14. #include <rtdevice.h>
  15. #include "board.h"
  16. #include "drv_gpio.h"
  17. #include "hpm_gpio_drv.h"
  18. #include "hpm_gpiom_drv.h"
  19. #include "hpm_clock_drv.h"
  20. typedef struct
  21. {
  22. uint32_t gpio_idx;
  23. uint32_t irq_num;
  24. } gpio_irq_map_t;
  25. static const gpio_irq_map_t hpm_gpio_irq_map[] = {
  26. #ifdef IRQn_GPIO0_A
  27. { GPIO_IE_GPIOA, IRQn_GPIO0_A },
  28. #endif
  29. #ifdef IRQn_GPIO0_B
  30. { GPIO_IE_GPIOB, IRQn_GPIO0_B },
  31. #endif
  32. #ifdef IRQn_GPIO0_C
  33. { GPIO_IE_GPIOC, IRQn_GPIO0_C },
  34. #endif
  35. #ifdef GPIO_IE_GPIOD
  36. { GPIO_IE_GPIOD, IRQn_GPIO0_D },
  37. #endif
  38. #ifdef IRQn_GPIO0_E
  39. { GPIO_IE_GPIOE, IRQn_GPIO0_E },
  40. #endif
  41. #ifdef IRQn_GPIO0_F
  42. { GPIO_IE_GPIOF, IRQn_GPIO0_F },
  43. #endif
  44. #ifdef IRQn_GPIO0_X
  45. { GPIO_IE_GPIOX, IRQn_GPIO0_X },
  46. #endif
  47. #ifdef IRQn_GPIO0_Y
  48. { GPIO_IE_GPIOY, IRQn_GPIO0_Y },
  49. #endif
  50. #ifdef IRQn_GPIO0_Z
  51. { GPIO_IE_GPIOZ, IRQn_GPIO0_Z },
  52. #endif
  53. };
  54. static struct rt_pin_irq_hdr hpm_gpio_pin_hdr_tbl[IOC_PAD_PZ11];
  55. static int hpm_get_gpi_irq_num(uint32_t gpio_idx)
  56. {
  57. int irq_num = -1;
  58. for (uint32_t i = 0; i < sizeof(hpm_gpio_irq_map) / sizeof(hpm_gpio_irq_map[0]); i++)
  59. {
  60. if (hpm_gpio_irq_map[i].gpio_idx == gpio_idx)
  61. {
  62. irq_num = hpm_gpio_irq_map[i].irq_num;
  63. break;
  64. }
  65. }
  66. return irq_num;
  67. }
  68. static void hpm_gpio_isr(uint32_t gpio_index, GPIO_Type *base)
  69. {
  70. uint32_t pin_idx = 0;
  71. for(pin_idx = 0; pin_idx < 32; pin_idx++)
  72. {
  73. if (gpio_check_pin_interrupt_flag(base, gpio_index, pin_idx))
  74. {
  75. uint32_t pin = gpio_index * 32U + pin_idx;
  76. gpio_clear_pin_interrupt_flag(base, gpio_index, pin_idx);
  77. if (hpm_gpio_pin_hdr_tbl[pin].hdr != RT_NULL)
  78. {
  79. hpm_gpio_pin_hdr_tbl[pin].hdr(hpm_gpio_pin_hdr_tbl[pin].args);
  80. }
  81. }
  82. }
  83. }
  84. #ifdef GPIO_IF_GPIOA
  85. void gpioa_isr(void)
  86. {
  87. hpm_gpio_isr(GPIO_IF_GPIOA, HPM_GPIO0);
  88. }
  89. SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_A, gpioa_isr)
  90. #endif
  91. #ifdef GPIO_IF_GPIOB
  92. void gpiob_isr(void)
  93. {
  94. hpm_gpio_isr(GPIO_IF_GPIOB, HPM_GPIO0);
  95. }
  96. SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_B, gpiob_isr)
  97. #endif
  98. #ifdef GPIO_IF_GPIOC
  99. void gpioc_isr(void)
  100. {
  101. hpm_gpio_isr(GPIO_IF_GPIOC, HPM_GPIO0);
  102. }
  103. SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_C, gpioc_isr)
  104. #endif
  105. #ifdef GPIO_IF_GPIOD
  106. void gpiod_isr(void)
  107. {
  108. hpm_gpio_isr(GPIO_IF_GPIOD, HPM_GPIO0);
  109. }
  110. SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_D, gpiod_isr)
  111. #endif
  112. #ifdef GPIO_IF_GPIOE
  113. void gpioe_isr(void)
  114. {
  115. hpm_gpio_isr(GPIO_IF_GPIOE, HPM_GPIO0);
  116. }
  117. SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_E, gpioe_isr)
  118. #endif
  119. #ifdef GPIO_IF_GPIOF
  120. void gpiof_isr(void)
  121. {
  122. hpm_gpio_isr(GPIO_IF_GPIOF, HPM_GPIO0);
  123. }
  124. SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_F, gpiof_isr)
  125. #endif
  126. #ifdef GPIO_IF_GPIOX
  127. void gpiox_isr(void)
  128. {
  129. hpm_gpio_isr(GPIO_IF_GPIOX, HPM_GPIO0);
  130. }
  131. SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_X, gpiox_isr)
  132. #endif
  133. #ifdef GPIO_IF_GPIOY
  134. void gpioy_isr(void)
  135. {
  136. hpm_gpio_isr(GPIO_IF_GPIOY, HPM_GPIO0);
  137. }
  138. SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_Y, gpioy_isr)
  139. #endif
  140. #ifdef GPIO_IF_GPIOZ
  141. void gpioz_isr(void)
  142. {
  143. hpm_gpio_isr(GPIO_IF_GPIOZ, HPM_GPIO0);
  144. }
  145. SDK_DECLARE_EXT_ISR_M(IRQn_GPIO0_Z, gpioz_isr)
  146. #endif
  147. static void hpm_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
  148. {
  149. /* TODO: Check the validity of the pin value */
  150. uint32_t gpio_idx = pin >> 5;
  151. uint32_t pin_idx = pin & 0x1FU;
  152. gpiom_set_pin_controller(HPM_GPIOM, gpio_idx, pin_idx, gpiom_soc_gpio0);
  153. HPM_IOC->PAD[pin].FUNC_CTL = 0;
  154. switch (gpio_idx)
  155. {
  156. case GPIO_DI_GPIOY :
  157. HPM_PIOC->PAD[pin].FUNC_CTL = 3;
  158. break;
  159. case GPIO_DI_GPIOZ :
  160. HPM_BIOC->PAD[pin].FUNC_CTL = 3;
  161. break;
  162. default :
  163. break;
  164. }
  165. switch (mode)
  166. {
  167. case PIN_MODE_OUTPUT:
  168. gpio_set_pin_output(HPM_GPIO0, gpio_idx, pin_idx);
  169. HPM_IOC->PAD[pin].PAD_CTL &= ~(IOC_PAD_PAD_CTL_PS_MASK | IOC_PAD_PAD_CTL_PE_MASK | IOC_PAD_PAD_CTL_OD_MASK);
  170. break;
  171. case PIN_MODE_INPUT:
  172. gpio_set_pin_input(HPM_GPIO0, gpio_idx, pin_idx);
  173. HPM_IOC->PAD[pin].PAD_CTL &= ~(IOC_PAD_PAD_CTL_PS_MASK | IOC_PAD_PAD_CTL_PE_MASK);
  174. break;
  175. case PIN_MODE_INPUT_PULLDOWN:
  176. gpio_set_pin_input(HPM_GPIO0, gpio_idx, pin_idx);
  177. HPM_IOC->PAD[pin].PAD_CTL = (HPM_IOC->PAD[pin].PAD_CTL & ~IOC_PAD_PAD_CTL_PS_MASK) | IOC_PAD_PAD_CTL_PE_SET(1);
  178. break;
  179. case PIN_MODE_INPUT_PULLUP:
  180. gpio_set_pin_input(HPM_GPIO0, gpio_idx, pin_idx);
  181. HPM_IOC->PAD[pin].PAD_CTL |= IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
  182. break;
  183. case PIN_MODE_OUTPUT_OD:
  184. gpio_set_pin_output(HPM_GPIO0, gpio_idx, pin_idx);
  185. HPM_IOC->PAD[pin].PAD_CTL = (HPM_IOC->PAD[pin].PAD_CTL & ~(IOC_PAD_PAD_CTL_PS_MASK | IOC_PAD_PAD_CTL_PE_MASK)) | IOC_PAD_PAD_CTL_OD_SET(1);
  186. break;
  187. default:
  188. /* Invalid mode */
  189. break;
  190. }
  191. }
  192. static int hpm_pin_read(rt_device_t dev, rt_base_t pin)
  193. {
  194. /* TODO: Check the validity of the pin value */
  195. uint32_t gpio_idx = pin >> 5;
  196. uint32_t pin_idx = pin & 0x1FU;
  197. return (int) gpio_read_pin(HPM_GPIO0, gpio_idx, pin_idx);
  198. }
  199. static void hpm_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
  200. {
  201. /* TODO: Check the validity of the pin value */
  202. uint32_t gpio_idx = pin >> 5;
  203. uint32_t pin_idx = pin & 0x1FU;
  204. gpio_write_pin(HPM_GPIO0, gpio_idx, pin_idx, value);
  205. }
  206. static rt_err_t hpm_pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode,
  207. void (*hdr)(void *args), void *args)
  208. {
  209. rt_base_t level;
  210. level = rt_hw_interrupt_disable();
  211. hpm_gpio_pin_hdr_tbl[pin].pin = pin;
  212. hpm_gpio_pin_hdr_tbl[pin].hdr = hdr;
  213. hpm_gpio_pin_hdr_tbl[pin].mode = mode;
  214. hpm_gpio_pin_hdr_tbl[pin].args = args;
  215. rt_hw_interrupt_enable(level);
  216. return RT_EOK;
  217. }
  218. static rt_err_t hpm_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
  219. {
  220. rt_base_t level;
  221. level = rt_hw_interrupt_disable();
  222. hpm_gpio_pin_hdr_tbl[pin].pin = -1;
  223. hpm_gpio_pin_hdr_tbl[pin].hdr = RT_NULL;
  224. hpm_gpio_pin_hdr_tbl[pin].mode = 0;
  225. hpm_gpio_pin_hdr_tbl[pin].args = RT_NULL;
  226. rt_hw_interrupt_enable(level);
  227. return RT_EOK;
  228. }
  229. static rt_err_t hpm_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
  230. {
  231. /* TODO: Check the validity of the pin value */
  232. uint32_t gpio_idx = pin >> 5;
  233. uint32_t pin_idx = pin & 0x1FU;
  234. gpio_interrupt_trigger_t trigger;
  235. if (enabled == PIN_IRQ_ENABLE)
  236. {
  237. switch(hpm_gpio_pin_hdr_tbl[pin].mode)
  238. {
  239. case PIN_IRQ_MODE_RISING:
  240. trigger = gpio_interrupt_trigger_edge_rising;
  241. break;
  242. case PIN_IRQ_MODE_FALLING:
  243. trigger = gpio_interrupt_trigger_edge_falling;
  244. break;
  245. case PIN_IRQ_MODE_HIGH_LEVEL:
  246. trigger = gpio_interrupt_trigger_level_high;
  247. break;
  248. case PIN_IRQ_MODE_LOW_LEVEL:
  249. trigger = gpio_interrupt_trigger_level_low;
  250. break;
  251. default:
  252. trigger = gpio_interrupt_trigger_edge_rising;
  253. break;
  254. }
  255. gpio_config_pin_interrupt(HPM_GPIO0, gpio_idx, pin_idx, trigger);
  256. uint32_t irq_num = hpm_get_gpi_irq_num(gpio_idx);
  257. gpio_enable_pin_interrupt(HPM_GPIO0, gpio_idx, pin_idx);
  258. intc_m_enable_irq_with_priority(irq_num, 1);
  259. }
  260. else if (enabled == PIN_IRQ_DISABLE)
  261. {
  262. gpio_disable_pin_interrupt(HPM_GPIO0, gpio_idx, pin_idx);
  263. }
  264. else
  265. {
  266. return RT_EINVAL;
  267. }
  268. return RT_EOK;
  269. }
  270. const static struct rt_pin_ops hpm_pin_ops = {
  271. .pin_mode = hpm_pin_mode,
  272. .pin_write = hpm_pin_write,
  273. .pin_read = hpm_pin_read,
  274. .pin_attach_irq = hpm_pin_attach_irq,
  275. .pin_detach_irq = hpm_pin_detach_irq,
  276. .pin_irq_enable = hpm_pin_irq_enable};
  277. int rt_hw_pin_init(void)
  278. {
  279. int ret = RT_EOK;
  280. ret = rt_device_pin_register("pin", &hpm_pin_ops, RT_NULL);
  281. return ret;
  282. }
  283. INIT_BOARD_EXPORT(rt_hw_pin_init);
  284. #endif /* BSP_USING_GPIO */