drv_uart.c 24 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010
  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. * 2022-3-15 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. #if defined(RT_SERIAL_USING_DMA)
  19. #include <drv_pdma.h>
  20. #endif
  21. /* Private define ---------------------------------------------------------------*/
  22. enum
  23. {
  24. UART_START = -1,
  25. #if defined(BSP_USING_UART0)
  26. UART0_IDX,
  27. #endif
  28. #if defined(BSP_USING_UART1)
  29. UART1_IDX,
  30. #endif
  31. #if defined(BSP_USING_UART2)
  32. UART2_IDX,
  33. #endif
  34. #if defined(BSP_USING_UART3)
  35. UART3_IDX,
  36. #endif
  37. #if defined(BSP_USING_UART4)
  38. UART4_IDX,
  39. #endif
  40. #if defined(BSP_USING_UART5)
  41. UART5_IDX,
  42. #endif
  43. #if defined(BSP_USING_UART6)
  44. UART6_IDX,
  45. #endif
  46. #if defined(BSP_USING_UART7)
  47. UART7_IDX,
  48. #endif
  49. UART_CNT
  50. };
  51. /* Private typedef --------------------------------------------------------------*/
  52. struct nu_uart
  53. {
  54. rt_serial_t dev;
  55. char *name;
  56. UART_T *uart_base;
  57. uint32_t uart_rst;
  58. IRQn_Type uart_irq_n;
  59. #if defined(RT_SERIAL_USING_DMA)
  60. uint32_t dma_flag;
  61. int16_t pdma_perp_tx;
  62. int8_t pdma_chanid_tx;
  63. int16_t pdma_perp_rx;
  64. int8_t pdma_chanid_rx;
  65. int32_t rx_write_offset;
  66. int32_t rxdma_trigger_len;
  67. nu_pdma_desc_t pdma_rx_desc;
  68. #endif
  69. };
  70. typedef struct nu_uart *nu_uart_t;
  71. /* Private functions ------------------------------------------------------------*/
  72. static rt_err_t nu_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg);
  73. static rt_err_t nu_uart_control(struct rt_serial_device *serial, int cmd, void *arg);
  74. static int nu_uart_send(struct rt_serial_device *serial, char c);
  75. static int nu_uart_receive(struct rt_serial_device *serial);
  76. static void nu_uart_isr(nu_uart_t serial);
  77. #if defined(RT_SERIAL_USING_DMA)
  78. static rt_ssize_t nu_uart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction);
  79. static void nu_pdma_uart_rx_cb(void *pvOwner, uint32_t u32Events);
  80. static void nu_pdma_uart_tx_cb(void *pvOwner, uint32_t u32Events);
  81. #endif
  82. /* Public functions ------------------------------------------------------------*/
  83. /* Private variables ------------------------------------------------------------*/
  84. static const struct rt_uart_ops nu_uart_ops =
  85. {
  86. .configure = nu_uart_configure,
  87. .control = nu_uart_control,
  88. .putc = nu_uart_send,
  89. .getc = nu_uart_receive,
  90. #if defined(RT_SERIAL_USING_DMA)
  91. .dma_transmit = nu_uart_dma_transmit
  92. #else
  93. .dma_transmit = RT_NULL
  94. #endif
  95. };
  96. static const struct serial_configure nu_uart_default_config =
  97. RT_SERIAL_CONFIG_DEFAULT;
  98. static struct nu_uart nu_uart_arr [] =
  99. {
  100. #if defined(BSP_USING_UART0)
  101. {
  102. .name = "uart0",
  103. .uart_base = UART0,
  104. .uart_rst = UART0_RST,
  105. .uart_irq_n = UART0_IRQn,
  106. #if defined(RT_SERIAL_USING_DMA)
  107. #if defined(BSP_USING_UART0_TX_DMA)
  108. .pdma_perp_tx = PDMA_UART0_TX,
  109. #else
  110. .pdma_perp_tx = NU_PDMA_UNUSED,
  111. #endif
  112. #if defined(BSP_USING_UART0_RX_DMA)
  113. .pdma_perp_rx = PDMA_UART0_RX,
  114. .rx_write_offset = 0,
  115. #else
  116. .pdma_perp_rx = NU_PDMA_UNUSED,
  117. #endif
  118. #endif
  119. },
  120. #endif
  121. #if defined(BSP_USING_UART1)
  122. {
  123. .name = "uart1",
  124. .uart_base = UART1,
  125. .uart_rst = UART1_RST,
  126. .uart_irq_n = UART1_IRQn,
  127. #if defined(RT_SERIAL_USING_DMA)
  128. #if defined(BSP_USING_UART1_TX_DMA)
  129. .pdma_perp_tx = PDMA_UART1_TX,
  130. #else
  131. .pdma_perp_tx = NU_PDMA_UNUSED,
  132. #endif
  133. #if defined(BSP_USING_UART1_RX_DMA)
  134. .pdma_perp_rx = PDMA_UART1_RX,
  135. .rx_write_offset = 0,
  136. #else
  137. .pdma_perp_rx = NU_PDMA_UNUSED,
  138. #endif
  139. #endif
  140. },
  141. #endif
  142. #if defined(BSP_USING_UART2)
  143. {
  144. .name = "uart2",
  145. .uart_base = UART2,
  146. .uart_rst = UART2_RST,
  147. .uart_irq_n = UART2_IRQn,
  148. #if defined(RT_SERIAL_USING_DMA)
  149. #if defined(BSP_USING_UART2_TX_DMA)
  150. .pdma_perp_tx = PDMA_UART2_TX,
  151. #else
  152. .pdma_perp_tx = NU_PDMA_UNUSED,
  153. #endif
  154. #if defined(BSP_USING_UART2_RX_DMA)
  155. .pdma_perp_rx = PDMA_UART2_RX,
  156. .rx_write_offset = 0,
  157. #else
  158. .pdma_perp_rx = NU_PDMA_UNUSED,
  159. #endif
  160. #endif
  161. },
  162. #endif
  163. #if defined(BSP_USING_UART3)
  164. {
  165. .name = "uart3",
  166. .uart_base = UART3,
  167. .uart_rst = UART3_RST,
  168. .uart_irq_n = UART3_IRQn,
  169. #if defined(RT_SERIAL_USING_DMA)
  170. #if defined(BSP_USING_UART3_TX_DMA)
  171. .pdma_perp_tx = PDMA_UART3_TX,
  172. #else
  173. .pdma_perp_tx = NU_PDMA_UNUSED,
  174. #endif
  175. #if defined(BSP_USING_UART3_RX_DMA)
  176. .pdma_perp_rx = PDMA_UART3_RX,
  177. .rx_write_offset = 0,
  178. #else
  179. .pdma_perp_rx = NU_PDMA_UNUSED,
  180. #endif
  181. #endif
  182. },
  183. #endif
  184. #if defined(BSP_USING_UART4)
  185. {
  186. .name = "uart4",
  187. .uart_base = UART4,
  188. .uart_rst = UART4_RST,
  189. .uart_irq_n = UART4_IRQn,
  190. #if defined(RT_SERIAL_USING_DMA)
  191. #if defined(BSP_USING_UART4_TX_DMA)
  192. .pdma_perp_tx = PDMA_UART4_TX,
  193. #else
  194. .pdma_perp_tx = NU_PDMA_UNUSED,
  195. #endif
  196. #if defined(BSP_USING_UART4_RX_DMA)
  197. .pdma_perp_rx = PDMA_UART4_RX,
  198. .rx_write_offset = 0,
  199. #else
  200. .pdma_perp_rx = NU_PDMA_UNUSED,
  201. #endif
  202. #endif
  203. },
  204. #endif
  205. #if defined(BSP_USING_UART5)
  206. {
  207. .name = "uart5",
  208. .uart_base = UART5,
  209. .uart_rst = UART5_RST,
  210. .uart_irq_n = UART5_IRQn,
  211. #if defined(RT_SERIAL_USING_DMA)
  212. #if defined(BSP_USING_UART5_TX_DMA)
  213. .pdma_perp_tx = PDMA_UART5_TX,
  214. #else
  215. .pdma_perp_tx = NU_PDMA_UNUSED,
  216. #endif
  217. #if defined(BSP_USING_UART5_RX_DMA)
  218. .pdma_perp_rx = PDMA_UART5_RX,
  219. .rx_write_offset = 0,
  220. #else
  221. .pdma_perp_rx = NU_PDMA_UNUSED,
  222. #endif
  223. #endif
  224. },
  225. #endif
  226. #if defined(BSP_USING_UART6)
  227. {
  228. .name = "uart6",
  229. .uart_base = UART6,
  230. .uart_rst = UART6_RST,
  231. .uart_irq_n = UART6_IRQn,
  232. #if defined(RT_SERIAL_USING_DMA)
  233. #if defined(BSP_USING_UART6_TX_DMA)
  234. .pdma_perp_tx = PDMA_UART6_TX,
  235. #else
  236. .pdma_perp_tx = NU_PDMA_UNUSED,
  237. #endif
  238. #if defined(BSP_USING_UART6_RX_DMA)
  239. .pdma_perp_rx = PDMA_UART6_RX,
  240. .rx_write_offset = 0,
  241. #else
  242. .pdma_perp_rx = NU_PDMA_UNUSED,
  243. #endif
  244. #endif
  245. },
  246. #endif
  247. #if defined(BSP_USING_UART7)
  248. {
  249. .name = "uart7",
  250. .uart_base = UART7,
  251. .uart_rst = UART7_RST,
  252. .uart_irq_n = UART7_IRQn,
  253. #if defined(RT_SERIAL_USING_DMA)
  254. #if defined(BSP_USING_UART7_TX_DMA)
  255. .pdma_perp_tx = PDMA_UART7_TX,
  256. #else
  257. .pdma_perp_tx = NU_PDMA_UNUSED,
  258. #endif
  259. #if defined(BSP_USING_UART7_RX_DMA)
  260. .pdma_perp_rx = PDMA_UART7_RX,
  261. .rx_write_offset = 0,
  262. #else
  263. .pdma_perp_rx = NU_PDMA_UNUSED,
  264. #endif
  265. #endif
  266. },
  267. #endif
  268. #if defined(BSP_USING_UART8)
  269. {
  270. .name = "uart7",
  271. .uart_base = UART7,
  272. .uart_rst = UART7_RST,
  273. .uart_irq_n = UART7_IRQn,
  274. #if defined(RT_SERIAL_USING_DMA)
  275. #if defined(BSP_USING_UART7_TX_DMA)
  276. .pdma_perp_tx = PDMA_UART7_TX,
  277. #else
  278. .pdma_perp_tx = NU_PDMA_UNUSED,
  279. #endif
  280. #if defined(BSP_USING_UART7_RX_DMA)
  281. .pdma_perp_rx = PDMA_UART7_RX,
  282. .rx_write_offset = 0,
  283. #else
  284. .pdma_perp_rx = NU_PDMA_UNUSED,
  285. #endif
  286. #endif
  287. },
  288. #endif
  289. #if defined(BSP_USING_UART9)
  290. {
  291. .name = "uart7",
  292. .uart_base = UART7,
  293. .uart_rst = UART7_RST,
  294. .uart_irq_n = UART7_IRQn,
  295. #if defined(RT_SERIAL_USING_DMA)
  296. #if defined(BSP_USING_UART7_TX_DMA)
  297. .pdma_perp_tx = PDMA_UART7_TX,
  298. #else
  299. .pdma_perp_tx = NU_PDMA_UNUSED,
  300. #endif
  301. #if defined(BSP_USING_UART7_RX_DMA)
  302. .pdma_perp_rx = PDMA_UART7_RX,
  303. .rx_write_offset = 0,
  304. #else
  305. .pdma_perp_rx = NU_PDMA_UNUSED,
  306. #endif
  307. #endif
  308. },
  309. #endif
  310. }; /* uart nu_uart */
  311. /* Interrupt Handle Function ----------------------------------------------------*/
  312. #if defined(BSP_USING_UART0)
  313. /* UART0 interrupt entry */
  314. void UART0_IRQHandler(void)
  315. {
  316. /* enter interrupt */
  317. rt_interrupt_enter();
  318. nu_uart_isr(&nu_uart_arr[UART0_IDX]);
  319. /* leave interrupt */
  320. rt_interrupt_leave();
  321. }
  322. #endif
  323. #if defined(BSP_USING_UART1)
  324. /* UART1 interrupt entry */
  325. void UART1_IRQHandler(void)
  326. {
  327. /* enter interrupt */
  328. rt_interrupt_enter();
  329. nu_uart_isr(&nu_uart_arr[UART1_IDX]);
  330. /* leave interrupt */
  331. rt_interrupt_leave();
  332. }
  333. #endif
  334. #if defined(BSP_USING_UART2)
  335. /* UART2 interrupt entry */
  336. void UART2_IRQHandler(void)
  337. {
  338. /* enter interrupt */
  339. rt_interrupt_enter();
  340. nu_uart_isr(&nu_uart_arr[UART2_IDX]);
  341. /* leave interrupt */
  342. rt_interrupt_leave();
  343. }
  344. #endif
  345. #if defined(BSP_USING_UART3)
  346. /* UART3 interrupt service routine */
  347. void UART3_IRQHandler(void)
  348. {
  349. /* enter interrupt */
  350. rt_interrupt_enter();
  351. nu_uart_isr(&nu_uart_arr[UART3_IDX]);
  352. /* leave interrupt */
  353. rt_interrupt_leave();
  354. }
  355. #endif
  356. #if defined(BSP_USING_UART4)
  357. /* UART4 interrupt entry */
  358. void UART4_IRQHandler(void)
  359. {
  360. /* enter interrupt */
  361. rt_interrupt_enter();
  362. nu_uart_isr(&nu_uart_arr[UART4_IDX]);
  363. /* leave interrupt */
  364. rt_interrupt_leave();
  365. }
  366. #endif
  367. #if defined(BSP_USING_UART5)
  368. /* UART5 interrupt entry */
  369. void UART5_IRQHandler(void)
  370. {
  371. /* enter interrupt */
  372. rt_interrupt_enter();
  373. nu_uart_isr(&nu_uart_arr[UART5_IDX]);
  374. /* leave interrupt */
  375. rt_interrupt_leave();
  376. }
  377. #endif
  378. #if defined(BSP_USING_UART6)
  379. /* UART6 interrupt entry */
  380. void UART6_IRQHandler(void)
  381. {
  382. /* enter interrupt */
  383. rt_interrupt_enter();
  384. nu_uart_isr(&nu_uart_arr[UART6_IDX]);
  385. /* leave interrupt */
  386. rt_interrupt_leave();
  387. }
  388. #endif
  389. #if defined(BSP_USING_UART7)
  390. /* UART7 interrupt entry */
  391. void UART7_IRQHandler(void)
  392. {
  393. /* enter interrupt */
  394. rt_interrupt_enter();
  395. nu_uart_isr(&nu_uart_arr[UART7_IDX]);
  396. /* leave interrupt */
  397. rt_interrupt_leave();
  398. }
  399. #endif
  400. #if defined(BSP_USING_UART8)
  401. /* UART8 interrupt entry */
  402. void UART8_IRQHandler(void)
  403. {
  404. /* enter interrupt */
  405. rt_interrupt_enter();
  406. nu_uart_isr(&nu_uart_arr[UART8_IDX]);
  407. /* leave interrupt */
  408. rt_interrupt_leave();
  409. }
  410. #endif
  411. #if defined(BSP_USING_UART9)
  412. /* UART9 interrupt entry */
  413. void UART9_IRQHandler(void)
  414. {
  415. /* enter interrupt */
  416. rt_interrupt_enter();
  417. nu_uart_isr(&nu_uart_arr[UART9_IDX]);
  418. /* leave interrupt */
  419. rt_interrupt_leave();
  420. }
  421. #endif
  422. /**
  423. * All UART interrupt service routine
  424. */
  425. static void nu_uart_isr(nu_uart_t serial)
  426. {
  427. /* Get base address of uart register */
  428. UART_T *uart_base = serial->uart_base;
  429. /* Get interrupt event */
  430. uint32_t u32IntSts = uart_base->INTSTS;
  431. uint32_t u32FIFOSts = uart_base->FIFOSTS;
  432. #if defined(RT_SERIAL_USING_DMA)
  433. if (u32IntSts & UART_INTSTS_HWRLSIF_Msk)
  434. {
  435. /* Drain RX FIFO to remove remain FEF frames in FIFO. */
  436. uart_base->FIFO |= UART_FIFO_RXRST_Msk;
  437. uart_base->FIFOSTS |= (UART_FIFOSTS_BIF_Msk | UART_FIFOSTS_FEF_Msk | UART_FIFOSTS_PEF_Msk);
  438. return;
  439. }
  440. #endif
  441. /* Handle RX event */
  442. if (u32IntSts & (UART_INTSTS_RDAINT_Msk | UART_INTSTS_RXTOINT_Msk))
  443. {
  444. rt_hw_serial_isr(&serial->dev, RT_SERIAL_EVENT_RX_IND);
  445. }
  446. uart_base->INTSTS = u32IntSts;
  447. uart_base->FIFOSTS = u32FIFOSts;
  448. }
  449. /**
  450. * Set RS-485 AUD mode
  451. */
  452. void nu_uart_set_rs485aud(struct rt_serial_device *serial, rt_bool_t bRTSActiveLowLevel)
  453. {
  454. UART_T *uart_base;
  455. RT_ASSERT(serial);
  456. /* Get base address of uart register */
  457. uart_base = ((nu_uart_t)serial)->uart_base;
  458. /* Set RTS as RS-485 phy direction controlling ping. */
  459. UART_SelectRS485Mode(uart_base, UART_ALTCTL_RS485AUD_Msk, 0);
  460. if (bRTSActiveLowLevel)
  461. {
  462. /* Set direction pin as active-low. */
  463. uart_base->MODEM |= UART_MODEM_RTSACTLV_Msk;
  464. }
  465. else
  466. {
  467. /* Set direction pin as active-high. */
  468. uart_base->MODEM &= ~UART_MODEM_RTSACTLV_Msk;
  469. }
  470. rt_kprintf("Set %s to RS-485 AUD function mode. ActiveLowLevel-%s\n", ((nu_uart_t)serial)->name, bRTSActiveLowLevel ? "YES" : "NO");
  471. }
  472. /**
  473. * Configure uart port
  474. */
  475. static rt_err_t nu_uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
  476. {
  477. rt_err_t ret = RT_EOK;
  478. uint32_t uart_word_len = 0;
  479. uint32_t uart_stop_bit = 0;
  480. uint32_t uart_parity = 0;
  481. RT_ASSERT(serial);
  482. RT_ASSERT(cfg);
  483. /* Check baudrate */
  484. RT_ASSERT(cfg->baud_rate != 0);
  485. /* Get base address of uart register */
  486. UART_T *uart_base = ((nu_uart_t)serial)->uart_base;
  487. /* Check word len */
  488. switch (cfg->data_bits)
  489. {
  490. case DATA_BITS_5:
  491. uart_word_len = UART_WORD_LEN_5;
  492. break;
  493. case DATA_BITS_6:
  494. uart_word_len = UART_WORD_LEN_6;
  495. break;
  496. case DATA_BITS_7:
  497. uart_word_len = UART_WORD_LEN_7;
  498. break;
  499. case DATA_BITS_8:
  500. uart_word_len = UART_WORD_LEN_8;
  501. break;
  502. default:
  503. rt_kprintf("Unsupported data length\n");
  504. ret = -RT_EINVAL;
  505. goto exit_nu_uart_configure;
  506. }
  507. /* Check stop bit */
  508. switch (cfg->stop_bits)
  509. {
  510. case STOP_BITS_1:
  511. uart_stop_bit = UART_STOP_BIT_1;
  512. break;
  513. case STOP_BITS_2:
  514. uart_stop_bit = UART_STOP_BIT_2;
  515. break;
  516. default:
  517. rt_kprintf("Unsupported stop bit\n");
  518. ret = -RT_EINVAL;
  519. goto exit_nu_uart_configure;
  520. }
  521. /* Check parity */
  522. switch (cfg->parity)
  523. {
  524. case PARITY_NONE:
  525. uart_parity = UART_PARITY_NONE;
  526. break;
  527. case PARITY_ODD:
  528. uart_parity = UART_PARITY_ODD;
  529. break;
  530. case PARITY_EVEN:
  531. uart_parity = UART_PARITY_EVEN;
  532. break;
  533. default:
  534. rt_kprintf("Unsupported parity\n");
  535. ret = -RT_EINVAL;
  536. goto exit_nu_uart_configure;
  537. }
  538. /* Reset this module */
  539. SYS_ResetModule(((nu_uart_t)serial)->uart_rst);
  540. /* Open Uart and set UART Baudrate */
  541. UART_Open(uart_base, cfg->baud_rate);
  542. /* Set line configuration. */
  543. UART_SetLineConfig(uart_base, 0, uart_word_len, uart_parity, uart_stop_bit);
  544. /* Enable NVIC interrupt. */
  545. NVIC_EnableIRQ(((nu_uart_t)serial)->uart_irq_n);
  546. exit_nu_uart_configure:
  547. if (ret != RT_EOK)
  548. UART_Close(uart_base);
  549. return -(ret);
  550. }
  551. #if defined(RT_SERIAL_USING_DMA)
  552. static rt_err_t nu_pdma_uart_rx_config(struct rt_serial_device *serial, uint8_t *pu8Buf, int32_t i32TriggerLen)
  553. {
  554. rt_err_t result = RT_EOK;
  555. struct nu_pdma_chn_cb sChnCB;
  556. nu_uart_t psNuUart = (nu_uart_t)serial;
  557. /* Get base address of uart register */
  558. UART_T *uart_base = psNuUart->uart_base;
  559. /* Register ISR callback function */
  560. sChnCB.m_eCBType = eCBType_Event;
  561. sChnCB.m_pfnCBHandler = nu_pdma_uart_rx_cb;
  562. sChnCB.m_pvUserData = (void *)serial;
  563. nu_pdma_filtering_set(psNuUart->pdma_chanid_rx, NU_PDMA_EVENT_TRANSFER_DONE | NU_PDMA_EVENT_TIMEOUT);
  564. result = nu_pdma_callback_register(psNuUart->pdma_chanid_rx, &sChnCB);
  565. if (result != RT_EOK)
  566. {
  567. goto exit_nu_pdma_uart_rx_config;
  568. }
  569. if (serial->config.bufsz == 0)
  570. {
  571. result = nu_pdma_transfer(((nu_uart_t)serial)->pdma_chanid_rx,
  572. 8,
  573. (uint32_t)uart_base,
  574. (uint32_t)pu8Buf,
  575. i32TriggerLen,
  576. 1000); //Idle-timeout, 1ms
  577. if (result != RT_EOK)
  578. {
  579. goto exit_nu_pdma_uart_rx_config;
  580. }
  581. }
  582. else
  583. {
  584. /* For Serial RX FIFO - Single buffer recycle SG trigger */
  585. /* Link to next */
  586. nu_pdma_desc_t next = psNuUart->pdma_rx_desc;
  587. result = nu_pdma_desc_setup(psNuUart->pdma_chanid_rx,
  588. psNuUart->pdma_rx_desc,
  589. 8,
  590. (uint32_t)uart_base,
  591. (uint32_t)pu8Buf,
  592. i32TriggerLen,
  593. next,
  594. 0);
  595. if (result != RT_EOK)
  596. {
  597. goto exit_nu_pdma_uart_rx_config;
  598. }
  599. /* Assign head descriptor & go */
  600. result = nu_pdma_sg_transfer(psNuUart->pdma_chanid_rx, psNuUart->pdma_rx_desc, 1000);
  601. if (result != RT_EOK)
  602. {
  603. goto exit_nu_pdma_uart_rx_config;
  604. }
  605. }
  606. /* Enable Receive Line interrupt & Start DMA RX transfer. */
  607. UART_ENABLE_INT(uart_base, UART_INTEN_RLSIEN_Msk);
  608. UART_PDMA_ENABLE(uart_base, UART_INTEN_RXPDMAEN_Msk);
  609. exit_nu_pdma_uart_rx_config:
  610. return result;
  611. }
  612. static void nu_pdma_uart_rx_cb(void *pvOwner, uint32_t u32Events)
  613. {
  614. rt_size_t recv_len = 0;
  615. rt_size_t transferred_rxbyte = 0;
  616. struct rt_serial_device *serial = (struct rt_serial_device *)pvOwner;
  617. nu_uart_t puart = (nu_uart_t)serial;
  618. RT_ASSERT(serial);
  619. /* Get base address of uart register */
  620. UART_T *uart_base = puart->uart_base;
  621. transferred_rxbyte = nu_pdma_transferred_byte_get(puart->pdma_chanid_rx, puart->rxdma_trigger_len);
  622. if (u32Events & (NU_PDMA_EVENT_TRANSFER_DONE | NU_PDMA_EVENT_TIMEOUT))
  623. {
  624. if (u32Events & NU_PDMA_EVENT_TRANSFER_DONE)
  625. {
  626. transferred_rxbyte = puart->rxdma_trigger_len;
  627. }
  628. else if ((u32Events & NU_PDMA_EVENT_TIMEOUT) && !UART_GET_RX_EMPTY(uart_base))
  629. {
  630. return;
  631. }
  632. recv_len = transferred_rxbyte - puart->rx_write_offset;
  633. if (recv_len > 0)
  634. {
  635. puart->rx_write_offset = transferred_rxbyte % puart->rxdma_trigger_len;
  636. }
  637. }
  638. if ((serial->config.bufsz == 0) && (u32Events & NU_PDMA_EVENT_TRANSFER_DONE))
  639. {
  640. recv_len = puart->rxdma_trigger_len;
  641. }
  642. if (recv_len > 0)
  643. {
  644. rt_hw_serial_isr(&puart->dev, RT_SERIAL_EVENT_RX_DMADONE | (recv_len << 8));
  645. }
  646. }
  647. static rt_err_t nu_pdma_uart_tx_config(struct rt_serial_device *serial)
  648. {
  649. struct nu_pdma_chn_cb sChnCB;
  650. RT_ASSERT(serial);
  651. /* Register ISR callback function */
  652. sChnCB.m_eCBType = eCBType_Event;
  653. sChnCB.m_pfnCBHandler = nu_pdma_uart_tx_cb;
  654. sChnCB.m_pvUserData = (void *)serial;
  655. nu_pdma_filtering_set(((nu_uart_t)serial)->pdma_chanid_tx, NU_PDMA_EVENT_TRANSFER_DONE);
  656. return nu_pdma_callback_register(((nu_uart_t)serial)->pdma_chanid_tx, &sChnCB);
  657. }
  658. static void nu_pdma_uart_tx_cb(void *pvOwner, uint32_t u32Events)
  659. {
  660. nu_uart_t puart = (nu_uart_t)pvOwner;
  661. RT_ASSERT(puart);
  662. UART_PDMA_DISABLE(puart->uart_base, UART_INTEN_TXPDMAEN_Msk);// Stop DMA TX transfer
  663. if (u32Events & NU_PDMA_EVENT_TRANSFER_DONE)
  664. {
  665. rt_hw_serial_isr(&puart->dev, RT_SERIAL_EVENT_TX_DMADONE);
  666. }
  667. }
  668. /**
  669. * Uart DMA transfer
  670. */
  671. static rt_ssize_t nu_uart_dma_transmit(struct rt_serial_device *serial, rt_uint8_t *buf, rt_size_t size, int direction)
  672. {
  673. rt_err_t result = RT_EOK;
  674. nu_uart_t psNuUart = (nu_uart_t)serial;
  675. RT_ASSERT(serial);
  676. RT_ASSERT(buf);
  677. /* Get base address of uart register */
  678. UART_T *uart_base = psNuUart->uart_base;
  679. if (direction == RT_SERIAL_DMA_TX)
  680. {
  681. result = nu_pdma_transfer(psNuUart->pdma_chanid_tx,
  682. 8,
  683. (uint32_t)buf,
  684. (uint32_t)uart_base,
  685. size,
  686. 0); // wait-forever
  687. // Start DMA TX transfer
  688. UART_PDMA_ENABLE(uart_base, UART_INTEN_TXPDMAEN_Msk);
  689. }
  690. else if (direction == RT_SERIAL_DMA_RX)
  691. {
  692. UART_DISABLE_INT(uart_base, UART_INTEN_RLSIEN_Msk);
  693. UART_PDMA_DISABLE(uart_base, UART_INTEN_RXPDMAEN_Msk);
  694. // If config.bufsz = 0, serial will trigger once.
  695. psNuUart->rxdma_trigger_len = size;
  696. psNuUart->rx_write_offset = 0;
  697. result = nu_pdma_uart_rx_config(serial, buf, size);
  698. }
  699. else
  700. {
  701. result = -RT_ERROR;
  702. }
  703. return result;
  704. }
  705. static int nu_hw_uart_dma_allocate(nu_uart_t pusrt)
  706. {
  707. RT_ASSERT(pusrt);
  708. /* Allocate UART_TX nu_dma channel */
  709. if (pusrt->pdma_perp_tx != NU_PDMA_UNUSED)
  710. {
  711. pusrt->pdma_chanid_tx = nu_pdma_channel_allocate(pusrt->pdma_perp_tx);
  712. if (pusrt->pdma_chanid_tx >= 0)
  713. {
  714. pusrt->dma_flag |= RT_DEVICE_FLAG_DMA_TX;
  715. }
  716. }
  717. /* Allocate UART_RX nu_dma channel */
  718. if (pusrt->pdma_perp_rx != NU_PDMA_UNUSED)
  719. {
  720. pusrt->pdma_chanid_rx = nu_pdma_channel_allocate(pusrt->pdma_perp_rx);
  721. if (pusrt->pdma_chanid_rx >= 0)
  722. {
  723. rt_err_t ret = RT_EOK;
  724. pusrt->dma_flag |= RT_DEVICE_FLAG_DMA_RX;
  725. ret = nu_pdma_sgtbls_allocate(&pusrt->pdma_rx_desc, 1);
  726. RT_ASSERT(ret == RT_EOK);
  727. }
  728. }
  729. return RT_EOK;
  730. }
  731. #endif
  732. /**
  733. * Uart interrupt control
  734. */
  735. static rt_err_t nu_uart_control(struct rt_serial_device *serial, int cmd, void *arg)
  736. {
  737. nu_uart_t psNuUart = (nu_uart_t)serial;
  738. rt_err_t result = RT_EOK;
  739. rt_ubase_t ctrl_arg = (rt_ubase_t)arg;
  740. RT_ASSERT(serial);
  741. /* Get base address of uart register */
  742. UART_T *uart_base = psNuUart->uart_base;
  743. switch (cmd)
  744. {
  745. case RT_DEVICE_CTRL_CLR_INT:
  746. if (ctrl_arg == RT_DEVICE_FLAG_INT_RX) /* Disable INT-RX */
  747. {
  748. UART_DISABLE_INT(uart_base, UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk | UART_INTEN_TOCNTEN_Msk);
  749. }
  750. else if (ctrl_arg == RT_DEVICE_FLAG_DMA_RX) /* Disable DMA-RX */
  751. {
  752. /* Disable Receive Line interrupt & Stop DMA RX transfer. */
  753. #if defined(RT_SERIAL_USING_DMA)
  754. if (psNuUart->dma_flag & RT_DEVICE_FLAG_DMA_RX)
  755. {
  756. nu_pdma_channel_terminate(psNuUart->pdma_chanid_rx);
  757. }
  758. UART_DISABLE_INT(uart_base, UART_INTEN_RLSIEN_Msk | UART_INTEN_RXPDMAEN_Msk);
  759. #endif
  760. }
  761. break;
  762. case RT_DEVICE_CTRL_SET_INT:
  763. if (ctrl_arg == RT_DEVICE_FLAG_INT_RX) /* Enable INT-RX */
  764. {
  765. UART_ENABLE_INT(uart_base, UART_INTEN_RDAIEN_Msk | UART_INTEN_RXTOIEN_Msk | UART_INTEN_TOCNTEN_Msk);
  766. }
  767. break;
  768. #if defined(RT_SERIAL_USING_DMA)
  769. case RT_DEVICE_CTRL_CONFIG:
  770. if (ctrl_arg == RT_DEVICE_FLAG_DMA_RX) /* Configure and trigger DMA-RX */
  771. {
  772. struct rt_serial_rx_fifo *rx_fifo = (struct rt_serial_rx_fifo *)serial->serial_rx;
  773. psNuUart->rxdma_trigger_len = serial->config.bufsz;
  774. psNuUart->rx_write_offset = 0;
  775. result = nu_pdma_uart_rx_config(serial, &rx_fifo->buffer[0], psNuUart->rxdma_trigger_len); // Config & trigger
  776. }
  777. else if (ctrl_arg == RT_DEVICE_FLAG_DMA_TX) /* Configure DMA-TX */
  778. {
  779. result = nu_pdma_uart_tx_config(serial);
  780. }
  781. break;
  782. #endif
  783. case RT_DEVICE_CTRL_CLOSE:
  784. /* Disable NVIC interrupt. */
  785. NVIC_DisableIRQ(psNuUart->uart_irq_n);
  786. #if defined(RT_SERIAL_USING_DMA)
  787. UART_DISABLE_INT(uart_base, UART_INTEN_RLSIEN_Msk | UART_INTEN_RXPDMAEN_Msk);
  788. UART_DISABLE_INT(uart_base, UART_INTEN_TXPDMAEN_Msk);
  789. if (psNuUart->dma_flag != 0)
  790. {
  791. nu_pdma_channel_terminate(psNuUart->pdma_chanid_tx);
  792. nu_pdma_channel_terminate(psNuUart->pdma_chanid_rx);
  793. }
  794. #endif
  795. /* Close UART port */
  796. UART_Close(uart_base);
  797. break;
  798. default:
  799. result = -RT_EINVAL;
  800. break;
  801. }
  802. return result;
  803. }
  804. /**
  805. * Uart put char
  806. */
  807. static int nu_uart_send(struct rt_serial_device *serial, char c)
  808. {
  809. RT_ASSERT(serial);
  810. /* Get base address of uart register */
  811. UART_T *uart_base = ((nu_uart_t)serial)->uart_base;
  812. /* Waiting if TX-FIFO is full. */
  813. while (UART_IS_TX_FULL(uart_base));
  814. /* Put char into TX-FIFO */
  815. UART_WRITE(uart_base, c);
  816. return 1;
  817. }
  818. /**
  819. * Uart get char
  820. */
  821. static int nu_uart_receive(struct rt_serial_device *serial)
  822. {
  823. RT_ASSERT(serial);
  824. /* Get base address of uart register */
  825. UART_T *uart_base = ((nu_uart_t)serial)->uart_base;
  826. /* Return failure if RX-FIFO is empty. */
  827. if (UART_GET_RX_EMPTY(uart_base))
  828. {
  829. return -1;
  830. }
  831. /* Get char from RX-FIFO */
  832. return UART_READ(uart_base);
  833. }
  834. /**
  835. * Hardware UART Initialization
  836. */
  837. rt_err_t rt_hw_uart_init(void)
  838. {
  839. int i;
  840. rt_uint32_t flag;
  841. rt_err_t ret = RT_EOK;
  842. for (i = (UART_START + 1); i < UART_CNT; i++)
  843. {
  844. flag = RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX;
  845. nu_uart_arr[i].dev.ops = &nu_uart_ops;
  846. nu_uart_arr[i].dev.config = nu_uart_default_config;
  847. #if defined(RT_SERIAL_USING_DMA)
  848. nu_uart_arr[i].dma_flag = 0;
  849. nu_hw_uart_dma_allocate(&nu_uart_arr[i]);
  850. flag |= nu_uart_arr[i].dma_flag;
  851. #endif
  852. ret = rt_hw_serial_register(&nu_uart_arr[i].dev, nu_uart_arr[i].name, flag, NULL);
  853. RT_ASSERT(ret == RT_EOK);
  854. }
  855. return ret;
  856. }
  857. #endif //#if defined(BSP_USING_UART)