drv_gpio.c 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023/01/5 chushicheng first version
  9. *
  10. */
  11. #include "drv_gpio.h"
  12. #include <stdbool.h>
  13. #ifdef BSP_USING_GPIO
  14. #define DBG_TAG "drv.gpio"
  15. #define DBG_LVL DBG_INFO
  16. #include <rtdbg.h>
  17. static struct bflb_device_s *gpio;
  18. static struct rt_pin_irq_hdr pin_irq_hdr_tab[GPIO_MAX];
  19. static void gpio_isr(int irq, void *arg)
  20. {
  21. rt_base_t i;
  22. for(i = 0; i < GPIO_MAX; i ++)
  23. {
  24. if(pin_irq_hdr_tab[i].pin != -1)
  25. {
  26. bool intstatus = bflb_gpio_get_intstatus(gpio, i);
  27. if (intstatus) {
  28. bflb_gpio_int_clear(gpio, i);
  29. if(pin_irq_hdr_tab[i].hdr)
  30. pin_irq_hdr_tab[i].hdr(pin_irq_hdr_tab[i].args);
  31. }
  32. }
  33. }
  34. }
  35. static void _pin_write(rt_device_t dev, rt_base_t pin, rt_uint8_t value)
  36. {
  37. if(value)
  38. bflb_gpio_set(gpio, pin);
  39. else
  40. bflb_gpio_reset(gpio, pin);
  41. }
  42. static rt_ssize_t _pin_read(rt_device_t dev, rt_base_t pin)
  43. {
  44. return bflb_gpio_read(gpio, pin);
  45. }
  46. static void _pin_mode(rt_device_t dev, rt_base_t pin, rt_uint8_t mode)
  47. {
  48. rt_uint32_t cfgset = 0;
  49. switch(mode)
  50. {
  51. case PIN_MODE_OUTPUT:
  52. cfgset = GPIO_OUTPUT;
  53. break;
  54. case PIN_MODE_INPUT:
  55. cfgset = GPIO_INPUT;
  56. break;
  57. case PIN_MODE_INPUT_PULLUP:
  58. cfgset = GPIO_INPUT | GPIO_PULLUP;
  59. break;
  60. case PIN_MODE_INPUT_PULLDOWN:
  61. cfgset = GPIO_INPUT | GPIO_PULLDOWN;
  62. break;
  63. case PIN_MODE_OUTPUT_OD:
  64. cfgset = GPIO_OUTPUT | GPIO_FLOAT;
  65. break;
  66. default:
  67. cfgset = GPIO_OUTPUT | GPIO_FLOAT;
  68. break;
  69. }
  70. cfgset |= GPIO_SMT_EN | GPIO_DRV_0;
  71. bflb_gpio_init(gpio, pin, cfgset);
  72. }
  73. static rt_err_t _pin_attach_irq(struct rt_device *device, rt_base_t pin,
  74. rt_uint8_t irq_mode, void (*hdr)(void *args), void *args)
  75. {
  76. rt_base_t level;
  77. level = rt_hw_interrupt_disable();
  78. if(pin_irq_hdr_tab[pin].pin == pin &&
  79. pin_irq_hdr_tab[pin].hdr == hdr &&
  80. pin_irq_hdr_tab[pin].mode == irq_mode &&
  81. pin_irq_hdr_tab[pin].args == args)
  82. {
  83. rt_hw_interrupt_enable(level);
  84. return RT_EOK;
  85. }
  86. if(pin_irq_hdr_tab[pin].pin != -1)
  87. {
  88. rt_hw_interrupt_enable(level);
  89. return -RT_EBUSY;
  90. }
  91. pin_irq_hdr_tab[pin].pin = pin;
  92. pin_irq_hdr_tab[pin].mode = irq_mode;
  93. pin_irq_hdr_tab[pin].hdr = hdr;
  94. pin_irq_hdr_tab[pin].args = args;
  95. rt_hw_interrupt_enable(level);
  96. return RT_EOK;
  97. }
  98. static rt_err_t _pin_detach_irq(struct rt_device *device, rt_base_t pin)
  99. {
  100. rt_base_t level;
  101. level = rt_hw_interrupt_disable();
  102. if(pin_irq_hdr_tab[pin].pin == -1)
  103. {
  104. rt_hw_interrupt_enable(level);
  105. return RT_EOK;
  106. }
  107. pin_irq_hdr_tab[pin].pin = -1;
  108. pin_irq_hdr_tab[pin].mode = 0;
  109. pin_irq_hdr_tab[pin].hdr = RT_NULL;
  110. pin_irq_hdr_tab[pin].args = RT_NULL;
  111. rt_hw_interrupt_enable(level);
  112. return RT_EOK;
  113. }
  114. static rt_err_t _pin_irq_enable(struct rt_device *device, rt_base_t pin,
  115. rt_uint8_t enabled)
  116. {
  117. rt_base_t level;
  118. rt_uint8_t trig_mode = 0;
  119. if (enabled == PIN_IRQ_ENABLE)
  120. {
  121. level = rt_hw_interrupt_disable();
  122. if(pin_irq_hdr_tab[pin].pin == -1)
  123. {
  124. rt_hw_interrupt_enable(level);
  125. return -RT_ENOSYS;
  126. }
  127. switch (pin_irq_hdr_tab[pin].mode)
  128. {
  129. case PIN_IRQ_MODE_RISING:
  130. trig_mode = GPIO_INT_TRIG_MODE_SYNC_RISING_EDGE;
  131. break;
  132. case PIN_IRQ_MODE_FALLING:
  133. trig_mode = GPIO_INT_TRIG_MODE_SYNC_FALLING_EDGE;
  134. break;
  135. case PIN_IRQ_MODE_RISING_FALLING:
  136. trig_mode = GPIO_INT_TRIG_MODE_ASYNC_FALLING_EDGE;
  137. break;
  138. case PIN_IRQ_MODE_HIGH_LEVEL:
  139. trig_mode = GPIO_INT_TRIG_MODE_SYNC_HIGH_LEVEL;
  140. break;
  141. case PIN_IRQ_MODE_LOW_LEVEL:
  142. trig_mode = GPIO_INT_TRIG_MODE_SYNC_LOW_LEVEL;
  143. break;
  144. }
  145. bflb_gpio_int_init(gpio, pin, trig_mode);
  146. bflb_gpio_int_mask(gpio, pin, false);
  147. rt_hw_interrupt_enable(level);
  148. }
  149. else if(enabled == PIN_IRQ_DISABLE)
  150. {
  151. level = rt_hw_interrupt_disable();
  152. bflb_gpio_int_mask(gpio, pin, true);
  153. rt_hw_interrupt_enable(level);
  154. }
  155. else
  156. {
  157. return -RT_ENOSYS;
  158. }
  159. return RT_EOK;
  160. }
  161. const static struct rt_pin_ops bl_drv_pin_ops =
  162. {
  163. _pin_mode,
  164. _pin_write,
  165. _pin_read,
  166. _pin_attach_irq,
  167. _pin_detach_irq,
  168. _pin_irq_enable,
  169. NULL,
  170. };
  171. int rt_hw_pin_init(void)
  172. {
  173. rt_uint8_t i;
  174. for(i = 0; i < GPIO_MAX; i ++)
  175. {
  176. pin_irq_hdr_tab[i].pin = -1;
  177. }
  178. gpio = bflb_device_get_by_name("gpio");
  179. bflb_irq_attach(gpio->irq_num, gpio_isr, gpio);
  180. bflb_irq_enable(gpio->irq_num);
  181. return rt_device_pin_register("pin", &bl_drv_pin_ops, RT_NULL);
  182. }
  183. INIT_BOARD_EXPORT(rt_hw_pin_init);
  184. #endif /*BSP_USING_GPIO */