drv_gpio.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. /*
  2. * Copyright (c) 2006-2026, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2026-04-20 rcitach first version
  9. */
  10. #include <rtdevice.h>
  11. #include "drv_gpio.h"
  12. #include "interrupt.h"
  13. #define S100_GPIO_PORT0_BASE 0x23480000U
  14. #define S100_GPIO_PORT1_BASE 0x23490000U
  15. #define S100_GPIO_PORT2_BASE 0x234A0000U
  16. #define S100_GPIO_PORT0_IRQ 68
  17. #define S100_GPIO_PORT1_IRQ 69
  18. #define S100_GPIO_PORT2_IRQ 70
  19. #define S100_GPIO_PORT_COUNT 3
  20. #define S100_GPIO_CHANNELS_PER_PORT 32
  21. typedef struct
  22. {
  23. volatile rt_uint32_t swporta_dr;
  24. volatile rt_uint32_t swporta_ddr;
  25. volatile rt_uint32_t rsvd0;
  26. volatile rt_uint32_t swportb_dr;
  27. volatile rt_uint32_t swportb_ddr;
  28. volatile rt_uint32_t rsvd1[7];
  29. volatile rt_uint32_t inten;
  30. volatile rt_uint32_t intmask;
  31. volatile rt_uint32_t inttype_level;
  32. volatile rt_uint32_t int_polarity;
  33. volatile rt_uint32_t intstatus;
  34. volatile rt_uint32_t raw_intstatus;
  35. volatile rt_uint32_t debounce;
  36. volatile rt_uint32_t porta_eoi;
  37. volatile rt_uint32_t ext_porta;
  38. volatile rt_uint32_t ext_portb;
  39. volatile rt_uint32_t rsvd2[2];
  40. volatile rt_uint32_t ls_sync;
  41. volatile rt_uint32_t id_code;
  42. volatile rt_uint32_t int_bothedge;
  43. volatile rt_uint32_t ver_id_code;
  44. } s100_gpio_reg_t;
  45. static s100_gpio_reg_t *const s100_gpio_ports[S100_GPIO_PORT_COUNT] =
  46. {
  47. (s100_gpio_reg_t *)S100_GPIO_PORT0_BASE,
  48. (s100_gpio_reg_t *)S100_GPIO_PORT1_BASE,
  49. (s100_gpio_reg_t *)S100_GPIO_PORT2_BASE,
  50. };
  51. static const int s100_gpio_port_irqs[S100_GPIO_PORT_COUNT] =
  52. {
  53. S100_GPIO_PORT0_IRQ,
  54. S100_GPIO_PORT1_IRQ,
  55. S100_GPIO_PORT2_IRQ,
  56. };
  57. static struct rt_pin_irq_hdr s100_pin_irq_hdr[S100_GPIO_PIN_COUNT];
  58. static rt_err_t s100_pin_to_gpio(s100_pin_t pin,
  59. rt_uint8_t *port_index,
  60. rt_uint8_t *bit_index)
  61. {
  62. rt_uint8_t gpio_pin;
  63. if (!s100_pin_is_valid(pin))
  64. {
  65. return -RT_EINVAL;
  66. }
  67. /* The MCU GPIO numbering skips pin 79, so pins >= 80 shift by one. */
  68. gpio_pin = (pin >= 80U) ? (pin - 1U) : pin;
  69. *port_index = gpio_pin / S100_GPIO_CHANNELS_PER_PORT;
  70. *bit_index = gpio_pin % S100_GPIO_CHANNELS_PER_PORT;
  71. if (*port_index >= S100_GPIO_PORT_COUNT)
  72. {
  73. return -RT_EINVAL;
  74. }
  75. return RT_EOK;
  76. }
  77. static rt_err_t s100_gpio_to_pin(rt_uint8_t port_index,
  78. rt_uint8_t bit_index,
  79. s100_pin_t *pin)
  80. {
  81. rt_uint8_t gpio_pin;
  82. if (port_index >= S100_GPIO_PORT_COUNT || bit_index >= S100_GPIO_CHANNELS_PER_PORT)
  83. {
  84. return -RT_EINVAL;
  85. }
  86. gpio_pin = (port_index * S100_GPIO_CHANNELS_PER_PORT) + bit_index;
  87. *pin = (gpio_pin >= 79U) ? (gpio_pin + 1U) : gpio_pin;
  88. if (!s100_pin_is_valid(*pin))
  89. {
  90. return -RT_EINVAL;
  91. }
  92. return RT_EOK;
  93. }
  94. static rt_err_t s100_gpio_config_irq(rt_base_t pin, rt_uint8_t mode)
  95. {
  96. rt_uint8_t port_index;
  97. rt_uint8_t bit_index;
  98. rt_uint32_t bit;
  99. s100_gpio_reg_t *gpio;
  100. rt_err_t ret;
  101. ret = s100_pin_to_gpio((s100_pin_t)pin, &port_index, &bit_index);
  102. if (ret != RT_EOK)
  103. {
  104. return ret;
  105. }
  106. gpio = s100_gpio_ports[port_index];
  107. bit = 1UL << bit_index;
  108. gpio->inten &= ~bit;
  109. gpio->intmask |= bit;
  110. gpio->int_bothedge &= ~bit;
  111. switch (mode)
  112. {
  113. case PIN_IRQ_MODE_RISING:
  114. gpio->inttype_level |= bit;
  115. gpio->int_polarity |= bit;
  116. break;
  117. case PIN_IRQ_MODE_FALLING:
  118. gpio->inttype_level |= bit;
  119. gpio->int_polarity &= ~bit;
  120. break;
  121. case PIN_IRQ_MODE_RISING_FALLING:
  122. gpio->inttype_level |= bit;
  123. gpio->int_bothedge |= bit;
  124. break;
  125. case PIN_IRQ_MODE_HIGH_LEVEL:
  126. gpio->inttype_level &= ~bit;
  127. gpio->int_polarity |= bit;
  128. break;
  129. case PIN_IRQ_MODE_LOW_LEVEL:
  130. gpio->inttype_level &= ~bit;
  131. gpio->int_polarity &= ~bit;
  132. break;
  133. default:
  134. return -RT_EINVAL;
  135. }
  136. gpio->porta_eoi = bit;
  137. return RT_EOK;
  138. }
  139. rt_err_t s100_gpio_set_direction(s100_pin_t pin, s100_pin_direction_t direction)
  140. {
  141. rt_uint8_t port_index;
  142. rt_uint8_t bit_index;
  143. rt_uint32_t bit;
  144. rt_err_t ret;
  145. ret = s100_pin_to_gpio(pin, &port_index, &bit_index);
  146. if (ret != RT_EOK)
  147. {
  148. return -RT_EINVAL;
  149. }
  150. bit = 1UL << bit_index;
  151. if (direction == S100_PIN_DIR_OUT)
  152. {
  153. s100_gpio_ports[port_index]->swporta_ddr |= bit;
  154. }
  155. else
  156. {
  157. s100_gpio_ports[port_index]->swporta_ddr &= ~bit;
  158. }
  159. return RT_EOK;
  160. }
  161. rt_err_t s100_gpio_write_pin(s100_pin_t pin, s100_pin_level_t level)
  162. {
  163. rt_uint8_t port_index;
  164. rt_uint8_t bit_index;
  165. rt_uint32_t bit;
  166. rt_err_t ret;
  167. ret = s100_pin_to_gpio(pin, &port_index, &bit_index);
  168. if (ret != RT_EOK)
  169. {
  170. return -RT_EINVAL;
  171. }
  172. bit = 1UL << bit_index;
  173. if (level == S100_PIN_LEVEL_HIGH)
  174. {
  175. s100_gpio_ports[port_index]->swporta_dr |= bit;
  176. }
  177. else
  178. {
  179. s100_gpio_ports[port_index]->swporta_dr &= ~bit;
  180. }
  181. return RT_EOK;
  182. }
  183. rt_err_t s100_gpio_read_pin(s100_pin_t pin, s100_pin_level_t *level)
  184. {
  185. rt_uint8_t port_index;
  186. rt_uint8_t bit_index;
  187. rt_err_t ret;
  188. if (level == RT_NULL)
  189. {
  190. return -RT_EINVAL;
  191. }
  192. ret = s100_pin_to_gpio(pin, &port_index, &bit_index);
  193. if (ret != RT_EOK)
  194. {
  195. return -RT_EINVAL;
  196. }
  197. *level = (s100_gpio_ports[port_index]->ext_porta & (1UL << bit_index)) ?
  198. S100_PIN_LEVEL_HIGH : S100_PIN_LEVEL_LOW;
  199. return RT_EOK;
  200. }
  201. void s100_gpio_write(rt_uint8_t pin, rt_uint8_t value)
  202. {
  203. (void)s100_pin_set_function(pin, S100_PIN_FUNC_GPIO);
  204. (void)s100_gpio_set_direction(pin, S100_PIN_DIR_OUT);
  205. (void)s100_gpio_write_pin(pin, value ? S100_PIN_LEVEL_HIGH : S100_PIN_LEVEL_LOW);
  206. }
  207. rt_uint8_t s100_gpio_read(rt_uint8_t pin)
  208. {
  209. s100_pin_level_t level = S100_PIN_LEVEL_LOW;
  210. (void)s100_gpio_read_pin(pin, &level);
  211. return (level == S100_PIN_LEVEL_HIGH) ? 1U : 0U;
  212. }
  213. static void s100_pin_mode(struct rt_device *device, rt_base_t pin, rt_uint8_t mode)
  214. {
  215. RT_UNUSED(device);
  216. switch (mode)
  217. {
  218. case PIN_MODE_OUTPUT:
  219. (void)s100_pin_set_function((s100_pin_t)pin, S100_PIN_FUNC_GPIO);
  220. (void)s100_gpio_set_direction((s100_pin_t)pin, S100_PIN_DIR_OUT);
  221. break;
  222. case PIN_MODE_INPUT:
  223. (void)s100_pin_set_function((s100_pin_t)pin, S100_PIN_FUNC_GPIO);
  224. (void)s100_gpio_set_direction((s100_pin_t)pin, S100_PIN_DIR_IN);
  225. (void)s100_pin_set_pull((s100_pin_t)pin, S100_PIN_PULL_NONE);
  226. break;
  227. case PIN_MODE_INPUT_PULLUP:
  228. (void)s100_pin_set_function((s100_pin_t)pin, S100_PIN_FUNC_GPIO);
  229. (void)s100_gpio_set_direction((s100_pin_t)pin, S100_PIN_DIR_IN);
  230. (void)s100_pin_set_pull((s100_pin_t)pin, S100_PIN_PULL_UP);
  231. break;
  232. case PIN_MODE_INPUT_PULLDOWN:
  233. (void)s100_pin_set_function((s100_pin_t)pin, S100_PIN_FUNC_GPIO);
  234. (void)s100_gpio_set_direction((s100_pin_t)pin, S100_PIN_DIR_IN);
  235. (void)s100_pin_set_pull((s100_pin_t)pin, S100_PIN_PULL_DOWN);
  236. break;
  237. case PIN_MODE_OUTPUT_OD:
  238. (void)s100_pin_set_function((s100_pin_t)pin, S100_PIN_FUNC_GPIO);
  239. (void)s100_gpio_set_direction((s100_pin_t)pin, S100_PIN_DIR_OUT);
  240. (void)s100_pin_set_pull((s100_pin_t)pin, S100_PIN_PULL_UP);
  241. break;
  242. default:
  243. break;
  244. }
  245. }
  246. static void s100_pin_write_device(struct rt_device *device, rt_base_t pin, rt_uint8_t value)
  247. {
  248. RT_UNUSED(device);
  249. (void)s100_gpio_write_pin((s100_pin_t)pin,
  250. value ? S100_PIN_LEVEL_HIGH : S100_PIN_LEVEL_LOW);
  251. }
  252. static rt_ssize_t s100_pin_read_device(struct rt_device *device, rt_base_t pin)
  253. {
  254. s100_pin_level_t level = S100_PIN_LEVEL_LOW;
  255. RT_UNUSED(device);
  256. if (s100_gpio_read_pin((s100_pin_t)pin, &level) != RT_EOK)
  257. {
  258. return PIN_LOW;
  259. }
  260. return (level == S100_PIN_LEVEL_HIGH) ? PIN_HIGH : PIN_LOW;
  261. }
  262. static rt_err_t s100_pin_attach_irq(struct rt_device *device,
  263. rt_base_t pin,
  264. rt_uint8_t mode,
  265. void (*hdr)(void *args),
  266. void *args)
  267. {
  268. rt_base_t level;
  269. RT_UNUSED(device);
  270. if (!s100_pin_is_valid((s100_pin_t)pin))
  271. {
  272. return -RT_EINVAL;
  273. }
  274. level = rt_hw_interrupt_disable();
  275. s100_pin_irq_hdr[pin].pin = pin;
  276. s100_pin_irq_hdr[pin].mode = mode;
  277. s100_pin_irq_hdr[pin].hdr = hdr;
  278. s100_pin_irq_hdr[pin].args = args;
  279. rt_hw_interrupt_enable(level);
  280. return RT_EOK;
  281. }
  282. static rt_err_t s100_pin_detach_irq(struct rt_device *device, rt_base_t pin)
  283. {
  284. rt_base_t level;
  285. RT_UNUSED(device);
  286. if (!s100_pin_is_valid((s100_pin_t)pin))
  287. {
  288. return -RT_EINVAL;
  289. }
  290. level = rt_hw_interrupt_disable();
  291. s100_pin_irq_hdr[pin].pin = -1;
  292. s100_pin_irq_hdr[pin].mode = 0;
  293. s100_pin_irq_hdr[pin].hdr = RT_NULL;
  294. s100_pin_irq_hdr[pin].args = RT_NULL;
  295. rt_hw_interrupt_enable(level);
  296. return RT_EOK;
  297. }
  298. static rt_err_t s100_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint8_t enabled)
  299. {
  300. rt_uint8_t port_index;
  301. rt_uint8_t bit_index;
  302. rt_uint32_t bit;
  303. s100_gpio_reg_t *gpio;
  304. rt_err_t ret;
  305. RT_UNUSED(device);
  306. ret = s100_pin_to_gpio((s100_pin_t)pin, &port_index, &bit_index);
  307. if (ret != RT_EOK)
  308. {
  309. return ret;
  310. }
  311. gpio = s100_gpio_ports[port_index];
  312. bit = 1UL << bit_index;
  313. if (enabled == PIN_IRQ_ENABLE)
  314. {
  315. ret = s100_gpio_config_irq(pin, s100_pin_irq_hdr[pin].mode);
  316. if (ret != RT_EOK)
  317. {
  318. return ret;
  319. }
  320. gpio->intmask &= ~bit;
  321. gpio->inten |= bit;
  322. }
  323. else if (enabled == PIN_IRQ_DISABLE)
  324. {
  325. gpio->intmask |= bit;
  326. gpio->inten &= ~bit;
  327. gpio->porta_eoi = bit;
  328. }
  329. else
  330. {
  331. return -RT_EINVAL;
  332. }
  333. return RT_EOK;
  334. }
  335. static const struct rt_pin_ops s100_pin_ops =
  336. {
  337. s100_pin_mode,
  338. s100_pin_write_device,
  339. s100_pin_read_device,
  340. s100_pin_attach_irq,
  341. s100_pin_detach_irq,
  342. s100_pin_irq_enable,
  343. RT_NULL,
  344. };
  345. static void s100_gpio_irq_dispatch(rt_uint8_t port_index)
  346. {
  347. rt_uint32_t status;
  348. rt_uint8_t bit;
  349. s100_gpio_reg_t *gpio;
  350. gpio = s100_gpio_ports[port_index];
  351. status = gpio->intstatus;
  352. gpio->porta_eoi = status;
  353. for (bit = 0; bit < S100_GPIO_CHANNELS_PER_PORT; bit++)
  354. {
  355. s100_pin_t pin;
  356. rt_uint32_t mask = 1UL << bit;
  357. if ((status & mask) == 0U)
  358. {
  359. continue;
  360. }
  361. if (s100_gpio_to_pin(port_index, bit, &pin) != RT_EOK)
  362. {
  363. continue;
  364. }
  365. if (s100_pin_irq_hdr[pin].hdr != RT_NULL)
  366. {
  367. s100_pin_irq_hdr[pin].hdr(s100_pin_irq_hdr[pin].args);
  368. }
  369. }
  370. }
  371. static void s100_gpio_irq0_isr(int vector, void *param)
  372. {
  373. RT_UNUSED(vector);
  374. RT_UNUSED(param);
  375. s100_gpio_irq_dispatch(0);
  376. }
  377. static void s100_gpio_irq1_isr(int vector, void *param)
  378. {
  379. RT_UNUSED(vector);
  380. RT_UNUSED(param);
  381. s100_gpio_irq_dispatch(1);
  382. }
  383. static void s100_gpio_irq2_isr(int vector, void *param)
  384. {
  385. RT_UNUSED(vector);
  386. RT_UNUSED(param);
  387. s100_gpio_irq_dispatch(2);
  388. }
  389. int rt_hw_pin_init(void)
  390. {
  391. rt_size_t i;
  392. rt_isr_handler_t handlers[S100_GPIO_PORT_COUNT] =
  393. {
  394. s100_gpio_irq0_isr,
  395. s100_gpio_irq1_isr,
  396. s100_gpio_irq2_isr,
  397. };
  398. for (i = 0; i < S100_GPIO_PIN_COUNT; i++)
  399. {
  400. s100_pin_irq_hdr[i].pin = -1;
  401. s100_pin_irq_hdr[i].mode = 0;
  402. s100_pin_irq_hdr[i].hdr = RT_NULL;
  403. s100_pin_irq_hdr[i].args = RT_NULL;
  404. }
  405. /*
  406. * Each GPIO block reports through one parent interrupt. The per-pin RT-
  407. * Thread callbacks are dispatched in s100_gpio_irq_dispatch() after the
  408. * block-level status register is decoded.
  409. */
  410. for (i = 0; i < S100_GPIO_PORT_COUNT; i++)
  411. {
  412. rt_hw_interrupt_install(s100_gpio_port_irqs[i], handlers[i], RT_NULL, "gpio");
  413. rt_hw_interrupt_set_triger_mode(s100_gpio_port_irqs[i], IRQ_MODE_TRIG_LEVEL);
  414. rt_hw_interrupt_umask(s100_gpio_port_irqs[i]);
  415. }
  416. return rt_device_pin_register("pin", &s100_pin_ops, RT_NULL);
  417. }
  418. INIT_DEVICE_EXPORT(rt_hw_pin_init);