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