ch56x_uart.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  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 <ipc/completion.h>
  12. #include <ipc/dataqueue.h>
  13. #ifdef RT_USING_SERIAL_V2
  14. #include <drivers/dev_serial_v2.h>
  15. #else
  16. #include <drivers/dev_serial.h>
  17. #endif
  18. #include <drivers/dev_pin.h>
  19. #include "ch56x_sys.h"
  20. #include "ch56x_uart.h"
  21. #include "isr_sp.h"
  22. #if !defined(BSP_USING_UART0) && !defined(BSP_USING_UART1) && \
  23. !defined(BSP_USING_UART2) && !defined(BSP_USING_UART3)
  24. #error "Please define at least one UARTx"
  25. #endif
  26. /* Type of irqn/rxd_pin/txd_pin are per uart driver perspective
  27. * to save some space, still compatible to RT api call, anyway.
  28. */
  29. struct serial_device
  30. {
  31. struct rt_serial_device parent;
  32. volatile struct uart_registers *reg_base;
  33. uint8_t irqn;
  34. uint8_t resv;
  35. uint8_t rxd_pin;
  36. uint8_t txd_pin;
  37. char *name;
  38. };
  39. #ifdef BSP_USING_UART0
  40. static struct serial_device serial_device_0 =
  41. {
  42. .reg_base = (struct uart_registers *)UART0_REG_BASE,
  43. .irqn = UART0_IRQn,
  44. #ifndef BSP_USING_UART0_PIN_ALT
  45. .rxd_pin = UART_RXD0_PIN,
  46. .txd_pin = UART_TXD0_PIN,
  47. #else
  48. .rxd_pin = UART_RXD0_ALT,
  49. .txd_pin = UART_TXD0_ALT,
  50. #endif
  51. .name = "uart0",
  52. };
  53. #endif
  54. #ifdef BSP_USING_UART1
  55. static struct serial_device serial_device_1 =
  56. {
  57. .reg_base = (struct uart_registers *)UART1_REG_BASE,
  58. .irqn = UART1_IRQn,
  59. .rxd_pin = UART_RXD1_PIN,
  60. .txd_pin = UART_TXD1_PIN,
  61. .name = "uart1",
  62. };
  63. #endif
  64. #ifdef BSP_USING_UART2
  65. static struct serial_device serial_device_2 =
  66. {
  67. .reg_base = (struct uart_registers *)UART2_REG_BASE,
  68. .irqn = UART2_IRQn,
  69. .rxd_pin = UART_RXD2_PIN,
  70. .txd_pin = UART_TXD2_PIN,
  71. .name = "uart2",
  72. };
  73. #endif
  74. #ifdef BSP_USING_UART3
  75. static struct serial_device serial_device_3 =
  76. {
  77. .reg_base = (struct uart_registers *)UART3_REG_BASE,
  78. .irqn = UART3_IRQn,
  79. .rxd_pin = UART_RXD3_PIN,
  80. .txd_pin = UART_TXD3_PIN,
  81. .name = "uart3",
  82. };
  83. #endif
  84. static rt_err_t uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  85. {
  86. struct serial_device *serial_device = (struct serial_device *)serial;
  87. volatile struct uart_registers *uxreg = serial_device->reg_base;
  88. union _uart_fcr fcr;
  89. union _uart_lcr lcr;
  90. uint32_t x;
  91. x = 10 * sys_hclk_get() / 8 / cfg->baud_rate;
  92. x = (x + 5) / 10;
  93. uxreg->DL = x;
  94. uxreg->DIV = 1;
  95. lcr.reg = 0;
  96. switch (cfg->data_bits)
  97. {
  98. case DATA_BITS_5:
  99. lcr.word_sz = LCR_DATA_BITS_5;
  100. break;
  101. case DATA_BITS_6:
  102. lcr.word_sz = LCR_DATA_BITS_6;
  103. break;
  104. case DATA_BITS_7:
  105. lcr.word_sz = LCR_DATA_BITS_7;
  106. break;
  107. case DATA_BITS_8:
  108. default:
  109. lcr.word_sz = LCR_DATA_BITS_8;
  110. break;
  111. }
  112. switch (cfg->stop_bits)
  113. {
  114. case STOP_BITS_2:
  115. lcr.stop_bit = LCR_STOP_BITS_2;
  116. break;
  117. case STOP_BITS_1:
  118. default:
  119. lcr.stop_bit = LCR_STOP_BITS_1;
  120. break;
  121. }
  122. switch (cfg->parity)
  123. {
  124. case PARITY_ODD:
  125. lcr.par_mod = LCR_PARITY_ODD;
  126. lcr.par_en = 1;
  127. break;
  128. case PARITY_EVEN:
  129. lcr.par_mod = LCR_PARITY_EVEN;
  130. lcr.par_en = 1;
  131. break;
  132. case PARITY_NONE:
  133. default:
  134. lcr.par_en = 0;
  135. break;
  136. }
  137. uxreg->LCR.reg = lcr.reg;
  138. fcr.reg = RB_FCR_FIFO_EN | RB_FCR_RX_FIFO_CLR | RB_FCR_TX_FIFO_CLR;
  139. fcr.fifo_trig = UART_1BYTE_TRIG;
  140. uxreg->FCR.reg = fcr.reg;
  141. /* TXD pin output enable */
  142. uxreg->IER.txd_en = 1;
  143. return RT_EOK;
  144. }
  145. static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *args)
  146. {
  147. struct serial_device *serial_device = (struct serial_device *)serial;
  148. volatile struct uart_registers *uxreg = serial_device->reg_base;
  149. switch (cmd)
  150. {
  151. case RT_DEVICE_CTRL_CLR_INT:
  152. uxreg->IER.recv_rdy = 0;
  153. uxreg->IER.line_stat = 0;
  154. uxreg->IER.thr_empty = 0;
  155. rt_hw_interrupt_mask(serial_device->irqn);
  156. break;
  157. case RT_DEVICE_CTRL_SET_INT:
  158. uxreg->FCR.fifo_trig = UART_1BYTE_TRIG;
  159. uxreg->MCR.int_oe = 1;
  160. uxreg->IER.recv_rdy = 1;
  161. uxreg->IER.line_stat = 1;
  162. if (serial->parent.open_flag & RT_DEVICE_FLAG_INT_TX)
  163. {
  164. uxreg->IER.thr_empty = 1;
  165. }
  166. rt_hw_interrupt_umask(serial_device->irqn);
  167. break;
  168. default:
  169. break;
  170. }
  171. return RT_EOK;
  172. }
  173. static int uart_putc(struct rt_serial_device *serial, char ch)
  174. {
  175. struct serial_device *serial_device = (struct serial_device *)serial;
  176. volatile struct uart_registers *uxreg = serial_device->reg_base;
  177. if (serial->parent.open_flag & RT_DEVICE_FLAG_INT_TX)
  178. {
  179. if (uxreg->TFC >= UART_FIFO_SIZE)
  180. return -1;
  181. }
  182. else
  183. {
  184. while (uxreg->TFC >= UART_FIFO_SIZE)
  185. {
  186. if (rt_thread_self() && rt_interrupt_get_nest() == 0)
  187. rt_thread_yield();
  188. }
  189. }
  190. uxreg->THR = ch;
  191. return 1;
  192. }
  193. static int uart_getc(struct rt_serial_device *serial)
  194. {
  195. struct serial_device *serial_device = (struct serial_device *)serial;
  196. volatile struct uart_registers *uxreg = serial_device->reg_base;
  197. /* UART_II_RECV_RDY is cleared by reading RBR */
  198. return (uxreg->RFC > 0) ? uxreg->RBR : -1;
  199. }
  200. static const struct rt_uart_ops uart_ops =
  201. {
  202. .configure = uart_configure,
  203. .control = uart_control,
  204. .putc = uart_putc,
  205. .getc = uart_getc,
  206. .dma_transmit = RT_NULL,
  207. };
  208. int rt_hw_uart_init(void)
  209. {
  210. struct serial_device *devices[4];
  211. /* Note: HCLK should be at least 8MHz for default 115200 baud to work */
  212. struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
  213. int n = 0;
  214. #ifdef BSP_USING_UART3
  215. devices[n++] = &serial_device_3;
  216. #endif
  217. #ifdef BSP_USING_UART2
  218. devices[n++] = &serial_device_2;
  219. #endif
  220. #ifdef BSP_USING_UART1
  221. devices[n++] = &serial_device_1;
  222. #endif
  223. #ifdef BSP_USING_UART0
  224. devices[n++] = &serial_device_0;
  225. #endif
  226. while (--n >= 0)
  227. {
  228. uint32_t flag;
  229. struct serial_device *serial = devices[n];
  230. serial->parent.ops = &uart_ops;
  231. serial->parent.config = config;
  232. rt_pin_mode(serial->txd_pin, PIN_MODE_OUTPUT);
  233. rt_pin_mode(serial->rxd_pin, PIN_MODE_INPUT_PULLUP);
  234. sys_clk_off_by_irqn(serial->irqn, SYS_SLP_CLK_ON);
  235. flag = RT_DEVICE_FLAG_RDWR |
  236. RT_DEVICE_FLAG_STREAM | // for converting '\n'
  237. RT_DEVICE_FLAG_INT_TX |
  238. RT_DEVICE_FLAG_INT_RX ;
  239. rt_hw_serial_register(&serial->parent, serial->name, flag, RT_NULL);
  240. /* rt_serial_open => uart_control with RT_DEVICE_CTRL_SET_INT */
  241. }
  242. return 0;
  243. }
  244. static void _uart_isr_common(struct serial_device *serial_device)
  245. {
  246. struct rt_serial_device *serial = &serial_device->parent;
  247. volatile struct uart_registers *uxreg = serial_device->reg_base;
  248. switch (uxreg->IIR.int_mask)
  249. {
  250. case UART_II_RECV_TOUT:
  251. /* FIXME: It's a bad idea to read RBR to clear UART_II_RECV_TOUT.
  252. * Race condition may happen that actual rx data is dropped.
  253. */
  254. if (uxreg->RFC == 0)
  255. {
  256. uxreg->RBR;
  257. //rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_TIMEOUT);
  258. break;
  259. }
  260. /* pass through as if UART_II_RECV_RDY */
  261. case UART_II_RECV_RDY:
  262. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
  263. break;
  264. case UART_II_THR_EMPTY:
  265. rt_hw_serial_isr(serial, RT_SERIAL_EVENT_TX_DONE);
  266. break;
  267. case UART_II_LINE_STAT:
  268. uxreg->LSR;
  269. break;
  270. case UART_II_MODEM_CHG:
  271. uxreg->MSR;
  272. break;
  273. case UART_II_SLV_ADDR:
  274. uxreg->IIR;
  275. break;
  276. default:
  277. break;
  278. }
  279. }
  280. #ifdef BSP_USING_UART0
  281. void uart0_irq_handler(void) __attribute__((interrupt()));
  282. void uart0_irq_handler(void)
  283. {
  284. isr_sp_enter();
  285. rt_interrupt_enter();
  286. _uart_isr_common(&serial_device_0);
  287. rt_interrupt_leave();
  288. isr_sp_leave();
  289. }
  290. #endif
  291. #ifdef BSP_USING_UART1
  292. void uart1_irq_handler(void) __attribute__((interrupt()));
  293. void uart1_irq_handler(void)
  294. {
  295. isr_sp_enter();
  296. rt_interrupt_enter();
  297. _uart_isr_common(&serial_device_1);
  298. rt_interrupt_leave();
  299. isr_sp_leave();
  300. }
  301. #endif
  302. #ifdef BSP_USING_UART2
  303. void uart2_irq_handler(void) __attribute__((interrupt()));
  304. void uart2_irq_handler(void)
  305. {
  306. isr_sp_enter();
  307. rt_interrupt_enter();
  308. _uart_isr_common(&serial_device_2);
  309. rt_interrupt_leave();
  310. isr_sp_leave();
  311. }
  312. #endif
  313. #ifdef BSP_USING_UART3
  314. void uart3_irq_handler(void) __attribute__((interrupt()));
  315. void uart3_irq_handler(void)
  316. {
  317. isr_sp_enter();
  318. rt_interrupt_enter();
  319. _uart_isr_common(&serial_device_3);
  320. rt_interrupt_leave();
  321. isr_sp_leave();
  322. }
  323. #endif