drv_uuart.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
  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. * 2020-2-7 ChingI 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_size_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 = USCI0_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 = USCI1_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)
  126. /* USCI0 interrupt entry */
  127. void USCI0_IRQHandler(void)
  128. {
  129. /* enter interrupt */
  130. rt_interrupt_enter();
  131. nu_uuart_isr(&nu_uuart_arr[UUART0_IDX]);
  132. /* leave interrupt */
  133. rt_interrupt_leave();
  134. }
  135. #endif
  136. #if defined(BSP_USING_UUART1)
  137. /* USCI1 interrupt entry */
  138. void USCI1_IRQHandler(void)
  139. {
  140. /* enter interrupt */
  141. rt_interrupt_enter();
  142. nu_uuart_isr(&nu_uuart_arr[UUART1_IDX]);
  143. /* leave interrupt */
  144. rt_interrupt_leave();
  145. }
  146. #endif
  147. /**
  148. * All UUART interrupt service routine
  149. */
  150. static void nu_uuart_isr(nu_uuart_t serial)
  151. {
  152. /* Get base address of uuart register */
  153. UUART_T *uuart_base = ((nu_uuart_t)serial)->uuart_base;
  154. /* Get interrupt event */
  155. uint32_t u32IntSts = uuart_base->PROTSTS;
  156. uint32_t u32FIFOSts = uuart_base->BUFSTS;
  157. if (u32IntSts & (UUART_PROTSTS_PARITYERR_Msk | UUART_PROTSTS_FRMERR_Msk | UUART_PROTSTS_BREAK_Msk))
  158. {
  159. uuart_base->PROTSTS |= (UUART_PROTSTS_PARITYERR_Msk | UUART_PROTSTS_FRMERR_Msk | UUART_PROTSTS_BREAK_Msk);
  160. return;
  161. }
  162. /* Handle RX event */
  163. if (u32IntSts & UUART_PROTSTS_RXENDIF_Msk)
  164. {
  165. rt_hw_serial_isr(&serial->dev, RT_SERIAL_EVENT_RX_IND);
  166. }
  167. uuart_base->PROTSTS = u32IntSts;
  168. uuart_base->BUFSTS = u32FIFOSts;
  169. }
  170. /**
  171. * Configure uuart port
  172. */
  173. static rt_err_t nu_uuart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  174. {
  175. rt_err_t ret = RT_EOK;
  176. uint32_t uuart_word_len = 0;
  177. uint32_t uuart_stop_bit = 0;
  178. uint32_t uuart_parity = 0;
  179. /* Get base address of uuart register */
  180. UUART_T *uuart_base = ((nu_uuart_t)serial)->uuart_base;
  181. /* Check baud rate */
  182. RT_ASSERT(cfg->baud_rate != 0);
  183. /* Check word len */
  184. switch (cfg->data_bits)
  185. {
  186. case DATA_BITS_5:
  187. rt_kprintf("Unsupported data length");
  188. goto exit_nu_uuart_configure;
  189. case DATA_BITS_6:
  190. uuart_word_len = UUART_WORD_LEN_6;
  191. break;
  192. case DATA_BITS_7:
  193. uuart_word_len = UUART_WORD_LEN_7;
  194. break;
  195. case DATA_BITS_8:
  196. uuart_word_len = UUART_WORD_LEN_8;
  197. break;
  198. default:
  199. rt_kprintf("Unsupported data length");
  200. ret = RT_EINVAL;
  201. goto exit_nu_uuart_configure;
  202. }
  203. /* Check stop bit */
  204. switch (cfg->stop_bits)
  205. {
  206. case STOP_BITS_1:
  207. uuart_stop_bit = UUART_STOP_BIT_1;
  208. break;
  209. case STOP_BITS_2:
  210. uuart_stop_bit = UUART_STOP_BIT_2;
  211. break;
  212. default:
  213. rt_kprintf("Unsupported stop bit");
  214. ret = RT_EINVAL;
  215. goto exit_nu_uuart_configure;
  216. }
  217. /* Check parity */
  218. switch (cfg->parity)
  219. {
  220. case PARITY_NONE:
  221. uuart_parity = UUART_PARITY_NONE;
  222. break;
  223. case PARITY_ODD:
  224. uuart_parity = UUART_PARITY_ODD;
  225. break;
  226. case PARITY_EVEN:
  227. uuart_parity = UUART_PARITY_EVEN;
  228. break;
  229. default:
  230. rt_kprintf("Unsupported parity");
  231. ret = RT_EINVAL;
  232. goto exit_nu_uuart_configure;
  233. }
  234. /* Reset this module */
  235. SYS_ResetModule(((nu_uuart_t)serial)->uuart_rst);
  236. /* Open UUart and set UUART baud rate */
  237. UUART_Open(uuart_base, cfg->baud_rate);
  238. /* Set line configuration. */
  239. UUART_SetLine_Config(uuart_base, 0, uuart_word_len, uuart_parity, uuart_stop_bit);
  240. /* Enable NVIC interrupt. */
  241. NVIC_EnableIRQ(((nu_uuart_t)serial)->uuart_irq_n);
  242. exit_nu_uuart_configure:
  243. if (ret != RT_EOK)
  244. UUART_Close(uuart_base);
  245. return -(ret);
  246. }
  247. #if defined(RT_SERIAL_USING_DMA)
  248. static rt_err_t nu_pdma_uuart_rx_config(struct rt_serial_device *serial, uint8_t *pu8Buf, int32_t i32TriggerLen)
  249. {
  250. rt_err_t result = RT_EOK;
  251. /* Get base address of uuart register */
  252. UUART_T *uuart_base = ((nu_uuart_t)serial)->uuart_base;
  253. result = nu_pdma_callback_register(((nu_uuart_t)serial)->pdma_chanid_rx,
  254. nu_pdma_uuart_rx_cb,
  255. (void *)serial,
  256. NU_PDMA_EVENT_TRANSFER_DONE | NU_PDMA_EVENT_TIMEOUT);
  257. if (result != RT_EOK)
  258. {
  259. goto exit_nu_pdma_uuart_rx_config;
  260. }
  261. result = nu_pdma_transfer(((nu_uuart_t)serial)->pdma_chanid_rx,
  262. 8,
  263. (uint32_t)&uuart_base->RXDAT,
  264. (uint32_t)pu8Buf,
  265. i32TriggerLen,
  266. 1000); //Idle-timeout, 1ms
  267. if (result != RT_EOK)
  268. {
  269. goto exit_nu_pdma_uuart_rx_config;
  270. }
  271. //UUART PDMA reset
  272. UUART_PDMA_ENABLE(uuart_base, UUART_PDMACTL_PDMARST_Msk);
  273. /* Enable Receive Line interrupt & Start DMA RX transfer. */
  274. UUART_EnableInt(uuart_base, UUART_RLS_INT_MASK);
  275. UUART_PDMA_ENABLE(uuart_base, UUART_PDMACTL_RXPDMAEN_Msk | UUART_PDMACTL_PDMAEN_Msk);
  276. exit_nu_pdma_uuart_rx_config:
  277. return result;
  278. }
  279. static void nu_pdma_uuart_rx_cb(void *pvOwner, uint32_t u32Events)
  280. {
  281. rt_size_t recv_len = 0;
  282. rt_size_t transferred_rxbyte = 0;
  283. struct rt_serial_device *serial = (struct rt_serial_device *)pvOwner;
  284. nu_uuart_t puuart = (nu_uuart_t)serial;
  285. RT_ASSERT(serial != RT_NULL);
  286. /* Get base address of uuart register */
  287. UUART_T *uuart_base = puuart->uuart_base;
  288. transferred_rxbyte = nu_pdma_transferred_byte_get(puuart->pdma_chanid_rx, puuart->rxdma_trigger_len);
  289. if (u32Events & (NU_PDMA_EVENT_TRANSFER_DONE | NU_PDMA_EVENT_TIMEOUT))
  290. {
  291. if (u32Events & NU_PDMA_EVENT_TRANSFER_DONE)
  292. {
  293. if (serial->config.bufsz != 0)
  294. {
  295. struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
  296. nu_pdma_uuart_rx_config(serial, &rx_fifo->buffer[0], puuart->rxdma_trigger_len); // Config & trigger next
  297. }
  298. transferred_rxbyte = puuart->rxdma_trigger_len;
  299. }
  300. else if ((u32Events & NU_PDMA_EVENT_TIMEOUT) && !UUART_GET_RX_EMPTY(uuart_base))
  301. {
  302. return;
  303. }
  304. recv_len = transferred_rxbyte - puuart->rx_write_offset;
  305. puuart->rx_write_offset = transferred_rxbyte % puuart->rxdma_trigger_len;
  306. }
  307. if ((serial->config.bufsz == 0) && (u32Events & NU_PDMA_EVENT_TRANSFER_DONE))
  308. {
  309. recv_len = puuart->rxdma_trigger_len;
  310. }
  311. if (recv_len)
  312. {
  313. rt_hw_serial_isr(&puuart->dev, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8));
  314. }
  315. }
  316. static rt_err_t nu_pdma_uuart_tx_config(struct rt_serial_device *serial)
  317. {
  318. rt_err_t result = RT_EOK;
  319. RT_ASSERT(serial != RT_NULL);
  320. result = nu_pdma_callback_register(((nu_uuart_t)serial)->pdma_chanid_tx,
  321. nu_pdma_uuart_tx_cb,
  322. (void *)serial,
  323. NU_PDMA_EVENT_TRANSFER_DONE);
  324. return result;
  325. }
  326. static void nu_pdma_uuart_tx_cb(void *pvOwner, uint32_t u32Events)
  327. {
  328. nu_uuart_t puuart = (nu_uuart_t)pvOwner;
  329. RT_ASSERT(puuart != RT_NULL);
  330. // Stop DMA TX transfer
  331. UUART_PDMA_DISABLE(puuart->uuart_base, UUART_PDMACTL_TXPDMAEN_Msk);
  332. if (u32Events & NU_PDMA_EVENT_TRANSFER_DONE)
  333. {
  334. rt_hw_serial_isr(&puuart->dev, RT_SERIAL_EVENT_TX_DMADONE);
  335. }
  336. }
  337. /**
  338. * UUart DMA transfer
  339. */
  340. static rt_size_t nu_uuart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
  341. {
  342. rt_err_t result = RT_EOK;
  343. RT_ASSERT(serial != RT_NULL);
  344. RT_ASSERT(buf != RT_NULL);
  345. /* Get base address of uuart register */
  346. UUART_T *uuart_base = ((nu_uuart_t)serial)->uuart_base;
  347. if (direction == RT_SERIAL_DMA_TX)
  348. {
  349. result = nu_pdma_transfer(((nu_uuart_t)serial)->pdma_chanid_tx,
  350. 8,
  351. (uint32_t)buf,
  352. (uint32_t)&uuart_base->TXDAT,
  353. size,
  354. 0); // wait-forever
  355. // Start DMA TX transfer
  356. UUART_PDMA_ENABLE(uuart_base, UUART_PDMACTL_TXPDMAEN_Msk | UUART_PDMACTL_PDMAEN_Msk);
  357. }
  358. else if (direction == RT_SERIAL_DMA_RX)
  359. {
  360. // If config.bufsz = 0, serial will trigger once.
  361. ((nu_uuart_t)serial)->rxdma_trigger_len = size;
  362. ((nu_uuart_t)serial)->rx_write_offset = 0;
  363. result = nu_pdma_uuart_rx_config(serial, buf, size);
  364. }
  365. else
  366. {
  367. result = RT_ERROR;
  368. }
  369. return result;
  370. }
  371. static int nu_hw_uuart_dma_allocate(nu_uuart_t puuart)
  372. {
  373. RT_ASSERT(puuart != RT_NULL);
  374. /* Allocate UUART_TX nu_dma channel */
  375. if (puuart->pdma_perp_tx != NU_PDMA_UNUSED)
  376. {
  377. puuart->pdma_chanid_tx = nu_pdma_channel_allocate(puuart->pdma_perp_tx);
  378. if (puuart->pdma_chanid_tx >= 0)
  379. {
  380. puuart->dma_flag |= RT_DEVICE_FLAG_DMA_TX;
  381. }
  382. }
  383. /* Allocate UUART_RX nu_dma channel */
  384. if (puuart->pdma_perp_rx != NU_PDMA_UNUSED)
  385. {
  386. puuart->pdma_chanid_rx = nu_pdma_channel_allocate(puuart->pdma_perp_rx);
  387. if (puuart->pdma_chanid_rx >= 0)
  388. {
  389. puuart->dma_flag |= RT_DEVICE_FLAG_DMA_RX;
  390. }
  391. }
  392. return RT_EOK;
  393. }
  394. #endif
  395. /**
  396. * UUart interrupt control
  397. */
  398. static rt_err_t nu_uuart_control(struct rt_serial_device *serial, int cmd, void *arg)
  399. {
  400. rt_err_t result = RT_EOK;
  401. rt_uint32_t flag = 0;
  402. rt_ubase_t ctrl_arg = (rt_ubase_t)arg;
  403. RT_ASSERT(serial != RT_NULL);
  404. /* Get base address of uuart register */
  405. UUART_T *uuart_base = ((nu_uuart_t)serial)->uuart_base;
  406. switch (cmd)
  407. {
  408. case RT_DEVICE_CTRL_CLR_INT:
  409. if (ctrl_arg == RT_DEVICE_FLAG_INT_RX) /* Disable INT-RX */
  410. {
  411. flag = UUART_RXEND_INT_MASK;
  412. UUART_DisableInt(uuart_base, flag);
  413. }
  414. else if (ctrl_arg == RT_DEVICE_FLAG_DMA_RX) /* Disable DMA-RX */
  415. {
  416. /* Disable Receive Line interrupt & Stop DMA RX transfer. */
  417. flag = UUART_RLS_INT_MASK;
  418. nu_pdma_channel_terminate(((nu_uuart_t)serial)->pdma_chanid_rx);
  419. UUART_PDMA_DISABLE(uuart_base, UUART_PDMACTL_RXPDMAEN_Msk);
  420. UUART_DisableInt(uuart_base, flag);
  421. }
  422. break;
  423. case RT_DEVICE_CTRL_SET_INT:
  424. if (ctrl_arg == RT_DEVICE_FLAG_INT_RX) /* Enable INT-RX */
  425. {
  426. flag = UUART_RXEND_INT_MASK;
  427. UUART_EnableInt(uuart_base, flag);
  428. }
  429. break;
  430. #if defined(RT_SERIAL_USING_DMA)
  431. case RT_DEVICE_CTRL_CONFIG:
  432. if (ctrl_arg == RT_DEVICE_FLAG_DMA_RX) /* Configure and trigger DMA-RX */
  433. {
  434. struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
  435. ((nu_uuart_t)serial)->rxdma_trigger_len = serial->config.bufsz;
  436. ((nu_uuart_t)serial)->rx_write_offset = 0;
  437. result = nu_pdma_uuart_rx_config(serial, &rx_fifo->buffer[0], ((nu_uuart_t)serial)->rxdma_trigger_len); // Config & trigger
  438. }
  439. else if (ctrl_arg == RT_DEVICE_FLAG_DMA_TX) /* Configure DMA-TX */
  440. {
  441. result = nu_pdma_uuart_tx_config(serial);
  442. }
  443. break;
  444. #endif
  445. case RT_DEVICE_CTRL_CLOSE:
  446. /* Disable NVIC interrupt. */
  447. NVIC_DisableIRQ(((nu_uuart_t)serial)->uuart_irq_n);
  448. #if defined(RT_SERIAL_USING_DMA)
  449. nu_pdma_channel_terminate(((nu_uuart_t)serial)->pdma_chanid_tx);
  450. nu_pdma_channel_terminate(((nu_uuart_t)serial)->pdma_chanid_rx);
  451. #endif
  452. /* Reset this module */
  453. SYS_ResetModule(((nu_uuart_t)serial)->uuart_rst);
  454. /* Close UUART port */
  455. UUART_Close(uuart_base);
  456. break;
  457. default:
  458. result = -RT_EINVAL;
  459. break;
  460. }
  461. return result;
  462. }
  463. /**
  464. * UUart put char
  465. */
  466. static int nu_uuart_send(struct rt_serial_device *serial, char c)
  467. {
  468. RT_ASSERT(serial != RT_NULL);
  469. /* Get base address of uuart register */
  470. UUART_T *uuart_base = ((nu_uuart_t)serial)->uuart_base;
  471. /* Waiting if TX-FIFO is full. */
  472. while (UUART_IS_TX_FULL(uuart_base)) {};
  473. /* Put char into TX-FIFO */
  474. UUART_WRITE(uuart_base, c);
  475. return 1;
  476. }
  477. /**
  478. * UUart get char
  479. */
  480. static int nu_uuart_receive(struct rt_serial_device *serial)
  481. {
  482. RT_ASSERT(serial != RT_NULL);
  483. /* Get base address of uuart register */
  484. UUART_T *uuart_base = ((nu_uuart_t)serial)->uuart_base;
  485. /* Return failure if RX-FIFO is empty. */
  486. if (UUART_GET_RX_EMPTY(uuart_base) != 0)
  487. {
  488. return -1;
  489. }
  490. /* Get char from RX-FIFO */
  491. return UUART_READ(uuart_base);
  492. }
  493. /**
  494. * Hardware UUART Initialization
  495. */
  496. static int rt_hw_uuart_init(void)
  497. {
  498. int i;
  499. rt_uint32_t flag;
  500. rt_err_t ret = RT_EOK;
  501. for (i = (UUART_START + 1); i < UUART_CNT; i++)
  502. {
  503. flag = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX;
  504. nu_uuart_arr[i].dev.ops = &nu_uuart_ops;
  505. nu_uuart_arr[i].dev.config = nu_uuart_default_config;
  506. #if defined(RT_SERIAL_USING_DMA)
  507. nu_uuart_arr[i].dma_flag = 0;
  508. nu_hw_uuart_dma_allocate(&nu_uuart_arr[i]);
  509. flag |= nu_uuart_arr[i].dma_flag;
  510. #endif
  511. ret = rt_hw_serial_register(&nu_uuart_arr[i].dev, nu_uuart_arr[i].name, flag, NULL);
  512. RT_ASSERT(ret == RT_EOK);
  513. }
  514. return (int)ret;
  515. }
  516. INIT_DEVICE_EXPORT(rt_hw_uuart_init);
  517. #endif //#if defined(BSP_USING_UUART)