drv_gpio.c 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /*
  2. * Copyright (c) 2006-2024, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023/10/19 xiunian first version
  9. */
  10. #include <rthw.h>
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include <board.h>
  14. #ifdef RT_USING_SMART
  15. #include <ioremap.h>
  16. #endif
  17. #ifdef RT_USING_PIN
  18. #include "drv_gpio.h"
  19. #define GPIO_SWPORTA_DR 0x00
  20. #define GPIO_SWPORTA_DDR 0x04
  21. #define GPIO_INTEN 0x30
  22. #define GPIO_INTTYPE_LEVEL 0x38
  23. #define GPIO_INT_POLARITY 0x3c
  24. #define GPIO_INTSTATUS 0x40
  25. #define GPIO_PORTA_EOI 0x4c
  26. #define GPIO_EXT_PORTA 0x50
  27. #define DWAPB_GPIOA_BASE 0x03020000
  28. #define DWAPB_GPIOE_BASE 0x05021000
  29. #define DWAPB_GPIO_SIZE 0x1000
  30. #define DWAPB_GPIO_PORT_NR 5
  31. #define DWAPB_GPIO_NR 32
  32. #define PIN_NUM(port, no) (((((port) & 0xFu) << 8) | ((no) & 0xFFu)))
  33. #define PIN_PORT(pin) ((uint8_t)(((pin) >> 8) & 0xFu))
  34. #define PIN_NO(pin) ((uint8_t)((pin) & 0xFFu))
  35. #define BIT(x) (1UL << (x))
  36. rt_inline rt_uint32_t dwapb_read32(rt_ubase_t addr)
  37. {
  38. return HWREG32(addr);
  39. }
  40. rt_inline void dwapb_write32(rt_ubase_t addr, rt_uint32_t value)
  41. {
  42. HWREG32(addr) = value;
  43. }
  44. static rt_ubase_t dwapb_gpio_base = DWAPB_GPIOA_BASE;
  45. static rt_ubase_t dwapb_gpio_base_e = DWAPB_GPIOE_BASE;
  46. static struct dwapb_event
  47. {
  48. void (*(hdr[DWAPB_GPIO_NR]))(void *args);
  49. void *args[DWAPB_GPIO_NR];
  50. rt_uint8_t is_both_edge[DWAPB_GPIO_NR];
  51. } _dwapb_events[DWAPB_GPIO_PORT_NR];
  52. static void dwapb_toggle_trigger(rt_uint8_t port, rt_uint8_t bit)
  53. {
  54. rt_uint8_t val;
  55. rt_ubase_t base_addr;
  56. rt_uint32_t pol;
  57. base_addr = (port == 4 ? dwapb_gpio_base_e : (dwapb_gpio_base + DWAPB_GPIO_SIZE * port));
  58. pol = dwapb_read32(base_addr + GPIO_INT_POLARITY);
  59. /* Just read the current value right out of the data register */
  60. val = (rt_uint8_t)((dwapb_read32(base_addr + GPIO_EXT_PORTA) >> (bit)) & 1);
  61. if (val)
  62. pol &= ~BIT(bit);
  63. else
  64. pol |= BIT(bit);
  65. dwapb_write32(base_addr + GPIO_INT_POLARITY, pol);
  66. }
  67. static void dwapb_pin_mode(struct rt_device *device, rt_base_t pin, rt_uint8_t mode)
  68. {
  69. rt_uint8_t bit, port;
  70. rt_ubase_t base_addr;
  71. rt_uint32_t reg_val;
  72. bit = PIN_NO(pin);
  73. port = PIN_PORT(pin);
  74. base_addr = (port == 4 ? dwapb_gpio_base_e : (dwapb_gpio_base + DWAPB_GPIO_SIZE * port));
  75. reg_val = dwapb_read32(base_addr + GPIO_SWPORTA_DDR);
  76. switch (mode)
  77. {
  78. case PIN_MODE_OUTPUT:
  79. reg_val |= BIT(bit);
  80. break;
  81. case PIN_MODE_INPUT:
  82. reg_val &= ~BIT(bit);
  83. break;
  84. }
  85. dwapb_write32(base_addr + GPIO_SWPORTA_DDR, reg_val);
  86. }
  87. static void dwapb_pin_write(struct rt_device *device, rt_base_t pin, rt_uint8_t value)
  88. {
  89. rt_uint8_t bit, port;
  90. rt_ubase_t base_addr;
  91. rt_uint32_t reg_val;
  92. bit = PIN_NO(pin);
  93. port = PIN_PORT(pin);
  94. base_addr = (port == 4 ? dwapb_gpio_base_e : (dwapb_gpio_base + DWAPB_GPIO_SIZE * port));
  95. reg_val = dwapb_read32(base_addr + GPIO_SWPORTA_DR);
  96. reg_val = (value ? (reg_val | BIT(bit)) : (reg_val & (~BIT(bit))));
  97. dwapb_write32(base_addr + GPIO_SWPORTA_DR, reg_val);
  98. }
  99. static rt_ssize_t dwapb_pin_read(struct rt_device *device, rt_base_t pin)
  100. {
  101. rt_uint8_t bit, port;
  102. rt_ubase_t base_addr;
  103. bit = PIN_NO(pin);
  104. port = PIN_PORT(pin);
  105. base_addr = (port == 4 ? dwapb_gpio_base_e : (dwapb_gpio_base + DWAPB_GPIO_SIZE * port));
  106. rt_uint32_t reg_val = dwapb_read32(GPIO_EXT_PORTA + base_addr);
  107. return ((reg_val >> (bit)) & 1);
  108. }
  109. static rt_base_t dwapb_pin_get(const char *name)
  110. {
  111. rt_base_t pin = 0;
  112. int port_num, pin_num = 0;
  113. int i, name_len;
  114. name_len = rt_strlen(name);
  115. if ((name_len < 2) || (name_len > 3))
  116. {
  117. goto out;
  118. }
  119. if ((name[0] >= 'A') && (name[0] <= 'E'))
  120. {
  121. port_num = (int)(name[0] - 'A');
  122. }
  123. else
  124. {
  125. goto out;
  126. }
  127. for (i = 1; i < name_len; i++)
  128. {
  129. pin_num *= 10;
  130. pin_num += name[i] - '0';
  131. }
  132. pin = PIN_NUM(port_num, pin_num);
  133. return pin;
  134. out:
  135. rt_kprintf("xy x:A~E y:0~31, e.g. C24\n");
  136. return -RT_EINVAL;
  137. }
  138. static rt_err_t dwapb_pin_attach_irq(struct rt_device *device, rt_base_t pin, rt_uint8_t mode, void (*hdr)(void *args), void *args)
  139. {
  140. rt_uint8_t bit, port;
  141. rt_ubase_t base_addr;
  142. rt_uint32_t it_val, ip_val;
  143. bit = PIN_NO(pin);
  144. port = PIN_PORT(pin);
  145. base_addr = (port == 4 ? dwapb_gpio_base_e : (dwapb_gpio_base + DWAPB_GPIO_SIZE * port));
  146. it_val = dwapb_read32(base_addr + GPIO_INTTYPE_LEVEL);
  147. ip_val = dwapb_read32(base_addr + GPIO_INT_POLARITY);
  148. if (mode == PIN_IRQ_MODE_HIGH_LEVEL || mode == PIN_IRQ_MODE_LOW_LEVEL)
  149. {
  150. rt_bool_t polarity = (mode == PIN_IRQ_MODE_HIGH_LEVEL);
  151. /* Enable level detection */
  152. it_val = (it_val & (~BIT(bit)));
  153. /* Select polarity */
  154. ip_val = (polarity ? (ip_val | BIT(bit)) : (ip_val & (~BIT(bit))));
  155. }
  156. else if (mode == PIN_IRQ_MODE_RISING_FALLING)
  157. {
  158. /* Disable level detection */
  159. it_val = (it_val | BIT(bit));
  160. /* Select both edges */
  161. dwapb_toggle_trigger(port, bit);
  162. }
  163. else if (mode == PIN_IRQ_MODE_RISING || mode == PIN_IRQ_MODE_FALLING)
  164. {
  165. rt_bool_t rising = (mode == PIN_IRQ_MODE_RISING);
  166. /* Disable level detection */
  167. it_val = (it_val | BIT(bit));
  168. /* Select edge */
  169. ip_val = (rising ? (ip_val | BIT(bit)) : (ip_val & (~BIT(bit))));
  170. }
  171. else
  172. {
  173. /* No trigger: disable everything */
  174. it_val = (it_val & (~BIT(bit)));
  175. ip_val = (ip_val & (~BIT(bit)));
  176. }
  177. dwapb_write32(base_addr + GPIO_INTTYPE_LEVEL, it_val);
  178. if (mode != PIN_IRQ_MODE_RISING_FALLING)
  179. dwapb_write32(base_addr + GPIO_INT_POLARITY, ip_val);
  180. _dwapb_events[PIN_PORT(pin)].hdr[PIN_NO(pin)] = hdr;
  181. _dwapb_events[PIN_PORT(pin)].args[PIN_NO(pin)] = args;
  182. _dwapb_events[PIN_PORT(pin)].is_both_edge[PIN_NO(pin)] = (mode == PIN_IRQ_MODE_RISING_FALLING);
  183. return RT_EOK;
  184. }
  185. static rt_err_t dwapb_pin_detach_irq(struct rt_device *device, rt_base_t pin)
  186. {
  187. _dwapb_events[PIN_PORT(pin)].hdr[PIN_NO(pin)] = RT_NULL;
  188. _dwapb_events[PIN_PORT(pin)].args[PIN_NO(pin)] = RT_NULL;
  189. _dwapb_events[PIN_PORT(pin)].is_both_edge[PIN_NO(pin)] = 0;
  190. return RT_EOK;
  191. }
  192. static rt_err_t dwapb_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled)
  193. {
  194. rt_uint8_t bit, port;
  195. rt_ubase_t base_addr;
  196. bit = PIN_NO(pin);
  197. port = PIN_PORT(pin);
  198. base_addr = (port == 4 ? dwapb_gpio_base_e : (dwapb_gpio_base + DWAPB_GPIO_SIZE * port));
  199. rt_uint32_t reg_val = dwapb_read32(base_addr + GPIO_INTEN);
  200. reg_val = (enabled ? (reg_val | BIT(bit)) : (reg_val & (~BIT(bit))));
  201. dwapb_write32(base_addr + GPIO_INTEN, reg_val);
  202. return RT_EOK;
  203. }
  204. static const struct rt_pin_ops _dwapb_ops =
  205. {
  206. dwapb_pin_mode,
  207. dwapb_pin_write,
  208. dwapb_pin_read,
  209. dwapb_pin_attach_irq,
  210. dwapb_pin_detach_irq,
  211. dwapb_pin_irq_enable,
  212. dwapb_pin_get,
  213. };
  214. static void rt_hw_gpio_isr(int irqno, void *param)
  215. {
  216. rt_uint8_t port;
  217. rt_ubase_t base_addr;
  218. rt_uint32_t pending, mask;
  219. mask = 0;
  220. port = (irqno == SYS_GPIO_IRQ_BASE ? 4 : (irqno - GPIO_IRQ_BASE));
  221. base_addr = (port == 4 ? dwapb_gpio_base_e : (dwapb_gpio_base + DWAPB_GPIO_SIZE * port));
  222. pending = dwapb_read32(base_addr + GPIO_INTSTATUS);
  223. if (pending)
  224. {
  225. rt_base_t bit;
  226. for (bit = 0; bit < DWAPB_GPIO_NR; ++bit)
  227. {
  228. if (pending & BIT(bit))
  229. {
  230. mask = (mask | (BIT(bit)));
  231. if (_dwapb_events[port].hdr[bit] != RT_NULL)
  232. {
  233. _dwapb_events[port].hdr[bit](_dwapb_events[port].args[bit]);
  234. }
  235. if (_dwapb_events[port].is_both_edge[bit]) {
  236. dwapb_toggle_trigger(port, bit);
  237. }
  238. }
  239. }
  240. }
  241. dwapb_write32(base_addr + GPIO_PORTA_EOI, mask);
  242. }
  243. int rt_hw_gpio_init(void)
  244. {
  245. rt_device_pin_register("gpio", &_dwapb_ops, RT_NULL);
  246. #define INT_INSTALL_GPIO_DEVICE(no) \
  247. rt_hw_interrupt_install(GPIO_IRQ_BASE + (no), rt_hw_gpio_isr, RT_NULL, "gpio"); \
  248. rt_hw_interrupt_umask(GPIO_IRQ_BASE + (no));
  249. INT_INSTALL_GPIO_DEVICE(0);
  250. INT_INSTALL_GPIO_DEVICE(1);
  251. INT_INSTALL_GPIO_DEVICE(2);
  252. INT_INSTALL_GPIO_DEVICE(3);
  253. rt_hw_interrupt_install(SYS_GPIO_IRQ_BASE, rt_hw_gpio_isr, RT_NULL, "gpio");
  254. rt_hw_interrupt_umask(SYS_GPIO_IRQ_BASE);
  255. return 0;
  256. }
  257. INIT_DEVICE_EXPORT(rt_hw_gpio_init);
  258. #endif /* RT_USING_PIN */