nu_uart.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776
  1. /**************************************************************************//**
  2. * @file uart.c
  3. * @version V3.00
  4. * @brief NUC980 series UART driver source file
  5. *
  6. * SPDX-License-Identifier: Apache-2.0
  7. * @copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
  8. *****************************************************************************/
  9. #include "nu_uart.h"
  10. /** @addtogroup Standard_Driver Standard Driver
  11. @{
  12. */
  13. /** @addtogroup UART_Driver UART Driver
  14. @{
  15. */
  16. /** @addtogroup UART_EXPORTED_FUNCTIONS UART Exported Functions
  17. @{
  18. */
  19. /**
  20. * @brief Clear UART specified interrupt flag
  21. *
  22. * @param[in] uart The pointer of the specified UART module.
  23. * @param[in] u32InterruptFlag The specified interrupt of UART module.
  24. * - \ref UART_INTSTS_LININT_Msk : LIN bus interrupt
  25. * - \ref UART_INTEN_WKIEN_Msk : Wake-up interrupt
  26. * - \ref UART_INTSTS_BUFERRINT_Msk : Buffer Error interrupt
  27. * - \ref UART_INTSTS_MODEMINT_Msk : Modem Status interrupt
  28. * - \ref UART_INTSTS_RLSINT_Msk : Receive Line Status interrupt
  29. *
  30. * @return None
  31. *
  32. * @details The function is used to clear UART specified interrupt flag.
  33. */
  34. void UART_ClearIntFlag(UART_T *uart, uint32_t u32InterruptFlag)
  35. {
  36. if (u32InterruptFlag & UART_INTSTS_RLSINT_Msk) /* Clear Receive Line Status Interrupt */
  37. {
  38. uart->FIFOSTS = UART_FIFOSTS_BIF_Msk | UART_FIFOSTS_FEF_Msk | UART_FIFOSTS_PEF_Msk;
  39. uart->FIFOSTS = UART_FIFOSTS_ADDRDETF_Msk;
  40. }
  41. if (u32InterruptFlag & UART_INTSTS_MODEMINT_Msk) /* Clear Modem Status Interrupt */
  42. {
  43. uart->MODEMSTS |= UART_MODEMSTS_CTSDETF_Msk;
  44. }
  45. else
  46. {
  47. }
  48. if (u32InterruptFlag & UART_INTSTS_BUFERRINT_Msk) /* Clear Buffer Error Interrupt */
  49. {
  50. uart->FIFOSTS = UART_FIFOSTS_RXOVIF_Msk | UART_FIFOSTS_TXOVIF_Msk;
  51. }
  52. if (u32InterruptFlag & UART_INTSTS_WKINT_Msk) /* Clear Wake-up Interrupt */
  53. {
  54. uart->WKSTS = UART_WKSTS_CTSWKF_Msk | UART_WKSTS_DATWKF_Msk |
  55. UART_WKSTS_RFRTWKF_Msk | UART_WKSTS_RS485WKF_Msk |
  56. UART_WKSTS_TOUTWKF_Msk;
  57. }
  58. if (u32InterruptFlag & UART_INTSTS_LININT_Msk) /* Clear LIN Bus Interrupt */
  59. {
  60. uart->INTSTS = UART_INTSTS_LINIF_Msk;
  61. uart->LINSTS = UART_LINSTS_BITEF_Msk | UART_LINSTS_BRKDETF_Msk |
  62. UART_LINSTS_SLVSYNCF_Msk | UART_LINSTS_SLVIDPEF_Msk |
  63. UART_LINSTS_SLVHEF_Msk | UART_LINSTS_SLVHDETF_Msk ;
  64. }
  65. }
  66. /**
  67. * @brief Disable UART interrupt
  68. *
  69. * @param[in] uart The pointer of the specified UART module.
  70. *
  71. * @return None
  72. *
  73. * @details The function is used to disable UART interrupt.
  74. */
  75. void UART_Close(UART_T *uart)
  76. {
  77. uart->INTEN = 0ul;
  78. }
  79. /**
  80. * @brief Disable UART auto flow control function
  81. *
  82. * @param[in] uart The pointer of the specified UART module.
  83. *
  84. * @return None
  85. *
  86. * @details The function is used to disable UART auto flow control.
  87. */
  88. void UART_DisableFlowCtrl(UART_T *uart)
  89. {
  90. uart->INTEN &= ~(UART_INTEN_ATORTSEN_Msk | UART_INTEN_ATOCTSEN_Msk);
  91. }
  92. /**
  93. * @brief Disable UART specified interrupt
  94. *
  95. * @param[in] uart The pointer of the specified UART module.
  96. * @param[in] u32InterruptFlag The specified interrupt of UART module.
  97. * - \ref UART_INTEN_WKIEN_Msk : Wake-up interrupt
  98. * - \ref UART_INTEN_LINIEN_Msk : Lin bus interrupt
  99. * - \ref UART_INTEN_BUFERRIEN_Msk : Buffer Error interrupt
  100. * - \ref UART_INTEN_RXTOIEN_Msk : Rx time-out interrupt
  101. * - \ref UART_INTEN_MODEMIEN_Msk : Modem status interrupt
  102. * - \ref UART_INTEN_RLSIEN_Msk : Receive Line status interrupt
  103. * - \ref UART_INTEN_THREIEN_Msk : Tx empty interrupt
  104. * - \ref UART_INTEN_RDAIEN_Msk : Rx ready interrupt *
  105. *
  106. * @return None
  107. *
  108. * @details The function is used to disable UART specified interrupt and disable NVIC UART IRQ.
  109. */
  110. void UART_DisableInt(UART_T *uart, uint32_t u32InterruptFlag)
  111. {
  112. /* Disable UART specified interrupt */
  113. UART_DISABLE_INT(uart, u32InterruptFlag);
  114. }
  115. /**
  116. * @brief Enable UART auto flow control function
  117. *
  118. * @param[in] uart The pointer of the specified UART module.
  119. *
  120. * @return None
  121. *
  122. * @details The function is used to Enable UART auto flow control.
  123. */
  124. void UART_EnableFlowCtrl(UART_T *uart)
  125. {
  126. /* Set RTS pin output is low level active */
  127. uart->MODEM |= UART_MODEM_RTSACTLV_Msk;
  128. /* Set CTS pin input is low level active */
  129. uart->MODEMSTS |= UART_MODEMSTS_CTSACTLV_Msk;
  130. /* Set RTS and CTS auto flow control enable */
  131. uart->INTEN |= UART_INTEN_ATORTSEN_Msk | UART_INTEN_ATOCTSEN_Msk;
  132. }
  133. /**
  134. * @brief The function is used to enable UART specified interrupt and enable NVIC UART IRQ.
  135. *
  136. * @param[in] uart The pointer of the specified UART module.
  137. * @param[in] u32InterruptFlag The specified interrupt of UART module:
  138. * - \ref UART_INTEN_WKIEN_Msk : Wake-up interrupt
  139. * - \ref UART_INTEN_LINIEN_Msk : Lin bus interrupt
  140. * - \ref UART_INTEN_BUFERRIEN_Msk : Buffer Error interrupt
  141. * - \ref UART_INTEN_RXTOIEN_Msk : Rx time-out interrupt
  142. * - \ref UART_INTEN_MODEMIEN_Msk : Modem status interrupt
  143. * - \ref UART_INTEN_RLSIEN_Msk : Receive Line status interrupt
  144. * - \ref UART_INTEN_THREIEN_Msk : Tx empty interrupt
  145. * - \ref UART_INTEN_RDAIEN_Msk : Rx ready interrupt *
  146. *
  147. * @return None
  148. *
  149. * @details The function is used to enable UART specified interrupt and enable NVIC UART IRQ.
  150. */
  151. void UART_EnableInt(UART_T *uart, uint32_t u32InterruptFlag)
  152. {
  153. /* Enable UART specified interrupt */
  154. UART_ENABLE_INT(uart, u32InterruptFlag);
  155. }
  156. /**
  157. * @brief Open and set UART function
  158. *
  159. * @param[in] uart The pointer of the specified UART module.
  160. * @param[in] u32baudrate The baudrate of UART module.
  161. *
  162. * @return None
  163. *
  164. * @details This function use to enable UART function and set baud-rate.
  165. */
  166. void UART_Open(UART_T *uart, uint32_t u32baudrate)
  167. {
  168. uint32_t u32UartClkSrcSel = 0ul, u32UartClkDivNum = 0ul;
  169. //uint32_t u32ClkTbl[4] = {XIN, LXT, ACLK, UCLK};
  170. uint32_t u32ClkTbl[4] = {12000000, 32768, 75000000, 150000000};
  171. uint32_t u32Baud_Div = 0ul;
  172. if ((uint32_t)uart == UART0_BA)
  173. {
  174. /* Get UART clock source selection */
  175. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL4) & (0x3ul << 3)) >> 3;
  176. /* Get UART clock divider number */
  177. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL4) & (0x7ul << 5)) >> 5;
  178. }
  179. else if ((uint32_t)uart == UART1_BA)
  180. {
  181. /* Get UART clock source selection */
  182. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL4) & (0x3ul << 11)) >> 11;
  183. /* Get UART clock divider number */
  184. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL4) & (0x7ul << 13)) >> 13;
  185. }
  186. else if ((uint32_t)uart == UART2_BA)
  187. {
  188. /* Get UART clock source selection */
  189. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL4) & (0x3ul << 19)) >> 19;
  190. /* Get UART clock divider number */
  191. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL4) & (0x7ul << 21)) >> 21;
  192. }
  193. else if ((uint32_t)uart == UART3_BA)
  194. {
  195. /* Get UART clock source selection */
  196. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL4) & (0x3ul << 27)) >> 27;
  197. /* Get UART clock divider number */
  198. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL4) & (0x7ul << 29)) >> 29;
  199. }
  200. else if ((uint32_t)uart == UART4_BA)
  201. {
  202. /* Get UART clock source selection */
  203. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL5) & (0x3ul << 3)) >> 3;
  204. /* Get UART clock divider number */
  205. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL5) & (0x7ul << 5)) >> 5;
  206. }
  207. else if ((uint32_t)uart == UART5_BA)
  208. {
  209. /* Get UART clock source selection */
  210. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL5) & (0x3ul << 11)) >> 11;
  211. /* Get UART clock divider number */
  212. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL5) & (0x7ul << 13)) >> 13;
  213. }
  214. else if ((uint32_t)uart == UART6_BA)
  215. {
  216. /* Get UART clock source selection */
  217. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL5) & (0x3ul << 19)) >> 19;
  218. /* Get UART clock divider number */
  219. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL5) & (0x7ul << 21)) >> 21;
  220. }
  221. else if ((uint32_t)uart == UART7_BA)
  222. {
  223. /* Get UART clock source selection */
  224. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL5) & (0x3ul << 27)) >> 27;
  225. /* Get UART clock divider number */
  226. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL5) & (0x7ul << 29)) >> 29;
  227. }
  228. else if ((uint32_t)uart == UART8_BA)
  229. {
  230. /* Get UART clock source selection */
  231. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL6) & (0x3ul << 3)) >> 3;
  232. /* Get UART clock divider number */
  233. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL6) & (0x7ul << 5)) >> 5;
  234. }
  235. else if ((uint32_t)uart == UART9_BA)
  236. {
  237. /* Get UART clock source selection */
  238. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL6) & (0x3ul << 11)) >> 11;
  239. /* Get UART clock divider number */
  240. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL6) & (0x7ul << 13)) >> 13;
  241. }
  242. /* Select UART function */
  243. uart->FUNCSEL = UART_FUNCSEL_UART;
  244. /* Set UART line configuration */
  245. uart->LINE = UART_WORD_LEN_8 | UART_PARITY_NONE | UART_STOP_BIT_1;
  246. /* Set UART Rx and RTS trigger level */
  247. uart->FIFO &= ~(UART_FIFO_RFITL_Msk | UART_FIFO_RTSTRGLV_Msk);
  248. /* Get PLL clock frequency if UART clock source selection is PLL */
  249. if (u32UartClkSrcSel == 2ul) // ACLK
  250. {
  251. //u32ClkTbl[u32UartClkSrcSel] = CLK_GetPLLClockFreq();
  252. }
  253. if (u32UartClkSrcSel == 3ul) // PCLK
  254. {
  255. //u32ClkTbl[u32UartClkSrcSel] = CLK_GetPLLClockFreq();
  256. }
  257. /* Set UART baud rate */
  258. if (u32baudrate != 0ul)
  259. {
  260. u32Baud_Div = UART_BAUD_MODE2_DIVIDER((u32ClkTbl[u32UartClkSrcSel]) / (u32UartClkDivNum + 1ul), u32baudrate);
  261. if (u32Baud_Div > 0xFFFFul)
  262. {
  263. uart->BAUD = (UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER((u32ClkTbl[u32UartClkSrcSel]) / (u32UartClkDivNum + 1ul), u32baudrate));
  264. }
  265. else
  266. {
  267. uart->BAUD = (UART_BAUD_MODE2 | u32Baud_Div);
  268. }
  269. }
  270. }
  271. /**
  272. * @brief Read UART data
  273. *
  274. * @param[in] uart The pointer of the specified UART module.
  275. * @param[in] pu8RxBuf The buffer to receive the data of receive FIFO.
  276. * @param[in] u32ReadBytes The the read bytes number of data.
  277. *
  278. * @return u32Count Receive byte count
  279. *
  280. * @details The function is used to read Rx data from RX FIFO and the data will be stored in pu8RxBuf.
  281. */
  282. uint32_t UART_Read(UART_T *uart, uint8_t pu8RxBuf[], uint32_t u32ReadBytes)
  283. {
  284. uint32_t u32Count, u32delayno;
  285. uint32_t u32Exit = 0ul;
  286. for (u32Count = 0ul; u32Count < u32ReadBytes; u32Count++)
  287. {
  288. u32delayno = 0ul;
  289. while (uart->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) /* Check RX empty => failed */
  290. {
  291. u32delayno++;
  292. if (u32delayno >= 0x40000000ul)
  293. {
  294. u32Exit = 1ul;
  295. break;
  296. }
  297. else
  298. {
  299. }
  300. }
  301. if (u32Exit == 1ul)
  302. {
  303. break;
  304. }
  305. else
  306. {
  307. pu8RxBuf[u32Count] = (uint8_t)uart->DAT; /* Get Data from UART RX */
  308. }
  309. }
  310. return u32Count;
  311. }
  312. /**
  313. * @brief Set UART line configuration
  314. *
  315. * @param[in] uart The pointer of the specified UART module.
  316. * @param[in] u32baudrate The register value of baudrate of UART module.
  317. * If u32baudrate = 0, UART baudrate will not change.
  318. * @param[in] u32data_width The data length of UART module.
  319. * - \ref UART_WORD_LEN_5
  320. * - \ref UART_WORD_LEN_6
  321. * - \ref UART_WORD_LEN_7
  322. * - \ref UART_WORD_LEN_8
  323. * @param[in] u32parity The parity setting (none/odd/even/mark/space) of UART module.
  324. * - \ref UART_PARITY_NONE
  325. * - \ref UART_PARITY_ODD
  326. * - \ref UART_PARITY_EVEN
  327. * - \ref UART_PARITY_MARK
  328. * - \ref UART_PARITY_SPACE
  329. * @param[in] u32stop_bits The stop bit length (1/1.5/2 bit) of UART module.
  330. * - \ref UART_STOP_BIT_1
  331. * - \ref UART_STOP_BIT_1_5
  332. * - \ref UART_STOP_BIT_2
  333. *
  334. * @return None
  335. *
  336. * @details This function use to config UART line setting.
  337. */
  338. void UART_SetLineConfig(UART_T *uart, uint32_t u32baudrate, uint32_t u32data_width, uint32_t u32parity, uint32_t u32stop_bits)
  339. {
  340. uint32_t u32UartClkSrcSel = 0ul, u32UartClkDivNum = 0ul;
  341. //uint32_t u32ClkTbl[4] = {XIN, LXT, ACLK, UCLK};
  342. uint32_t u32ClkTbl[4] = {12000000, 32768, 75000000, 150000000};
  343. uint32_t u32Baud_Div = 0ul;
  344. if ((uint32_t)uart == UART0_BA)
  345. {
  346. /* Get UART clock source selection */
  347. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL4) & (0x3ul << 3)) >> 3;
  348. /* Get UART clock divider number */
  349. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL4) & (0x7ul << 5)) >> 5;
  350. }
  351. else if ((uint32_t)uart == UART1_BA)
  352. {
  353. /* Get UART clock source selection */
  354. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL4) & (0x3ul << 11)) >> 11;
  355. /* Get UART clock divider number */
  356. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL4) & (0x7ul << 13)) >> 13;
  357. }
  358. else if ((uint32_t)uart == UART2_BA)
  359. {
  360. /* Get UART clock source selection */
  361. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL4) & (0x3ul << 19)) >> 19;
  362. /* Get UART clock divider number */
  363. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL4) & (0x7ul << 21)) >> 21;
  364. }
  365. else if ((uint32_t)uart == UART3_BA)
  366. {
  367. /* Get UART clock source selection */
  368. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL4) & (0x3ul << 27)) >> 27;
  369. /* Get UART clock divider number */
  370. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL4) & (0x7ul << 29)) >> 29;
  371. }
  372. else if ((uint32_t)uart == UART4_BA)
  373. {
  374. /* Get UART clock source selection */
  375. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL5) & (0x3ul << 3)) >> 3;
  376. /* Get UART clock divider number */
  377. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL5) & (0x7ul << 5)) >> 5;
  378. }
  379. else if ((uint32_t)uart == UART5_BA)
  380. {
  381. /* Get UART clock source selection */
  382. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL5) & (0x3ul << 11)) >> 11;
  383. /* Get UART clock divider number */
  384. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL5) & (0x7ul << 13)) >> 13;
  385. }
  386. else if ((uint32_t)uart == UART6_BA)
  387. {
  388. /* Get UART clock source selection */
  389. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL5) & (0x3ul << 19)) >> 19;
  390. /* Get UART clock divider number */
  391. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL5) & (0x7ul << 21)) >> 21;
  392. }
  393. else if ((uint32_t)uart == UART7_BA)
  394. {
  395. /* Get UART clock source selection */
  396. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL5) & (0x3ul << 27)) >> 27;
  397. /* Get UART clock divider number */
  398. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL5) & (0x7ul << 29)) >> 29;
  399. }
  400. else if ((uint32_t)uart == UART8_BA)
  401. {
  402. /* Get UART clock source selection */
  403. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL6) & (0x3ul << 3)) >> 3;
  404. /* Get UART clock divider number */
  405. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL6) & (0x7ul << 5)) >> 5;
  406. }
  407. else if ((uint32_t)uart == UART9_BA)
  408. {
  409. /* Get UART clock source selection */
  410. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL6) & (0x3ul << 11)) >> 11;
  411. /* Get UART clock divider number */
  412. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL6) & (0x7ul << 13)) >> 13;
  413. }
  414. /* Get PLL clock frequency if UART clock source selection is PLL */
  415. if (u32UartClkSrcSel == 2ul) // ACLK
  416. {
  417. //u32ClkTbl[u32UartClkSrcSel] = CLK_GetPLLClockFreq();
  418. }
  419. if (u32UartClkSrcSel == 3ul) // PCLK
  420. {
  421. //u32ClkTbl[u32UartClkSrcSel] = CLK_GetPLLClockFreq();
  422. }
  423. /* Set UART baud rate */
  424. if (u32baudrate != 0ul)
  425. {
  426. u32Baud_Div = UART_BAUD_MODE2_DIVIDER((u32ClkTbl[u32UartClkSrcSel]) / (u32UartClkDivNum + 1ul), u32baudrate);
  427. if (u32Baud_Div > 0xFFFFul)
  428. {
  429. uart->BAUD = (UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER((u32ClkTbl[u32UartClkSrcSel]) / (u32UartClkDivNum + 1ul), u32baudrate));
  430. }
  431. else
  432. {
  433. uart->BAUD = (UART_BAUD_MODE2 | u32Baud_Div);
  434. }
  435. }
  436. /* Set UART line configuration */
  437. uart->LINE = u32data_width | u32parity | u32stop_bits;
  438. }
  439. /**
  440. * @brief Set Rx timeout count
  441. *
  442. * @param[in] uart The pointer of the specified UART module.
  443. * @param[in] u32TOC Rx timeout counter.
  444. *
  445. * @return None
  446. *
  447. * @details This function use to set Rx timeout count.
  448. */
  449. void UART_SetTimeoutCnt(UART_T *uart, uint32_t u32TOC)
  450. {
  451. /* Set time-out interrupt comparator */
  452. uart->TOUT = (uart->TOUT & ~UART_TOUT_TOIC_Msk) | (u32TOC);
  453. /* Set time-out counter enable */
  454. uart->INTEN |= UART_INTEN_TOCNTEN_Msk;
  455. }
  456. /**
  457. * @brief Select and configure IrDA function
  458. *
  459. * @param[in] uart The pointer of the specified UART module.
  460. * @param[in] u32Buadrate The baudrate of UART module.
  461. * @param[in] u32Direction The direction of UART module in IrDA mode:
  462. * - \ref UART_IRDA_TXEN
  463. * - \ref UART_IRDA_RXEN
  464. *
  465. * @return None
  466. *
  467. * @details The function is used to configure IrDA relative settings. It consists of TX or RX mode and baudrate.
  468. */
  469. void UART_SelectIrDAMode(UART_T *uart, uint32_t u32Buadrate, uint32_t u32Direction)
  470. {
  471. uint32_t u32UartClkSrcSel = 0ul, u32UartClkDivNum = 0ul;
  472. //uint32_t u32ClkTbl[4] = {XIN, LXT, ACLK, UCLK};
  473. uint32_t u32ClkTbl[4] = {12000000, 32768, 75000000, 150000000};
  474. uint32_t u32Baud_Div = 0ul;
  475. if ((uint32_t)uart == UART0_BA)
  476. {
  477. /* Get UART clock source selection */
  478. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL4) & (0x3ul << 3)) >> 3;
  479. /* Get UART clock divider number */
  480. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL4) & (0x7ul << 5)) >> 5;
  481. }
  482. else if ((uint32_t)uart == UART1_BA)
  483. {
  484. /* Get UART clock source selection */
  485. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL4) & (0x3ul << 11)) >> 11;
  486. /* Get UART clock divider number */
  487. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL4) & (0x7ul << 13)) >> 13;
  488. }
  489. else if ((uint32_t)uart == UART2_BA)
  490. {
  491. /* Get UART clock source selection */
  492. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL4) & (0x3ul << 19)) >> 19;
  493. /* Get UART clock divider number */
  494. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL4) & (0x7ul << 21)) >> 21;
  495. }
  496. else if ((uint32_t)uart == UART3_BA)
  497. {
  498. /* Get UART clock source selection */
  499. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL4) & (0x3ul << 27)) >> 27;
  500. /* Get UART clock divider number */
  501. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL4) & (0x7ul << 29)) >> 29;
  502. }
  503. else if ((uint32_t)uart == UART4_BA)
  504. {
  505. /* Get UART clock source selection */
  506. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL5) & (0x3ul << 3)) >> 3;
  507. /* Get UART clock divider number */
  508. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL5) & (0x7ul << 5)) >> 5;
  509. }
  510. else if ((uint32_t)uart == UART5_BA)
  511. {
  512. /* Get UART clock source selection */
  513. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL5) & (0x3ul << 11)) >> 11;
  514. /* Get UART clock divider number */
  515. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL5) & (0x7ul << 13)) >> 13;
  516. }
  517. else if ((uint32_t)uart == UART6_BA)
  518. {
  519. /* Get UART clock source selection */
  520. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL5) & (0x3ul << 19)) >> 19;
  521. /* Get UART clock divider number */
  522. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL5) & (0x7ul << 21)) >> 21;
  523. }
  524. else if ((uint32_t)uart == UART7_BA)
  525. {
  526. /* Get UART clock source selection */
  527. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL5) & (0x3ul << 27)) >> 27;
  528. /* Get UART clock divider number */
  529. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL5) & (0x7ul << 29)) >> 29;
  530. }
  531. else if ((uint32_t)uart == UART8_BA)
  532. {
  533. /* Get UART clock source selection */
  534. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL6) & (0x3ul << 3)) >> 3;
  535. /* Get UART clock divider number */
  536. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL6) & (0x7ul << 5)) >> 5;
  537. }
  538. else if ((uint32_t)uart == UART9_BA)
  539. {
  540. /* Get UART clock source selection */
  541. u32UartClkSrcSel = (inp32(REG_CLK_DIVCTL6) & (0x3ul << 11)) >> 11;
  542. /* Get UART clock divider number */
  543. u32UartClkDivNum = (inp32(REG_CLK_DIVCTL6) & (0x7ul << 13)) >> 13;
  544. }
  545. /* Get PLL clock frequency if UART clock source selection is PLL */
  546. if (u32UartClkSrcSel == 2ul) // ACLK
  547. {
  548. //u32ClkTbl[u32UartClkSrcSel] = CLK_GetPLLClockFreq();
  549. }
  550. if (u32UartClkSrcSel == 3ul) // PCLK
  551. {
  552. //u32ClkTbl[u32UartClkSrcSel] = CLK_GetPLLClockFreq();
  553. }
  554. /* Set UART IrDA baud rate in mode 0 */
  555. if (u32Buadrate != 0ul)
  556. {
  557. u32Baud_Div = UART_BAUD_MODE0_DIVIDER((u32ClkTbl[u32UartClkSrcSel]) / (u32UartClkDivNum + 1ul), u32Buadrate);
  558. if (u32Baud_Div < 0xFFFFul)
  559. {
  560. uart->BAUD = (UART_BAUD_MODE0 | u32Baud_Div);
  561. }
  562. else
  563. {
  564. }
  565. }
  566. /* Configure IrDA relative settings */
  567. if (u32Direction == UART_IRDA_RXEN)
  568. {
  569. uart->IRDA |= UART_IRDA_RXINV_Msk; /*Rx signal is inverse*/
  570. uart->IRDA &= ~UART_IRDA_TXEN_Msk;
  571. }
  572. else
  573. {
  574. uart->IRDA &= ~UART_IRDA_TXINV_Msk; /*Tx signal is not inverse*/
  575. uart->IRDA |= UART_IRDA_TXEN_Msk;
  576. }
  577. }
  578. /**
  579. * @brief Select and configure RS485 function
  580. *
  581. * @param[in] uart The pointer of the specified UART module.
  582. * @param[in] u32Mode The operation mode(NMM/AUD/AAD).
  583. * - \ref UART_ALTCTL_RS485NMM_Msk
  584. * - \ref UART_ALTCTL_RS485AUD_Msk
  585. * - \ref UART_ALTCTL_RS485AAD_Msk
  586. * @param[in] u32Addr The RS485 address.
  587. *
  588. * @return None
  589. *
  590. * @details The function is used to set RS485 relative setting.
  591. */
  592. void UART_SelectRS485Mode(UART_T *uart, uint32_t u32Mode, uint32_t u32Addr)
  593. {
  594. /* Select UART RS485 function mode */
  595. uart->FUNCSEL = UART_FUNCSEL_RS485;
  596. /* Set RS585 configuration */
  597. uart->ALTCTL &= ~(UART_ALTCTL_RS485NMM_Msk | UART_ALTCTL_RS485AUD_Msk | UART_ALTCTL_RS485AAD_Msk | UART_ALTCTL_ADDRMV_Msk);
  598. uart->ALTCTL |= (u32Mode | (u32Addr << UART_ALTCTL_ADDRMV_Pos));
  599. }
  600. /**
  601. * @brief Select and configure LIN function
  602. *
  603. * @param[in] uart The pointer of the specified UART module.
  604. * @param[in] u32Mode The LIN direction :
  605. * - \ref UART_ALTCTL_LINTXEN_Msk
  606. * - \ref UART_ALTCTL_LINRXEN_Msk
  607. * @param[in] u32BreakLength The break field length.
  608. *
  609. * @return None
  610. *
  611. * @details The function is used to set LIN relative setting.
  612. */
  613. void UART_SelectLINMode(UART_T *uart, uint32_t u32Mode, uint32_t u32BreakLength)
  614. {
  615. /* Select LIN function mode */
  616. uart->FUNCSEL = UART_FUNCSEL_LIN;
  617. /* Select LIN function setting : Tx enable, Rx enable and break field length */
  618. uart->ALTCTL &= ~(UART_ALTCTL_LINTXEN_Msk | UART_ALTCTL_LINRXEN_Msk | UART_ALTCTL_BRKFL_Msk);
  619. uart->ALTCTL |= (u32Mode | (u32BreakLength << UART_ALTCTL_BRKFL_Pos));
  620. }
  621. /**
  622. * @brief Write UART data
  623. *
  624. * @param[in] uart The pointer of the specified UART module.
  625. * @param[in] pu8TxBuf The buffer to send the data to UART transmission FIFO.
  626. * @param[out] u32WriteBytes The byte number of data.
  627. *
  628. * @return u32Count transfer byte count
  629. *
  630. * @details The function is to write data into TX buffer to transmit data by UART.
  631. */
  632. uint32_t UART_Write(UART_T *uart, uint8_t pu8TxBuf[], uint32_t u32WriteBytes)
  633. {
  634. uint32_t u32Count, u32delayno;
  635. uint32_t u32Exit = 0ul;
  636. for (u32Count = 0ul; u32Count != u32WriteBytes; u32Count++)
  637. {
  638. u32delayno = 0ul;
  639. while ((uart->FIFOSTS & UART_FIFOSTS_TXEMPTYF_Msk) == 0ul) /* Wait Tx empty and Time-out manner */
  640. {
  641. u32delayno++;
  642. if (u32delayno >= 0x40000000ul)
  643. {
  644. u32Exit = 1ul;
  645. break;
  646. }
  647. else
  648. {
  649. }
  650. }
  651. if (u32Exit == 1ul)
  652. {
  653. break;
  654. }
  655. else
  656. {
  657. uart->DAT = pu8TxBuf[u32Count]; /* Send UART Data from buffer */
  658. }
  659. }
  660. return u32Count;
  661. }
  662. /**
  663. * @brief Set RTS pin to low
  664. *
  665. * @param[in] uart The pointer of the specified UART module
  666. *
  667. * @return None
  668. *
  669. * @details This macro set RTS pin to low.
  670. */
  671. void UART_CLEAR_RTS(UART_T *uart)
  672. {
  673. uart->MODEM |= UART_MODEM_RTSACTLV_Msk;
  674. uart->MODEM &= ~UART_MODEM_RTS_Msk;
  675. }
  676. /**
  677. * @brief Set RTS pin to high
  678. *
  679. * @param[in] uart The pointer of the specified UART module
  680. *
  681. * @return None
  682. *
  683. * @details This macro set RTS pin to high.
  684. */
  685. void UART_SET_RTS(UART_T *uart)
  686. {
  687. uart->MODEM |= UART_MODEM_RTSACTLV_Msk | UART_MODEM_RTS_Msk;
  688. }
  689. /*@}*/ /* end of group UART_EXPORTED_FUNCTIONS */
  690. /*@}*/ /* end of group UART_Driver */
  691. /*@}*/ /* end of group Standard_Driver */
  692. /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/