1 /**************************************************************************//**
2  * @file     sc.h
3  * @version  V3.00
4  * @brief    Smartcard(SC) driver header file
5  *
6  * @copyright SPDX-License-Identifier: Apache-2.0
7  * @copyright Copyright (C) 2021 Nuvoton Technology Corp. All rights reserved.
8  *****************************************************************************/
9 #ifndef __SC_H__
10 #define __SC_H__
11 
12 #ifdef __cplusplus
13 extern "C"
14 {
15 #endif
16 
17 
18 /** @addtogroup Standard_Driver Standard Driver
19   @{
20 */
21 
22 /** @addtogroup SC_Driver SC Driver
23   @{
24 */
25 
26 /** @addtogroup SC_EXPORTED_CONSTANTS SC Exported Constants
27   @{
28 */
29 #define SC_INTERFACE_NUM                (3UL)               /*!< Smartcard interface numbers \hideinitializer */
30 #define SC_PIN_STATE_HIGH               (1UL)               /*!< Smartcard pin status high   \hideinitializer */
31 #define SC_PIN_STATE_LOW                (0UL)               /*!< Smartcard pin status low    \hideinitializer */
32 #define SC_PIN_STATE_IGNORE             (0xFFFFFFFFUL)      /*!< Ignore pin status           \hideinitializer */
33 #define SC_CLK_ON                       (1UL)               /*!< Smartcard clock on          \hideinitializer */
34 #define SC_CLK_OFF                      (0UL)               /*!< Smartcard clock off         \hideinitializer */
35 
36 #define SC_TMR_MODE_0                   (0UL << SC_TMRCTL0_OPMODE_Pos)      /*!<Timer Operation Mode 0, down count                                                      \hideinitializer */
37 #define SC_TMR_MODE_1                   (1UL << SC_TMRCTL0_OPMODE_Pos)      /*!<Timer Operation Mode 1, down count, start after detect start bit                        \hideinitializer */
38 #define SC_TMR_MODE_2                   (2UL << SC_TMRCTL0_OPMODE_Pos)      /*!<Timer Operation Mode 2, down count, start after receive start bit                       \hideinitializer */
39 #define SC_TMR_MODE_3                   (3UL << SC_TMRCTL0_OPMODE_Pos)      /*!<Timer Operation Mode 3, down count, use for activation, only timer 0 support this mode  \hideinitializer */
40 #define SC_TMR_MODE_4                   (4UL << SC_TMRCTL0_OPMODE_Pos)      /*!<Timer Operation Mode 4, down count with reload after timeout                            \hideinitializer */
41 #define SC_TMR_MODE_5                   (5UL << SC_TMRCTL0_OPMODE_Pos)      /*!<Timer Operation Mode 5, down count, start after detect start bit, reload after timeout  \hideinitializer */
42 #define SC_TMR_MODE_6                   (6UL << SC_TMRCTL0_OPMODE_Pos)      /*!<Timer Operation Mode 6, down count, start after receive start bit, reload after timeout \hideinitializer */
43 #define SC_TMR_MODE_7                   (7UL << SC_TMRCTL0_OPMODE_Pos)      /*!<Timer Operation Mode 7, down count, start and reload after detect start bit             \hideinitializer */
44 #define SC_TMR_MODE_8                   (8UL << SC_TMRCTL0_OPMODE_Pos)      /*!<Timer Operation Mode 8, up count                                                        \hideinitializer */
45 #define SC_TMR_MODE_F                   (0xFUL << SC_TMRCTL0_OPMODE_Pos)    /*!<Timer Operation Mode 15, down count, reload after detect start bit                      \hideinitializer */
46 
47 #define SC_TIMEOUT                      (SystemCoreClock)   /*!< SC time-out counter (1 second time-out) \hideinitializer */
48 
49 /**@}*/ /* end of group SC_EXPORTED_CONSTANTS */
50 
51 
52 /** @addtogroup SC_EXPORTED_FUNCTIONS SC Exported Functions
53   @{
54 */
55 
56 /**
57   * @brief      This macro enable smartcard interrupt
58   *
59   * @param[in]  sc      The pointer of smartcard module.
60   * @param[in]  u32Mask Interrupt mask to be enabled. A combination of
61   *                         - \ref SC_INTEN_ACERRIEN_Msk
62   *                         - \ref SC_INTEN_RXTOIEN_Msk
63   *                         - \ref SC_INTEN_INITIEN_Msk
64   *                         - \ref SC_INTEN_CDIEN_Msk
65   *                         - \ref SC_INTEN_BGTIEN_Msk
66   *                         - \ref SC_INTEN_TMR2IEN_Msk
67   *                         - \ref SC_INTEN_TMR1IEN_Msk
68   *                         - \ref SC_INTEN_TMR0IEN_Msk
69   *                         - \ref SC_INTEN_TERRIEN_Msk
70   *                         - \ref SC_INTEN_TBEIEN_Msk
71   *                         - \ref SC_INTEN_RDAIEN_Msk
72   *
73   * @return     None
74   *
75   * @details    The macro is used to enable Auto-convention error interrupt, Receiver buffer time-out interrupt, Initial end interrupt,
76   *             Card detect interrupt, Block guard time interrupt, Timer2 interrupt, Timer1 interrupt, Timer0 interrupt,
77   *             Transfer error interrupt, Transmit buffer empty interrupt or Receive data reach trigger level interrupt.
78   * \hideinitializer
79   */
80 #define SC_ENABLE_INT(sc, u32Mask)      ((sc)->INTEN |= (u32Mask))
81 
82 /**
83   * @brief      This macro disable smartcard interrupt
84   *
85   * @param[in]  sc      The pointer of smartcard module.
86   * @param[in]  u32Mask Interrupt mask to be disabled. A combination of
87   *                         - \ref SC_INTEN_ACERRIEN_Msk
88   *                         - \ref SC_INTEN_RXTOIEN_Msk
89   *                         - \ref SC_INTEN_INITIEN_Msk
90   *                         - \ref SC_INTEN_CDIEN_Msk
91   *                         - \ref SC_INTEN_BGTIEN_Msk
92   *                         - \ref SC_INTEN_TMR2IEN_Msk
93   *                         - \ref SC_INTEN_TMR1IEN_Msk
94   *                         - \ref SC_INTEN_TMR0IEN_Msk
95   *                         - \ref SC_INTEN_TERRIEN_Msk
96   *                         - \ref SC_INTEN_TBEIEN_Msk
97   *                         - \ref SC_INTEN_RDAIEN_Msk
98   *
99   * @return     None
100   *
101   * @details    The macro is used to disable Auto-convention error interrupt, Receiver buffer time-out interrupt, Initial end interrupt,
102   *             Card detect interrupt, Block guard time interrupt, Timer2 interrupt, Timer1 interrupt, Timer0 interrupt,
103   *             Transfer error interrupt, Transmit buffer empty interrupt or Receive data reach trigger level interrupt.
104   * \hideinitializer
105   */
106 #define SC_DISABLE_INT(sc, u32Mask)     ((sc)->INTEN &= ~(u32Mask))
107 
108 /**
109   * @brief      This macro set VCC pin state of smartcard interface
110   *
111   * @param[in]  sc          The pointer of smartcard module.
112   * @param[in]  u32State    Pin state of VCC pin, valid parameters are \ref SC_PIN_STATE_HIGH and \ref SC_PIN_STATE_LOW.
113   *
114   * @return     None
115   *
116   * @details    User can set PWREN (SC_PINCTL[0]) and PWRINV (SC_PINCTL[11]) to decide SC_PWR pin is in high or low level.
117   * \hideinitializer
118   */
119 #define SC_SET_VCC_PIN(sc, u32State) \
120     do {\
121             uint32_t u32TimeOutCount = SC_TIMEOUT;\
122             while(((sc)->PINCTL & SC_PINCTL_SYNC_Msk) == SC_PINCTL_SYNC_Msk)\
123                 if(--u32TimeOutCount == 0) break;\
124             if(u32State)\
125                 (sc)->PINCTL |= SC_PINCTL_PWREN_Msk;\
126             else\
127                 (sc)->PINCTL &= ~SC_PINCTL_PWREN_Msk;\
128     }while(0)
129 
130 
131 /**
132   * @brief      This macro turns CLK output on or off
133   *
134   * @param[in]  sc          The pointer of smartcard module.
135   * @param[in] u32OnOff     Clock on or off for selected smartcard module, valid values are \ref SC_CLK_ON and \ref SC_CLK_OFF.
136   *
137   * @return     None
138   *
139   * @details    User can set CLKKEEP (SC_PINCTL[6]) to decide SC_CLK pin always keeps free running or not.
140   * \hideinitializer
141   */
142 #define SC_SET_CLK_PIN(sc, u32OnOff)\
143     do {\
144             uint32_t u32TimeOutCount = SC_TIMEOUT;\
145             while(((sc)->PINCTL & SC_PINCTL_SYNC_Msk) == SC_PINCTL_SYNC_Msk)\
146                 if(--u32TimeOutCount == 0) break;\
147             if(u32OnOff)\
148                 (sc)->PINCTL |= SC_PINCTL_CLKKEEP_Msk;\
149             else\
150                 (sc)->PINCTL &= ~(SC_PINCTL_CLKKEEP_Msk);\
151     }while(0)
152 
153 /**
154   * @brief      This macro set I/O pin state of smartcard interface
155   *
156   * @param[in]  sc          The pointer of smartcard module.
157   * @param[in] u32State     Pin state of I/O pin, valid parameters are \ref SC_PIN_STATE_HIGH and \ref SC_PIN_STATE_LOW.
158   *
159   * @return     None
160   *
161   * @details    User can set SCDATA (SC_PINCTL[9]) to decide SC_DATA pin to high or low.
162   * \hideinitializer
163   */
164 #define SC_SET_IO_PIN(sc, u32State)\
165     do {\
166             uint32_t u32TimeOutCount = SC_TIMEOUT;\
167             while(((sc)->PINCTL & SC_PINCTL_SYNC_Msk) == SC_PINCTL_SYNC_Msk)\
168                 if(--u32TimeOutCount == 0) break;\
169             if(u32State)\
170                 (sc)->PINCTL |= SC_PINCTL_SCDATA_Msk;\
171             else\
172                 (sc)->PINCTL &= ~SC_PINCTL_SCDATA_Msk;\
173     }while(0)
174 
175 /**
176   * @brief      This macro set RST pin state of smartcard interface
177   *
178   * @param[in]  sc          The pointer of smartcard module.
179   * @param[in] u32State     Pin state of RST pin, valid parameters are \ref SC_PIN_STATE_HIGH and \ref SC_PIN_STATE_LOW.
180   *
181   * @return     None
182   *
183   * @details    User can set SCRST (SC_PINCTL[1]) to decide SC_RST pin to high or low.
184   * \hideinitializer
185   */
186 #define SC_SET_RST_PIN(sc, u32State)\
187     do {\
188             uint32_t u32TimeOutCount = SC_TIMEOUT;\
189             while(((sc)->PINCTL & SC_PINCTL_SYNC_Msk) == SC_PINCTL_SYNC_Msk)\
190                 if(--u32TimeOutCount == 0) break;\
191             if(u32State)\
192                 (sc)->PINCTL |= SC_PINCTL_RSTEN_Msk;\
193             else\
194                 (sc)->PINCTL &= ~SC_PINCTL_RSTEN_Msk;\
195     }while(0)
196 
197 /**
198   * @brief      This macro read one byte from smartcard module receive FIFO
199   *
200   * @param[in]  sc      The pointer of smartcard module.
201   *
202   * @return     One byte read from receive FIFO
203   *
204   * @details    By reading DAT register, the SC will return an 8-bit received data.
205   * \hideinitializer
206   */
207 #define SC_READ(sc)             ((char)((sc)->DAT))
208 
209 /**
210   * @brief      This macro write one byte to smartcard module transmit FIFO
211   *
212   * @param[in]  sc      The pointer of smartcard module.
213   * @param[in]  u8Data  Data to write to transmit FIFO.
214   *
215   * @return     None
216   *
217   * @details    By writing data to DAT register, the SC will send out an 8-bit data.
218   * \hideinitializer
219   */
220 #define SC_WRITE(sc, u8Data)    ((sc)->DAT = (u8Data))
221 
222 /**
223   * @brief      This macro set smartcard stop bit length
224   *
225   * @param[in]  sc      The pointer of smartcard module.
226   * @param[in]  u32Len  Stop bit length, ether 1 or 2.
227   *
228   * @return     None
229   *
230   * @details    Stop bit length must be 1 for T = 1 protocol and 2 for T = 0 protocol.
231   * \hideinitializer
232   */
233 #define SC_SET_STOP_BIT_LEN(sc, u32Len) ((sc)->CTL = ((sc)->CTL & ~SC_CTL_NSB_Msk) | (((u32Len) == 1)? SC_CTL_NSB_Msk : 0))
234 
235 
236 /*---------------------------------------------------------------------------------------------------------*/
237 /* static inline functions                                                                                 */
238 /*---------------------------------------------------------------------------------------------------------*/
239 /* Declare these inline functions here to avoid MISRA C 2004 rule 8.1 error */
240 __STATIC_INLINE void SC_SetTxRetry(SC_T *sc, uint32_t u32Count);
241 __STATIC_INLINE void SC_SetRxRetry(SC_T *sc, uint32_t u32Count);
242 
243 
244 /**
245   * @brief      Enable/Disable Tx error retry, and set Tx error retry count
246   *
247   * @param[in]  sc          The pointer of smartcard module.
248   * @param[in]  u32Count    The number of times of Tx error retry count, between 0~8. 0 means disable Tx error retry.
249   *
250   * @return     None
251   *
252   * @details    This function is used to enable/disable transmitter retry function when parity error has occurred, and set error retry count.
253   */
SC_SetTxRetry(SC_T * sc,uint32_t u32Count)254 __STATIC_INLINE void SC_SetTxRetry(SC_T *sc, uint32_t u32Count)
255 {
256     uint32_t u32TimeOutCount = 0;
257 
258     u32TimeOutCount = SC_TIMEOUT;
259     while(((sc)->CTL & SC_CTL_SYNC_Msk) == SC_CTL_SYNC_Msk)
260     {
261         if(--u32TimeOutCount == 0) break;
262     }
263 
264     /* Retry count must set while enable bit disabled, so disable it first */
265     (sc)->CTL &= ~(SC_CTL_TXRTY_Msk | SC_CTL_TXRTYEN_Msk);
266 
267     if((u32Count) != 0UL)
268     {
269         u32TimeOutCount = SC_TIMEOUT;
270         while(((sc)->CTL & SC_CTL_SYNC_Msk) == SC_CTL_SYNC_Msk)
271         {
272             if(--u32TimeOutCount == 0) break;
273         }
274         (sc)->CTL |= (((u32Count) - 1UL) << SC_CTL_TXRTY_Pos) | SC_CTL_TXRTYEN_Msk;
275     }
276 }
277 
278 /**
279   * @brief      Enable/Disable Rx error retry, and set Rx error retry count
280   *
281   * @param[in]  sc          The pointer of smartcard module.
282   * @param[in]  u32Count    The number of times of Rx error retry count, between 0~8. 0 means disable Rx error retry.
283   *
284   * @return     None
285   *
286   * @details    This function is used to enable/disable receiver retry function when parity error has occurred, and set error retry count.
287   */
SC_SetRxRetry(SC_T * sc,uint32_t u32Count)288 __STATIC_INLINE void SC_SetRxRetry(SC_T *sc, uint32_t u32Count)
289 {
290     uint32_t u32TimeOutCount = 0;
291 
292     u32TimeOutCount = SC_TIMEOUT;
293     while(((sc)->CTL & SC_CTL_SYNC_Msk) == SC_CTL_SYNC_Msk)
294     {
295         if(--u32TimeOutCount == 0) break;
296     }
297 
298     /* Retry count must set while enable bit disabled, so disable it first */
299     (sc)->CTL &= ~(SC_CTL_RXRTY_Msk | SC_CTL_RXRTYEN_Msk);
300 
301     if((u32Count) != 0UL)
302     {
303         u32TimeOutCount = SC_TIMEOUT;
304         while(((sc)->CTL & SC_CTL_SYNC_Msk) == SC_CTL_SYNC_Msk)
305         {
306             if(--u32TimeOutCount == 0) break;
307         }
308         (sc)->CTL |= (((u32Count) - 1UL) << SC_CTL_RXRTY_Pos) | SC_CTL_RXRTYEN_Msk;
309     }
310 }
311 
312 
313 uint32_t SC_IsCardInserted(SC_T *sc);
314 void SC_ClearFIFO(SC_T *sc);
315 void SC_Close(SC_T *sc);
316 void SC_Open(SC_T *sc, uint32_t u32CardDet, uint32_t u32PWR);
317 void SC_ResetReader(SC_T *sc);
318 void SC_SetBlockGuardTime(SC_T *sc, uint32_t u32BGT);
319 void SC_SetCharGuardTime(SC_T *sc, uint32_t u32CGT);
320 void SC_StopAllTimer(SC_T *sc);
321 void SC_StartTimer(SC_T *sc, uint32_t u32TimerNum, uint32_t u32Mode, uint32_t u32ETUCount);
322 void SC_StopTimer(SC_T *sc, uint32_t u32TimerNum);
323 uint32_t SC_GetInterfaceClock(SC_T *sc);
324 
325 /**@}*/ /* end of group SC_EXPORTED_FUNCTIONS */
326 
327 /**@}*/ /* end of group SC_Driver */
328 
329 /**@}*/ /* end of group Standard_Driver */
330 
331 #ifdef __cplusplus
332 }
333 #endif
334 
335 #endif /* __SC_H__ */
336