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