1 /**************************************************************************//**
2  * @file     usci_uart.c
3  * @version  V3.00
4  * @brief    USCI UART (UUART) driver source file
5  *
6  * @copyright SPDX-License-Identifier: Apache-2.0
7  * @copyright Copyright (C) 2020 Nuvoton Technology Corp. All rights reserved.
8  *****************************************************************************/
9 
10 #include <stdio.h>
11 #include "NuMicro.h"
12 
13 /** @addtogroup Standard_Driver Standard Driver
14   @{
15 */
16 
17 /** @addtogroup USCI_UART_Driver USCI_UART Driver
18   @{
19 */
20 
21 /** @addtogroup USCI_UART_EXPORTED_FUNCTIONS USCI_UART Exported Functions
22   @{
23 */
24 
25 /**
26  *    @brief        Clear USCI_UART specified interrupt flag
27  *
28  *    @param[in]    uuart   The pointer of the specified USCI_UART module.
29  *    @param[in]    u32Mask The combination of all related interrupt sources.
30  *                          Each bit corresponds to a interrupt source.
31  *                          This parameter decides which interrupt flags will be cleared. It could be the combination of:
32  *                          - \ref UUART_ABR_INT_MASK
33  *                          - \ref UUART_RLS_INT_MASK
34  *                          - \ref UUART_BUF_RXOV_INT_MASK
35  *                          - \ref UUART_TXST_INT_MASK
36  *                          - \ref UUART_TXEND_INT_MASK
37  *                          - \ref UUART_RXST_INT_MASK
38  *                          - \ref UUART_RXEND_INT_MASK
39  *
40  *    @return       None
41  *
42  *    @details      The function is used to clear USCI_UART related interrupt flags specified by u32Mask parameter.
43  */
44 
UUART_ClearIntFlag(UUART_T * uuart,uint32_t u32Mask)45 void UUART_ClearIntFlag(UUART_T* uuart, uint32_t u32Mask)
46 {
47 
48     if(u32Mask & UUART_ABR_INT_MASK)   /* Clear Auto-baud Rate Interrupt */
49     {
50         uuart->PROTSTS = UUART_PROTSTS_ABRDETIF_Msk;
51     }
52 
53     if(u32Mask & UUART_RLS_INT_MASK)   /* Clear Receive Line Status Interrupt */
54     {
55         uuart->PROTSTS = (UUART_PROTSTS_BREAK_Msk | UUART_PROTSTS_FRMERR_Msk | UUART_PROTSTS_PARITYERR_Msk);
56     }
57 
58     if(u32Mask & UUART_BUF_RXOV_INT_MASK)   /* Clear Receive Buffer Over-run Error Interrupt */
59     {
60         uuart->BUFSTS = UUART_BUFSTS_RXOVIF_Msk;
61     }
62 
63     if(u32Mask & UUART_TXST_INT_MASK)   /* Clear Transmit Start Interrupt */
64     {
65         uuart->PROTSTS = UUART_PROTSTS_TXSTIF_Msk;
66     }
67 
68     if(u32Mask & UUART_TXEND_INT_MASK)   /* Clear Transmit End Interrupt */
69     {
70         uuart->PROTSTS = UUART_PROTSTS_TXENDIF_Msk;
71     }
72 
73     if(u32Mask & UUART_RXST_INT_MASK)   /* Clear Receive Start Interrupt */
74     {
75         uuart->PROTSTS = UUART_PROTSTS_RXSTIF_Msk;
76     }
77 
78     if(u32Mask & UUART_RXEND_INT_MASK)   /* Clear Receive End Interrupt */
79     {
80         uuart->PROTSTS = UUART_PROTSTS_RXENDIF_Msk;
81     }
82 
83 }
84 
85 
86 /**
87  *    @brief        Get USCI_UART specified interrupt flag
88  *
89  *    @param[in]    uuart   The pointer of the specified USCI_UART module.
90  *    @param[in]    u32Mask The combination of all related interrupt sources.
91  *                          Each bit corresponds to a interrupt source.
92  *                          This parameter decides which interrupt flags will be read. It is combination of:
93  *                          - \ref UUART_ABR_INT_MASK
94  *                          - \ref UUART_RLS_INT_MASK
95  *                          - \ref UUART_BUF_RXOV_INT_MASK
96  *                          - \ref UUART_TXST_INT_MASK
97  *                          - \ref UUART_TXEND_INT_MASK
98  *                          - \ref UUART_RXST_INT_MASK
99  *                          - \ref UUART_RXEND_INT_MASK
100  *
101  *    @return       Interrupt flags of selected sources.
102  *
103  *    @details      The function is used to get USCI_UART related interrupt flags specified by u32Mask parameter.
104  */
105 
UUART_GetIntFlag(UUART_T * uuart,uint32_t u32Mask)106 uint32_t UUART_GetIntFlag(UUART_T* uuart, uint32_t u32Mask)
107 {
108     uint32_t u32IntFlag = 0ul;
109     uint32_t u32Tmp1, u32Tmp2;
110 
111     /* Check Auto-baud Rate Interrupt Flag */
112     u32Tmp1 = (u32Mask & UUART_ABR_INT_MASK);
113     u32Tmp2 = (uuart->PROTSTS & UUART_PROTSTS_ABRDETIF_Msk);
114     if(u32Tmp1 && u32Tmp2)
115     {
116         u32IntFlag |= UUART_ABR_INT_MASK;
117     }
118 
119     /* Check Receive Line Status Interrupt Flag */
120     u32Tmp1 = (u32Mask & UUART_RLS_INT_MASK);
121     u32Tmp2 = (uuart->PROTSTS & (UUART_PROTSTS_BREAK_Msk | UUART_PROTSTS_FRMERR_Msk | UUART_PROTSTS_PARITYERR_Msk));
122     if(u32Tmp1 && u32Tmp2)
123     {
124         u32IntFlag |= UUART_RLS_INT_MASK;
125     }
126 
127     /* Check Receive Buffer Over-run Error Interrupt Flag */
128     u32Tmp1 = (u32Mask & UUART_BUF_RXOV_INT_MASK);
129     u32Tmp2 = (uuart->BUFSTS & UUART_BUFSTS_RXOVIF_Msk);
130     if(u32Tmp1 && u32Tmp2)
131     {
132         u32IntFlag |= UUART_BUF_RXOV_INT_MASK;
133     }
134 
135     /* Check Transmit Start Interrupt Flag */
136     u32Tmp1 = (u32Mask & UUART_TXST_INT_MASK);
137     u32Tmp2 = (uuart->PROTSTS & UUART_PROTSTS_TXSTIF_Msk);
138     if(u32Tmp1 && u32Tmp2)
139     {
140         u32IntFlag |= UUART_TXST_INT_MASK;
141     }
142 
143     /* Check Transmit End Interrupt Flag */
144     u32Tmp1 = (u32Mask & UUART_TXEND_INT_MASK);
145     u32Tmp2 = (uuart->PROTSTS & UUART_PROTSTS_TXENDIF_Msk);
146     if(u32Tmp1 && u32Tmp2)
147     {
148         u32IntFlag |= UUART_TXEND_INT_MASK;
149     }
150 
151     /* Check Receive Start Interrupt Flag */
152     u32Tmp1 = (u32Mask & UUART_RXST_INT_MASK);
153     u32Tmp2 = (uuart->PROTSTS & UUART_PROTSTS_RXSTIF_Msk);
154     if(u32Tmp1 && u32Tmp2)
155     {
156         u32IntFlag |= UUART_RXST_INT_MASK;
157     }
158 
159     /* Check Receive End Interrupt Flag */
160     u32Tmp1 = (u32Mask & UUART_RXEND_INT_MASK);
161     u32Tmp2 = (uuart->PROTSTS & UUART_PROTSTS_RXENDIF_Msk);
162     if(u32Tmp1 && u32Tmp2)
163     {
164         u32IntFlag |= UUART_RXEND_INT_MASK;
165     }
166 
167     return u32IntFlag;
168 }
169 
170 
171 /**
172  *  @brief      Disable USCI_UART function mode
173  *
174  *  @param[in]  uuart The pointer of the specified USCI_UART module.
175  *
176  *  @return     None
177  *
178  *  @details    The function is used to disable USCI_UART function mode.
179  */
UUART_Close(UUART_T * uuart)180 void UUART_Close(UUART_T* uuart)
181 {
182     uuart->CTL = 0UL;
183 }
184 
185 
186 /**
187  *    @brief        Disable interrupt function.
188  *
189  *    @param[in]    uuart   The pointer of the specified USCI_UART module.
190  *    @param[in]    u32Mask The combination of all related interrupt enable bits.
191  *                          Each bit corresponds to a interrupt enable bit.
192  *                          This parameter decides which interrupts will be disabled. It is combination of:
193  *                          - \ref UUART_ABR_INT_MASK
194  *                          - \ref UUART_RLS_INT_MASK
195  *                          - \ref UUART_BUF_RXOV_INT_MASK
196  *                          - \ref UUART_TXST_INT_MASK
197  *                          - \ref UUART_TXEND_INT_MASK
198  *                          - \ref UUART_RXST_INT_MASK
199  *                          - \ref UUART_RXEND_INT_MASK
200  *
201  *    @return       None
202  *
203  *    @details      The function is used to disabled USCI_UART related interrupts specified by u32Mask parameter.
204  */
UUART_DisableInt(UUART_T * uuart,uint32_t u32Mask)205 void UUART_DisableInt(UUART_T* uuart, uint32_t u32Mask)
206 {
207 
208     /* Disable Auto-baud rate interrupt flag */
209     if((u32Mask & UUART_ABR_INT_MASK) == UUART_ABR_INT_MASK)
210     {
211         uuart->PROTIEN &= ~UUART_PROTIEN_ABRIEN_Msk;
212     }
213 
214     /* Disable receive line status interrupt flag */
215     if((u32Mask & UUART_RLS_INT_MASK) == UUART_RLS_INT_MASK)
216     {
217         uuart->PROTIEN &= ~UUART_PROTIEN_RLSIEN_Msk;
218     }
219 
220     /* Disable RX overrun interrupt flag */
221     if((u32Mask & UUART_BUF_RXOV_INT_MASK) == UUART_BUF_RXOV_INT_MASK)
222     {
223         uuart->BUFCTL &= ~UUART_BUFCTL_RXOVIEN_Msk;
224     }
225 
226     /* Disable TX start interrupt flag */
227     if((u32Mask & UUART_TXST_INT_MASK) == UUART_TXST_INT_MASK)
228     {
229         uuart->INTEN &= ~UUART_INTEN_TXSTIEN_Msk;
230     }
231 
232     /* Disable TX end interrupt flag */
233     if((u32Mask & UUART_TXEND_INT_MASK) == UUART_TXEND_INT_MASK)
234     {
235         uuart->INTEN &= ~UUART_INTEN_TXENDIEN_Msk;
236     }
237 
238     /* Disable RX start interrupt flag */
239     if((u32Mask & UUART_RXST_INT_MASK) == UUART_RXST_INT_MASK)
240     {
241         uuart->INTEN &= ~UUART_INTEN_RXSTIEN_Msk;
242     }
243 
244     /* Disable RX end interrupt flag */
245     if((u32Mask & UUART_RXEND_INT_MASK) == UUART_RXEND_INT_MASK)
246     {
247         uuart->INTEN &= ~UUART_INTEN_RXENDIEN_Msk;
248     }
249 }
250 
251 
252 /**
253  *    @brief        Enable interrupt function.
254  *
255  *    @param[in]    uuart       The pointer of the specified USCI_UART module.
256  *    @param[in]    u32Mask     The combination of all related interrupt enable bits.
257  *                              Each bit corresponds to a interrupt enable bit.
258  *                              This parameter decides which interrupts will be enabled. It is combination of:
259  *                              - \ref UUART_ABR_INT_MASK
260  *                              - \ref UUART_RLS_INT_MASK
261  *                              - \ref UUART_BUF_RXOV_INT_MASK
262  *                              - \ref UUART_TXST_INT_MASK
263  *                              - \ref UUART_TXEND_INT_MASK
264  *                              - \ref UUART_RXST_INT_MASK
265  *                              - \ref UUART_RXEND_INT_MASK
266  *
267  *    @return       None
268  *
269  *    @details      The function is used to enable USCI_UART related interrupts specified by u32Mask parameter..
270  */
UUART_EnableInt(UUART_T * uuart,uint32_t u32Mask)271 void UUART_EnableInt(UUART_T*  uuart, uint32_t u32Mask)
272 {
273     /* Enable Auto-baud rate interrupt flag */
274     if((u32Mask & UUART_ABR_INT_MASK) == UUART_ABR_INT_MASK)
275     {
276         uuart->PROTIEN |= UUART_PROTIEN_ABRIEN_Msk;
277     }
278 
279     /* Enable receive line status interrupt flag */
280     if((u32Mask & UUART_RLS_INT_MASK) == UUART_RLS_INT_MASK)
281     {
282         uuart->PROTIEN |= UUART_PROTIEN_RLSIEN_Msk;
283     }
284 
285     /* Enable RX overrun interrupt flag */
286     if((u32Mask & UUART_BUF_RXOV_INT_MASK) == UUART_BUF_RXOV_INT_MASK)
287     {
288         uuart->BUFCTL |= UUART_BUFCTL_RXOVIEN_Msk;
289     }
290 
291     /* Enable TX start interrupt flag */
292     if((u32Mask & UUART_TXST_INT_MASK) == UUART_TXST_INT_MASK)
293     {
294         uuart->INTEN |= UUART_INTEN_TXSTIEN_Msk;
295     }
296 
297     /* Enable TX end interrupt flag */
298     if((u32Mask & UUART_TXEND_INT_MASK) == UUART_TXEND_INT_MASK)
299     {
300         uuart->INTEN |= UUART_INTEN_TXENDIEN_Msk;
301     }
302 
303     /* Enable RX start interrupt flag */
304     if((u32Mask & UUART_RXST_INT_MASK) == UUART_RXST_INT_MASK)
305     {
306         uuart->INTEN |= UUART_INTEN_RXSTIEN_Msk;
307     }
308 
309     /* Enable RX end interrupt flag */
310     if((u32Mask & UUART_RXEND_INT_MASK) == UUART_RXEND_INT_MASK)
311     {
312         uuart->INTEN |= UUART_INTEN_RXENDIEN_Msk;
313     }
314 }
315 
316 
317 /**
318  *    @brief        Open and set USCI_UART function
319  *
320  *    @param[in]    uuart           The pointer of the specified USCI_UART module.
321  *    @param[in]    u32baudrate     The baud rate of USCI_UART module.
322  *
323  *    @return       Real baud rate of USCI_UART module.
324  *
325  *    @details      This function use to enable USCI_UART function and set baud-rate.
326  */
UUART_Open(UUART_T * uuart,uint32_t u32baudrate)327 uint32_t UUART_Open(UUART_T* uuart, uint32_t u32baudrate)
328 {
329     uint32_t u32PCLKFreq, u32PDSCnt, u32DSCnt, u32ClkDiv;
330     uint32_t u32Tmp, u32Tmp2, u32Min, u32MinClkDiv, u32MinDSCnt;
331     uint32_t u32Div;
332 
333     /* Get PCLK frequency */
334     if((uuart == UUART0) || (uuart == UUART0_NS))
335     {
336         u32PCLKFreq = CLK_GetPCLK0Freq();
337     }
338     else
339     {
340         u32PCLKFreq = CLK_GetPCLK1Freq();
341     }
342 
343     /* Calculate baud rate divider */
344     u32Div = u32PCLKFreq / u32baudrate;
345     u32Tmp = (u32PCLKFreq / u32Div) - u32baudrate;
346     u32Tmp2 = u32baudrate - (u32PCLKFreq / (u32Div + 1ul));
347 
348     if(u32Tmp >= u32Tmp2) u32Div = u32Div + 1ul;
349 
350     if(u32Div >= 65536ul)
351     {
352 
353         /* Set the smallest baud rate that USCI_UART can generate */
354         u32PDSCnt = 0x4ul;
355         u32MinDSCnt = 0x10ul;
356         u32MinClkDiv = 0x400ul;
357 
358     }
359     else
360     {
361 
362         u32Tmp = 0x400ul * 0x10ul;
363         for(u32PDSCnt = 1ul; u32PDSCnt <= 0x04ul; u32PDSCnt++)
364         {
365             if(u32Div <= (u32Tmp * u32PDSCnt)) break;
366         }
367 
368         if(u32PDSCnt > 0x4ul) u32PDSCnt = 0x4ul;
369 
370         u32Div = u32Div / u32PDSCnt;
371 
372         /* Find best solution */
373         u32Min = (uint32_t) - 1;
374         u32MinDSCnt = 0ul;
375         u32MinClkDiv = 0ul;
376         u32Tmp = 0ul;
377 
378         for(u32DSCnt = 6ul; u32DSCnt <= 0x10ul; u32DSCnt++)   /* DSCNT could be 0x5~0xF */
379         {
380 
381             u32ClkDiv = u32Div / u32DSCnt;
382 
383             if(u32ClkDiv > 0x400ul)
384             {
385                 u32ClkDiv = 0x400ul;
386                 u32Tmp = u32Div - (u32ClkDiv * u32DSCnt);
387                 u32Tmp2 = u32Tmp + 1ul;
388             }
389             else
390             {
391                 u32Tmp = u32Div - (u32ClkDiv * u32DSCnt);
392                 u32Tmp2 = ((u32ClkDiv + 1ul) * u32DSCnt) - u32Div;
393             }
394 
395             if(u32Tmp >= u32Tmp2)
396             {
397                 u32ClkDiv = u32ClkDiv + 1ul;
398             }
399             else u32Tmp2 = u32Tmp;
400 
401             if(u32Tmp2 < u32Min)
402             {
403                 u32Min = u32Tmp2;
404                 u32MinDSCnt = u32DSCnt;
405                 u32MinClkDiv = u32ClkDiv;
406 
407                 /* Break when get good results */
408                 if(u32Min == 0ul)
409                 {
410                     break;
411                 }
412             }
413         }
414 
415     }
416 
417     /* Enable USCI_UART protocol */
418     uuart->CTL &= ~UUART_CTL_FUNMODE_Msk;
419     uuart->CTL = 2ul << UUART_CTL_FUNMODE_Pos;
420 
421     /* Set USCI_UART line configuration */
422     uuart->LINECTL = UUART_WORD_LEN_8 | UUART_LINECTL_LSB_Msk;
423     uuart->DATIN0 = (2ul << UUART_DATIN0_EDGEDET_Pos);  /* Set falling edge detection */
424 
425     /* Set USCI_UART baud rate */
426     uuart->BRGEN = ((u32MinClkDiv - 1ul) << UUART_BRGEN_CLKDIV_Pos) |
427                    ((u32MinDSCnt - 1ul) << UUART_BRGEN_DSCNT_Pos) |
428                    ((u32PDSCnt - 1ul) << UUART_BRGEN_PDSCNT_Pos);
429 
430     uuart->PROTCTL |= UUART_PROTCTL_PROTEN_Msk;
431 
432     return (u32PCLKFreq / u32PDSCnt / u32MinDSCnt / u32MinClkDiv);
433 }
434 
435 
436 /**
437  *    @brief        Read USCI_UART data
438  *
439  *    @param[in]    uuart           The pointer of the specified USCI_UART module.
440  *    @param[in]    pu8RxBuf        The buffer to receive the data of receive buffer.
441  *    @param[in]    u32ReadBytes    The read bytes number of data.
442  *
443  *    @return       Receive byte count
444  *
445  *    @details      The function is used to read Rx data from RX buffer and the data will be stored in pu8RxBuf.
446  */
UUART_Read(UUART_T * uuart,uint8_t pu8RxBuf[],uint32_t u32ReadBytes)447 uint32_t UUART_Read(UUART_T* uuart, uint8_t pu8RxBuf[], uint32_t u32ReadBytes)
448 {
449     uint32_t  u32Count, u32delayno;
450 
451     for(u32Count = 0ul; u32Count < u32ReadBytes; u32Count++)
452     {
453         u32delayno = 0ul;
454 
455         while(uuart->BUFSTS & UUART_BUFSTS_RXEMPTY_Msk)   /* Check RX empty => failed */
456         {
457             u32delayno++;
458             if(u32delayno >= 0x40000000ul)
459             {
460                 break;
461             }
462         }
463 
464         if(u32delayno >= 0x40000000ul)
465         {
466             break;
467         }
468 
469         pu8RxBuf[u32Count] = (uint8_t)uuart->RXDAT;    /* Get Data from USCI RX  */
470     }
471 
472     return u32Count;
473 
474 }
475 
476 
477 /**
478  *    @brief        Set USCI_UART line configuration
479  *
480  *    @param[in]    uuart           The pointer of the specified USCI_UART module.
481  *    @param[in]    u32baudrate     The register value of baud rate of USCI_UART module.
482  *                                  If u32baudrate = 0, USCI_UART baud rate will not change.
483  *    @param[in]    u32data_width   The data length of USCI_UART module.
484  *                                  - \ref UUART_WORD_LEN_6
485  *                                  - \ref UUART_WORD_LEN_7
486  *                                  - \ref UUART_WORD_LEN_8
487  *                                  - \ref UUART_WORD_LEN_9
488  *    @param[in]    u32parity       The parity setting (none/odd/even) of USCI_UART module.
489  *                                  - \ref UUART_PARITY_NONE
490  *                                  - \ref UUART_PARITY_ODD
491  *                                  - \ref UUART_PARITY_EVEN
492  *    @param[in]    u32stop_bits    The stop bit length (1/2 bit) of USCI_UART module.
493  *                                  - \ref UUART_STOP_BIT_1
494  *                                  - \ref UUART_STOP_BIT_2
495  *
496  *    @return       Real baud rate of USCI_UART module.
497  *
498  *    @details      This function use to config USCI_UART line setting.
499  */
UUART_SetLine_Config(UUART_T * uuart,uint32_t u32baudrate,uint32_t u32data_width,uint32_t u32parity,uint32_t u32stop_bits)500 uint32_t UUART_SetLine_Config(UUART_T* uuart, uint32_t u32baudrate, uint32_t u32data_width, uint32_t u32parity, uint32_t u32stop_bits)
501 {
502     uint32_t u32PCLKFreq, u32PDSCnt, u32DSCnt, u32ClkDiv;
503     uint32_t u32Tmp, u32Tmp2, u32Min, u32MinClkDiv, u32MinDSCnt;
504     uint32_t u32Div;
505 
506     /* Get PCLK frequency */
507     if((uuart == UUART0) || (uuart == UUART0_NS))
508     {
509         u32PCLKFreq = CLK_GetPCLK0Freq();
510     }
511     else     /* UUART1 */
512     {
513         u32PCLKFreq = CLK_GetPCLK1Freq();
514     }
515 
516     if(u32baudrate != 0ul)
517     {
518 
519         /* Calculate baud rate divider */
520         u32Div = u32PCLKFreq / u32baudrate;
521         u32Tmp = (u32PCLKFreq / u32Div) - u32baudrate;
522         u32Tmp2 = u32baudrate - (u32PCLKFreq / (u32Div + 1ul));
523 
524         if(u32Tmp >= u32Tmp2) u32Div = u32Div + 1ul;
525 
526         if(u32Div >= 65536ul)
527         {
528 
529             /* Set the smallest baud rate that USCI_UART can generate */
530             u32PDSCnt = 0x4ul;
531             u32MinDSCnt = 0x10ul;
532             u32MinClkDiv = 0x400ul;
533 
534         }
535         else
536         {
537 
538             u32Tmp = 0x400ul * 0x10ul;
539             for(u32PDSCnt = 1ul; u32PDSCnt <= 0x04ul; u32PDSCnt++)
540             {
541                 if(u32Div <= (u32Tmp * u32PDSCnt)) break;
542             }
543 
544             if(u32PDSCnt > 0x4ul) u32PDSCnt = 0x4ul;
545 
546             u32Div = u32Div / u32PDSCnt;
547 
548             /* Find best solution */
549             u32Min = (uint32_t) - 1;
550             u32MinDSCnt = 0ul;
551             u32MinClkDiv = 0ul;
552 
553             for(u32DSCnt = 6ul; u32DSCnt <= 0x10ul; u32DSCnt++)   /* DSCNT could be 0x5~0xF */
554             {
555                 u32ClkDiv = u32Div / u32DSCnt;
556 
557                 if(u32ClkDiv > 0x400ul)
558                 {
559                     u32ClkDiv = 0x400ul;
560                     u32Tmp = u32Div - (u32ClkDiv * u32DSCnt);
561                     u32Tmp2 = u32Tmp + 1ul;
562                 }
563                 else
564                 {
565                     u32Tmp = u32Div - (u32ClkDiv * u32DSCnt);
566                     u32Tmp2 = ((u32ClkDiv + 1ul) * u32DSCnt) - u32Div;
567                 }
568 
569                 if(u32Tmp >= u32Tmp2)
570                 {
571                     u32ClkDiv = u32ClkDiv + 1ul;
572                 }
573                 else u32Tmp2 = u32Tmp;
574 
575                 if(u32Tmp2 < u32Min)
576                 {
577                     u32Min = u32Tmp2;
578                     u32MinDSCnt = u32DSCnt;
579                     u32MinClkDiv = u32ClkDiv;
580 
581                     /* Break when get good results */
582                     if(u32Min == 0ul)
583                     {
584                         break;
585                     }
586                 }
587             }
588 
589         }
590 
591         /* Set USCI_UART baud rate */
592         uuart->BRGEN = ((u32MinClkDiv - 1ul) << UUART_BRGEN_CLKDIV_Pos) |
593                        ((u32MinDSCnt - 1ul) << UUART_BRGEN_DSCNT_Pos) |
594                        ((u32PDSCnt - 1ul) << UUART_BRGEN_PDSCNT_Pos);
595     }
596     else
597     {
598         u32PDSCnt = ((uuart->BRGEN & UUART_BRGEN_PDSCNT_Msk) >> UUART_BRGEN_PDSCNT_Pos) + 1ul;
599         u32MinDSCnt = ((uuart->BRGEN & UUART_BRGEN_DSCNT_Msk) >> UUART_BRGEN_DSCNT_Pos) + 1ul;
600         u32MinClkDiv = ((uuart->BRGEN & UUART_BRGEN_CLKDIV_Msk) >> UUART_BRGEN_CLKDIV_Pos) + 1ul;
601     }
602 
603     /* Set USCI_UART line configuration */
604     uuart->LINECTL = (uuart->LINECTL & ~UUART_LINECTL_DWIDTH_Msk) | u32data_width;
605     uuart->PROTCTL = (uuart->PROTCTL & ~(UUART_PROTCTL_STICKEN_Msk | UUART_PROTCTL_EVENPARITY_Msk |
606                                          UUART_PROTCTL_PARITYEN_Msk)) | u32parity;
607     uuart->PROTCTL = (uuart->PROTCTL & ~UUART_PROTCTL_STOPB_Msk) | u32stop_bits;
608 
609     return (u32PCLKFreq / u32PDSCnt / u32MinDSCnt / u32MinClkDiv);
610 }
611 
612 
613 /**
614  *    @brief        Write USCI_UART data
615  *
616  *    @param[in]    uuart           The pointer of the specified USCI_UART module.
617  *    @param[in]    pu8TxBuf        The buffer to send the data to USCI transmission buffer.
618  *    @param[out]   u32WriteBytes   The byte number of data.
619  *
620  *    @return       Transfer byte count
621  *
622  *    @details      The function is to write data into TX buffer to transmit data by USCI_UART.
623  */
UUART_Write(UUART_T * uuart,uint8_t pu8TxBuf[],uint32_t u32WriteBytes)624 uint32_t UUART_Write(UUART_T* uuart, uint8_t pu8TxBuf[], uint32_t u32WriteBytes)
625 {
626     uint32_t  u32Count, u32delayno;
627 
628     for(u32Count = 0ul; u32Count != u32WriteBytes; u32Count++)
629     {
630         u32delayno = 0ul;
631         while((uuart->BUFSTS & UUART_BUFSTS_TXEMPTY_Msk) == 0ul)   /* Wait Tx empty */
632         {
633             u32delayno++;
634             if(u32delayno >= 0x40000000ul)
635             {
636                 break;
637             }
638         }
639 
640         if(u32delayno >= 0x40000000ul)
641         {
642             break;
643         }
644 
645         uuart->TXDAT = (uint8_t)pu8TxBuf[u32Count];    /* Send USCI_UART Data to buffer */
646     }
647 
648     return u32Count;
649 }
650 
651 
652 /**
653  *    @brief        Enable USCI_UART Wake-up Function
654  *
655  *    @param[in]    uuart           The pointer of the specified USCI_UART module.
656  *    @param[in]    u32WakeupMode   The wakeup mode of USCI_UART module.
657 *                                   - \ref UUART_PROTCTL_DATWKEN_Msk    : Data wake-up Mode
658 *                                   - \ref UUART_PROTCTL_CTSWKEN_Msk    : nCTS wake-up Mode
659  *
660  *    @return       None
661  *
662  *    @details      The function is used to enable Wake-up function of USCI_UART.
663  */
UUART_EnableWakeup(UUART_T * uuart,uint32_t u32WakeupMode)664 void UUART_EnableWakeup(UUART_T* uuart, uint32_t u32WakeupMode)
665 {
666     uuart->PROTCTL |= u32WakeupMode;
667     uuart->WKCTL |= UUART_WKCTL_WKEN_Msk;
668 }
669 
670 
671 /**
672  *    @brief        Disable USCI_UART Wake-up Function
673  *
674  *    @param[in]    uuart   The pointer of the specified USCI_UART module.
675  *
676  *    @return       None
677  *
678  *    @details      The function is used to disable Wake-up function of USCI_UART.
679  */
UUART_DisableWakeup(UUART_T * uuart)680 void UUART_DisableWakeup(UUART_T* uuart)
681 {
682     uuart->PROTCTL &= ~(UUART_PROTCTL_DATWKEN_Msk | UUART_PROTCTL_CTSWKEN_Msk);
683     uuart->WKCTL &= ~UUART_WKCTL_WKEN_Msk;
684 }
685 
686 /**
687  *    @brief        Enable USCI_UART auto flow control
688  *
689  *    @param[in]    uuart   The pointer of the specified USCI_UART module.
690  *
691  *    @return       None
692  *
693  *    @details      The function is used to enable USCI_UART auto flow control.
694  */
UUART_EnableFlowCtrl(UUART_T * uuart)695 void UUART_EnableFlowCtrl(UUART_T* uuart)
696 {
697     /* Set RTS signal is low level active */
698     uuart->LINECTL &= ~UUART_LINECTL_CTLOINV_Msk;
699 
700     /* Set CTS signal is low level active */
701     uuart->CTLIN0 &= ~UUART_CTLIN0_ININV_Msk;
702 
703     /* Enable CTS and RTS auto flow control function */
704     uuart->PROTCTL |= UUART_PROTCTL_RTSAUTOEN_Msk | UUART_PROTCTL_CTSAUTOEN_Msk;
705 }
706 
707 /**
708  *    @brief        Disable USCI_UART auto flow control
709  *
710  *    @param[in]    uuart    The pointer of the specified USCI_UART module.
711  *
712  *    @return       None
713  *
714  *    @details      The function is used to disable USCI_UART auto flow control.
715  */
UUART_DisableFlowCtrl(UUART_T * uuart)716 void UUART_DisableFlowCtrl(UUART_T* uuart)
717 {
718     /* Disable CTS and RTS auto flow control function */
719     uuart->PROTCTL &= ~(UUART_PROTCTL_RTSAUTOEN_Msk | UUART_PROTCTL_CTSAUTOEN_Msk);
720 }
721 
722 
723 
724 
725 /**@}*/ /* end of group USCI_UART_EXPORTED_FUNCTIONS */
726 
727 /**@}*/ /* end of group USCI_UART_Driver */
728 
729 /**@}*/ /* end of group Standard_Driver */
730