ch56x_gpio.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  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. * 2022-07-15 Emuzit first version
  9. */
  10. #include <rthw.h>
  11. #include <drivers/pin.h>
  12. #include "ch56x_gpio.h"
  13. #include "isr_sp.h"
  14. struct port_info
  15. {
  16. uint32_t pin_mark;
  17. struct gpio_px_regs *regbase;
  18. };
  19. static const struct port_info pin_ports[GPIO_PORTS] =
  20. {
  21. {GPIO_PA_PIN_MARK, (struct gpio_px_regs *)GPIO_REG_BASE_PA},
  22. {GPIO_PB_PIN_MARK, (struct gpio_px_regs *)GPIO_REG_BASE_PB},
  23. };
  24. static struct rt_pin_irq_hdr pin_irq_hdr_table[8] =
  25. {
  26. {-1, 0, RT_NULL, RT_NULL},
  27. {-1, 0, RT_NULL, RT_NULL},
  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. };
  35. #if defined(SOC_SERIES_CH569)
  36. static int _gpio_pin_to_ibit(rt_base_t pin)
  37. {
  38. /* gpio ext interrupt 7-0 : {PB15,PB12,PB11,PB4,PB3,PA4,PA3,PA2}
  39. * not time critical, use linear search
  40. */
  41. switch (pin)
  42. {
  43. case GET_PIN(A, 2): return 0;
  44. case GET_PIN(A, 3): return 1;
  45. case GET_PIN(A, 4): return 2;
  46. case GET_PIN(B, 3): return 3;
  47. case GET_PIN(B, 4): return 4;
  48. case GET_PIN(B, 11): return 5;
  49. case GET_PIN(B, 12): return 6;
  50. case GET_PIN(B, 15): return 7;
  51. }
  52. return -1;
  53. }
  54. #else
  55. static int _gpio_pin_to_ibit(rt_base_t pin)
  56. {
  57. /* gpio ext interrupt 7-0 : {PB10,PB4,PA12,PA11,PA10,PA6,PA4,PA3}
  58. * not time critical, use linear search
  59. */
  60. switch (pin)
  61. {
  62. case GET_PIN(A, 3): return 0;
  63. case GET_PIN(A, 4): return 1;
  64. case GET_PIN(A, 6): return 2;
  65. case GET_PIN(A, 10): return 3;
  66. case GET_PIN(A, 11): return 4;
  67. case GET_PIN(A, 12): return 5;
  68. case GET_PIN(B, 4): return 6;
  69. case GET_PIN(B, 10): return 7;
  70. }
  71. return -1;
  72. }
  73. #endif
  74. static struct gpio_px_regs *_gpio_px_regbase(rt_base_t pin)
  75. {
  76. /* fixed linear mapping : 32 pins per port, for ports A,B,C,D...
  77. */
  78. uint32_t port = (uint32_t)pin >> 5;
  79. uint32_t bitpos = 1 << (pin & 0x1f);
  80. if (port < GPIO_PORTS && (pin_ports[port].pin_mark & bitpos))
  81. return pin_ports[port].regbase;
  82. else
  83. return RT_NULL;
  84. }
  85. static void gpio_pin_mode(struct rt_device *device, rt_base_t pin, rt_uint8_t mode)
  86. {
  87. volatile struct gpio_px_regs *px;
  88. uint32_t port = (uint32_t)pin >> 5;
  89. uint32_t bitpos = 1 << (pin & 0x1f);
  90. if (port < GPIO_PORTS && (pin_ports[port].pin_mark & bitpos))
  91. px = pin_ports[port].regbase;
  92. else
  93. return;
  94. switch (mode)
  95. {
  96. case PIN_MODE_OUTPUT:
  97. BITS_CLR(px->PD, bitpos);
  98. BITS_SET(px->DIR, bitpos);
  99. break;
  100. case PIN_MODE_INPUT:
  101. BITS_CLR(px->PU, bitpos);
  102. BITS_CLR(px->PD, bitpos);
  103. BITS_CLR(px->DIR, bitpos);
  104. break;
  105. case PIN_MODE_INPUT_PULLUP:
  106. BITS_SET(px->PU, bitpos);
  107. BITS_CLR(px->PD, bitpos);
  108. BITS_CLR(px->DIR, bitpos);
  109. break;
  110. case PIN_MODE_INPUT_PULLDOWN:
  111. BITS_CLR(px->PU, bitpos);
  112. BITS_SET(px->PD, bitpos);
  113. BITS_CLR(px->DIR, bitpos);
  114. break;
  115. case PIN_MODE_OUTPUT_OD:
  116. BITS_SET(px->PD, bitpos);
  117. BITS_SET(px->OUT, bitpos);
  118. }
  119. }
  120. static void gpio_pin_write(struct rt_device *device, rt_base_t pin, rt_uint8_t value)
  121. {
  122. volatile struct gpio_px_regs *px;
  123. uint32_t port = (uint32_t)pin >> 5;
  124. uint32_t bitpos = 1 << (pin & 0x1f);
  125. if (port < GPIO_PORTS && (pin_ports[port].pin_mark & bitpos))
  126. px = pin_ports[port].regbase;
  127. else
  128. return;
  129. if (value == 0)
  130. BITS_CLR(px->OUT, bitpos);
  131. else
  132. BITS_SET(px->OUT, bitpos);
  133. }
  134. static rt_ssize_t gpio_pin_read(struct rt_device *device, rt_base_t pin)
  135. {
  136. volatile struct gpio_px_regs *px;
  137. uint32_t port = (uint32_t)pin >> 5;
  138. uint32_t bitpos = 1 << (pin & 0x1f);
  139. if (port < GPIO_PORTS && (pin_ports[port].pin_mark & bitpos))
  140. px = pin_ports[port].regbase;
  141. else
  142. return PIN_LOW;
  143. return (px->PIN & bitpos) ? PIN_HIGH : PIN_LOW;
  144. }
  145. static rt_base_t gpio_pin_get(const char *name)
  146. {
  147. int port, pin, sz, n;
  148. /* pin name is in the form "PX.nn" (X: A,B,C,D...; nn: 0~31)
  149. * fixed linear mapping : 32 pins per port, for ports A,B,C,D...
  150. */
  151. sz = rt_strlen(name);
  152. if ((sz == 4 || sz == 5) && name[0] == 'P' && name[2] == '.')
  153. {
  154. port = name[1] - 'A';
  155. pin = name[3] - '0';
  156. if (0 <= port && port < GPIO_PORTS && 0 <= pin && pin <= 9)
  157. {
  158. if (sz == 5)
  159. {
  160. n = name[4] - '0';
  161. pin = (0 <= n && n <= 9) ? (pin * 10 + n) : 32;
  162. }
  163. if (pin < 32 && (pin_ports[port].pin_mark & (1 << pin)))
  164. {
  165. return port * 32 + pin;
  166. }
  167. }
  168. }
  169. out:
  170. rt_kprintf("PX.nn X: A,B,C,D... nn: 0~31, e.g. PA.0\n");
  171. return -1;
  172. }
  173. static rt_err_t gpio_pin_attach_irq(struct rt_device *device, rt_base_t pin,
  174. rt_uint8_t mode, void (*hdr)(void *args), void *args)
  175. {
  176. rt_base_t level;
  177. int ibit;
  178. switch (mode)
  179. {
  180. case PIN_IRQ_MODE_RISING:
  181. case PIN_IRQ_MODE_FALLING:
  182. case PIN_IRQ_MODE_HIGH_LEVEL:
  183. case PIN_IRQ_MODE_LOW_LEVEL:
  184. break;
  185. case PIN_IRQ_MODE_RISING_FALLING:
  186. /* hardware not supported */
  187. default:
  188. return -RT_EINVAL;
  189. }
  190. ibit = _gpio_pin_to_ibit(pin);
  191. if (ibit < 0)
  192. return -RT_EINVAL;
  193. level = rt_hw_interrupt_disable();
  194. if (pin_irq_hdr_table[ibit].pin == pin &&
  195. pin_irq_hdr_table[ibit].mode == mode &&
  196. pin_irq_hdr_table[ibit].hdr == hdr &&
  197. pin_irq_hdr_table[ibit].args == args)
  198. {
  199. rt_hw_interrupt_enable(level);
  200. return RT_EOK;
  201. }
  202. if (pin_irq_hdr_table[ibit].pin >= 0)
  203. {
  204. rt_hw_interrupt_enable(level);
  205. return -RT_EFULL;
  206. }
  207. pin_irq_hdr_table[ibit].pin = pin;
  208. pin_irq_hdr_table[ibit].mode = mode;
  209. pin_irq_hdr_table[ibit].hdr = hdr;
  210. pin_irq_hdr_table[ibit].args = args;
  211. rt_hw_interrupt_enable(level);
  212. return RT_EOK;
  213. }
  214. static rt_err_t gpio_pin_detach_irq(struct rt_device *device, rt_base_t pin)
  215. {
  216. rt_base_t level;
  217. int ibit;
  218. ibit = _gpio_pin_to_ibit(pin);
  219. if (ibit < 0)
  220. return -RT_EINVAL;
  221. level = rt_hw_interrupt_disable();
  222. if (pin_irq_hdr_table[ibit].pin < 0)
  223. {
  224. rt_hw_interrupt_enable(level);
  225. return RT_EOK;
  226. }
  227. pin_irq_hdr_table[ibit].pin = -1;
  228. pin_irq_hdr_table[ibit].mode = 0;
  229. pin_irq_hdr_table[ibit].hdr = RT_NULL;
  230. pin_irq_hdr_table[ibit].args = RT_NULL;
  231. rt_hw_interrupt_enable(level);
  232. return RT_EOK;
  233. }
  234. static rt_err_t gpio_pin_irq_enable(struct rt_device *device, rt_base_t pin,
  235. rt_uint8_t enabled)
  236. {
  237. volatile struct gpio_registers *gpio;
  238. rt_base_t level, int_enable;
  239. int ibit, bitpos;
  240. ibit = _gpio_pin_to_ibit(pin);
  241. if (ibit < 0)
  242. return -RT_EINVAL;
  243. bitpos = (1 << ibit);
  244. gpio = (struct gpio_registers *)GPIO_REG_BASE;
  245. if (enabled == PIN_IRQ_ENABLE)
  246. {
  247. level = rt_hw_interrupt_disable();
  248. if (pin_irq_hdr_table[ibit].pin != pin)
  249. {
  250. rt_hw_interrupt_enable(level);
  251. return -RT_EINVAL;
  252. }
  253. switch (pin_irq_hdr_table[ibit].mode)
  254. {
  255. case PIN_IRQ_MODE_RISING:
  256. BITS_SET(gpio->INT_MODE.reg, bitpos);
  257. BITS_SET(gpio->INT_POLAR.reg, bitpos);
  258. break;
  259. case PIN_IRQ_MODE_FALLING:
  260. BITS_SET(gpio->INT_MODE.reg, bitpos);
  261. BITS_CLR(gpio->INT_POLAR.reg, bitpos);
  262. break;
  263. case PIN_IRQ_MODE_HIGH_LEVEL:
  264. BITS_CLR(gpio->INT_MODE.reg, bitpos);
  265. BITS_SET(gpio->INT_POLAR.reg, bitpos);
  266. break;
  267. case PIN_IRQ_MODE_LOW_LEVEL:
  268. BITS_CLR(gpio->INT_MODE.reg, bitpos);
  269. BITS_CLR(gpio->INT_POLAR.reg, bitpos);
  270. break;
  271. case PIN_IRQ_MODE_RISING_FALLING:
  272. default:
  273. rt_hw_interrupt_enable(level);
  274. return -RT_EINVAL;
  275. }
  276. /* clear possible pending intr, then enable pin intr */
  277. int_enable = gpio->INT_ENABLE.reg;
  278. gpio->INT_FLAG.reg = bitpos;
  279. gpio->INT_ENABLE.reg = int_enable | bitpos;
  280. /* enable GPIO_IRQn if this is the first enabled EXTIx */
  281. if (int_enable == 0)
  282. {
  283. rt_hw_interrupt_umask(GPIO_IRQn);
  284. }
  285. rt_hw_interrupt_enable(level);
  286. }
  287. else if (enabled == PIN_IRQ_DISABLE)
  288. {
  289. level = rt_hw_interrupt_disable();
  290. int_enable = gpio->INT_ENABLE.reg;
  291. BITS_CLR(int_enable, bitpos);
  292. gpio->INT_ENABLE.reg = int_enable;
  293. /* disable GPIO_IRQn if no EXTIx enabled */
  294. if (int_enable == 0)
  295. {
  296. rt_hw_interrupt_mask(GPIO_IRQn);
  297. }
  298. rt_hw_interrupt_enable(level);
  299. }
  300. else
  301. {
  302. return -RT_EINVAL;
  303. }
  304. return RT_EOK;
  305. }
  306. static const struct rt_pin_ops pin_ops =
  307. {
  308. .pin_mode = gpio_pin_mode,
  309. .pin_write = gpio_pin_write,
  310. .pin_read = gpio_pin_read,
  311. .pin_attach_irq = gpio_pin_attach_irq,
  312. .pin_detach_irq = gpio_pin_detach_irq,
  313. .pin_irq_enable = gpio_pin_irq_enable,
  314. .pin_get = gpio_pin_get,
  315. };
  316. static int rt_hw_pin_init(void)
  317. {
  318. return rt_device_pin_register("pin", &pin_ops, RT_NULL);
  319. }
  320. INIT_BOARD_EXPORT(rt_hw_pin_init);
  321. void gpio_irq_handler(void) __attribute__((interrupt()));
  322. void gpio_irq_handler(void)
  323. {
  324. volatile struct gpio_registers *gpio;
  325. uint8_t iflags;
  326. int ibit, bitpos;
  327. isr_sp_enter();
  328. rt_interrupt_enter();
  329. gpio = (struct gpio_registers *)GPIO_REG_BASE;
  330. iflags = gpio->INT_FLAG.reg;
  331. /* prioritized as pb15 -> pa2 (CH569), or pb10 -> pa3 */
  332. for (ibit = 7; ibit >= 0; ibit--)
  333. {
  334. bitpos = (1 << ibit);
  335. if (iflags & bitpos)
  336. {
  337. if (pin_irq_hdr_table[ibit].hdr)
  338. {
  339. pin_irq_hdr_table[ibit].hdr(pin_irq_hdr_table[ibit].args);
  340. }
  341. /* clear interrupt */
  342. gpio->INT_FLAG.reg = bitpos;
  343. }
  344. }
  345. rt_interrupt_leave();
  346. isr_sp_leave();
  347. }