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