summaryrefslogtreecommitdiff
path: root/bsp/nuvoton/libraries/m460/StdDriver/inc/nu_sc.h
blob: 9b5e104bb7a22771072f1274b6fda78e0893c417 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
/**************************************************************************//**
 * @file     nu_sc.h
 * @version  V3.00
 * @brief    Smartcard(SC) driver header file
 *
 * @copyright SPDX-License-Identifier: Apache-2.0
 * @copyright Copyright (C) 2021 Nuvoton Technology Corp. All rights reserved.
 *****************************************************************************/
#ifndef __NU_SC_H__
#define __NU_SC_H__

#ifdef __cplusplus
extern "C"
{
#endif


/** @addtogroup Standard_Driver Standard Driver
  @{
*/

/** @addtogroup SC_Driver SC Driver
  @{
*/

/** @addtogroup SC_EXPORTED_CONSTANTS SC Exported Constants
  @{
*/
#define SC_INTERFACE_NUM                (3UL)               /*!< Smartcard interface numbers \hideinitializer */
#define SC_PIN_STATE_HIGH               (1UL)               /*!< Smartcard pin status high   \hideinitializer */
#define SC_PIN_STATE_LOW                (0UL)               /*!< Smartcard pin status low    \hideinitializer */
#define SC_PIN_STATE_IGNORE             (0xFFFFFFFFUL)      /*!< Ignore pin status           \hideinitializer */
#define SC_CLK_ON                       (1UL)               /*!< Smartcard clock on          \hideinitializer */
#define SC_CLK_OFF                      (0UL)               /*!< Smartcard clock off         \hideinitializer */

#define SC_TMR_MODE_0                   (0UL << SC_TMRCTL0_OPMODE_Pos)      /*!<Timer Operation Mode 0, down count                                                      \hideinitializer */
#define SC_TMR_MODE_1                   (1UL << SC_TMRCTL0_OPMODE_Pos)      /*!<Timer Operation Mode 1, down count, start after detect start bit                        \hideinitializer */
#define SC_TMR_MODE_2                   (2UL << SC_TMRCTL0_OPMODE_Pos)      /*!<Timer Operation Mode 2, down count, start after receive start bit                       \hideinitializer */
#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 */
#define SC_TMR_MODE_4                   (4UL << SC_TMRCTL0_OPMODE_Pos)      /*!<Timer Operation Mode 4, down count with reload after timeout                            \hideinitializer */
#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 */
#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 */
#define SC_TMR_MODE_7                   (7UL << SC_TMRCTL0_OPMODE_Pos)      /*!<Timer Operation Mode 7, down count, start and reload after detect start bit             \hideinitializer */
#define SC_TMR_MODE_8                   (8UL << SC_TMRCTL0_OPMODE_Pos)      /*!<Timer Operation Mode 8, up count                                                        \hideinitializer */
#define SC_TMR_MODE_F                   (0xFUL << SC_TMRCTL0_OPMODE_Pos)    /*!<Timer Operation Mode 15, down count, reload after detect start bit                      \hideinitializer */

#define SC_TIMEOUT                      (SystemCoreClock)   /*!< 1 second time-out */

/**@}*/ /* end of group SC_EXPORTED_CONSTANTS */


/** @addtogroup SC_EXPORTED_FUNCTIONS SC Exported Functions
  @{
*/

/**
  * @brief      This macro enable smartcard interrupt
  *
  * @param[in]  sc      The pointer of smartcard module.
  * @param[in]  u32Mask Interrupt mask to be enabled. A combination of
  *                         - \ref SC_INTEN_ACERRIEN_Msk
  *                         - \ref SC_INTEN_RXTOIEN_Msk
  *                         - \ref SC_INTEN_INITIEN_Msk
  *                         - \ref SC_INTEN_CDIEN_Msk
  *                         - \ref SC_INTEN_BGTIEN_Msk
  *                         - \ref SC_INTEN_TMR2IEN_Msk
  *                         - \ref SC_INTEN_TMR1IEN_Msk
  *                         - \ref SC_INTEN_TMR0IEN_Msk
  *                         - \ref SC_INTEN_TERRIEN_Msk
  *                         - \ref SC_INTEN_TBEIEN_Msk
  *                         - \ref SC_INTEN_RDAIEN_Msk
  *
  * @return     None
  *
  * @details    The macro is used to enable Auto-convention error interrupt, Receiver buffer time-out interrupt, Initial end interrupt,
  *             Card detect interrupt, Block guard time interrupt, Timer2 interrupt, Timer1 interrupt, Timer0 interrupt,
  *             Transfer error interrupt, Transmit buffer empty interrupt or Receive data reach trigger level interrupt.
  * \hideinitializer
  */
#define SC_ENABLE_INT(sc, u32Mask)      ((sc)->INTEN |= (u32Mask))

/**
  * @brief      This macro disable smartcard interrupt
  *
  * @param[in]  sc      The pointer of smartcard module.
  * @param[in]  u32Mask Interrupt mask to be disabled. A combination of
  *                         - \ref SC_INTEN_ACERRIEN_Msk
  *                         - \ref SC_INTEN_RXTOIEN_Msk
  *                         - \ref SC_INTEN_INITIEN_Msk
  *                         - \ref SC_INTEN_CDIEN_Msk
  *                         - \ref SC_INTEN_BGTIEN_Msk
  *                         - \ref SC_INTEN_TMR2IEN_Msk
  *                         - \ref SC_INTEN_TMR1IEN_Msk
  *                         - \ref SC_INTEN_TMR0IEN_Msk
  *                         - \ref SC_INTEN_TERRIEN_Msk
  *                         - \ref SC_INTEN_TBEIEN_Msk
  *                         - \ref SC_INTEN_RDAIEN_Msk
  *
  * @return     None
  *
  * @details    The macro is used to disable Auto-convention error interrupt, Receiver buffer time-out interrupt, Initial end interrupt,
  *             Card detect interrupt, Block guard time interrupt, Timer2 interrupt, Timer1 interrupt, Timer0 interrupt,
  *             Transfer error interrupt, Transmit buffer empty interrupt or Receive data reach trigger level interrupt.
  * \hideinitializer
  */
#define SC_DISABLE_INT(sc, u32Mask)     ((sc)->INTEN &= ~(u32Mask))

/**
  * @brief      This macro set VCC pin state of smartcard interface
  *
  * @param[in]  sc          The pointer of smartcard module.
  * @param[in]  u32State    Pin state of VCC pin, valid parameters are \ref SC_PIN_STATE_HIGH and \ref SC_PIN_STATE_LOW.
  *
  * @return     None
  *
  * @details    User can set PWREN (SC_PINCTL[0]) and PWRINV (SC_PINCTL[11]) to decide SC_PWR pin is in high or low level.
  * \hideinitializer
  */
#define SC_SET_VCC_PIN(sc, u32State) \
    do {\
            uint32_t u32TimeOutCount = SC_TIMEOUT;\
            while(((sc)->PINCTL & SC_PINCTL_SYNC_Msk) == SC_PINCTL_SYNC_Msk)\
                if(--u32TimeOutCount == 0) break;\
            if(u32State)\
                (sc)->PINCTL |= SC_PINCTL_PWREN_Msk;\
            else\
                (sc)->PINCTL &= ~SC_PINCTL_PWREN_Msk;\
    }while(0)


/**
  * @brief      This macro turns CLK output on or off
  *
  * @param[in]  sc          The pointer of smartcard module.
  * @param[in] u32OnOff     Clock on or off for selected smartcard module, valid values are \ref SC_CLK_ON and \ref SC_CLK_OFF.
  *
  * @return     None
  *
  * @details    User can set CLKKEEP (SC_PINCTL[6]) to decide SC_CLK pin always keeps free running or not.
  * \hideinitializer
  */
#define SC_SET_CLK_PIN(sc, u32OnOff)\
    do {\
            uint32_t u32TimeOutCount = SC_TIMEOUT;\
            while(((sc)->PINCTL & SC_PINCTL_SYNC_Msk) == SC_PINCTL_SYNC_Msk)\
                if(--u32TimeOutCount == 0) break;\
            if(u32OnOff)\
                (sc)->PINCTL |= SC_PINCTL_CLKKEEP_Msk;\
            else\
                (sc)->PINCTL &= ~(SC_PINCTL_CLKKEEP_Msk);\
    }while(0)

/**
  * @brief      This macro set I/O pin state of smartcard interface
  *
  * @param[in]  sc          The pointer of smartcard module.
  * @param[in] u32State     Pin state of I/O pin, valid parameters are \ref SC_PIN_STATE_HIGH and \ref SC_PIN_STATE_LOW.
  *
  * @return     None
  *
  * @details    User can set SCDATA (SC_PINCTL[9]) to decide SC_DATA pin to high or low.
  * \hideinitializer
  */
#define SC_SET_IO_PIN(sc, u32State)\
    do {\
            uint32_t u32TimeOutCount = SC_TIMEOUT;\
            while(((sc)->PINCTL & SC_PINCTL_SYNC_Msk) == SC_PINCTL_SYNC_Msk)\
                if(--u32TimeOutCount == 0) break;\
            if(u32State)\
                (sc)->PINCTL |= SC_PINCTL_SCDATA_Msk;\
            else\
                (sc)->PINCTL &= ~SC_PINCTL_SCDATA_Msk;\
    }while(0)

/**
  * @brief      This macro set RST pin state of smartcard interface
  *
  * @param[in]  sc          The pointer of smartcard module.
  * @param[in] u32State     Pin state of RST pin, valid parameters are \ref SC_PIN_STATE_HIGH and \ref SC_PIN_STATE_LOW.
  *
  * @return     None
  *
  * @details    User can set SCRST (SC_PINCTL[1]) to decide SC_RST pin to high or low.
  * \hideinitializer
  */
#define SC_SET_RST_PIN(sc, u32State)\
    do {\
            uint32_t u32TimeOutCount = SC_TIMEOUT;\
            while(((sc)->PINCTL & SC_PINCTL_SYNC_Msk) == SC_PINCTL_SYNC_Msk)\
                if(--u32TimeOutCount == 0) break;\
            if(u32State)\
                (sc)->PINCTL |= SC_PINCTL_RSTEN_Msk;\
            else\
                (sc)->PINCTL &= ~SC_PINCTL_RSTEN_Msk;\
    }while(0)

/**
  * @brief      This macro read one byte from smartcard module receive FIFO
  *
  * @param[in]  sc      The pointer of smartcard module.
  *
  * @return     One byte read from receive FIFO
  *
  * @details    By reading DAT register, the SC will return an 8-bit received data.
  * \hideinitializer
  */
#define SC_READ(sc)             ((char)((sc)->DAT))

/**
  * @brief      This macro write one byte to smartcard module transmit FIFO
  *
  * @param[in]  sc      The pointer of smartcard module.
  * @param[in]  u8Data  Data to write to transmit FIFO.
  *
  * @return     None
  *
  * @details    By writing data to DAT register, the SC will send out an 8-bit data.
  * \hideinitializer
  */
#define SC_WRITE(sc, u8Data)    ((sc)->DAT = (u8Data))

/**
  * @brief      This macro set smartcard stop bit length
  *
  * @param[in]  sc      The pointer of smartcard module.
  * @param[in]  u32Len  Stop bit length, ether 1 or 2.
  *
  * @return     None
  *
  * @details    Stop bit length must be 1 for T = 1 protocol and 2 for T = 0 protocol.
  * \hideinitializer
  */
#define SC_SET_STOP_BIT_LEN(sc, u32Len) ((sc)->CTL = ((sc)->CTL & ~SC_CTL_NSB_Msk) | (((u32Len) == 1)? SC_CTL_NSB_Msk : 0))


/*---------------------------------------------------------------------------------------------------------*/
/* static inline functions                                                                                 */
/*---------------------------------------------------------------------------------------------------------*/
/* Declare these inline functions here to avoid MISRA C 2004 rule 8.1 error */
__STATIC_INLINE void SC_SetTxRetry(SC_T *sc, uint32_t u32Count);
__STATIC_INLINE void SC_SetRxRetry(SC_T *sc, uint32_t u32Count);


/**
  * @brief      Enable/Disable Tx error retry, and set Tx error retry count
  *
  * @param[in]  sc          The pointer of smartcard module.
  * @param[in]  u32Count    The number of times of Tx error retry count, between 0~8. 0 means disable Tx error retry.
  *
  * @return     None
  *
  * @details    This function is used to enable/disable transmitter retry function when parity error has occurred, and set error retry count.
  */
__STATIC_INLINE void SC_SetTxRetry(SC_T *sc, uint32_t u32Count)
{
    uint32_t u32TimeOutCount = 0;

    u32TimeOutCount = SC_TIMEOUT;
    while (((sc)->CTL & SC_CTL_SYNC_Msk) == SC_CTL_SYNC_Msk)
    {
        if (--u32TimeOutCount == 0) break;
    }

    /* Retry count must set while enable bit disabled, so disable it first */
    (sc)->CTL &= ~(SC_CTL_TXRTY_Msk | SC_CTL_TXRTYEN_Msk);

    if ((u32Count) != 0UL)
    {
        u32TimeOutCount = SC_TIMEOUT;
        while (((sc)->CTL & SC_CTL_SYNC_Msk) == SC_CTL_SYNC_Msk)
        {
            if (--u32TimeOutCount == 0) break;
        }
        (sc)->CTL |= (((u32Count) - 1UL) << SC_CTL_TXRTY_Pos) | SC_CTL_TXRTYEN_Msk;
    }
}

/**
  * @brief      Enable/Disable Rx error retry, and set Rx error retry count
  *
  * @param[in]  sc          The pointer of smartcard module.
  * @param[in]  u32Count    The number of times of Rx error retry count, between 0~8. 0 means disable Rx error retry.
  *
  * @return     None
  *
  * @details    This function is used to enable/disable receiver retry function when parity error has occurred, and set error retry count.
  */
__STATIC_INLINE void SC_SetRxRetry(SC_T *sc, uint32_t u32Count)
{
    uint32_t u32TimeOutCount = 0;

    u32TimeOutCount = SC_TIMEOUT;
    while (((sc)->CTL & SC_CTL_SYNC_Msk) == SC_CTL_SYNC_Msk)
    {
        if (--u32TimeOutCount == 0) break;
    }

    /* Retry count must set while enable bit disabled, so disable it first */
    (sc)->CTL &= ~(SC_CTL_RXRTY_Msk | SC_CTL_RXRTYEN_Msk);

    if ((u32Count) != 0UL)
    {
        u32TimeOutCount = SC_TIMEOUT;
        while (((sc)->CTL & SC_CTL_SYNC_Msk) == SC_CTL_SYNC_Msk)
        {
            if (--u32TimeOutCount == 0) break;
        }
        (sc)->CTL |= (((u32Count) - 1UL) << SC_CTL_RXRTY_Pos) | SC_CTL_RXRTYEN_Msk;
    }
}


uint32_t SC_IsCardInserted(SC_T *sc);
void SC_ClearFIFO(SC_T *sc);
void SC_Close(SC_T *sc);
void SC_Open(SC_T *sc, uint32_t u32CardDet, uint32_t u32PWR);
void SC_ResetReader(SC_T *sc);
void SC_SetBlockGuardTime(SC_T *sc, uint32_t u32BGT);
void SC_SetCharGuardTime(SC_T *sc, uint32_t u32CGT);
void SC_StopAllTimer(SC_T *sc);
void SC_StartTimer(SC_T *sc, uint32_t u32TimerNum, uint32_t u32Mode, uint32_t u32ETUCount);
void SC_StopTimer(SC_T *sc, uint32_t u32TimerNum);
uint32_t SC_GetInterfaceClock(SC_T *sc);

/**@}*/ /* end of group SC_EXPORTED_FUNCTIONS */

/**@}*/ /* end of group SC_Driver */

/**@}*/ /* end of group Standard_Driver */

#ifdef __cplusplus
}
#endif

#endif /* __NU_SC_H__ */