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