drv_uart.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482
  1. /**************************************************************************//**
  2. *
  3. * @copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. *
  7. * Change Logs:
  8. * Date Author Notes
  9. * 2021-1-11 Wayne First version
  10. *
  11. ******************************************************************************/
  12. #include <rtconfig.h>
  13. #if defined(BSP_USING_UART)
  14. #include <rtdevice.h>
  15. #include <rthw.h>
  16. #include "NuMicro.h"
  17. #include <drv_uart.h>
  18. #include <drv_sys.h>
  19. /* Private define ---------------------------------------------------------------*/
  20. enum
  21. {
  22. UART_START = -1,
  23. #if defined(BSP_USING_UART0)
  24. UART0_IDX,
  25. #endif
  26. #if defined(BSP_USING_UART1)
  27. UART1_IDX,
  28. #endif
  29. #if defined(BSP_USING_UART2)
  30. UART2_IDX,
  31. #endif
  32. #if defined(BSP_USING_UART3)
  33. UART3_IDX,
  34. #endif
  35. #if defined(BSP_USING_UART4)
  36. UART4_IDX,
  37. #endif
  38. #if defined(BSP_USING_UART5)
  39. UART5_IDX,
  40. #endif
  41. #if defined(BSP_USING_UART6)
  42. UART6_IDX,
  43. #endif
  44. #if defined(BSP_USING_UART7)
  45. UART7_IDX,
  46. #endif
  47. #if defined(BSP_USING_UART8)
  48. UART8_IDX,
  49. #endif
  50. #if defined(BSP_USING_UART9)
  51. UART9_IDX,
  52. #endif
  53. #if defined(BSP_USING_UART10)
  54. UART10_IDX,
  55. #endif
  56. UART_CNT
  57. };
  58. /* Private typedef --------------------------------------------------------------*/
  59. struct nu_uart
  60. {
  61. rt_serial_t dev;
  62. char *name;
  63. UART_T *uart_base;
  64. IRQn_Type irqn;
  65. E_SYS_IPRST rstidx;
  66. E_SYS_IPCLK clkidx;
  67. };
  68. typedef struct nu_uart *nu_uart_t;
  69. /* Private functions ------------------------------------------------------------*/
  70. static rt_err_t nu_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg);
  71. static rt_err_t nu_uart_control(struct rt_serial_device *serial, int cmd, void *arg);
  72. static int nu_uart_send(struct rt_serial_device *serial, char c);
  73. static int nu_uart_receive(struct rt_serial_device *serial);
  74. /* Public functions ------------------------------------------------------------*/
  75. /* Private variables ------------------------------------------------------------*/
  76. static const struct rt_uart_ops nu_uart_ops =
  77. {
  78. .configure = nu_uart_configure,
  79. .control = nu_uart_control,
  80. .putc = nu_uart_send,
  81. .getc = nu_uart_receive,
  82. .dma_transmit = RT_NULL
  83. };
  84. static const struct serial_configure nu_uart_default_config =
  85. RT_SERIAL_CONFIG_DEFAULT;
  86. static struct nu_uart nu_uart_arr [] =
  87. {
  88. #if defined(BSP_USING_UART0)
  89. {
  90. .name = "uart0",
  91. .uart_base = UART0,
  92. .irqn = IRQ_UART0,
  93. .rstidx = UART0RST,
  94. .clkidx = UART0CKEN,
  95. },
  96. #endif
  97. #if defined(BSP_USING_UART1)
  98. {
  99. .name = "uart1",
  100. .uart_base = UART1,
  101. .irqn = IRQ_UART1,
  102. .rstidx = UART1RST,
  103. .clkidx = UART1CKEN,
  104. },
  105. #endif
  106. #if defined(BSP_USING_UART2)
  107. {
  108. .name = "uart2",
  109. .uart_base = UART2,
  110. .irqn = IRQ_UART2,
  111. .rstidx = UART2RST,
  112. .clkidx = UART2CKEN,
  113. },
  114. #endif
  115. #if defined(BSP_USING_UART3)
  116. {
  117. .name = "uart3",
  118. .uart_base = UART3,
  119. .irqn = IRQ_UART3,
  120. .rstidx = UART3RST,
  121. .clkidx = UART3CKEN,
  122. },
  123. #endif
  124. #if defined(BSP_USING_UART4)
  125. {
  126. .name = "uart4",
  127. .uart_base = UART4,
  128. .irqn = IRQ_UART4,
  129. .rstidx = UART4RST,
  130. .clkidx = UART4CKEN,
  131. },
  132. #endif
  133. #if defined(BSP_USING_UART5)
  134. {
  135. .name = "uart5",
  136. .uart_base = UART5,
  137. .irqn = IRQ_UART5,
  138. .rstidx = UART5RST,
  139. .clkidx = UART5CKEN,
  140. },
  141. #endif
  142. #if defined(BSP_USING_UART6)
  143. {
  144. .name = "uart6",
  145. .uart_base = UART6,
  146. .irqn = IRQ_UART6,
  147. .rstidx = UART6RST,
  148. .clkidx = UART6CKEN,
  149. },
  150. #endif
  151. #if defined(BSP_USING_UART7)
  152. {
  153. .name = "uart7",
  154. .uart_base = UART7,
  155. .irqn = IRQ_UART7,
  156. .rstidx = UART7RST,
  157. .clkidx = UART7CKEN,
  158. },
  159. #endif
  160. #if defined(BSP_USING_UART8)
  161. {
  162. .name = "uart8",
  163. .uart_base = UART8,
  164. .irqn = IRQ_UART8,
  165. .rstidx = UART8RST,
  166. .clkidx = UART8CKEN,
  167. },
  168. #endif
  169. #if defined(BSP_USING_UART9)
  170. {
  171. .name = "uart9",
  172. .uart_base = UART9,
  173. .irqn = IRQ_UART9,
  174. .rstidx = UART9RST,
  175. .clkidx = UART9CKEN,
  176. },
  177. #endif
  178. #if defined(BSP_USING_UART10)
  179. {
  180. .name = "uart10",
  181. .uart_base = UARTA,
  182. .irqn = IRQ_UART10,
  183. .rstidx = UART10RST,
  184. .clkidx = UART10CKEN,
  185. },
  186. #endif
  187. }; /* uart nu_uart */
  188. /**
  189. * All UART interrupt service routine
  190. */
  191. static void nu_uart_isr(int vector, void *param)
  192. {
  193. /* Get base address of uart register */
  194. nu_uart_t serial = (nu_uart_t)param;
  195. UART_T *uart_base = ((nu_uart_t)serial)->uart_base;
  196. /* Get interrupt event */
  197. uint32_t u32IntSts = uart_base->INTSTS;
  198. uint32_t u32FIFOSts = uart_base->FIFOSTS;
  199. /* Handle RX event */
  200. if (u32IntSts & (UART_ISR_RDA_INT_Msk | UART_ISR_TOUT_INT_Msk))
  201. {
  202. rt_hw_serial_isr(&serial->dev, RT_SERIAL_EVENT_RX_IND);
  203. }
  204. uart_base->INTSTS = u32IntSts;
  205. uart_base->FIFOSTS = u32FIFOSts;
  206. }
  207. /**
  208. * Set RS-485 AUD mode
  209. */
  210. void nu_uart_set_rs485aud(struct rt_serial_device *serial, rt_bool_t bRTSActiveLowLevel)
  211. {
  212. UART_T *uart_base;
  213. RT_ASSERT(serial != RT_NULL);
  214. /* Get base address of uart register */
  215. uart_base = ((nu_uart_t)serial)->uart_base;
  216. /* Set RTS as RS-485 phy direction controlling ping. */
  217. uart_base->FUNCSEL = UART_FUNCSEL_RS485;
  218. /* Set RS585 configuration */
  219. uart_base->ALTCTL &= ~(UART_ALT_CSR_RS485_NMM_Msk | UART_ALT_CSR_RS485_AAD_Msk | UART_ALT_CSR_RS485_AUD_Msk | UART_ALT_CSR_RS485_ADD_EN_Msk);
  220. uart_base->ALTCTL |= UART_ALT_CSR_RS485_AUD_Msk;
  221. if (bRTSActiveLowLevel)
  222. {
  223. /* Set direction pin as active-high. */
  224. uart_base->MODEM &= ~UART_MCR_LEV_RTS_Msk;
  225. }
  226. else
  227. {
  228. /* Set direction pin as active-low. */
  229. uart_base->MODEM |= UART_MCR_LEV_RTS_Msk;
  230. }
  231. rt_kprintf("Set %s to RS-485 AUD function mode. ActiveLowLevel-%s\n", ((nu_uart_t)serial)->name, bRTSActiveLowLevel ? "YES" : "NO");
  232. }
  233. /**
  234. * Configure uart port
  235. */
  236. static rt_err_t nu_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  237. {
  238. rt_err_t ret = RT_EOK;
  239. uint32_t uart_word_len = 0;
  240. uint32_t uart_stop_bit = 0;
  241. uint32_t uart_parity = 0;
  242. /* Get base address of uart register */
  243. UART_T *uart_base = ((nu_uart_t)serial)->uart_base;
  244. /* Check baudrate */
  245. RT_ASSERT(cfg->baud_rate != 0);
  246. /* Check word len */
  247. switch (cfg->data_bits)
  248. {
  249. case DATA_BITS_5:
  250. uart_word_len = UART_WORD_LEN_5;
  251. break;
  252. case DATA_BITS_6:
  253. uart_word_len = UART_WORD_LEN_6;
  254. break;
  255. case DATA_BITS_7:
  256. uart_word_len = UART_WORD_LEN_7;
  257. break;
  258. case DATA_BITS_8:
  259. uart_word_len = UART_WORD_LEN_8;
  260. break;
  261. default:
  262. rt_kprintf("Unsupported data length");
  263. ret = RT_EINVAL;
  264. goto exit_nu_uart_configure;
  265. }
  266. /* Check stop bit */
  267. switch (cfg->stop_bits)
  268. {
  269. case STOP_BITS_1:
  270. uart_stop_bit = UART_STOP_BIT_1;
  271. break;
  272. case STOP_BITS_2:
  273. uart_stop_bit = UART_STOP_BIT_2;
  274. break;
  275. default:
  276. rt_kprintf("Unsupported stop bit");
  277. ret = RT_EINVAL;
  278. goto exit_nu_uart_configure;
  279. }
  280. /* Check parity */
  281. switch (cfg->parity)
  282. {
  283. case PARITY_NONE:
  284. uart_parity = UART_PARITY_NONE;
  285. break;
  286. case PARITY_ODD:
  287. uart_parity = UART_PARITY_ODD;
  288. break;
  289. case PARITY_EVEN:
  290. uart_parity = UART_PARITY_EVEN;
  291. break;
  292. default:
  293. rt_kprintf("Unsupported parity");
  294. ret = RT_EINVAL;
  295. goto exit_nu_uart_configure;
  296. }
  297. nu_sys_ip_reset(((nu_uart_t)serial)->rstidx);
  298. /* Open Uart and set UART Baudrate */
  299. UART_Open(uart_base, cfg->baud_rate);
  300. /* Set line configuration. */
  301. UART_SetLineConfig(uart_base, 0, uart_word_len, uart_parity, uart_stop_bit);
  302. /* Enable interrupt. */
  303. rt_hw_interrupt_umask(((nu_uart_t)serial)->irqn);
  304. exit_nu_uart_configure:
  305. if (ret != RT_EOK)
  306. UART_Close(uart_base);
  307. return -(ret);
  308. }
  309. /**
  310. * Uart interrupt control
  311. */
  312. static rt_err_t nu_uart_control(struct rt_serial_device *serial, int cmd, void *arg)
  313. {
  314. nu_uart_t psNuUart = (nu_uart_t)serial;
  315. rt_err_t result = RT_EOK;
  316. rt_uint32_t flag;
  317. rt_ubase_t ctrl_arg = (rt_ubase_t)arg;
  318. RT_ASSERT(serial != RT_NULL);
  319. /* Get base address of uart register */
  320. UART_T *uart_base = psNuUart->uart_base;
  321. switch (cmd)
  322. {
  323. case RT_DEVICE_CTRL_CLR_INT:
  324. if (ctrl_arg == RT_DEVICE_FLAG_INT_RX) /* Disable INT-RX */
  325. {
  326. flag = UART_IER_RDA_IEN_Msk | UART_IER_RTO_IEN_Msk | UART_IER_TIME_OUT_EN_Msk;
  327. UART_DISABLE_INT(uart_base, flag);
  328. }
  329. else if (ctrl_arg == RT_DEVICE_FLAG_DMA_RX) /* Disable DMA-RX */
  330. {
  331. /* Disable Receive Line interrupt & Stop DMA RX transfer. */
  332. }
  333. break;
  334. case RT_DEVICE_CTRL_SET_INT:
  335. if (ctrl_arg == RT_DEVICE_FLAG_INT_RX) /* Enable INT-RX */
  336. {
  337. flag = UART_IER_RDA_IEN_Msk | UART_IER_RTO_IEN_Msk | UART_IER_TIME_OUT_EN_Msk;
  338. UART_ENABLE_INT(uart_base, flag);
  339. }
  340. break;
  341. case RT_DEVICE_CTRL_CLOSE:
  342. /* Disable interrupt. */
  343. rt_hw_interrupt_mask(psNuUart->irqn);
  344. /* Close UART port */
  345. UART_Close(uart_base);
  346. break;
  347. default:
  348. result = -RT_EINVAL;
  349. break;
  350. }
  351. return result;
  352. }
  353. /**
  354. * Uart put char
  355. */
  356. static int nu_uart_send(struct rt_serial_device *serial, char c)
  357. {
  358. RT_ASSERT(serial != RT_NULL);
  359. /* Get base address of uart register */
  360. UART_T *uart_base = ((nu_uart_t)serial)->uart_base;
  361. /* Waiting if TX-FIFO is full. */
  362. while (UART_IS_TX_FULL(uart_base));
  363. /* Put char into TX-FIFO */
  364. UART_WRITE(uart_base, c);
  365. return 1;
  366. }
  367. /**
  368. * Uart get char
  369. */
  370. static int nu_uart_receive(struct rt_serial_device *serial)
  371. {
  372. RT_ASSERT(serial != RT_NULL);
  373. /* Get base address of uart register */
  374. UART_T *uart_base = ((nu_uart_t)serial)->uart_base;
  375. /* Return failure if RX-FIFO is empty. */
  376. if (UART_GET_RX_EMPTY(uart_base))
  377. {
  378. return -1;
  379. }
  380. /* Get char from RX-FIFO */
  381. return UART_READ(uart_base);
  382. }
  383. /**
  384. * Hardware UART Initialization
  385. */
  386. rt_err_t rt_hw_uart_init(void)
  387. {
  388. int i;
  389. rt_uint32_t flag = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX;
  390. rt_err_t ret = RT_EOK;
  391. for (i = (UART_START + 1); i < UART_CNT; i++)
  392. {
  393. nu_uart_arr[i].dev.ops = &nu_uart_ops;
  394. nu_uart_arr[i].dev.config = nu_uart_default_config;
  395. rt_hw_interrupt_install(nu_uart_arr[i].irqn, nu_uart_isr, &nu_uart_arr[i], nu_uart_arr[i].name);
  396. nu_sys_ipclk_enable(nu_uart_arr[i].clkidx);
  397. ret = rt_hw_serial_register(&nu_uart_arr[i].dev, nu_uart_arr[i].name, flag, NULL);
  398. RT_ASSERT(ret == RT_EOK);
  399. }
  400. return ret;
  401. }
  402. #endif //#if defined(BSP_USING_UART)