MINI58_BSP V3.01.005
The Board Support Package for Mini58 Series MCU
uart.c
Go to the documentation of this file.
1/**************************************************************************/
13#include <stdio.h>
14#include "Mini58Series.h"
15
37void UART_ClearIntFlag(UART_T* uart, uint32_t u32InterruptFlag)
38{
39
40 if(u32InterruptFlag & UART_INTSTS_RLSINT_Msk) /* clear Receive Line Status Interrupt */
41 {
44 }
45
46 if(u32InterruptFlag & UART_INTSTS_MODEMINT_Msk) /* clear Modem Interrupt */
48
49 if(u32InterruptFlag & UART_INTSTS_BUFERRINT_Msk) /* clear Buffer Error Interrupt */
50 {
52 }
53
54 if(u32InterruptFlag & UART_INTSTS_RXTOINT_Msk) /* clear Modem Interrupt */
56
57}
58
59
67void UART_Close(UART_T* uart)
68{
69 uart->INTEN = 0;
70}
71
72
81{
83}
84
85
102void UART_DisableInt(UART_T* uart, uint32_t u32InterruptFlag )
103{
104 uart->INTEN &= ~ u32InterruptFlag;
105}
106
107
108
117{
119 uart->MODEM &= ~UART_MODEM_RTS_Msk;
122}
123
124
141void UART_EnableInt(UART_T* uart, uint32_t u32InterruptFlag )
142{
143 uart->INTEN |= u32InterruptFlag;
144}
145
146
155void UART_Open(UART_T* uart, uint32_t u32baudrate)
156{
157 uint8_t u8UartClkSrcSel;
158 uint32_t u32Clk = 0;
159 uint32_t u32ClkDiv = 0;
160 uint32_t u32Baud_Div;
161 uint32_t i = 0;
162 uint32_t u32RealBaudrate = 0, u32Err = 0, u32OldErr = 0;
163 uint32_t u32A = 0, u32B = 0;
164
165 u8UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UARTSEL_Msk) >> CLK_CLKSEL1_UARTSEL_Pos;
169
170 if(u8UartClkSrcSel == 0)
171 u32Clk = __XTAL;
172 else if(u8UartClkSrcSel == 1)
173 u32Clk = CLK_GetPLLClockFreq();
174 else if(u8UartClkSrcSel >= 2)
175 u32Clk = __HSI;
176
177 u32ClkDiv = ( (CLK->CLKDIV & CLK_CLKDIV_UARTDIV_Msk) >> CLK_CLKDIV_UARTDIV_Pos );
178 u32Clk = u32Clk/(u32ClkDiv + 1);
179
180 if (u32baudrate != 0)
181 {
182 if (uart != UART1)
183 {
184 u32Baud_Div = UART_BAUD_MODE2_DIVIDER(u32Clk, u32baudrate);
185
186 if(u32Baud_Div > 0xFFFF)
187 uart->BAUD = (UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER(u32Clk, u32baudrate));
188 else
189 uart->BAUD = (UART_BAUD_MODE2 | u32Baud_Div);
190 }
191 else
192 {
193 for(i = 0; i < 0xf; i++)
194 {
195 u32Baud_Div = ((u32Clk + (u32baudrate*(9+i)/2)) / u32baudrate / (9+i));
196 u32RealBaudrate = u32Clk/(u32Baud_Div) / (9+i);
197
198 if(u32RealBaudrate > u32baudrate)
199 {
200 u32Err = u32RealBaudrate - u32baudrate;
201 }
202 else if (u32RealBaudrate < u32baudrate)
203 {
204 u32Err = u32baudrate - u32RealBaudrate;
205 }
206 else
207 {
208 u32B = 8 + i;
209 u32A = u32Baud_Div - 2;
210 break;
211 }
212
213 if (i == 0)
214 {
215 u32B = 8 + i;
216 u32A = u32Baud_Div - 2;
217 u32OldErr = u32Err;
218 }
219 else
220 {
221 if (u32OldErr > u32Err)
222 {
223 u32B = 8 + i;
224 u32A = u32Baud_Div - 2;
225 u32OldErr = u32Err;
226 }
227 }
228 }
229 u32Baud_Div = (u32A << UART_BAUD_BRD_Pos) | (u32B << UART_BAUD_EDIVM1_Pos);
230 uart->BAUD = (UART_BAUD_MODE1 | u32Baud_Div);
231 }
232 }
233}
234
235
246uint32_t UART_Read(UART_T* uart, uint8_t *pu8RxBuf, uint32_t u32ReadBytes)
247{
248 uint32_t u32Count, u32delayno;
249
250 for (u32Count = 0; u32Count < u32ReadBytes; u32Count++)
251 {
252 u32delayno = (SystemCoreClock / 10);
253
254 while ((uart->FIFOSTS & UART_FIFOSTS_RXEMPTY_Msk) && /* Check RX empty => failed */
255 (u32delayno-- > 0)) ;
256
258 return 0;
259
260 pu8RxBuf[u32Count] = uart->DAT; /* Get Data from UART RX */
261 }
262
263 return u32Count;
264
265}
266
267
280void UART_SetLine_Config(UART_T* uart, uint32_t u32baudrate, uint32_t u32data_width, uint32_t u32parity, uint32_t u32stop_bits)
281{
282 uint8_t u8UartClkSrcSel;
283 uint32_t u32Clk = 0;
284 uint32_t u32ClkDiv = 0;
285 uint32_t u32Baud_Div = 0;
286 uint32_t i = 0;
287 uint32_t u32RealBaudrate = 0, u32Err = 0, u32OldErr = 0;
288 uint32_t u32A = 0, u32B = 0;
289
290 u8UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UARTSEL_Msk) >> CLK_CLKSEL1_UARTSEL_Pos;
291
292 if(u8UartClkSrcSel == 0)
293 u32Clk = __XTAL;
294 else if(u8UartClkSrcSel == 1)
295 u32Clk = CLK_GetPLLClockFreq();
296 else if(u8UartClkSrcSel >= 2)
297 u32Clk = __HSI;
298
299 u32ClkDiv = ( (CLK->CLKDIV & CLK_CLKDIV_UARTDIV_Msk) >> CLK_CLKDIV_UARTDIV_Pos );
300 u32Clk = u32Clk/(u32ClkDiv + 1);
301
302 if (u32baudrate != 0)
303 {
304 if (uart != UART1)
305 {
306 u32Baud_Div = UART_BAUD_MODE2_DIVIDER(u32Clk, u32baudrate);
307
308 if(u32Baud_Div > 0xFFFF)
309 uart->BAUD = (UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER(u32Clk, u32baudrate));
310 else
311 uart->BAUD = (UART_BAUD_MODE2 | u32Baud_Div);
312 }
313 else
314 {
315 for(i = 0; i < 0xf; i++)
316 {
317 u32Baud_Div = ((u32Clk + (u32baudrate*(9+i)/2)) / u32baudrate / (9+i));
318 u32RealBaudrate = u32Clk/(u32Baud_Div) / (9+i);
319
320 if(u32RealBaudrate > u32baudrate)
321 {
322 u32Err = u32RealBaudrate - u32baudrate;
323 }
324 else if (u32RealBaudrate < u32baudrate)
325 {
326 u32Err = u32baudrate - u32RealBaudrate;
327 }
328 else
329 {
330 u32B = 8 + i;
331 u32A = u32Baud_Div - 2;
332 break;
333 }
334
335 if (i == 0)
336 {
337 u32B = 8 + i;
338 u32A = u32Baud_Div - 2;
339 u32OldErr = u32Err;
340 }
341 else
342 {
343 if (u32OldErr > u32Err)
344 {
345 u32B = 8 + i;
346 u32A = u32Baud_Div - 2;
347 u32OldErr = u32Err;
348 }
349 }
350 }
351 u32Baud_Div = (u32A << UART_BAUD_BRD_Pos) | (u32B << UART_BAUD_EDIVM1_Pos);
352 uart->BAUD = (UART_BAUD_MODE1 | u32Baud_Div);
353 }
354 }
355 uart->LINE = u32data_width | u32parity | u32stop_bits;
356}
357
358
367void UART_SetTimeoutCnt(UART_T* uart, uint32_t u32TOC)
368{
369 uart->TOUT = (uart->TOUT & ~UART_TOUT_TOIC_Msk)| (u32TOC);
371}
372
373
383void UART_SelectIrDAMode(UART_T* uart, uint32_t u32Buadrate, uint32_t u32Direction)
384{
385 uint8_t u8UartClkSrcSel;
386 uint32_t u32Clk = 0;
387 uint32_t u32ClkDiv = 0;
388
389 u8UartClkSrcSel = (CLK->CLKSEL1 & CLK_CLKSEL1_UARTSEL_Msk) >> CLK_CLKSEL1_UARTSEL_Pos;
390
391 if(u8UartClkSrcSel == 0)
392 u32Clk = __XTAL;
393 else if(u8UartClkSrcSel == 1)
394 u32Clk = CLK_GetPLLClockFreq();
395 else if(u8UartClkSrcSel >= 2)
396 u32Clk = __HSI;
397
398 u32ClkDiv = ( (CLK->CLKDIV & CLK_CLKDIV_UARTDIV_Msk) >> CLK_CLKDIV_UARTDIV_Pos );
399 u32Clk = u32Clk/(u32ClkDiv + 1);
400
401 uart->BAUD = UART_BAUD_MODE0 | UART_BAUD_MODE0_DIVIDER(u32Clk, u32Buadrate);
402
403 uart->IRDA &= ~UART_IRDA_TXINV_Msk;
404 uart->IRDA |= UART_IRDA_RXINV_Msk;
405 uart->IRDA = u32Direction ? uart->IRDA | UART_IRDA_TXEN_Msk : uart->IRDA &~ UART_IRDA_TXEN_Msk;
406 uart->FUNSEL = (0x2 << UART_FUNSEL_FUN_SEL_Pos);
407}
408
409
419void UART_SelectRS485Mode(UART_T* uart, uint32_t u32Mode, uint32_t u32Addr)
420{
422 uart->ALTCTL = 0;
423 uart->ALTCTL |= u32Mode | (u32Addr << UART_ALTCTL_ADDRMV_Pos);
424}
425
426
436uint32_t UART_Write(UART_T* uart,uint8_t *pu8TxBuf, uint32_t u32WriteBytes)
437{
438 uint32_t u32Count, u32delayno;
439
440 for(u32Count=0; u32Count != u32WriteBytes; u32Count++)
441 {
442 u32delayno = (SystemCoreClock / 10);
443
444 while (((uart->FIFOSTS & UART_FIFOSTS_TXEMPTYF_Msk) == 0) && /* Wait Tx empty and Time-out manner */
445 (u32delayno-- > 0)) ;
446
447 if ((uart->FIFOSTS & UART_FIFOSTS_TXEMPTYF_Msk) == 0)
448 return 0;
449
450 uart->DAT = pu8TxBuf[u32Count]; /* Send UART Data from buffer */
451 }
452 return u32Count;
453}
454
455 /* end of group Mini58_UART_EXPORTED_FUNCTIONS */
457 /* end of group Mini58_UART_Driver */
459 /* end of group Mini58_Device_Driver */
461
462/*** (C) COPYRIGHT 2022 Nuvoton Technology Corp. ***/
463
Mini58 series peripheral access layer header file. This file contains all the peripheral register's d...
#define UART_FIFOSTS_BIF_Msk
#define UART_FIFOSTS_TXOVIF_Msk
#define UART_FIFOSTS_RXOVIF_Msk
#define UART_INTEN_ATORTSEN_Msk
#define UART_INTSTS_BUFERRINT_Msk
#define UART_ALTCTL_ADDRMV_Pos
#define UART_FIFOSTS_ADDRDETF_Msk
#define UART_IRDA_RXINV_Msk
#define UART_INTSTS_RXTOINT_Msk
#define UART_INTSTS_MODEMINT_Msk
#define UART_FUNSEL_FUN_SEL_Pos
#define UART_INTEN_ATOCTSEN_Msk
#define UART_INTSTS_RLSINT_Msk
#define UART_MODEM_RTSACTLV_Msk
#define UART_FIFOSTS_TXEMPTYF_Msk
#define UART_BAUD_EDIVM1_Pos
#define UART_FIFOSTS_RXEMPTY_Msk
#define UART_FIFOSTS_PEF_Msk
#define UART_MODEMSTS_CTSDETF_Msk
#define UART_BAUD_BRD_Pos
#define UART_FIFOSTS_FEF_Msk
#define UART_INTSTS_RXTOIF_Msk
#define UART_IRDA_TXEN_Msk
#define UART_MODEMSTS_CTSACTLV_Msk
#define UART_INTEN_TOCNTEN_Msk
__STATIC_INLINE uint32_t CLK_GetPLLClockFreq(void)
Get PLL clock frequency.
Definition: clk.h:197
#define CLK_CLKSEL1_UARTSEL_Msk
#define CLK_CLKSEL1_UARTSEL_Pos
#define CLK_CLKDIV_UARTDIV_Pos
#define CLK_CLKDIV_UARTDIV_Msk
#define CLK
Pointer to CLK register structure.
#define UART1
Pointer to UART1 register structure.
#define UART_PARITY_NONE
Definition: uart.h:55
#define UART_FIFO_RTSTRGLV_1BYTE
Definition: uart.h:42
#define UART_STOP_BIT_1
Definition: uart.h:61
#define UART_WORD_LEN_8
Definition: uart.h:53
#define UART_FIFO_RFITL_1BYTE
Definition: uart.h:37
#define UART_FUNC_SEL_UART
Definition: uart.h:75
#define UART_FUNC_SEL_RS485
Definition: uart.h:77
void UART_SelectRS485Mode(UART_T *uart, uint32_t u32Mode, uint32_t u32Addr)
The function is used to set RS485 relative setting.
Definition: uart.c:419
void UART_EnableInt(UART_T *uart, uint32_t u32InterruptFlag)
The function is used to enable UART specified interrupt and disable NVIC UART IRQ.
Definition: uart.c:141
#define UART_BAUD_MODE1
Calculate UART baudrate mode0 divider.
Definition: uart.h:105
#define UART_BAUD_MODE2
Calculate UART baudrate mode0 divider.
Definition: uart.h:115
#define UART_BAUD_MODE0
Calculate UART baudrate mode0 divider.
Definition: uart.h:95
void UART_SetTimeoutCnt(UART_T *uart, uint32_t u32TOC)
This function use to set Rx timeout count.
Definition: uart.c:367
void UART_Close(UART_T *uart)
The function is used to disable UART.
Definition: uart.c:67
#define UART_BAUD_MODE0_DIVIDER(u32SrcFreq, u32BaudRate)
Calculate UART baudrate mode0 divider.
Definition: uart.h:127
void UART_ClearIntFlag(UART_T *uart, uint32_t u32InterruptFlag)
The function is used to clear UART specified interrupt flag.
Definition: uart.c:37
void UART_DisableFlowCtrl(UART_T *uart)
The function is used to disable UART auto flow control.
Definition: uart.c:80
void UART_EnableFlowCtrl(UART_T *uart)
The function is used to Enable UART auto flow control.
Definition: uart.c:116
uint32_t UART_Write(UART_T *uart, uint8_t *pu8TxBuf, uint32_t u32WriteBytes)
The function is to write data into TX buffer to transmit data by UART.
Definition: uart.c:436
#define UART_BAUD_MODE2_DIVIDER(u32SrcFreq, u32BaudRate)
Calculate UART baudrate mode2 divider.
Definition: uart.h:137
void UART_SetLine_Config(UART_T *uart, uint32_t u32baudrate, uint32_t u32data_width, uint32_t u32parity, uint32_t u32stop_bits)
This function use to config UART line setting.
Definition: uart.c:280
void UART_DisableInt(UART_T *uart, uint32_t u32InterruptFlag)
The function is used to disable UART specified interrupt and disable NVIC UART IRQ.
Definition: uart.c:102
void UART_SelectIrDAMode(UART_T *uart, uint32_t u32Buadrate, uint32_t u32Direction)
The function is used to configure IrDA relative settings. It consists of TX or RX mode and baudrate.
Definition: uart.c:383
uint32_t UART_Read(UART_T *uart, uint8_t *pu8RxBuf, uint32_t u32ReadBytes)
The function is used to read Rx data from RX FIFO and the data will be stored in pu8RxBuf.
Definition: uart.c:246
void UART_Open(UART_T *uart, uint32_t u32baudrate)
This function use to enable UART function and set baud-rate.
Definition: uart.c:155
__IO uint32_t INTEN
__IO uint32_t BAUD
__IO uint32_t IRDA
__IO uint32_t DAT
__IO uint32_t FUNSEL
__IO uint32_t MODEMSTS
__IO uint32_t LINE
__IO uint32_t FIFOSTS
__IO uint32_t TOUT
__IO uint32_t FIFO
__IO uint32_t MODEM
__IO uint32_t ALTCTL
__IO uint32_t INTSTS
uint32_t __HSI
#define __XTAL
uint32_t SystemCoreClock