1 /**************************************************************************//**
\r
4 * @brief Smartcard UART mode (SCUART) driver source file
\r
6 * @copyright (C) 2016 Nuvoton Technology Corp. All rights reserved.
\r
7 *****************************************************************************/
\r
10 static uint32_t SCUART_GetClock(SC_T *sc);
\r
12 /** @addtogroup Standard_Driver Standard Driver
\r
16 /** @addtogroup SCUART_Driver SCUART Driver
\r
20 /** @addtogroup SCUART_EXPORTED_FUNCTIONS SCUART Exported Functions
\r
25 * @brief Disable smartcard interface
\r
27 * @param sc The pointer of smartcard module.
\r
31 * @details The function is used to disable smartcard interface UART mode.
\r
33 void SCUART_Close(SC_T* sc)
\r
40 /** @cond HIDDEN_SYMBOLS */
\r
42 * @brief Returns module clock of specified SC interface
\r
44 * @param[in] sc The pointer of smartcard module.
\r
46 * @return Module clock of specified SC interface.
\r
48 static uint32_t SCUART_GetClock(SC_T *sc)
\r
50 uint32_t u32ClkSrc, u32Num, u32Clk = __HIRC, u32Div;
\r
52 /* Get smartcard module clock source and divider */
\r
53 if((sc == SC0) || (sc == SC0_NS))
\r
56 u32ClkSrc = CLK_GetModuleClockSource(SC0_MODULE);
\r
57 u32Div = CLK_GetModuleClockDivider(SC0_MODULE);
\r
59 else if((sc == SC1) || (sc == SC1_NS))
\r
62 u32ClkSrc = CLK_GetModuleClockSource(SC1_MODULE);
\r
63 u32Div = CLK_GetModuleClockDivider(SC1_MODULE);
\r
65 else if((sc == SC2) || (sc == SC2_NS))
\r
68 u32ClkSrc = CLK_GetModuleClockSource(SC2_MODULE);
\r
69 u32Div = CLK_GetModuleClockDivider(SC2_MODULE);
\r
78 ; /* Invalid sc port */
\r
82 /* Get smartcard module clock */
\r
83 if(u32ClkSrc == 0UL)
\r
87 else if(u32ClkSrc == 1UL)
\r
89 u32Clk = CLK_GetPLLClockFreq();
\r
91 else if(u32ClkSrc == 2UL)
\r
95 u32Clk = CLK_GetPCLK1Freq();
\r
99 u32Clk = CLK_GetPCLK0Freq();
\r
107 u32Clk /= (u32Div + 1UL);
\r
112 /** @endcond HIDDEN_SYMBOLS */
\r
115 * @brief Enable smartcard module UART mode and set baudrate
\r
117 * @param[in] sc The pointer of smartcard module.
\r
118 * @param[in] u32Baudrate Target baudrate of smartcard UART module.
\r
120 * @return Actual baudrate of smartcard UART mode
\r
122 * @details This function use to enable smartcard module UART mode and set baudrate.
\r
124 * @note This function configures character width to 8 bits, 1 stop bit, and no parity.
\r
125 * And can use \ref SCUART_SetLineConfig function to update these settings.
\r
126 * The baudrate clock source comes from SC_CLK/SC_DIV, where SC_CLK is controlled
\r
127 * by SCxSEL in CLKSEL3 register, SC_DIV is controlled by SCxDIV in CLKDIV1
\r
128 * register. Since the baudrate divider is 12-bit wide and must be larger than 4,
\r
129 * (clock source / baudrate) must be larger or equal to 5 and smaller or equal to
\r
130 * 4096. Otherwise this function cannot configure SCUART to work with target baudrate.
\r
132 uint32_t SCUART_Open(SC_T* sc, uint32_t u32Baudrate)
\r
134 uint32_t u32Clk = SCUART_GetClock(sc), u32Div;
\r
136 /* Calculate divider for target baudrate */
\r
137 u32Div = (u32Clk + (u32Baudrate >> 1) - 1UL) / u32Baudrate - 1UL;
\r
139 sc->CTL = SC_CTL_SCEN_Msk | SC_CTL_NSB_Msk; /* Enable smartcard interface and stop bit = 1 */
\r
140 sc->UARTCTL = SCUART_CHAR_LEN_8 | SCUART_PARITY_NONE | SC_UARTCTL_UARTEN_Msk; /* Enable UART mode, disable parity and 8 bit per character */
\r
141 sc->ETUCTL = u32Div;
\r
143 return(u32Clk / (u32Div + 1UL));
\r
147 * @brief Read Rx data from Rx FIFO
\r
149 * @param[in] sc The pointer of smartcard module.
\r
150 * @param[in] pu8RxBuf The buffer to store receive the data.
\r
151 * @param[in] u32ReadBytes Target number of characters to receive
\r
153 * @return Actual character number reads to buffer
\r
155 * @details The function is used to read data from Rx FIFO.
\r
157 * @note This function does not block and return immediately if there's no data available.
\r
159 uint32_t SCUART_Read(SC_T* sc, uint8_t pu8RxBuf[], uint32_t u32ReadBytes)
\r
163 for(u32Count = 0UL; u32Count < u32ReadBytes; u32Count++)
\r
165 if(SCUART_GET_RX_EMPTY(sc)) /* no data available */
\r
169 pu8RxBuf[u32Count] = (uint8_t)SCUART_READ(sc); /* get data from FIFO */
\r
176 * @brief Configure smartcard UART mode line setting
\r
178 * @param[in] sc The pointer of smartcard module.
\r
179 * @param[in] u32Baudrate Target baudrate of smartcard UART mode. If this value is 0, SC UART baudrate will not change.
\r
180 * @param[in] u32DataWidth The data length, could be:
\r
181 * - \ref SCUART_CHAR_LEN_5
\r
182 * - \ref SCUART_CHAR_LEN_6
\r
183 * - \ref SCUART_CHAR_LEN_7
\r
184 * - \ref SCUART_CHAR_LEN_8
\r
185 * @param[in] u32Parity The parity setting, could be:
\r
186 * - \ref SCUART_PARITY_NONE
\r
187 * - \ref SCUART_PARITY_ODD
\r
188 * - \ref SCUART_PARITY_EVEN
\r
189 * @param[in] u32StopBits The stop bit length, could be:
\r
190 * - \ref SCUART_STOP_BIT_1
\r
191 * - \ref SCUART_STOP_BIT_2
\r
193 * @return Actual baudrate of smartcard UART mode
\r
195 * @details The baudrate clock source comes from SC_CLK/SC_DIV, where SC_CLK is controlled
\r
196 * by SCxSEL in CLKSEL3 register, SC_DIV is controlled by SCxDIV in CLKDIV1
\r
197 * register. Since the baudrate divider is 12-bit wide and must be larger than 4,
\r
198 * (clock source / baudrate) must be larger or equal to 5 and smaller or equal to
\r
199 * 4096. Otherwise this function cannot configure SCUART to work with target baudrate.
\r
201 uint32_t SCUART_SetLineConfig(SC_T* sc, uint32_t u32Baudrate, uint32_t u32DataWidth, uint32_t u32Parity, uint32_t u32StopBits)
\r
203 uint32_t u32Clk = SCUART_GetClock(sc), u32Div;
\r
205 if(u32Baudrate == 0UL)
\r
207 /* Keep original baudrate setting */
\r
208 u32Div = sc->ETUCTL & SC_ETUCTL_ETURDIV_Msk;
\r
212 /* Calculate divider for target baudrate */
\r
213 u32Div = ((u32Clk + (u32Baudrate >> 1) - 1UL) / u32Baudrate) - 1UL;
\r
214 sc->ETUCTL = u32Div;
\r
217 sc->CTL = u32StopBits | SC_CTL_SCEN_Msk; /* Set stop bit */
\r
218 sc->UARTCTL = u32Parity | u32DataWidth | SC_UARTCTL_UARTEN_Msk; /* Set character width and parity */
\r
220 return (u32Clk / (u32Div + 1UL));
\r
224 * @brief Set receive timeout count
\r
226 * @param[in] sc The pointer of smartcard module.
\r
227 * @param[in] u32TOC Rx time-out counter, using baudrate as counter unit. Valid range are 0~0x1FF,
\r
228 * set this value to 0 will disable time-out counter.
\r
232 * @details The time-out counter resets and starts counting whenever the Rx buffer received a
\r
233 * new data word. Once the counter decrease to 1 and no new data is received or CPU
\r
234 * does not read any data from FIFO, a receiver time-out interrupt will be generated.
\r
236 void SCUART_SetTimeoutCnt(SC_T* sc, uint32_t u32TOC)
\r
238 sc->RXTOUT = u32TOC;
\r
242 * @brief Write data into transmit FIFO to send data out
\r
244 * @param[in] sc The pointer of smartcard module.
\r
245 * @param[in] pu8TxBuf The buffer containing data to send to transmit FIFO.
\r
246 * @param[in] u32WriteBytes Number of data to send.
\r
250 * @details This function is used to write data into Tx FIFO to send data out.
\r
252 * @note This function blocks until all data write into FIFO.
\r
254 void SCUART_Write(SC_T* sc, uint8_t pu8TxBuf[], uint32_t u32WriteBytes)
\r
258 for(u32Count = 0UL; u32Count != u32WriteBytes; u32Count++)
\r
260 /* Wait 'til FIFO not full */
\r
261 while(SCUART_GET_TX_FULL(sc))
\r
265 /* Write 1 byte to FIFO */
\r
266 sc->DAT = pu8TxBuf[u32Count]; /* Write 1 byte to FIFO */
\r
271 /*@}*/ /* end of group SCUART_EXPORTED_FUNCTIONS */
\r
273 /*@}*/ /* end of group SCUART_Driver */
\r
275 /*@}*/ /* end of group Standard_Driver */
\r
277 /*** (C) COPYRIGHT 2016 Nuvoton Technology Corp. ***/
\r