M4521_BSP V3.02.000
The Board Support Package for M4521
scuart.c
Go to the documentation of this file.
1/**************************************************************************/
12#include "M4521.h"
13
35{
36 sc->INTEN = 0;
37 sc->UARTCTL = 0;
38 sc->CTL = 0;
39
40}
41
43
48static uint32_t SCUART_GetClock(SC_T *sc)
49{
50 uint32_t u32ClkSrc, u32Num, u32Clk;
51
52 if(sc == SC0)
53 u32Num = 0;
54#if 0 /* M4521 has only one SC interface */
55 else if(sc == SC1)
56 u32Num = 1;
57 else if(sc == SC2)
58 u32Num = 2;
59 else if(sc == SC3)
60 u32Num = 3;
61 else if(sc == SC4)
62 u32Num = 4;
63 else if(sc == SC5)
64 u32Intf = 5;
65#endif
66 else
67 return FALSE;
68
69 u32ClkSrc = (CLK->CLKSEL3 >> (2 * u32Num)) & CLK_CLKSEL3_SC0SEL_Msk;
70
71 // Get smartcard module clock
72 if(u32ClkSrc == 0)
73 u32Clk = __HXT;
74 else if(u32ClkSrc == 1)
75 u32Clk = CLK_GetPLLClockFreq();
76 else if(u32ClkSrc == 2)
77 {
79 if(CLK->CLKSEL0 & CLK_CLKSEL0_PCLK0SEL_Msk)
80 u32Clk = SystemCoreClock / 2;
81 else
82 u32Clk = SystemCoreClock;
83 }
84 else
85 u32Clk = __HIRC;
86
87#if 0 /* M4521 has only one SC interface */
88 if(u32Num < 4)
89 {
90 u32Clk /= (((CLK->CLKDIV1 >> (8 * u32Num)) & CLK_CLKDIV1_SC0DIV_Msk) + 1);
91 }
92 else
93 {
94 u32Clk /= (((CLK->CLKDIV2 >> (8 * (u32Num - 4))) & CLK_CLKDIV2_SC4DIV_Msk) + 1);
95 }
96#else
97 u32Clk /= (((CLK->CLKDIV1 >> (8 * u32Num)) & CLK_CLKDIV1_SC0DIV_Msk) + 1);
98#endif
99
100 return u32Clk;
101}
103
113uint32_t SCUART_Open(SC_T* sc, uint32_t u32baudrate)
114{
115 uint32_t u32Clk = SCUART_GetClock(sc), u32Div;
116
117 // Calculate divider for target baudrate
118 u32Div = (u32Clk + (u32baudrate >> 1) - 1) / u32baudrate - 1;
119
120 sc->CTL = SC_CTL_SCEN_Msk | SC_CTL_NSB_Msk; // Enable smartcard interface and stop bit = 1
121 sc->UARTCTL = SCUART_CHAR_LEN_8 | SCUART_PARITY_NONE | SC_UARTCTL_UARTEN_Msk; // Enable UART mode, disable parity and 8 bit per character
122 sc->ETUCTL = u32Div;
123
124 return(u32Clk / (u32Div+1));
125}
126
136uint32_t SCUART_Read(SC_T* sc, uint8_t *pu8RxBuf, uint32_t u32ReadBytes)
137{
138 uint32_t u32Count;
139
140 for(u32Count = 0; u32Count < u32ReadBytes; u32Count++)
141 {
142 if(SCUART_GET_RX_EMPTY(sc)) // no data available
143 {
144 break;
145 }
146 pu8RxBuf[u32Count] = SCUART_READ(sc); // get data from FIFO
147 }
148
149 return u32Count;
150}
151
171uint32_t SCUART_SetLineConfig(SC_T* sc, uint32_t u32Baudrate, uint32_t u32DataWidth, uint32_t u32Parity, uint32_t u32StopBits)
172{
173
174 uint32_t u32Clk = SCUART_GetClock(sc), u32Div;
175
176 if(u32Baudrate == 0) // keep original baudrate setting
177 {
178 u32Div = sc->ETUCTL & SC_ETUCTL_ETURDIV_Msk;
179 }
180 else
181 {
182 // Calculate divider for target baudrate
183 u32Div = (u32Clk + (u32Baudrate >> 1) - 1) / u32Baudrate - 1;
184 sc->ETUCTL = u32Div;
185 }
186
187 sc->CTL = u32StopBits | SC_CTL_SCEN_Msk; // Set stop bit
188 sc->UARTCTL = u32Parity | u32DataWidth | SC_UARTCTL_UARTEN_Msk; // Set character width and parity
189
190 return(u32Clk / (u32Div+1));
191}
192
203void SCUART_SetTimeoutCnt(SC_T* sc, uint32_t u32TOC)
204{
205 sc->RXTOUT = u32TOC;
206}
207
208
218uint32_t SCUART_Write(SC_T* sc, uint8_t *pu8TxBuf, uint32_t u32WriteBytes)
219{
220 uint32_t u32Count;
221 /* Baudrate * (start bit + 8-bit data + 1-bit parity + 2-bit stop) */
222 uint32_t u32Delay = (SystemCoreClock / SCUART_GetClock(sc)) * sc->ETUCTL * 12, i;
223
224 for(u32Count = 0; u32Count != u32WriteBytes; u32Count++)
225 {
226 while(SCUART_GET_TX_FULL(sc)) // Wait 'til FIFO not full
227 {
228 /* Block longer than expected. Maybe some interrupt disable SCUART clock? */
229 if(i++ > u32Delay)
230 {
232 return u32Count;
233 }
234 }
235 sc->DAT = pu8TxBuf[u32Count]; // Write 1 byte to FIFO
236 }
237 return u32Count;
238}
239
240 /* end of group SCUART_EXPORTED_FUNCTIONS */
242 /* end of group SCUART_Driver */
244 /* end of group Standard_Driver */
246
247/*** (C) COPYRIGHT 2022 Nuvoton Technology Corp. ***/
#define SC_CTL_NSB_Msk
Definition: M4521.h:8550
#define SC_ETUCTL_ETURDIV_Msk
Definition: M4521.h:8628
#define SC_CTL_SCEN_Msk
Definition: M4521.h:8526
#define SC_UARTCTL_UARTEN_Msk
Definition: M4521.h:8814
__STATIC_INLINE uint32_t CLK_GetPLLClockFreq(void)
Get PLL clock frequency.
Definition: clk.h:332
#define CLK_CLKSEL3_SC0SEL_Msk
Definition: M4521.h:1617
#define CLK_CLKDIV1_SC0DIV_Msk
Definition: M4521.h:1635
#define CLK_CLKSEL0_PCLK0SEL_Msk
Definition: M4521.h:1572
__IO uint32_t DAT
Definition: M4521.h:8496
__IO uint32_t ETUCTL
Definition: M4521.h:8501
#define CLK
Definition: M4521.h:13822
__IO uint32_t INTEN
Definition: M4521.h:8502
__IO uint32_t CTL
Definition: M4521.h:8497
#define FALSE
Definition: M4521.h:13908
__IO uint32_t UARTCTL
Definition: M4521.h:8509
__IO uint32_t RXTOUT
Definition: M4521.h:8500
#define SC0
Definition: M4521.h:13856
int32_t g_SCUART_i32ErrCode
Definition: scuart.c:22
#define SCUART_CHAR_LEN_8
Definition: scuart.h:35
#define SCUART_PARITY_NONE
Definition: scuart.h:37
#define SCUART_TIMEOUT_ERR
Definition: scuart.h:44
void SCUART_SetTimeoutCnt(SC_T *sc, uint32_t u32TOC)
This function use to set receive timeout count.
Definition: scuart.c:203
#define SCUART_GET_TX_FULL(sc)
Get TX FIFO full flag status from register.
Definition: scuart.h:85
uint32_t SCUART_Read(SC_T *sc, uint8_t *pu8RxBuf, uint32_t u32ReadBytes)
Read data from smartcard UART interface.
Definition: scuart.c:136
#define SCUART_GET_RX_EMPTY(sc)
Get RX FIFO empty flag status from register.
Definition: scuart.h:139
#define SCUART_READ(sc)
Read Rx data register.
Definition: scuart.h:128
uint32_t SCUART_SetLineConfig(SC_T *sc, uint32_t u32Baudrate, uint32_t u32DataWidth, uint32_t u32Parity, uint32_t u32StopBits)
This function use to config smartcard UART mode line setting.
Definition: scuart.c:171
uint32_t SCUART_Open(SC_T *sc, uint32_t u32baudrate)
Enable smartcard uart interface.
Definition: scuart.c:113
uint32_t SCUART_Write(SC_T *sc, uint8_t *pu8TxBuf, uint32_t u32WriteBytes)
Write data to smartcard UART interface.
Definition: scuart.c:218
void SCUART_Close(SC_T *sc)
Disable smartcard uart interface.
Definition: scuart.c:34
Definition: M4521.h:7895
#define __HIRC
Definition: system_M4521.h:37
#define __HXT
Definition: system_M4521.h:35
uint32_t SystemCoreClock
Definition: system_M4521.c:24
void SystemCoreClockUpdate(void)
Updates the SystemCoreClock with current core Clock retrieved from cpu registers.
Definition: system_M4521.c:32