drv_uuart.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621
  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-01-28 klcheng First version
  10. *
  11. ******************************************************************************/
  12. #include <rtconfig.h>
  13. #if defined(BSP_USING_UUART)
  14. #include <rtdevice.h>
  15. #include <rthw.h>
  16. #include "NuMicro.h"
  17. #if defined(RT_SERIAL_USING_DMA)
  18. #include <drv_pdma.h>
  19. #endif
  20. /* Private define ---------------------------------------------------------------*/
  21. enum
  22. {
  23. UUART_START = -1,
  24. #if defined(BSP_USING_UUART0)
  25. UUART0_IDX,
  26. #endif
  27. #if defined(BSP_USING_UUART1)
  28. UUART1_IDX,
  29. #endif
  30. UUART_CNT
  31. };
  32. /* Private typedef --------------------------------------------------------------*/
  33. struct nu_uuart
  34. {
  35. rt_serial_t dev;
  36. char *name;
  37. UUART_T *uuart_base;
  38. uint32_t uuart_rst;
  39. IRQn_Type uuart_irq_n;
  40. #if defined(RT_SERIAL_USING_DMA)
  41. uint32_t dma_flag;
  42. int16_t pdma_perp_tx;
  43. int8_t pdma_chanid_tx;
  44. int16_t pdma_perp_rx;
  45. int8_t pdma_chanid_rx;
  46. int32_t rx_write_offset;
  47. int32_t rxdma_trigger_len;
  48. #endif
  49. };
  50. typedef struct nu_uuart *nu_uuart_t;
  51. /* Private functions ------------------------------------------------------------*/
  52. static rt_err_t nu_uuart_configure(struct rt_serial_device *serial, struct serial_configure *cfg);
  53. static rt_err_t nu_uuart_control(struct rt_serial_device *serial, int cmd, void *arg);
  54. static int nu_uuart_send(struct rt_serial_device *serial, char c);
  55. static int nu_uuart_receive(struct rt_serial_device *serial);
  56. static void nu_uuart_isr(nu_uuart_t serial);
  57. #if defined(RT_SERIAL_USING_DMA)
  58. static rt_ssize_t nu_uuart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction);
  59. static void nu_pdma_uuart_rx_cb(void *pvOwner, uint32_t u32Events);
  60. static void nu_pdma_uuart_tx_cb(void *pvOwner, uint32_t u32Events);
  61. #endif
  62. /* Public functions ------------------------------------------------------------*/
  63. /* Private variables ------------------------------------------------------------*/
  64. static const struct rt_uart_ops nu_uuart_ops =
  65. {
  66. .configure = nu_uuart_configure,
  67. .control = nu_uuart_control,
  68. .putc = nu_uuart_send,
  69. .getc = nu_uuart_receive,
  70. #if defined(RT_SERIAL_USING_DMA)
  71. .dma_transmit = nu_uuart_dma_transmit
  72. #else
  73. .dma_transmit = RT_NULL
  74. #endif
  75. };
  76. static const struct serial_configure nu_uuart_default_config =
  77. RT_SERIAL_CONFIG_DEFAULT;
  78. static struct nu_uuart nu_uuart_arr [] =
  79. {
  80. #if defined(BSP_USING_UUART0)
  81. {
  82. .name = "uuart0",
  83. .uuart_base = UUART0,
  84. .uuart_rst = USCI0_RST,
  85. .uuart_irq_n = USCI01_IRQn,
  86. #if defined(RT_SERIAL_USING_DMA)
  87. #if defined(BSP_USING_UUART0_TX_DMA)
  88. .pdma_perp_tx = PDMA_USCI0_TX,
  89. #else
  90. .pdma_perp_tx = NU_PDMA_UNUSED,
  91. #endif
  92. #if defined(BSP_USING_UUART0_RX_DMA)
  93. .pdma_perp_rx = PDMA_USCI0_RX,
  94. .rx_write_offset = 0,
  95. #else
  96. .pdma_perp_rx = NU_PDMA_UNUSED,
  97. #endif
  98. #endif
  99. },
  100. #endif
  101. #if defined(BSP_USING_UUART1)
  102. {
  103. .name = "uuart1",
  104. .uuart_base = UUART1,
  105. .uuart_rst = USCI1_RST,
  106. .uuart_irq_n = USCI01_IRQn,
  107. #if defined(RT_SERIAL_USING_DMA)
  108. #if defined(BSP_USING_UUART1_TX_DMA)
  109. .pdma_perp_tx = PDMA_USCI1_TX,
  110. #else
  111. .pdma_perp_tx = NU_PDMA_UNUSED,
  112. #endif
  113. #if defined(BSP_USING_UUART1_RX_DMA)
  114. .pdma_perp_rx = PDMA_USCI1_RX,
  115. .rx_write_offset = 0,
  116. #else
  117. .pdma_perp_rx = NU_PDMA_UNUSED,
  118. #endif
  119. #endif
  120. },
  121. #endif
  122. {0}
  123. }; /* uuart nu_uuart */
  124. /* Interrupt Handle Function ----------------------------------------------------*/
  125. #if defined(BSP_USING_UUART0) || defined(BSP_USING_UUART1)
  126. /* USCI0 interrupt entry */
  127. void USCI01_IRQHandler(void)
  128. {
  129. /* enter interrupt */
  130. rt_interrupt_enter();
  131. #if defined(BSP_USING_UUART0)
  132. nu_uuart_isr(&nu_uuart_arr[UUART0_IDX]);
  133. #endif
  134. #if defined(BSP_USING_UUART1)
  135. nu_uuart_isr(&nu_uuart_arr[UUART1_IDX]);
  136. #endif
  137. /* leave interrupt */
  138. rt_interrupt_leave();
  139. }
  140. #endif
  141. /**
  142. * All UUART interrupt service routine
  143. */
  144. static void nu_uuart_isr(nu_uuart_t serial)
  145. {
  146. /* Get base address of uuart register */
  147. UUART_T *uuart_base = ((nu_uuart_t)serial)->uuart_base;
  148. /* Get interrupt event */
  149. uint32_t u32IntSts = uuart_base->PROTSTS;
  150. uint32_t u32FIFOSts = uuart_base->BUFSTS;
  151. if (u32IntSts & (UUART_PROTSTS_PARITYERR_Msk | UUART_PROTSTS_FRMERR_Msk | UUART_PROTSTS_BREAK_Msk))
  152. {
  153. uuart_base->PROTSTS |= (UUART_PROTSTS_PARITYERR_Msk | UUART_PROTSTS_FRMERR_Msk | UUART_PROTSTS_BREAK_Msk);
  154. return;
  155. }
  156. /* Handle RX event */
  157. if (u32IntSts & UUART_PROTSTS_RXENDIF_Msk)
  158. {
  159. rt_hw_serial_isr(&serial->dev, RT_SERIAL_EVENT_RX_IND);
  160. }
  161. uuart_base->PROTSTS = u32IntSts;
  162. uuart_base->BUFSTS = u32FIFOSts;
  163. }
  164. /**
  165. * Configure uuart port
  166. */
  167. static rt_err_t nu_uuart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  168. {
  169. rt_err_t ret = RT_EOK;
  170. uint32_t uuart_word_len = 0;
  171. uint32_t uuart_stop_bit = 0;
  172. uint32_t uuart_parity = 0;
  173. /* Get base address of uuart register */
  174. UUART_T *uuart_base = ((nu_uuart_t)serial)->uuart_base;
  175. /* Check baud rate */
  176. RT_ASSERT(cfg->baud_rate != 0);
  177. /* Check word len */
  178. switch (cfg->data_bits)
  179. {
  180. case DATA_BITS_5:
  181. rt_kprintf("Unsupported data length");
  182. goto exit_nu_uuart_configure;
  183. case DATA_BITS_6:
  184. uuart_word_len = UUART_WORD_LEN_6;
  185. break;
  186. case DATA_BITS_7:
  187. uuart_word_len = UUART_WORD_LEN_7;
  188. break;
  189. case DATA_BITS_8:
  190. uuart_word_len = UUART_WORD_LEN_8;
  191. break;
  192. default:
  193. rt_kprintf("Unsupported data length");
  194. ret = -RT_EINVAL;
  195. goto exit_nu_uuart_configure;
  196. }
  197. /* Check stop bit */
  198. switch (cfg->stop_bits)
  199. {
  200. case STOP_BITS_1:
  201. uuart_stop_bit = UUART_STOP_BIT_1;
  202. break;
  203. case STOP_BITS_2:
  204. uuart_stop_bit = UUART_STOP_BIT_2;
  205. break;
  206. default:
  207. rt_kprintf("Unsupported stop bit");
  208. ret = -RT_EINVAL;
  209. goto exit_nu_uuart_configure;
  210. }
  211. /* Check parity */
  212. switch (cfg->parity)
  213. {
  214. case PARITY_NONE:
  215. uuart_parity = UUART_PARITY_NONE;
  216. break;
  217. case PARITY_ODD:
  218. uuart_parity = UUART_PARITY_ODD;
  219. break;
  220. case PARITY_EVEN:
  221. uuart_parity = UUART_PARITY_EVEN;
  222. break;
  223. default:
  224. rt_kprintf("Unsupported parity");
  225. ret = -RT_EINVAL;
  226. goto exit_nu_uuart_configure;
  227. }
  228. /* Reset this module */
  229. SYS_ResetModule(((nu_uuart_t)serial)->uuart_rst);
  230. /* Open UUart and set UUART baud rate */
  231. UUART_Open(uuart_base, cfg->baud_rate);
  232. /* Set line configuration. */
  233. UUART_SetLine_Config(uuart_base, 0, uuart_word_len, uuart_parity, uuart_stop_bit);
  234. /* Enable NVIC interrupt. */
  235. NVIC_EnableIRQ(((nu_uuart_t)serial)->uuart_irq_n);
  236. exit_nu_uuart_configure:
  237. if (ret != RT_EOK)
  238. UUART_Close(uuart_base);
  239. return -(ret);
  240. }
  241. #if defined(RT_SERIAL_USING_DMA)
  242. static rt_err_t nu_pdma_uuart_rx_config(struct rt_serial_device *serial, uint8_t *pu8Buf, int32_t i32TriggerLen)
  243. {
  244. rt_err_t result = RT_EOK;
  245. /* Get base address of uuart register */
  246. UUART_T *uuart_base = ((nu_uuart_t)serial)->uuart_base;
  247. result = nu_pdma_callback_register(((nu_uuart_t)serial)->pdma_chanid_rx,
  248. nu_pdma_uuart_rx_cb,
  249. (void *)serial,
  250. NU_PDMA_EVENT_TRANSFER_DONE | NU_PDMA_EVENT_TIMEOUT);
  251. if (result != RT_EOK)
  252. {
  253. goto exit_nu_pdma_uuart_rx_config;
  254. }
  255. result = nu_pdma_transfer(((nu_uuart_t)serial)->pdma_chanid_rx,
  256. 8,
  257. (uint32_t)&uuart_base->RXDAT,
  258. (uint32_t)pu8Buf,
  259. i32TriggerLen,
  260. 1000); //Idle-timeout, 1ms
  261. if (result != RT_EOK)
  262. {
  263. goto exit_nu_pdma_uuart_rx_config;
  264. }
  265. //UUART PDMA reset
  266. UUART_PDMA_ENABLE(uuart_base, UUART_PDMACTL_PDMARST_Msk);
  267. /* Enable Receive Line interrupt & Start DMA RX transfer. */
  268. UUART_EnableInt(uuart_base, UUART_RLS_INT_MASK);
  269. UUART_PDMA_ENABLE(uuart_base, UUART_PDMACTL_RXPDMAEN_Msk | UUART_PDMACTL_PDMAEN_Msk);
  270. exit_nu_pdma_uuart_rx_config:
  271. return result;
  272. }
  273. static void nu_pdma_uuart_rx_cb(void *pvOwner, uint32_t u32Events)
  274. {
  275. rt_size_t recv_len = 0;
  276. rt_size_t transferred_rxbyte = 0;
  277. struct rt_serial_device *serial = (struct rt_serial_device *)pvOwner;
  278. nu_uuart_t puuart = (nu_uuart_t)serial;
  279. RT_ASSERT(serial != RT_NULL);
  280. /* Get base address of uuart register */
  281. UUART_T *uuart_base = puuart->uuart_base;
  282. transferred_rxbyte = nu_pdma_transferred_byte_get(puuart->pdma_chanid_rx, puuart->rxdma_trigger_len);
  283. if (u32Events & (NU_PDMA_EVENT_TRANSFER_DONE | NU_PDMA_EVENT_TIMEOUT))
  284. {
  285. if (u32Events & NU_PDMA_EVENT_TRANSFER_DONE)
  286. {
  287. if (serial->config.bufsz != 0)
  288. {
  289. struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
  290. nu_pdma_uuart_rx_config(serial, &rx_fifo->buffer[0], puuart->rxdma_trigger_len); // Config & trigger next
  291. }
  292. transferred_rxbyte = puuart->rxdma_trigger_len;
  293. }
  294. else if ((u32Events & NU_PDMA_EVENT_TIMEOUT) && !UUART_GET_RX_EMPTY(uuart_base))
  295. {
  296. return;
  297. }
  298. recv_len = transferred_rxbyte - puuart->rx_write_offset;
  299. puuart->rx_write_offset = transferred_rxbyte % puuart->rxdma_trigger_len;
  300. }
  301. if ((serial->config.bufsz == 0) && (u32Events & NU_PDMA_EVENT_TRANSFER_DONE))
  302. {
  303. recv_len = puuart->rxdma_trigger_len;
  304. }
  305. if (recv_len)
  306. {
  307. rt_hw_serial_isr(&puuart->dev, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8));
  308. }
  309. }
  310. static rt_err_t nu_pdma_uuart_tx_config(struct rt_serial_device *serial)
  311. {
  312. rt_err_t result = RT_EOK;
  313. RT_ASSERT(serial != RT_NULL);
  314. result = nu_pdma_callback_register(((nu_uuart_t)serial)->pdma_chanid_tx,
  315. nu_pdma_uuart_tx_cb,
  316. (void *)serial,
  317. NU_PDMA_EVENT_TRANSFER_DONE);
  318. return result;
  319. }
  320. static void nu_pdma_uuart_tx_cb(void *pvOwner, uint32_t u32Events)
  321. {
  322. nu_uuart_t puuart = (nu_uuart_t)pvOwner;
  323. RT_ASSERT(puuart != RT_NULL);
  324. // Stop DMA TX transfer
  325. UUART_PDMA_DISABLE(puuart->uuart_base, UUART_PDMACTL_TXPDMAEN_Msk);
  326. if (u32Events & NU_PDMA_EVENT_TRANSFER_DONE)
  327. {
  328. rt_hw_serial_isr(&puuart->dev, RT_SERIAL_EVENT_TX_DMADONE);
  329. }
  330. }
  331. /**
  332. * UUart DMA transfer
  333. */
  334. static rt_ssize_t nu_uuart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
  335. {
  336. rt_err_t result = RT_EOK;
  337. RT_ASSERT(serial != RT_NULL);
  338. RT_ASSERT(buf != RT_NULL);
  339. /* Get base address of uuart register */
  340. UUART_T *uuart_base = ((nu_uuart_t)serial)->uuart_base;
  341. if (direction == RT_SERIAL_DMA_TX)
  342. {
  343. result = nu_pdma_transfer(((nu_uuart_t)serial)->pdma_chanid_tx,
  344. 8,
  345. (uint32_t)buf,
  346. (uint32_t)&uuart_base->TXDAT,
  347. size,
  348. 0); // wait-forever
  349. // Start DMA TX transfer
  350. UUART_PDMA_ENABLE(uuart_base, UUART_PDMACTL_TXPDMAEN_Msk | UUART_PDMACTL_PDMAEN_Msk);
  351. }
  352. else if (direction == RT_SERIAL_DMA_RX)
  353. {
  354. // If config.bufsz = 0, serial will trigger once.
  355. ((nu_uuart_t)serial)->rxdma_trigger_len = size;
  356. ((nu_uuart_t)serial)->rx_write_offset = 0;
  357. result = nu_pdma_uuart_rx_config(serial, buf, size);
  358. }
  359. else
  360. {
  361. result = RT_ERROR;
  362. }
  363. return result;
  364. }
  365. static int nu_hw_uuart_dma_allocate(nu_uuart_t puuart)
  366. {
  367. RT_ASSERT(puuart != RT_NULL);
  368. /* Allocate UUART_TX nu_dma channel */
  369. if (puuart->pdma_perp_tx != NU_PDMA_UNUSED)
  370. {
  371. puuart->pdma_chanid_tx = nu_pdma_channel_allocate(puuart->pdma_perp_tx);
  372. if (puuart->pdma_chanid_tx >= 0)
  373. {
  374. puuart->dma_flag |= RT_DEVICE_FLAG_DMA_TX;
  375. }
  376. }
  377. /* Allocate UUART_RX nu_dma channel */
  378. if (puuart->pdma_perp_rx != NU_PDMA_UNUSED)
  379. {
  380. puuart->pdma_chanid_rx = nu_pdma_channel_allocate(puuart->pdma_perp_rx);
  381. if (puuart->pdma_chanid_rx >= 0)
  382. {
  383. puuart->dma_flag |= RT_DEVICE_FLAG_DMA_RX;
  384. }
  385. }
  386. return RT_EOK;
  387. }
  388. #endif
  389. /**
  390. * UUart interrupt control
  391. */
  392. static rt_err_t nu_uuart_control(struct rt_serial_device *serial, int cmd, void *arg)
  393. {
  394. rt_err_t result = RT_EOK;
  395. rt_uint32_t flag = 0;
  396. rt_ubase_t ctrl_arg = (rt_ubase_t)arg;
  397. RT_ASSERT(serial != RT_NULL);
  398. /* Get base address of uuart register */
  399. UUART_T *uuart_base = ((nu_uuart_t)serial)->uuart_base;
  400. switch (cmd)
  401. {
  402. case RT_DEVICE_CTRL_CLR_INT:
  403. if (ctrl_arg == RT_DEVICE_FLAG_INT_RX) /* Disable INT-RX */
  404. {
  405. flag = UUART_RXEND_INT_MASK;
  406. UUART_DisableInt(uuart_base, flag);
  407. }
  408. else if (ctrl_arg == RT_DEVICE_FLAG_DMA_RX) /* Disable DMA-RX */
  409. {
  410. /* Disable Receive Line interrupt & Stop DMA RX transfer. */
  411. flag = UUART_RLS_INT_MASK;
  412. nu_pdma_channel_terminate(((nu_uuart_t)serial)->pdma_chanid_rx);
  413. UUART_PDMA_DISABLE(uuart_base, UUART_PDMACTL_RXPDMAEN_Msk);
  414. UUART_DisableInt(uuart_base, flag);
  415. }
  416. break;
  417. case RT_DEVICE_CTRL_SET_INT:
  418. if (ctrl_arg == RT_DEVICE_FLAG_INT_RX) /* Enable INT-RX */
  419. {
  420. flag = UUART_RXEND_INT_MASK;
  421. UUART_EnableInt(uuart_base, flag);
  422. }
  423. break;
  424. #if defined(RT_SERIAL_USING_DMA)
  425. case RT_DEVICE_CTRL_CONFIG:
  426. if (ctrl_arg == RT_DEVICE_FLAG_DMA_RX) /* Configure and trigger DMA-RX */
  427. {
  428. struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
  429. ((nu_uuart_t)serial)->rxdma_trigger_len = serial->config.bufsz;
  430. ((nu_uuart_t)serial)->rx_write_offset = 0;
  431. result = nu_pdma_uuart_rx_config(serial, &rx_fifo->buffer[0], ((nu_uuart_t)serial)->rxdma_trigger_len); // Config & trigger
  432. }
  433. else if (ctrl_arg == RT_DEVICE_FLAG_DMA_TX) /* Configure DMA-TX */
  434. {
  435. result = nu_pdma_uuart_tx_config(serial);
  436. }
  437. break;
  438. #endif
  439. case RT_DEVICE_CTRL_CLOSE:
  440. /* Disable NVIC interrupt. */
  441. NVIC_DisableIRQ(((nu_uuart_t)serial)->uuart_irq_n);
  442. #if defined(RT_SERIAL_USING_DMA)
  443. nu_pdma_channel_terminate(((nu_uuart_t)serial)->pdma_chanid_tx);
  444. nu_pdma_channel_terminate(((nu_uuart_t)serial)->pdma_chanid_rx);
  445. #endif
  446. /* Reset this module */
  447. SYS_ResetModule(((nu_uuart_t)serial)->uuart_rst);
  448. /* Close UUART port */
  449. UUART_Close(uuart_base);
  450. break;
  451. default:
  452. result = -RT_EINVAL;
  453. break;
  454. }
  455. return result;
  456. }
  457. /**
  458. * UUart put char
  459. */
  460. static int nu_uuart_send(struct rt_serial_device *serial, char c)
  461. {
  462. RT_ASSERT(serial != RT_NULL);
  463. /* Get base address of uuart register */
  464. UUART_T *uuart_base = ((nu_uuart_t)serial)->uuart_base;
  465. /* Waiting if TX-FIFO is full. */
  466. while (UUART_IS_TX_FULL(uuart_base)) {};
  467. /* Put char into TX-FIFO */
  468. UUART_WRITE(uuart_base, c);
  469. return 1;
  470. }
  471. /**
  472. * UUart get char
  473. */
  474. static int nu_uuart_receive(struct rt_serial_device *serial)
  475. {
  476. RT_ASSERT(serial != RT_NULL);
  477. /* Get base address of uuart register */
  478. UUART_T *uuart_base = ((nu_uuart_t)serial)->uuart_base;
  479. /* Return failure if RX-FIFO is empty. */
  480. if (UUART_GET_RX_EMPTY(uuart_base) != 0)
  481. {
  482. return -1;
  483. }
  484. /* Get char from RX-FIFO */
  485. return UUART_READ(uuart_base);
  486. }
  487. /**
  488. * Hardware UUART Initialization
  489. */
  490. static int rt_hw_uuart_init(void)
  491. {
  492. int i;
  493. rt_uint32_t flag;
  494. rt_err_t ret = RT_EOK;
  495. for (i = (UUART_START + 1); i < UUART_CNT; i++)
  496. {
  497. flag = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX;
  498. nu_uuart_arr[i].dev.ops = &nu_uuart_ops;
  499. nu_uuart_arr[i].dev.config = nu_uuart_default_config;
  500. #if defined(RT_SERIAL_USING_DMA)
  501. nu_uuart_arr[i].dma_flag = 0;
  502. nu_hw_uuart_dma_allocate(&nu_uuart_arr[i]);
  503. flag |= nu_uuart_arr[i].dma_flag;
  504. #endif
  505. ret = rt_hw_serial_register(&nu_uuart_arr[i].dev, nu_uuart_arr[i].name, flag, NULL);
  506. RT_ASSERT(ret == RT_EOK);
  507. }
  508. return (int)ret;
  509. }
  510. INIT_DEVICE_EXPORT(rt_hw_uuart_init);
  511. #endif //#if defined(BSP_USING_UUART)