drv_gpio.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. /*
  2. * Copyright (c) 2006-2021, YICHIP Technology Co.,Ltd.
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2021-09-09 WSY first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <board.h>
  13. #include <rthw.h>
  14. #define PIN_MAX_NUM (48)
  15. typedef void (*pin_callback_t)(void *args);
  16. struct pin
  17. {
  18. uint32_t package_index;
  19. const char *name;
  20. IRQn_Type irq;
  21. rt_uint32_t irq_mode;
  22. pin_callback_t callback;
  23. void *callback_args;
  24. };
  25. typedef struct pin pin_t;
  26. struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
  27. {
  28. {-1, 0, RT_NULL, RT_NULL},
  29. {-1, 0, RT_NULL, RT_NULL},
  30. {-1, 0, RT_NULL, RT_NULL},
  31. {-1, 0, RT_NULL, RT_NULL},
  32. {-1, 0, RT_NULL, RT_NULL},
  33. {-1, 0, RT_NULL, RT_NULL},
  34. {-1, 0, RT_NULL, RT_NULL},
  35. {-1, 0, RT_NULL, RT_NULL},
  36. {-1, 0, RT_NULL, RT_NULL},
  37. {-1, 0, RT_NULL, RT_NULL},
  38. {-1, 0, RT_NULL, RT_NULL},
  39. {-1, 0, RT_NULL, RT_NULL},
  40. {-1, 0, RT_NULL, RT_NULL},
  41. {-1, 0, RT_NULL, RT_NULL},
  42. {-1, 0, RT_NULL, RT_NULL},
  43. {-1, 0, RT_NULL, RT_NULL},
  44. {-1, 0, RT_NULL, RT_NULL},
  45. {-1, 0, RT_NULL, RT_NULL},
  46. {-1, 0, RT_NULL, RT_NULL},
  47. {-1, 0, RT_NULL, RT_NULL},
  48. {-1, 0, RT_NULL, RT_NULL},
  49. {-1, 0, RT_NULL, RT_NULL},
  50. {-1, 0, RT_NULL, RT_NULL},
  51. {-1, 0, RT_NULL, RT_NULL},
  52. {-1, 0, RT_NULL, RT_NULL},
  53. {-1, 0, RT_NULL, RT_NULL},
  54. {-1, 0, RT_NULL, RT_NULL},
  55. {-1, 0, RT_NULL, RT_NULL},
  56. {-1, 0, RT_NULL, RT_NULL},
  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. {-1, 0, RT_NULL, RT_NULL},
  74. {-1, 0, RT_NULL, RT_NULL},
  75. {-1, 0, RT_NULL, RT_NULL},
  76. };
  77. static void yc_pin_mode(rt_device_t dev, rt_base_t pin, rt_uint8_t mode)
  78. {
  79. /* Configure GPIO_InitStructure */
  80. if (mode == PIN_MODE_OUTPUT)
  81. {
  82. /* output setting */
  83. GPIO_CONFIG(pin) = OUTPUT_LOW;
  84. }
  85. else if (mode == PIN_MODE_INPUT)
  86. {
  87. /* input setting: not pull. */
  88. GPIO_CONFIG(pin) = INPUT;
  89. }
  90. else if (mode == PIN_MODE_INPUT_PULLUP)
  91. {
  92. /* input setting: pull up. */
  93. GPIO_CONFIG(pin) = PULL_UP;
  94. }
  95. else if (mode == PIN_MODE_INPUT_PULLDOWN)
  96. {
  97. /* input setting: pull down. */
  98. GPIO_CONFIG(pin) = PULL_DOWN;
  99. }
  100. else if (mode == PIN_MODE_OUTPUT_OD)
  101. {
  102. /* output setting: od. */
  103. GPIO_CONFIG(pin) = PULL_UP;
  104. }
  105. }
  106. static void yc_pin_write(rt_device_t dev, rt_base_t pin, rt_uint8_t value)
  107. {
  108. if (value)
  109. {
  110. GPIO_CONFIG(pin) = OUTPUT_HIGH;
  111. }
  112. else
  113. {
  114. GPIO_CONFIG(pin) = OUTPUT_LOW;
  115. }
  116. }
  117. static rt_ssize_t yc_pin_read(rt_device_t dev, rt_base_t pin)
  118. {
  119. return GPIO_IN(pin / 16) & (1 << (pin % 16)) ? 1 : 0;
  120. }
  121. static rt_err_t yc_pin_attach_irq(struct rt_device *device,
  122. rt_base_t pin,
  123. rt_uint8_t mode,
  124. pin_callback_t cb,
  125. void *args)
  126. {
  127. rt_int32_t index = -1;
  128. rt_base_t level;
  129. if (pin >= PIN_MAX_NUM)
  130. {
  131. return -RT_EINVAL;
  132. }
  133. index = pin;
  134. level = rt_hw_interrupt_disable();
  135. pin_irq_hdr_tab[index].pin = pin;
  136. pin_irq_hdr_tab[index].hdr = cb;
  137. pin_irq_hdr_tab[index].mode = mode;
  138. pin_irq_hdr_tab[index].args = args;
  139. rt_hw_interrupt_enable(level);
  140. return RT_EOK;
  141. }
  142. static rt_err_t yc_pin_detach_irq(struct rt_device *device, rt_base_t pin)
  143. {
  144. rt_int32_t index = -1;
  145. rt_base_t level;
  146. if (pin >= PIN_MAX_NUM)
  147. {
  148. return -RT_EINVAL;
  149. }
  150. index = pin;
  151. level = rt_hw_interrupt_disable();
  152. pin_irq_hdr_tab[index].pin = -1;
  153. pin_irq_hdr_tab[index].hdr = RT_NULL;
  154. pin_irq_hdr_tab[index].mode = 0;
  155. pin_irq_hdr_tab[index].args = RT_NULL;
  156. rt_hw_interrupt_enable(level);
  157. return RT_EOK;
  158. }
  159. static rt_err_t yc_pin_irq_enable(struct rt_device *device,
  160. rt_base_t pin,
  161. rt_uint8_t enabled)
  162. {
  163. rt_int32_t index;
  164. rt_base_t level = 0;
  165. if (pin >= PIN_MAX_NUM)
  166. {
  167. return -RT_EINVAL;
  168. }
  169. index = pin;
  170. if (enabled == PIN_IRQ_ENABLE)
  171. {
  172. switch (pin_irq_hdr_tab[index].mode)
  173. {
  174. case PIN_IRQ_MODE_RISING:
  175. break;
  176. case PIN_IRQ_MODE_FALLING:
  177. break;
  178. case PIN_IRQ_MODE_RISING_FALLING:
  179. break;
  180. case PIN_IRQ_MODE_HIGH_LEVEL:
  181. GPIO_CONFIG(pin) = PULL_DOWN;
  182. GPIO_TRIG_MODE(pin / 16) &= (1 << (pin % 16));
  183. break;
  184. case PIN_IRQ_MODE_LOW_LEVEL:
  185. GPIO_CONFIG(pin) = PULL_UP;
  186. GPIO_TRIG_MODE(pin / 16) |= (1 << (pin % 16));
  187. break;
  188. default:
  189. rt_hw_interrupt_enable(level);
  190. return -RT_EINVAL;
  191. }
  192. level = rt_hw_interrupt_disable();
  193. NVIC_EnableIRQ(GPIO_IRQn);
  194. GPIO_INTR_EN(pin / 16) |= (1 << (pin % 16));
  195. rt_hw_interrupt_enable(level);
  196. }
  197. else if (enabled == PIN_IRQ_DISABLE)
  198. {
  199. NVIC_DisableIRQ(GPIO_IRQn);
  200. GPIO_INTR_EN(pin / 16) &= ~(1 << (pin % 16));
  201. }
  202. else
  203. {
  204. return -RT_ENOSYS;
  205. }
  206. return RT_EOK;
  207. }
  208. const static struct rt_pin_ops yc3121_pin_ops =
  209. {
  210. yc_pin_mode,
  211. yc_pin_write,
  212. yc_pin_read,
  213. yc_pin_attach_irq,
  214. yc_pin_detach_irq,
  215. yc_pin_irq_enable,
  216. RT_NULL,
  217. };
  218. int rt_hw_pin_init(void)
  219. {
  220. int result;
  221. result = rt_device_pin_register("pin", &yc3121_pin_ops, RT_NULL);
  222. return result;
  223. }
  224. INIT_BOARD_EXPORT(rt_hw_pin_init);
  225. void GPIO_IRQHandler(void)
  226. {
  227. int i;
  228. rt_interrupt_enter();
  229. for (i = 0; i < PIN_MAX_NUM; i++)
  230. {
  231. if ((GPIO_TRIG_MODE(i / 16) & (1 << (i % 16))) == (GPIO_IN(i / 16) & (1 << (i % 16))))
  232. {
  233. if (pin_irq_hdr_tab[i].hdr)
  234. {
  235. pin_irq_hdr_tab[i].hdr(pin_irq_hdr_tab[i].args);
  236. }
  237. }
  238. }
  239. rt_interrupt_leave();
  240. }