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) 2020 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 /**@}*/ /* end of group SC_EXPORTED_CONSTANTS */
48 
49 
50 /** @addtogroup SC_EXPORTED_FUNCTIONS SC Exported Functions
51   @{
52 */
53 
54 /**
55   * @brief      This macro enable smartcard interrupt
56   *
57   * @param[in]  sc      The pointer of smartcard module.
58   * @param[in]  u32Mask Interrupt mask to be enabled. A combination of
59   *                         - \ref SC_INTEN_ACERRIEN_Msk
60   *                         - \ref SC_INTEN_RXTOIEN_Msk
61   *                         - \ref SC_INTEN_INITIEN_Msk
62   *                         - \ref SC_INTEN_CDIEN_Msk
63   *                         - \ref SC_INTEN_BGTIEN_Msk
64   *                         - \ref SC_INTEN_TMR2IEN_Msk
65   *                         - \ref SC_INTEN_TMR1IEN_Msk
66   *                         - \ref SC_INTEN_TMR0IEN_Msk
67   *                         - \ref SC_INTEN_TERRIEN_Msk
68   *                         - \ref SC_INTEN_TBEIEN_Msk
69   *                         - \ref SC_INTEN_RDAIEN_Msk
70   *
71   * @return     None
72   *
73   * @details    The macro is used to enable Auto-convention error interrupt, Receiver buffer time-out interrupt, Initial end interrupt,
74   *             Card detect interrupt, Block guard time interrupt, Timer2 interrupt, Timer1 interrupt, Timer0 interrupt,
75   *             Transfer error interrupt, Transmit buffer empty interrupt or Receive data reach trigger level interrupt.
76   * \hideinitializer
77   */
78 #define SC_ENABLE_INT(sc, u32Mask)      ((sc)->INTEN |= (u32Mask))
79 
80 /**
81   * @brief      This macro disable smartcard interrupt
82   *
83   * @param[in]  sc      The pointer of smartcard module.
84   * @param[in]  u32Mask Interrupt mask to be disabled. A combination of
85   *                         - \ref SC_INTEN_ACERRIEN_Msk
86   *                         - \ref SC_INTEN_RXTOIEN_Msk
87   *                         - \ref SC_INTEN_INITIEN_Msk
88   *                         - \ref SC_INTEN_CDIEN_Msk
89   *                         - \ref SC_INTEN_BGTIEN_Msk
90   *                         - \ref SC_INTEN_TMR2IEN_Msk
91   *                         - \ref SC_INTEN_TMR1IEN_Msk
92   *                         - \ref SC_INTEN_TMR0IEN_Msk
93   *                         - \ref SC_INTEN_TERRIEN_Msk
94   *                         - \ref SC_INTEN_TBEIEN_Msk
95   *                         - \ref SC_INTEN_RDAIEN_Msk
96   *
97   * @return     None
98   *
99   * @details    The macro is used to disable Auto-convention error interrupt, Receiver buffer time-out interrupt, Initial end interrupt,
100   *             Card detect interrupt, Block guard time interrupt, Timer2 interrupt, Timer1 interrupt, Timer0 interrupt,
101   *             Transfer error interrupt, Transmit buffer empty interrupt or Receive data reach trigger level interrupt.
102   * \hideinitializer
103   */
104 #define SC_DISABLE_INT(sc, u32Mask)     ((sc)->INTEN &= ~(u32Mask))
105 
106 /**
107   * @brief      This macro set VCC pin state of smartcard interface
108   *
109   * @param[in]  sc          The pointer of smartcard module.
110   * @param[in]  u32State    Pin state of VCC pin, valid parameters are \ref SC_PIN_STATE_HIGH and \ref SC_PIN_STATE_LOW.
111   *
112   * @return     None
113   *
114   * @details    User can set PWREN (SC_PINCTL[0]) and PWRINV (SC_PINCTL[11]) to decide SC_PWR pin is in high or low level.
115   * \hideinitializer
116   */
117 #define SC_SET_VCC_PIN(sc, u32State) \
118     do {\
119             while(((sc)->PINCTL & SC_PINCTL_SYNC_Msk) == SC_PINCTL_SYNC_Msk);\
120             if(u32State)\
121                 (sc)->PINCTL |= SC_PINCTL_PWREN_Msk;\
122             else\
123                 (sc)->PINCTL &= ~SC_PINCTL_PWREN_Msk;\
124     }while(0)
125 
126 
127 /**
128   * @brief      This macro turns CLK output on or off
129   *
130   * @param[in]  sc          The pointer of smartcard module.
131   * @param[in] u32OnOff     Clock on or off for selected smartcard module, valid values are \ref SC_CLK_ON and \ref SC_CLK_OFF.
132   *
133   * @return     None
134   *
135   * @details    User can set CLKKEEP (SC_PINCTL[6]) to decide SC_CLK pin always keeps free running or not.
136   * \hideinitializer
137   */
138 #define SC_SET_CLK_PIN(sc, u32OnOff)\
139     do {\
140             while(((sc)->PINCTL & SC_PINCTL_SYNC_Msk) == SC_PINCTL_SYNC_Msk);\
141             if(u32OnOff)\
142                 (sc)->PINCTL |= SC_PINCTL_CLKKEEP_Msk;\
143             else\
144                 (sc)->PINCTL &= ~(SC_PINCTL_CLKKEEP_Msk);\
145     }while(0)
146 
147 /**
148   * @brief      This macro set I/O pin state of smartcard interface
149   *
150   * @param[in]  sc          The pointer of smartcard module.
151   * @param[in] u32State     Pin state of I/O pin, valid parameters are \ref SC_PIN_STATE_HIGH and \ref SC_PIN_STATE_LOW.
152   *
153   * @return     None
154   *
155   * @details    User can set SCDATA (SC_PINCTL[9]) to decide SC_DATA pin to high or low.
156   * \hideinitializer
157   */
158 #define SC_SET_IO_PIN(sc, u32State)\
159     do {\
160             while(((sc)->PINCTL & SC_PINCTL_SYNC_Msk) == SC_PINCTL_SYNC_Msk);\
161             if(u32State)\
162                 (sc)->PINCTL |= SC_PINCTL_SCDATA_Msk;\
163             else\
164                 (sc)->PINCTL &= ~SC_PINCTL_SCDATA_Msk;\
165     }while(0)
166 
167 /**
168   * @brief      This macro set RST pin state of smartcard interface
169   *
170   * @param[in]  sc          The pointer of smartcard module.
171   * @param[in] u32State     Pin state of RST pin, valid parameters are \ref SC_PIN_STATE_HIGH and \ref SC_PIN_STATE_LOW.
172   *
173   * @return     None
174   *
175   * @details    User can set SCRST (SC_PINCTL[1]) to decide SC_RST pin to high or low.
176   * \hideinitializer
177   */
178 #define SC_SET_RST_PIN(sc, u32State)\
179     do {\
180             while(((sc)->PINCTL & SC_PINCTL_SYNC_Msk) == SC_PINCTL_SYNC_Msk);\
181             if(u32State)\
182                 (sc)->PINCTL |= SC_PINCTL_RSTEN_Msk;\
183             else\
184                 (sc)->PINCTL &= ~SC_PINCTL_RSTEN_Msk;\
185     }while(0)
186 
187 /**
188   * @brief      This macro read one byte from smartcard module receive FIFO
189   *
190   * @param[in]  sc      The pointer of smartcard module.
191   *
192   * @return     One byte read from receive FIFO
193   *
194   * @details    By reading DAT register, the SC will return an 8-bit received data.
195   * \hideinitializer
196   */
197 #define SC_READ(sc)             ((char)((sc)->DAT))
198 
199 /**
200   * @brief      This macro write one byte to smartcard module transmit FIFO
201   *
202   * @param[in]  sc      The pointer of smartcard module.
203   * @param[in]  u8Data  Data to write to transmit FIFO.
204   *
205   * @return     None
206   *
207   * @details    By writing data to DAT register, the SC will send out an 8-bit data.
208   * \hideinitializer
209   */
210 #define SC_WRITE(sc, u8Data)    ((sc)->DAT = (u8Data))
211 
212 /**
213   * @brief      This macro set smartcard stop bit length
214   *
215   * @param[in]  sc      The pointer of smartcard module.
216   * @param[in]  u32Len  Stop bit length, ether 1 or 2.
217   *
218   * @return     None
219   *
220   * @details    Stop bit length must be 1 for T = 1 protocol and 2 for T = 0 protocol.
221   * \hideinitializer
222   */
223 #define SC_SET_STOP_BIT_LEN(sc, u32Len) ((sc)->CTL = ((sc)->CTL & ~SC_CTL_NSB_Msk) | (((u32Len) == 1)? SC_CTL_NSB_Msk : 0))
224 
225 
226 /*---------------------------------------------------------------------------------------------------------*/
227 /* static inline functions                                                                                 */
228 /*---------------------------------------------------------------------------------------------------------*/
229 /* Declare these inline functions here to avoid MISRA C 2004 rule 8.1 error */
230 __STATIC_INLINE void SC_SetTxRetry(SC_T *sc, uint32_t u32Count);
231 __STATIC_INLINE void SC_SetRxRetry(SC_T *sc, uint32_t u32Count);
232 
233 
234 /**
235   * @brief      Enable/Disable Tx error retry, and set Tx error retry count
236   *
237   * @param[in]  sc          The pointer of smartcard module.
238   * @param[in]  u32Count    The number of times of Tx error retry count, between 0~8. 0 means disable Tx error retry.
239   *
240   * @return     None
241   *
242   * @details    This function is used to enable/disable transmitter retry function when parity error has occurred, and set error retry count.
243   */
SC_SetTxRetry(SC_T * sc,uint32_t u32Count)244 __STATIC_INLINE void SC_SetTxRetry(SC_T *sc, uint32_t u32Count)
245 {
246     while(((sc)->CTL & SC_CTL_SYNC_Msk) == SC_CTL_SYNC_Msk) {}
247 
248     /* Retry count must set while enable bit disabled, so disable it first */
249     (sc)->CTL &= ~(SC_CTL_TXRTY_Msk | SC_CTL_TXRTYEN_Msk);
250 
251     if((u32Count) != 0UL)
252     {
253         while(((sc)->CTL & SC_CTL_SYNC_Msk) == SC_CTL_SYNC_Msk) {}
254         (sc)->CTL |= (((u32Count) - 1UL) << SC_CTL_TXRTY_Pos) | SC_CTL_TXRTYEN_Msk;
255     }
256 }
257 
258 /**
259   * @brief      Enable/Disable Rx error retry, and set Rx error retry count
260   *
261   * @param[in]  sc          The pointer of smartcard module.
262   * @param[in]  u32Count    The number of times of Rx error retry count, between 0~8. 0 means disable Rx error retry.
263   *
264   * @return     None
265   *
266   * @details    This function is used to enable/disable receiver retry function when parity error has occurred, and set error retry count.
267   */
SC_SetRxRetry(SC_T * sc,uint32_t u32Count)268 __STATIC_INLINE void SC_SetRxRetry(SC_T *sc, uint32_t u32Count)
269 {
270     while(((sc)->CTL & SC_CTL_SYNC_Msk) == SC_CTL_SYNC_Msk) {}
271 
272     /* Retry count must set while enable bit disabled, so disable it first */
273     (sc)->CTL &= ~(SC_CTL_RXRTY_Msk | SC_CTL_RXRTYEN_Msk);
274 
275     if((u32Count) != 0UL)
276     {
277         while(((sc)->CTL & SC_CTL_SYNC_Msk) == SC_CTL_SYNC_Msk) {}
278         (sc)->CTL |= (((u32Count) - 1UL) << SC_CTL_RXRTY_Pos) | SC_CTL_RXRTYEN_Msk;
279     }
280 }
281 
282 
283 uint32_t SC_IsCardInserted(SC_T *sc);
284 void SC_ClearFIFO(SC_T *sc);
285 void SC_Close(SC_T *sc);
286 void SC_Open(SC_T *sc, uint32_t u32CardDet, uint32_t u32PWR);
287 void SC_ResetReader(SC_T *sc);
288 void SC_SetBlockGuardTime(SC_T *sc, uint32_t u32BGT);
289 void SC_SetCharGuardTime(SC_T *sc, uint32_t u32CGT);
290 void SC_StopAllTimer(SC_T *sc);
291 void SC_StartTimer(SC_T *sc, uint32_t u32TimerNum, uint32_t u32Mode, uint32_t u32ETUCount);
292 void SC_StopTimer(SC_T *sc, uint32_t u32TimerNum);
293 uint32_t SC_GetInterfaceClock(SC_T *sc);
294 
295 /**@}*/ /* end of group SC_EXPORTED_FUNCTIONS */
296 
297 /**@}*/ /* end of group SC_Driver */
298 
299 /**@}*/ /* end of group Standard_Driver */
300 
301 #ifdef __cplusplus
302 }
303 #endif
304 
305 #endif /* __SC_H__ */
306