M4521_BSP V3.02.000
The Board Support Package for M4521
uart.c
Go to the documentation of this file.
1/**************************************************************************/
13#include <stdio.h>
14#include "M4521.h"
15
44void UART_ClearIntFlag(UART_T* uart, uint32_t u32InterruptFlag)
45{
46
47 if(u32InterruptFlag & UART_INTSTS_RLSINT_Msk) /* Clear Receive Line Status Interrupt */
48 {
51 }
52
53 if(u32InterruptFlag & UART_INTSTS_MODEMINT_Msk) /* Clear Modem Status Interrupt */
55
56 if(u32InterruptFlag & UART_INTSTS_BUFERRINT_Msk) /* Clear Buffer Error Interrupt */
57 {
59 }
60
61 if(u32InterruptFlag & UART_INTSTS_CTSWKIF_Msk) /* Clear CTS Wake-up Interrupt */
62 {
64 }
65
66 if(u32InterruptFlag & UART_INTSTS_DATWKIF_Msk) /* Clear Data Wake-up Interrupt */
67 {
69 }
70}
71
72
82void UART_Close(UART_T* uart)
83{
84 uart->INTEN = 0;
85}
86
87
98{
100}
101
102
121void UART_DisableInt(UART_T* uart, uint32_t u32InterruptFlag)
122{
123 /* Disable UART specified interrupt */
124 UART_DISABLE_INT(uart, u32InterruptFlag);
125}
126
127
138{
139 /* Set RTS pin output is low level active */
141
142 /* Set CTS pin input is low level active */
144
145 /* Set RTS and CTS auto flow control enable */
147}
148
149
168void UART_EnableInt(UART_T* uart, uint32_t u32InterruptFlag)
169{
170 /* Enable UART specified interrupt */
171 UART_ENABLE_INT(uart, u32InterruptFlag);
172}
173
174
185void UART_Open(UART_T* uart, uint32_t u32baudrate)
186{
187 uint8_t u8UartClkSrcSel, u8UartClkDivNum;
188 uint32_t u32ClkTbl[4] = {__HXT, 0, __LXT, __HIRC};
189 uint32_t u32Baud_Div = 0;
190
191 /* Get UART clock source selection */
192 u8UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UARTSEL_Msk) >> CLK_CLKSEL1_UARTSEL_Pos;
193
194 /* Get UART clock divider number */
195 u8UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UARTDIV_Msk) >> CLK_CLKDIV0_UARTDIV_Pos;
196
197 /* Select UART function */
199
200 /* Set UART line configuration */
202
203 /* Set UART Rx and RTS trigger level */
205
206 /* Get PLL clock frequency if UART clock source selection is PLL */
207 if(u8UartClkSrcSel == 1)
208 u32ClkTbl[u8UartClkSrcSel] = CLK_GetPLLClockFreq();
209
210 /* Set UART baud rate */
211 if(u32baudrate != 0)
212 {
213 u32Baud_Div = UART_BAUD_MODE2_DIVIDER((u32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1), u32baudrate);
214
215 if(u32Baud_Div > 0xFFFF)
216 uart->BAUD = (UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER((u32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1), u32baudrate));
217 else
218 uart->BAUD = (UART_BAUD_MODE2 | u32Baud_Div);
219 }
220}
221
222
234uint32_t UART_Read(UART_T* uart, uint8_t *pu8RxBuf, uint32_t u32ReadBytes)
235{
236 uint32_t u32Count, u32delayno;
237 uint32_t u32Timeout = 3 * SystemCoreClock; // timeout 3 second
238
239 for(u32Count = 0; u32Count < u32ReadBytes; u32Count++)
240 {
241 u32delayno = 0;
242
243 while(uart->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) /* Check RX empty => failed */
244 {
245 u32delayno++;
246 if(u32delayno >= u32Timeout)
247 return u32Count;
248 }
249 pu8RxBuf[u32Count] = uart->DAT; /* Get Data from UART RX */
250 }
251
252 return u32Count;
253
254}
255
256
283void UART_SetLine_Config(UART_T* uart, uint32_t u32baudrate, uint32_t u32data_width, uint32_t u32parity, uint32_t u32stop_bits)
284{
285 uint8_t u8UartClkSrcSel, u8UartClkDivNum;
286 uint32_t u32ClkTbl[4] = {__HXT, 0, __LXT, __HIRC};
287 uint32_t u32Baud_Div = 0;
288
289 /* Get UART clock source selection */
290 u8UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UARTSEL_Msk) >> CLK_CLKSEL1_UARTSEL_Pos;
291
292 /* Get UART clock divider number */
293 u8UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UARTDIV_Msk) >> CLK_CLKDIV0_UARTDIV_Pos;
294
295 /* Get PLL clock frequency if UART clock source selection is PLL */
296 if(u8UartClkSrcSel == 1)
297 u32ClkTbl[u8UartClkSrcSel] = CLK_GetPLLClockFreq();
298
299 /* Set UART baud rate */
300 if(u32baudrate != 0)
301 {
302 u32Baud_Div = UART_BAUD_MODE2_DIVIDER((u32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1), u32baudrate);
303
304 if(u32Baud_Div > 0xFFFF)
305 uart->BAUD = (UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER((u32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1), u32baudrate));
306 else
307 uart->BAUD = (UART_BAUD_MODE2 | u32Baud_Div);
308 }
309
310 /* Set UART line configuration */
311 uart->LINE = u32data_width | u32parity | u32stop_bits;
312}
313
314
325void UART_SetTimeoutCnt(UART_T* uart, uint32_t u32TOC)
326{
327 /* Set time-out interrupt comparator */
328 uart->TOUT = (uart->TOUT & ~UART_TOUT_TOIC_Msk) | (u32TOC);
329
330 /* Set time-out counter enable */
332}
333
334
348void UART_SelectIrDAMode(UART_T* uart, uint32_t u32Buadrate, uint32_t u32Direction)
349{
350 uint8_t u8UartClkSrcSel, u8UartClkDivNum;
351 uint32_t u32ClkTbl[4] = {__HXT, 0, __LXT, __HIRC};
352 uint32_t u32Baud_Div;
353
354 /* Select IrDA function mode */
356
357 /* Get UART clock source selection */
358 u8UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UARTSEL_Msk) >> CLK_CLKSEL1_UARTSEL_Pos;
359
360 /* Get UART clock divider number */
361 u8UartClkDivNum = (CLK->CLKDIV0 & CLK_CLKDIV0_UARTDIV_Msk) >> CLK_CLKDIV0_UARTDIV_Pos;
362
363 /* Get PLL clock frequency if UART clock source selection is PLL */
364 if(u8UartClkSrcSel == 1)
365 u32ClkTbl[u8UartClkSrcSel] = CLK_GetPLLClockFreq();
366
367 /* Set UART IrDA baud rate in mode 0 */
368 if(u32Buadrate != 0)
369 {
370 u32Baud_Div = UART_BAUD_MODE0_DIVIDER((u32ClkTbl[u8UartClkSrcSel]) / (u8UartClkDivNum + 1), u32Buadrate);
371
372 if(u32Baud_Div < 0xFFFF)
373 uart->BAUD = (UART_BAUD_MODE0 | u32Baud_Div);
374 }
375
376 /* Configure IrDA relative settings */
377 if(u32Direction == UART_IRDA_RXEN)
378 {
379 uart->IRDA |= UART_IRDA_RXINV_Msk; //Rx signal is inverse
380 uart->IRDA &= ~UART_IRDA_TXEN_Msk;
381 }
382 else
383 {
384 uart->IRDA &= ~UART_IRDA_TXINV_Msk; //Tx signal is not inverse
385 uart->IRDA |= UART_IRDA_TXEN_Msk;
386 }
387
388}
389
390
405void UART_SelectRS485Mode(UART_T* uart, uint32_t u32Mode, uint32_t u32Addr)
406{
407 /* Select UART RS485 function mode */
409
410 /* Set RS585 configuration */
412 uart->ALTCTL |= (u32Mode | (u32Addr << UART_ALTCTL_ADDRMV_Pos));
413}
414
415
416
417
429uint32_t UART_Write(UART_T* uart, uint8_t *pu8TxBuf, uint32_t u32WriteBytes)
430{
431 uint32_t u32Count, u32delayno;
432 uint32_t u32Exit = 0ul;
433 uint32_t u32Timeout = 3 * SystemCoreClock; // timeout 3 second
434
435 for (u32Count = 0ul; u32Count != u32WriteBytes; u32Count++)
436 {
437 u32delayno = 0ul;
438
439 while (uart->FIFOSTS & UART_FIFOSTS_TXFULL_Msk) /* Check Tx Full */
440 {
441 u32delayno++;
442
443 if (u32delayno >= u32Timeout)
444 {
445 u32Exit = 1ul;
446 break;
447 }
448 }
449
450 if (u32Exit == 1ul)
451 {
452 break;
453 }
454 else
455 {
456 uart->DAT = pu8TxBuf[u32Count]; /* Send UART Data from buffer */
457 }
458 }
459
460 return u32Count;
461
462}
463
464 /* end of group UART_EXPORTED_FUNCTIONS */
466 /* end of group UART_Driver */
468 /* end of group Standard_Driver */
470
471/*** (C) COPYRIGHT 2022 Nuvoton Technology Corp. ***/
#define UART_FIFOSTS_BIF_Msk
Definition: M4521.h:12027
#define UART_FIFOSTS_TXOVIF_Msk
Definition: M4521.h:12048
#define UART_FIFOSTS_RXOVIF_Msk
Definition: M4521.h:12009
#define UART_INTEN_ATORTSEN_Msk
Definition: M4521.h:11943
#define UART_INTSTS_BUFERRINT_Msk
Definition: M4521.h:12093
#define UART_ALTCTL_ADDRMV_Msk
Definition: M4521.h:12186
#define UART_FIFOSTS_TXFULL_Msk
Definition: M4521.h:12045
#define UART_ALTCTL_ADDRMV_Pos
Definition: M4521.h:12185
#define UART_FIFOSTS_ADDRDETF_Msk
Definition: M4521.h:12018
#define UART_ALTCTL_RS485AUD_Msk
Definition: M4521.h:12171
#define UART_IRDA_RXINV_Msk
Definition: M4521.h:12153
#define UART_INTSTS_CTSWKIF_Msk
Definition: M4521.h:12099
#define UART_FIFO_RFITL_Msk
Definition: M4521.h:11964
#define UART_INTSTS_MODEMINT_Msk
Definition: M4521.h:12087
#define UART_INTEN_ATOCTSEN_Msk
Definition: M4521.h:11946
#define UART_INTSTS_RLSINT_Msk
Definition: M4521.h:12084
#define UART_MODEM_RTSACTLV_Msk
Definition: M4521.h:11994
#define UART_ALTCTL_RS485NMM_Msk
Definition: M4521.h:12165
#define UART_INTSTS_DATWKIF_Msk
Definition: M4521.h:12102
#define UART_FIFOSTS_RXEMPTY_Msk
Definition: M4521.h:12033
#define UART_FIFOSTS_PEF_Msk
Definition: M4521.h:12021
#define UART_MODEMSTS_CTSDETF_Msk
Definition: M4521.h:12000
#define UART_FIFOSTS_FEF_Msk
Definition: M4521.h:12024
#define UART_FIFO_RTSTRGLV_Msk
Definition: M4521.h:11970
#define UART_ALTCTL_RS485AAD_Msk
Definition: M4521.h:12168
#define UART_IRDA_TXEN_Msk
Definition: M4521.h:12147
#define UART_MODEMSTS_CTSACTLV_Msk
Definition: M4521.h:12006
#define UART_INTEN_TOCNTEN_Msk
Definition: M4521.h:11940
__STATIC_INLINE uint32_t CLK_GetPLLClockFreq(void)
Get PLL clock frequency.
Definition: clk.h:332
#define CLK_CLKDIV0_UARTDIV_Pos
Definition: M4521.h:1628
#define CLK_CLKSEL1_UARTSEL_Msk
Definition: M4521.h:1596
#define CLK_CLKDIV0_UARTDIV_Msk
Definition: M4521.h:1629
#define CLK_CLKSEL1_UARTSEL_Pos
Definition: M4521.h:1595
__IO uint32_t DAT
Definition: M4521.h:11887
__IO uint32_t INTEN
Definition: M4521.h:11888
__IO uint32_t FIFOSTS
Definition: M4521.h:11893
__IO uint32_t ALTCTL
Definition: M4521.h:11898
#define CLK
Definition: M4521.h:13822
__IO uint32_t FUNCSEL
Definition: M4521.h:11899
__IO uint32_t BAUD
Definition: M4521.h:11896
__IO uint32_t FIFO
Definition: M4521.h:11889
__IO uint32_t MODEM
Definition: M4521.h:11891
__IO uint32_t MODEMSTS
Definition: M4521.h:11892
__IO uint32_t TOUT
Definition: M4521.h:11895
__IO uint32_t IRDA
Definition: M4521.h:11897
__IO uint32_t INTSTS
Definition: M4521.h:11894
__IO uint32_t LINE
Definition: M4521.h:11890
#define UART_BAUD_MODE2
Definition: uart.h:102
#define UART_PARITY_NONE
Definition: uart.h:65
#define UART_BAUD_MODE0
Definition: uart.h:101
#define UART_IRDA_RXEN
Definition: uart.h:87
#define UART_FUNCSEL_IrDA
Definition: uart.h:94
#define UART_STOP_BIT_1
Definition: uart.h:71
#define UART_WORD_LEN_8
Definition: uart.h:63
#define UART_FUNCSEL_RS485
Definition: uart.h:95
#define UART_FUNCSEL_UART
Definition: uart.h:93
void UART_SelectRS485Mode(UART_T *uart, uint32_t u32Mode, uint32_t u32Addr)
Select and configure RS485 function.
Definition: uart.c:405
void UART_EnableInt(UART_T *uart, uint32_t u32InterruptFlag)
The function is used to enable UART specified interrupt and enable NVIC UART IRQ.
Definition: uart.c:168
void UART_SetTimeoutCnt(UART_T *uart, uint32_t u32TOC)
Set Rx timeout count.
Definition: uart.c:325
void UART_Close(UART_T *uart)
Disable UART interrupt.
Definition: uart.c:82
#define UART_BAUD_MODE0_DIVIDER(u32SrcFreq, u32BaudRate)
Calculate UART baudrate mode0 divider.
Definition: uart.h:123
#define UART_DISABLE_INT(uart, u32eIntSel)
Disable specified UART interrupt.
Definition: uart.h:322
void UART_ClearIntFlag(UART_T *uart, uint32_t u32InterruptFlag)
Clear UART specified interrupt flag.
Definition: uart.c:44
void UART_DisableFlowCtrl(UART_T *uart)
Disable UART auto flow control function.
Definition: uart.c:97
void UART_EnableFlowCtrl(UART_T *uart)
Enable UART auto flow control function.
Definition: uart.c:137
uint32_t UART_Write(UART_T *uart, uint8_t *pu8TxBuf, uint32_t u32WriteBytes)
Write UART data.
Definition: uart.c:429
#define UART_BAUD_MODE2_DIVIDER(u32SrcFreq, u32BaudRate)
Calculate UART baudrate mode2 divider.
Definition: uart.h:136
void UART_SetLine_Config(UART_T *uart, uint32_t u32baudrate, uint32_t u32data_width, uint32_t u32parity, uint32_t u32stop_bits)
Set UART line configuration.
Definition: uart.c:283
void UART_DisableInt(UART_T *uart, uint32_t u32InterruptFlag)
Disable UART specified interrupt.
Definition: uart.c:121
void UART_SelectIrDAMode(UART_T *uart, uint32_t u32Buadrate, uint32_t u32Direction)
Select and configure IrDA function.
Definition: uart.c:348
uint32_t UART_Read(UART_T *uart, uint8_t *pu8RxBuf, uint32_t u32ReadBytes)
Read UART data.
Definition: uart.c:234
void UART_Open(UART_T *uart, uint32_t u32baudrate)
Open and set UART function.
Definition: uart.c:185
#define UART_ENABLE_INT(uart, u32eIntSel)
Enable specified UART interrupt.
Definition: uart.h:300
#define __HIRC
Definition: system_M4521.h:37
#define __HXT
Definition: system_M4521.h:35
uint32_t SystemCoreClock
Definition: system_M4521.c:24
#define __LXT
Definition: system_M4521.h:36