1 /*
2 * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2019 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_smartcard_emvsim.h"
10
11 /* Component ID definition, used by tools. */
12 #ifndef FSL_COMPONENT_ID
13 #define FSL_COMPONENT_ID "platform.drivers.smartcard_emvsim"
14 #endif
15
16 /*******************************************************************************
17 * Variables
18 ******************************************************************************/
19 /*! @brief Pointers to emvsim bases for each instance. */
20 static EMVSIM_Type *const s_emvsimBases[] = EMVSIM_BASE_PTRS;
21
22 /*! @brief Pointers to emvsim IRQ number for each instance. */
23 static const IRQn_Type s_emvsimIRQ[] = EMVSIM_IRQS;
24
25 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
26 /*! @brief Pointers to emvsim clocks for each instance. */
27 static const clock_ip_name_t s_emvsimClock[] = EMVSIM_CLOCKS;
28 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
29
30 /* #define CARDSIM_EXTRADELAY_USED */
31
32 /*******************************************************************************
33 * Private Functions
34 ******************************************************************************/
35 static void smartcard_emvsim_CompleteSendData(EMVSIM_Type *base, smartcard_context_t *context);
36 static void smartcard_emvsim_StartSendData(EMVSIM_Type *base, smartcard_context_t *context);
37 static void smartcard_emvsim_CompleteReceiveData(EMVSIM_Type *base, smartcard_context_t *context);
38 static void smartcard_emvsim_StartReceiveData(EMVSIM_Type *base, smartcard_context_t *context);
39 static void smartcard_emvsim_SetTransferType(EMVSIM_Type *base,
40 smartcard_context_t *context,
41 smartcard_control_t control);
42 static uint32_t smartcard_emvsim_GetInstance(EMVSIM_Type *base);
43
44 /*******************************************************************************
45 * Code
46 ******************************************************************************/
47 /*!
48 * @brief Get the UART instance from peripheral base address.
49 *
50 * @param base UART peripheral base address.
51 * @return UART instance.
52 */
smartcard_emvsim_GetInstance(EMVSIM_Type * base)53 static uint32_t smartcard_emvsim_GetInstance(EMVSIM_Type *base)
54 {
55 uint8_t instance = 0;
56 uint32_t emvsimArrayCount = (sizeof(s_emvsimBases) / sizeof(s_emvsimBases[0]));
57
58 /* Find the instance index from base address mappings. */
59 for (instance = 0; instance < emvsimArrayCount; instance++)
60 {
61 if (s_emvsimBases[instance] == base)
62 {
63 break;
64 }
65 }
66
67 assert(instance < emvsimArrayCount);
68
69 return instance;
70 }
71 /*!
72 * @brief Finish up a transmit by completing the process of sending data and disabling the interrupt.
73 *
74 * @param base The EMVSIM peripheral base address.
75 * @param context A pointer to a SMARTCARD driver context structure.
76 */
smartcard_emvsim_CompleteSendData(EMVSIM_Type * base,smartcard_context_t * context)77 static void smartcard_emvsim_CompleteSendData(EMVSIM_Type *base, smartcard_context_t *context)
78 {
79 assert((NULL != context));
80
81 /* Disable ETC and TDT interrupt */
82 base->INT_MASK |= (EMVSIM_INT_MASK_ETC_IM_MASK | EMVSIM_INT_MASK_TDT_IM_MASK);
83
84 /* Disable transmitter */
85 base->CTRL &= ~EMVSIM_CTRL_XMT_EN_MASK;
86 /* Clear receive status flag */
87 base->RX_STATUS = EMVSIM_RX_STATUS_RX_DATA_MASK;
88 /* Enable Receiver */
89 base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK;
90 /* Update the information of the module driver context */
91 context->xIsBusy = false;
92 context->transferState = kSMARTCARD_IdleState;
93 /* Clear txSize to avoid any spurious transmit from ISR */
94 context->xSize = 0u;
95 /* Invoke user call-back */
96 if (NULL != context->transferCallback)
97 {
98 context->transferCallback(context, context->transferCallbackParam);
99 }
100 }
101
102 /*!
103 * @brief Finish up a receive by completing the process of receiving data and disabling the interrupt.
104 *
105 * @param base The EMVSIM peripheral base address.
106 * @param context A pointer to a SMARTCARD driver context structure.
107 */
smartcard_emvsim_CompleteReceiveData(EMVSIM_Type * base,smartcard_context_t * context)108 static void smartcard_emvsim_CompleteReceiveData(EMVSIM_Type *base, smartcard_context_t *context)
109 {
110 assert((NULL != context));
111
112 /* Disable RDT and RX_DATA interrupt */
113 base->INT_MASK |= (EMVSIM_INT_MASK_RDT_IM_MASK | EMVSIM_INT_MASK_RX_DATA_IM_MASK);
114
115 /* Read data from fifo */
116 while (((base->RX_STATUS & EMVSIM_RX_STATUS_RX_CNT_MASK) != 0u) && ((context->xSize) > 0u))
117 {
118 /* Get data and put into receive buffer */
119 *context->xBuff = (uint8_t)(base->RX_BUF);
120 ++context->xBuff;
121 --context->xSize;
122 }
123
124 /* Update the information of the module driver context */
125 context->xIsBusy = false;
126 /* Invoke user call-back */
127 if (NULL != context->transferCallback)
128 {
129 context->transferCallback(context, context->transferCallbackParam);
130 }
131 }
132
133 /*!
134 * @brief Initiate (start) a transmit by beginning the process of sending data and enabling the interrupt.
135 *
136 * @param base The EMVSIM peripheral base address.
137 * @param context A pointer to a SMARTCARD driver context structure.
138 */
smartcard_emvsim_StartSendData(EMVSIM_Type * base,smartcard_context_t * context)139 static void smartcard_emvsim_StartSendData(EMVSIM_Type *base, smartcard_context_t *context)
140 {
141 assert((NULL != context));
142
143 uint32_t delay = 0u;
144 uint32_t control = 0u;
145
146 /* Block guard time */
147 /* 22 etus (16 Receiver Clocks == 1 etu) */
148 delay = 22u * 16u;
149 /* Disable all functionality like protocol timers, NACK generation */
150 control = base->CTRL;
151 base->CTRL = 0u;
152 base->TX_GETU = context->cardParams.GTN;
153 /* Clear Global counter time-out flag */
154 base->TX_STATUS = EMVSIM_TX_STATUS_GPCNT1_TO_MASK;
155 /* Disable counter interrupt */
156 base->INT_MASK |= EMVSIM_INT_MASK_GPCNT1_IM_MASK;
157 /* Set counter value */
158 base->GPCNT1_VAL = delay;
159 /* Select the clock for GPCNT */
160 base->CLKCFG =
161 (base->CLKCFG & ~EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK) | EMVSIM_CLKCFG_GPCNT1_CLK_SEL(kEMVSIM_GPCRxClock);
162 /* Trigger the counter */
163 base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK;
164 /* Wait until counter overflow event occur */
165 while ((base->TX_STATUS & EMVSIM_TX_STATUS_GPCNT1_TO_MASK) == 0u)
166 {
167 }
168 /* Clear status flag and disable GPCNT1 clock */
169 base->TX_STATUS = EMVSIM_TX_STATUS_GPCNT1_TO_MASK;
170 base->CLKCFG &= ~EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK;
171 /* Restore Control register */
172 base->CTRL = control & ~(EMVSIM_CTRL_XMT_EN_MASK | EMVSIM_CTRL_RCV_EN_MASK);
173 /* Update transferState */
174 context->transferState = kSMARTCARD_TransmittingState;
175 context->xIsBusy = true;
176
177 /* Flush transmitter */
178 base->CTRL |= EMVSIM_CTRL_FLSH_TX_MASK;
179
180 /* Enable transmitter */
181 base->CTRL |= EMVSIM_CTRL_XMT_EN_MASK;
182
183 /* Set transmitter data threshold value to 0 - TDTF is set when the fifo is empty */
184 base->TX_THD &= ~EMVSIM_TX_THD_TDT_MASK;
185
186 /* Enable TDT interrupt */
187 base->INT_MASK &= ~EMVSIM_INT_MASK_TDT_IM_MASK;
188 }
189
190 /*!
191 * @brief Initiate (start) a receive by beginning the process of receiving data and enabling the interrupt.
192 *
193 * @param base The EMVSIM peripheral base address.
194 * @param context A pointer to a SMARTCARD driver context structure.
195 */
smartcard_emvsim_StartReceiveData(EMVSIM_Type * base,smartcard_context_t * context)196 static void smartcard_emvsim_StartReceiveData(EMVSIM_Type *base, smartcard_context_t *context)
197 {
198 assert((NULL != context));
199
200 /* Initialize the module driver context structure to indicate transfer in progress */
201 context->xIsBusy = true;
202 /* Enable BWT Timer interrupt to occur */
203 base->INT_MASK &= ~EMVSIM_INT_MASK_BWT_ERR_IM_MASK;
204 /* Disable transmitter */
205 base->CTRL &= ~EMVSIM_CTRL_XMT_EN_MASK;
206 /* Enable receiver and switch to receive direction */
207 base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK;
208
209 /* Set rx threshold value - number of bytes that must exist in the Receive FIFO to trigger the receive data
210 * threshold interrupt flag (RDTF).*/
211 if (context->xSize < context->rxFifoThreshold)
212 {
213 uint32_t rx_thd;
214 rx_thd = (base->RX_THD & ~EMVSIM_RX_THD_RDT_MASK);
215 rx_thd |= context->xSize;
216 base->RX_THD = rx_thd;
217 }
218 else
219 {
220 base->RX_THD = ((base->RX_THD & ~EMVSIM_RX_THD_RDT_MASK) | context->rxFifoThreshold);
221 }
222
223 /* Enable RDT interrupt - count of bytes in rx fifo is equal or greater than threshold RX_THD[RDT] */
224 base->INT_MASK &= ~EMVSIM_INT_MASK_RDT_IM_MASK;
225
226 if (context->tType == kSMARTCARD_T1Transport)
227 {
228 /* Enable interrupt when new byte is received - in T=1 is necessary to disable BWT interrupt and enable CWT
229 * interrupt after receiving the first byte */
230 base->INT_MASK &= ~EMVSIM_INT_MASK_RX_DATA_IM_MASK;
231 }
232 }
233
234 /*!
235 * @brief Sets up the EMVSIM hardware for T=0 or T=1 protocol data exchange and initialize timer values.
236 *
237 * @param base The EMVSIM peripheral base address.
238 * @param context A pointer to a SMARTCARD driver context structure.
239 */
smartcard_emvsim_SetTransferType(EMVSIM_Type * base,smartcard_context_t * context,smartcard_control_t control)240 static void smartcard_emvsim_SetTransferType(EMVSIM_Type *base,
241 smartcard_context_t *context,
242 smartcard_control_t control)
243 {
244 assert((NULL != context));
245 assert((control == kSMARTCARD_SetupATRMode) || (control == kSMARTCARD_SetupT0Mode) ||
246 (control == kSMARTCARD_SetupT1Mode));
247
248 uint16_t temp16 = 0u;
249 uint32_t bwiVal = 0u;
250 uint8_t tdt = 0u;
251
252 if (control == kSMARTCARD_SetupATRMode)
253 {
254 /* Disable all functionality at first */
255 base->CTRL &= ~(EMVSIM_CTRL_RCVR_11_MASK | EMVSIM_CTRL_XMT_CRC_LRC_MASK | EMVSIM_CTRL_LRC_EN_MASK |
256 EMVSIM_CTRL_ANACK_MASK | EMVSIM_CTRL_ONACK_MASK | EMVSIM_CTRL_RCV_EN_MASK);
257 /* Set default values as per EMV specification */
258 context->cardParams.Fi = 372u;
259 context->cardParams.Di = 1u;
260 context->cardParams.currentD = 1u;
261 context->cardParams.WI = 0x0Au;
262 context->cardParams.GTN = 0x00u;
263 /* Set default baudrate/ETU time based on EMV parameters and card clock */
264 base->DIVISOR = (((uint32_t)context->cardParams.Fi / context->cardParams.currentD) & 0x1FFu);
265 /* EMV expectation: WWT = (960 x D x WI) + (D x 480)
266 * EMVSIM formula: BWT_VAL[15:0] = CWT_VAL[15:0] */
267 temp16 = (960u * context->cardParams.currentD * context->cardParams.WI) +
268 (context->cardParams.currentD * 480u) + SMARTCARD_WWT_ADJUSTMENT;
269 base->CWT_VAL = temp16;
270 base->BWT_VAL = temp16;
271 /* Set Extended Guard Timer value
272 * EMV expectation: GT = GTN not equal to 255 -> 12 + GTN = GTN equal to 255 -> 12
273 * EMVSIM formula: same as above */
274 base->TX_GETU = context->cardParams.GTN;
275 /* Setting Rx threshold so that an interrupt is generated when a NACK is
276 sent either due to parity error or wrong INIT char*/
277 base->RX_THD = EMVSIM_RX_THD_RDT(1);
278 /* Setting up Tx NACK threshold */
279 tdt = (uint8_t)(((base->PARAM & EMVSIM_PARAM_TX_FIFO_DEPTH_MASK) >> EMVSIM_PARAM_TX_FIFO_DEPTH_SHIFT) - 1u);
280 base->TX_THD = (EMVSIM_TX_THD_TNCK_THD(SMARTCARD_EMV_TX_NACK_THRESHOLD) | EMVSIM_TX_THD_TDT(tdt));
281 /* Clear all pending interrupts */
282 base->RX_STATUS = 0xFFFFFFFFu;
283 /* Enable Tx NACK threshold interrupt to occur */
284 base->INT_MASK &= ~EMVSIM_INT_MASK_TNACK_IM_MASK;
285 /* Set transport type to T=0 in SMARTCARD context structure */
286 context->tType = kSMARTCARD_T0Transport;
287 }
288 else if (control == kSMARTCARD_SetupT0Mode)
289 {
290 /* Disable receiver at first if it's not, Disable T=0 mode counters 1st,
291 * Setup for single wire ISO7816 mode (setup 12 etu mode).
292 * Set transport protocol type to T=0, Disable initial character detection.*/
293 base->CTRL &=
294 ~(EMVSIM_CTRL_RCV_EN_MASK | EMVSIM_CTRL_CWT_EN_MASK | EMVSIM_CTRL_BWT_EN_MASK | EMVSIM_CTRL_RCVR_11_MASK |
295 EMVSIM_CTRL_XMT_CRC_LRC_MASK | EMVSIM_CTRL_LRC_EN_MASK | EMVSIM_CTRL_ICM_MASK);
296 /* EMV expectation: WWT = (960 x D x WI) + (D x 480)
297 * EMVSIM formula: BWT_VAL[15:0] = CWT_VAL[15:0] */
298 temp16 = (960u * context->cardParams.currentD * context->cardParams.WI) +
299 (context->cardParams.currentD * 480u) + SMARTCARD_WWT_ADJUSTMENT;
300 base->CWT_VAL = temp16;
301 base->BWT_VAL = temp16;
302 /* Set Extended Guard Timer value
303 * EMV expectation: GT = GTN not equal to 255 -> 12 + GTN = GTN equal to 255 -> 12
304 * EMVSIM formula: same as above for range [0:254]
305 * Fix for EMV. If TX_GETU == 0 in T0 mode, 3 stop bits are inserted. */
306 context->cardParams.GTN = (context->cardParams.GTN == 0xFFu) ? 0x00u : context->cardParams.GTN;
307 base->TX_GETU = context->cardParams.GTN;
308 /* Setting Rx threshold so that an interrupt is generated when a NACK is
309 sent either due to parity error or wrong INIT char */
310 base->RX_THD = (EMVSIM_RX_THD_RNCK_THD(SMARTCARD_EMV_RX_NACK_THRESHOLD) | EMVSIM_RX_THD_RDT(1));
311 /* Setting up Tx NACK threshold */
312 tdt = (uint8_t)(((base->PARAM & EMVSIM_PARAM_TX_FIFO_DEPTH_MASK) >> EMVSIM_PARAM_TX_FIFO_DEPTH_SHIFT) - 1u);
313 base->TX_THD = (EMVSIM_TX_THD_TNCK_THD(SMARTCARD_EMV_TX_NACK_THRESHOLD) | EMVSIM_TX_THD_TDT(tdt));
314 /* Enable Tx NACK threshold interrupt to occur */
315 base->INT_MASK &= ~EMVSIM_INT_MASK_TNACK_IM_MASK;
316 /* Enable T=0 mode counters, Enable NACK on error interrupt and NACK on overflow interrupt */
317 base->CTRL |=
318 (EMVSIM_CTRL_CWT_EN_MASK | EMVSIM_CTRL_BWT_EN_MASK | EMVSIM_CTRL_ANACK_MASK | EMVSIM_CTRL_ONACK_MASK);
319 /* Set transport type to T=0 in SMARTCARD context structure */
320 context->tType = kSMARTCARD_T0Transport;
321 }
322 else
323 { /* Disable T=1 mode counters 1st, Disable NACK on error interrupt, Disable NACK on overflow interrupt */
324 base->CTRL &= ~(EMVSIM_CTRL_CWT_EN_MASK | EMVSIM_CTRL_BWT_EN_MASK | EMVSIM_CTRL_ANACK_MASK |
325 EMVSIM_CTRL_ONACK_MASK | EMVSIM_CTRL_XMT_CRC_LRC_MASK | EMVSIM_CTRL_LRC_EN_MASK);
326 /* Calculate and set Block Wait Timer (BWT) value
327 * EMV expectation: BWT = 11 + (2^BWI x 960 x D) + (D x 960) = 11 + (2^BWI + 1) x 960 x D
328 * EMVSIM formula: BWT = Same */
329 bwiVal = 11u + ((((uint32_t)1u << context->cardParams.BWI) + 1u) * 960u * context->cardParams.currentD);
330 #ifdef CARDSIM_EXTRADELAY_USED
331 base->BWT_VAL = bwiVal + 100u;
332 #else
333 base->BWT_VAL = bwiVal;
334 #endif
335 /* Calculate and set Character Wait Timer (CWT) value
336 * EMV expectation: CWT = ((2^CWI + 11) + 4)
337 * EMVSIM formula: CWT = Same */
338 if (context->cardParams.currentD == 1u)
339 {
340 #ifdef CARDSIM_EXTRADELAY_USED
341 temp16 = ((uint16_t)1u << context->cardParams.CWI) + 16u;
342 #else
343 temp16 = ((uint16_t)1u << context->cardParams.CWI) + 15u;
344 #endif
345 }
346 else
347 {
348 #ifdef CARDSIM_EXTRADELAY_USED
349 temp16 = ((uint16_t)1u << context->cardParams.CWI) + 20u + SMARTCARD_CWT_ADJUSTMENT;
350 #else
351 temp16 = ((uint16_t)1u << context->cardParams.CWI) + 15u + SMARTCARD_CWT_ADJUSTMENT;
352 #endif
353 }
354 /* EMV = 15, ISO = 11,
355 * EMV expectation: BGT = 22
356 * EMVSIM formula: BGT = Same */
357 base->CWT_VAL = temp16;
358 context->cardParams.BGI = 22u;
359 base->BGT_VAL = context->cardParams.BGI;
360 /* Set Extended Guard Timer value
361 * EMV expectation: GT = GTN not equal to 255 -> 12 + GTN = GTN equal to 255 -> 11
362 * EMVSIM formula: same as above */
363 base->TX_GETU = context->cardParams.GTN;
364 /* Setup for single wire ISO7816 mode,
365 * Set transport protocol type to T=1, Enable T=0 mode counters */
366 base->CTRL |= (EMVSIM_CTRL_RCVR_11_MASK | EMVSIM_CTRL_CWT_EN_MASK | EMVSIM_CTRL_BWT_EN_MASK);
367 /* Setting Rx threshold */
368 base->RX_THD = (EMVSIM_RX_THD_RNCK_THD(SMARTCARD_EMV_RX_NACK_THRESHOLD) | EMVSIM_RX_THD_RDT(1));
369 /* Setting up Tx threshold */
370 tdt = (uint8_t)(((base->PARAM & EMVSIM_PARAM_TX_FIFO_DEPTH_MASK) >> EMVSIM_PARAM_TX_FIFO_DEPTH_SHIFT) - 1u);
371 base->TX_THD = (EMVSIM_TX_THD_TDT(tdt) | EMVSIM_TX_THD_TNCK_THD(SMARTCARD_EMV_TX_NACK_THRESHOLD));
372 /* Set transport type to T=1 in SMARTCARD context structure */
373 context->tType = kSMARTCARD_T1Transport;
374 }
375 }
376
377 /*!
378 * brief Fills in the smartcard_card_params structure with default values according to the EMV 4.3 specification.
379 *
380 * param cardParams The configuration structure of type smartcard_interface_config_t.
381 * Function fill in members:
382 * Fi = 372;
383 * Di = 1;
384 * currentD = 1;
385 * WI = 0x0A;
386 * GTN = 0x00;
387 * with default values.
388 */
SMARTCARD_EMVSIM_GetDefaultConfig(smartcard_card_params_t * cardParams)389 void SMARTCARD_EMVSIM_GetDefaultConfig(smartcard_card_params_t *cardParams)
390 {
391 /* Initializes the configure structure to zero. */
392 (void)memset(cardParams, 0, sizeof(*cardParams));
393
394 /* EMV default values */
395 cardParams->Fi = 372u;
396 cardParams->Di = 1u;
397 cardParams->currentD = 1u;
398 cardParams->WI = 0x0Au;
399 cardParams->GTN = 0x00u;
400 }
401
402 /*!
403 * brief Initializes an EMVSIM peripheral for the Smart card/ISO-7816 operation.
404 *
405 * This function un-gates the EMVSIM clock, initializes the module to EMV default settings,
406 * configures the IRQ, enables the module-level interrupt to the core and, initializes the driver context.
407 *
408 * param base The EMVSIM peripheral base address.
409 * param context A pointer to the smart card driver context structure.
410 * param srcClock_Hz Smart card clock generation module source clock.
411 *
412 * return An error code or kStatus_SMARTCARD_Success.
413 */
SMARTCARD_EMVSIM_Init(EMVSIM_Type * base,smartcard_context_t * context,uint32_t srcClock_Hz)414 status_t SMARTCARD_EMVSIM_Init(EMVSIM_Type *base, smartcard_context_t *context, uint32_t srcClock_Hz)
415 {
416 assert((NULL != base));
417
418 if ((NULL == context) || (srcClock_Hz == 0u))
419 {
420 return kStatus_SMARTCARD_InvalidInput;
421 }
422
423 uint32_t instance = smartcard_emvsim_GetInstance(base);
424 /* Set source clock for EMVSIM MCGPLLCLK */
425 #if (defined(FSL_FEATURE_SOC_MCG_COUNT) && FSL_FEATURE_SOC_MCG_COUNT)
426 CLOCK_SetEmvsimClock(1u);
427 #endif
428 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
429 /* Enable emvsim clock */
430 CLOCK_EnableClock(s_emvsimClock[instance]);
431 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
432 context->base = base;
433 /* Initialize EMVSIM to a known context. */
434 base->CLKCFG = 0u;
435 base->DIVISOR = 372u;
436 base->CTRL = 0x300u;
437 base->INT_MASK = 0x7FFFu;
438 base->RX_THD = 1u;
439 base->TX_THD = 0u;
440 base->PCSR = 0x1000000u;
441 base->TX_GETU = 0u;
442 base->CWT_VAL = 0xFFFFu;
443 base->BWT_VAL = 0xFFFFFFFFu;
444 base->BGT_VAL = 0u;
445 base->GPCNT0_VAL = 0xFFFFu;
446 base->GPCNT1_VAL = 0xFFFFu;
447 /* Initialize EMVSIM module for SMARTCARD mode of default operation */
448 smartcard_emvsim_SetTransferType(base, context, kSMARTCARD_SetupATRMode);
449 /* Store information about tx fifo depth */
450 context->txFifoEntryCount =
451 (uint8_t)((base->PARAM & EMVSIM_PARAM_TX_FIFO_DEPTH_MASK) >> EMVSIM_PARAM_TX_FIFO_DEPTH_SHIFT);
452 /* Compute max value of rx fifo threshold */
453 context->rxFifoThreshold =
454 (uint8_t)((base->PARAM & EMVSIM_PARAM_RX_FIFO_DEPTH_MASK) >> EMVSIM_PARAM_RX_FIFO_DEPTH_SHIFT);
455 if ((EMVSIM_RX_THD_RDT_MASK >> EMVSIM_RX_THD_RDT_SHIFT) < context->rxFifoThreshold)
456 {
457 context->rxFifoThreshold = (EMVSIM_RX_THD_RDT_MASK >> EMVSIM_RX_THD_RDT_SHIFT);
458 }
459 /* Enable EMVSIM interrupt on NVIC level. */
460 #if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && FSL_FEATURE_SOC_INTMUX_COUNT
461 if ((uint32_t)s_emvsimIRQ[instance] < (uint32_t)FSL_FEATURE_INTMUX_IRQ_START_INDEX)
462 {
463 NVIC_EnableIRQ(s_emvsimIRQ[instance]);
464 }
465 #else
466 NVIC_EnableIRQ(s_emvsimIRQ[instance]);
467 #endif
468 /* Finally, disable the EMVSIM receiver and transmitter */
469 base->CTRL &= ~EMVSIM_CTRL_XMT_EN_MASK & ~EMVSIM_CTRL_RCV_EN_MASK;
470
471 return kStatus_SMARTCARD_Success;
472 }
473
474 /*!
475 * brief This function disables the EMVSIM interrupts, disables the transmitter and receiver,
476 * flushes the FIFOs, and gates EMVSIM clock in SIM.
477 *
478 * param base The EMVSIM module base address.
479 */
SMARTCARD_EMVSIM_Deinit(EMVSIM_Type * base)480 void SMARTCARD_EMVSIM_Deinit(EMVSIM_Type *base)
481 {
482 uint32_t instance = 0u;
483 /* In case there is still data in the TX FIFO or shift register that is
484 * being transmitted wait till transmit is complete.
485 * Wait until the data is completely shifted out of shift register */
486 if ((base->TX_STATUS & EMVSIM_TX_STATUS_TX_CNT_MASK) != 0u)
487 {
488 while ((base->TX_STATUS & EMVSIM_TX_STATUS_ETCF_MASK) == 0u)
489 {
490 }
491 }
492 instance = smartcard_emvsim_GetInstance(base);
493 /* Disable TX and RX */
494 base->CTRL &= ~EMVSIM_CTRL_XMT_EN_MASK & ~EMVSIM_CTRL_RCV_EN_MASK;
495 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
496 /* Gate EMVSIM module clock */
497 CLOCK_DisableClock(s_emvsimClock[instance]);
498 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
499 /* Disable emvsim interrupt in NVIC */
500 #if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && FSL_FEATURE_SOC_INTMUX_COUNT
501 if ((uint32_t)s_emvsimIRQ[instance] < (uint32_t)FSL_FEATURE_INTMUX_IRQ_START_INDEX)
502 {
503 NVIC_DisableIRQ(s_emvsimIRQ[instance]);
504 }
505 #else
506 NVIC_DisableIRQ(s_emvsimIRQ[instance]);
507 #endif
508 }
509
510 /*!
511 * brief Transfer data using interrupts.
512 *
513 * A non-blocking (also known as asynchronous) function means that the function returns
514 * immediately after initiating the transfer function. The application has to get the
515 * transfer status to see when the transfer is complete. In other words, after calling the non-blocking
516 * (asynchronous) transfer function, the application must get the transfer status to check if the transmit
517 * is completed or not.
518 *
519 * param base The EMVSIM peripheral base address.
520 * param context A pointer to a smart card driver context structure.
521 * param xfer A pointer to the smart card transfer structure where the linked buffers and sizes are stored.
522 *
523 * return An error code or kStatus_SMARTCARD_Success.
524 */
SMARTCARD_EMVSIM_TransferNonBlocking(EMVSIM_Type * base,smartcard_context_t * context,smartcard_xfer_t * xfer)525 status_t SMARTCARD_EMVSIM_TransferNonBlocking(EMVSIM_Type *base, smartcard_context_t *context, smartcard_xfer_t *xfer)
526 {
527 if ((NULL == context) || (NULL == xfer) || (xfer->buff == NULL))
528 {
529 return kStatus_SMARTCARD_InvalidInput;
530 }
531
532 /* Check input parameters */
533 if ((0u == xfer->size))
534 {
535 return kStatus_SMARTCARD_Success;
536 }
537 /* Check if some transfer is in progress */
538 if (0 != SMARTCARD_EMVSIM_GetTransferRemainingBytes(base, context))
539 {
540 if (kSMARTCARD_Receive == context->direction)
541 {
542 return kStatus_SMARTCARD_RxBusy;
543 }
544 else
545 {
546 return kStatus_SMARTCARD_TxBusy;
547 }
548 }
549 /* Initialize error check flags */
550 context->rxtCrossed = false;
551 context->txtCrossed = false;
552 context->parityError = false;
553 /* Initialize SMARTCARD context structure to start transfer */
554 context->xBuff = xfer->buff;
555 context->xSize = xfer->size;
556
557 if (kSMARTCARD_Receive == xfer->direction)
558 {
559 context->direction = xfer->direction;
560 context->transferState = kSMARTCARD_ReceivingState;
561 /* Start transfer */
562 smartcard_emvsim_StartReceiveData(base, context);
563 }
564 else if (kSMARTCARD_Transmit == xfer->direction)
565 {
566 context->direction = xfer->direction;
567 context->transferState = kSMARTCARD_TransmittingState;
568 /* Start transfer */
569 smartcard_emvsim_StartSendData(base, context);
570 }
571 else
572 {
573 return kStatus_SMARTCARD_InvalidInput;
574 }
575
576 return kStatus_SMARTCARD_Success;
577 }
578
579 /*!
580 * brief Returns whether the previous EMVSIM transfer has finished.
581 *
582 * When performing an async transfer, call this function to ascertain the context of the
583 * current transfer: in progress (or busy) or complete (success). If the
584 * transfer is still in progress, the user can obtain the number of words that have not been
585 * transferred.
586 *
587 * param base The EMVSIM module base address.
588 * param context A pointer to a smart card driver context structure.
589 *
590 * return The number of bytes not transferred.
591 */
SMARTCARD_EMVSIM_GetTransferRemainingBytes(EMVSIM_Type * base,smartcard_context_t * context)592 int32_t SMARTCARD_EMVSIM_GetTransferRemainingBytes(EMVSIM_Type *base, smartcard_context_t *context)
593 {
594 if ((NULL == context))
595 {
596 return -1;
597 }
598 if (context->xIsBusy)
599 {
600 if (context->direction == kSMARTCARD_Transmit)
601 {
602 /* Count of bytes in buffer + data in fifo */
603 uint32_t count;
604 count = context->xSize;
605 count += ((base->TX_STATUS & EMVSIM_TX_STATUS_TX_CNT_MASK) >> EMVSIM_TX_STATUS_TX_CNT_SHIFT);
606 return (int32_t)count;
607 }
608 return (int32_t)context->xSize;
609 }
610
611 return 0;
612 }
613
614 /*!
615 * brief Terminates an asynchronous EMVSIM transfer early.
616 *
617 * During an async EMVSIM transfer, the user can terminate the transfer early
618 * if the transfer is still in progress.
619 *
620 * param base The EMVSIM peripheral address.
621 * param context A pointer to a smart card driver context structure.
622 * retval kStatus_SMARTCARD_Success The transmit abort was successful.
623 * retval kStatus_SMARTCARD_NoTransmitInProgress No transmission is currently in progress.
624 */
SMARTCARD_EMVSIM_AbortTransfer(EMVSIM_Type * base,smartcard_context_t * context)625 status_t SMARTCARD_EMVSIM_AbortTransfer(EMVSIM_Type *base, smartcard_context_t *context)
626 {
627 if ((NULL == context))
628 {
629 return kStatus_SMARTCARD_InvalidInput;
630 }
631
632 context->abortTransfer = true;
633
634 /* Check if a transfer is running. */
635 if ((!context->xIsBusy))
636 {
637 return kStatus_SMARTCARD_NoTransferInProgress;
638 }
639 /* Call transfer complete to abort transfer */
640 if (kSMARTCARD_Receive == context->direction)
641 { /* Stop the running transfer. */
642 smartcard_emvsim_CompleteReceiveData(base, context);
643 }
644 else if (kSMARTCARD_Transmit == context->direction)
645 { /* Stop the running transfer. */
646 smartcard_emvsim_CompleteSendData(base, context);
647 }
648 else
649 {
650 return kStatus_SMARTCARD_InvalidInput;
651 }
652
653 return kStatus_SMARTCARD_Success;
654 }
655
656 /*!
657 * brief Handles EMVSIM module interrupts.
658 *
659 * param base The EMVSIM peripheral base address.
660 * param context A pointer to a smart card driver context structure.
661 */
SMARTCARD_EMVSIM_IRQHandler(EMVSIM_Type * base,smartcard_context_t * context)662 void SMARTCARD_EMVSIM_IRQHandler(EMVSIM_Type *base, smartcard_context_t *context)
663 {
664 if (NULL == context)
665 {
666 return;
667 }
668
669 /* Check card insertion/removal interrupt occurs, only EMVSIM DIRECT interface driver using enables this interrupt
670 * to occur */
671 if (((base->PCSR & EMVSIM_PCSR_SPDIM_MASK) == 0u) && ((base->PCSR & EMVSIM_PCSR_SPDIF_MASK) != 0u))
672 {
673 /* Clear card presence interrupt status */
674 base->PCSR |= EMVSIM_PCSR_SPDIF_MASK;
675 /* Set PD signal edge behaviour */
676 if (((emvsim_presence_detect_edge_t)(uint32_t)((base->PCSR & EMVSIM_PCSR_SPDES_MASK) >>
677 EMVSIM_PCSR_SPDES_SHIFT) == kEMVSIM_DetectOnFallingEdge) &&
678 ((emvsim_presence_detect_status_t)(uint32_t)((base->PCSR & EMVSIM_PCSR_SPDP_MASK) >>
679 EMVSIM_PCSR_SPDP_SHIFT) == kEMVSIM_DetectPinIsLow))
680 { /* Set rising edge interrupt */
681 base->PCSR |= EMVSIM_PCSR_SPDES_MASK;
682 }
683 if (((emvsim_presence_detect_edge_t)(uint32_t)((base->PCSR & EMVSIM_PCSR_SPDES_MASK) >>
684 EMVSIM_PCSR_SPDES_SHIFT) == kEMVSIM_DetectOnRisingEdge) &&
685 ((emvsim_presence_detect_status_t)(uint32_t)((base->PCSR & EMVSIM_PCSR_SPDP_MASK) >>
686 EMVSIM_PCSR_SPDP_SHIFT) == kEMVSIM_DetectPinIsHigh))
687 { /* Set falling edge interrupt */
688 base->PCSR &= ~EMVSIM_PCSR_SPDES_MASK;
689 }
690 /* Card presence(insertion)/removal detected */
691 /* Invoke callback if there is one */
692 if (NULL != context->interfaceCallback)
693 {
694 context->interfaceCallback(context, context->interfaceCallbackParam);
695 }
696 return;
697 }
698 /* Check if timer for initial character (TS) detection has expired */
699 if (((base->INT_MASK & EMVSIM_INT_MASK_GPCNT0_IM_MASK) >> EMVSIM_INT_MASK_GPCNT0_IM_SHIFT == 0u) &&
700 ((base->TX_STATUS & EMVSIM_TX_STATUS_GPCNT0_TO_MASK) != 0u))
701 {
702 /* Disable TS and ADT timers by clearing source clock to 0 */
703 base->CLKCFG &= ~(EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK | EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK);
704 context->timersState.initCharTimerExpired = true;
705 /* Disable and clear GPCNT interrupt */
706 base->INT_MASK |= EMVSIM_INT_MASK_GPCNT0_IM_MASK;
707 base->TX_STATUS = EMVSIM_TX_STATUS_GPCNT0_TO_MASK;
708 /* Down counter trigger, and clear any pending counter status flag */
709 base->CTRL &= ~EMVSIM_CTRL_RCV_EN_MASK;
710 base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK;
711 context->transferState = kSMARTCARD_IdleState;
712 /* Unblock the caller */
713 smartcard_emvsim_CompleteReceiveData(base, context);
714 return;
715 }
716 /* Check if timer for ATR duration timer has expired */
717 if (((base->INT_MASK & EMVSIM_INT_MASK_GPCNT1_IM_MASK) == 0u) &&
718 ((base->TX_STATUS & EMVSIM_TX_STATUS_GPCNT1_TO_MASK) != 0u))
719 { /* Disable clock counter by clearing source clock to 0 */
720 base->CLKCFG &= ~EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK;
721 /* Disable and clear GPCNT interrupt */
722 base->INT_MASK |= EMVSIM_INT_MASK_GPCNT1_IM_MASK;
723 base->TX_STATUS = EMVSIM_TX_STATUS_GPCNT1_TO_MASK;
724 context->timersState.adtExpired = true;
725 /* Unblock the caller */
726 smartcard_emvsim_CompleteReceiveData(base, context);
727 return;
728 }
729 /*
730 * Check if a parity error was indicated.
731 * A parity error will cause transmission of NACK if ANACK bit is set in
732 * CTRL register and PEF bit will not be asserted. When ANACK is not set,
733 * PEF will be asserted.
734 */
735 if ((base->RX_STATUS & EMVSIM_RX_STATUS_PEF_MASK) != 0u)
736 {
737 context->parityError = true;
738 /* Clear parity error indication */
739 base->RX_STATUS = EMVSIM_RX_STATUS_PEF_MASK;
740 }
741 /* Check if transmit NACK generation threshold was reached */
742 if ((base->TX_STATUS & EMVSIM_TX_STATUS_TNTE_MASK) != 0u)
743 {
744 context->txtCrossed = true;
745 /* Disable transmit NACK threshold interrupt */
746 base->INT_MASK |= EMVSIM_INT_MASK_TNACK_IM_MASK;
747 /* Clear transmit NACK threshold error flag */
748 base->TX_STATUS = EMVSIM_TX_STATUS_TNTE_MASK;
749 /* Unblock the caller */
750 smartcard_emvsim_CompleteSendData(base, context);
751 return;
752 }
753 /* Check if receive NACK generation threshold was reached */
754 if ((base->RX_STATUS & EMVSIM_RX_STATUS_RTE_MASK) != 0u)
755 {
756 context->rxtCrossed = true;
757 /* Clear receiver NACK threshold interrupt status */
758 base->RX_STATUS = EMVSIM_RX_STATUS_RTE_MASK;
759 if (context->xIsBusy)
760 { /* Unblock the caller */
761 smartcard_emvsim_CompleteReceiveData(base, context);
762 }
763 }
764 /* Check if a Character Wait Timer expired */
765 if (((base->INT_MASK & EMVSIM_INT_MASK_CWT_ERR_IM_MASK) == 0u) &&
766 ((base->RX_STATUS & EMVSIM_RX_STATUS_CWT_ERR_MASK) != 0u))
767 { /* Disable Character Wait Timer interrupt */
768 base->INT_MASK |= EMVSIM_INT_MASK_CWT_ERR_IM_MASK;
769 /* Reset the counter */
770 base->CTRL &= ~EMVSIM_CTRL_CWT_EN_MASK;
771 /* Clear interrupt status */
772 base->RX_STATUS = EMVSIM_RX_STATUS_CWT_ERR_MASK;
773 /* Enable CWT timer */
774 base->CTRL |= EMVSIM_CTRL_CWT_EN_MASK;
775 context->transferState = kSMARTCARD_IdleState;
776
777 if (kSMARTCARD_T0Transport == context->tType)
778 { /* Indicate WWT expired */
779 context->timersState.wwtExpired = true;
780 }
781 else
782 { /* Indicate CWT expired */
783 context->timersState.cwtExpired = true;
784 }
785 if (context->xIsBusy)
786 { /* Terminate and unblock any caller */
787 smartcard_emvsim_CompleteReceiveData(base, context);
788 }
789 }
790 /* Check if a Block Wait Timer expired */
791 if (((base->INT_MASK & EMVSIM_INT_MASK_BWT_ERR_IM_MASK) == 0u) &&
792 ((base->RX_STATUS & EMVSIM_RX_STATUS_BWT_ERR_MASK) != 0u))
793 { /* Disable Block Wait Timer interrupt */
794 base->INT_MASK |= EMVSIM_INT_MASK_BWT_ERR_IM_MASK;
795 /* Clear interrupt status flag */
796 base->CTRL &= ~EMVSIM_CTRL_BWT_EN_MASK;
797 /* Clear error */
798 base->RX_STATUS = EMVSIM_RX_STATUS_BWT_ERR_MASK;
799 /* Enable BWT timer */
800 base->CTRL |= EMVSIM_CTRL_BWT_EN_MASK;
801
802 if (kSMARTCARD_T0Transport == context->tType)
803 { /* Indicate WWT expired */
804 context->timersState.wwtExpired = true;
805 }
806 else
807 { /* Indicate BWT expired */
808 context->timersState.bwtExpired = true;
809 }
810 /* Check if Wait Time Extension(WTX) was requested */
811 if (context->wtxRequested)
812 { /* Reset WTX to default */
813 (void)SMARTCARD_EMVSIM_Control(base, context, kSMARTCARD_ResetWaitTimeMultiplier, 1u);
814 }
815 if (context->xIsBusy)
816 { /* Terminate and unblock any caller */
817 smartcard_emvsim_CompleteReceiveData(base, context);
818 }
819 }
820
821 /* RX_DATA IRQ */
822 /* Used in T=1 after receive 1st byte - disable BWT and enable CWT interrupt */
823 if (((base->INT_MASK & EMVSIM_INT_MASK_RX_DATA_IM_MASK) == 0u) &&
824 ((base->RX_STATUS & EMVSIM_RX_STATUS_RX_DATA_MASK) != 0u))
825 {
826 if ((context->tType == kSMARTCARD_T1Transport) && (context->xSize > 0u) &&
827 ((base->INT_MASK & EMVSIM_INT_MASK_BWT_ERR_IM_MASK) == 0u))
828 {
829 context->timersState.cwtExpired = false;
830 /* Clear CWT error flag */
831 base->RX_STATUS = EMVSIM_RX_STATUS_CWT_ERR_MASK;
832 /* Enable CWT */
833 base->CTRL |= EMVSIM_CTRL_CWT_EN_MASK;
834 /* Only the 1st byte has been received, now time to disable BWT interrupt and enable CWT interrupt */
835 base->INT_MASK = (base->INT_MASK & ~EMVSIM_INT_MASK_CWT_ERR_IM_MASK) | EMVSIM_INT_MASK_BWT_ERR_IM_MASK;
836 }
837 /* Disable interrupt when is received new byte */
838 base->INT_MASK |= EMVSIM_INT_MASK_RX_DATA_IM_MASK;
839 }
840
841 /* RDT IRQ - count of bytes in rx fifo reached the rx threshold value RX_THD[RDT] */
842 if (((base->INT_MASK & EMVSIM_INT_MASK_RDT_IM_MASK) == 0u) &&
843 ((base->RX_STATUS & EMVSIM_RX_STATUS_RDTF_MASK) != 0u))
844 {
845 if (kSMARTCARD_WaitingForTSState == context->transferState)
846 {
847 /* Read byte */
848 (void)(base->RX_BUF);
849
850 if ((base->CTRL & EMVSIM_CTRL_ICM_MASK) != 0u)
851 { /* ICM mode still enabled, this is due to parity error */
852 context->transferState = kSMARTCARD_InvalidTSDetecetedState;
853 }
854 else
855 { /* Received valid TS */
856 context->transferState = kSMARTCARD_ReceivingState;
857 /* Get Data Convention form by reading IC bit of EMVSIM_CTRL register */
858 context->cardParams.convention =
859 (smartcard_card_convention_t)(uint32_t)((base->CTRL & EMVSIM_CTRL_IC_MASK) >> EMVSIM_CTRL_IC_SHIFT);
860 }
861 if (kSMARTCARD_InvalidTSDetecetedState == context->transferState)
862 { /* Stop initial character (TS) detection timer, ADT timer and it's interrupt to occur */
863 base->CLKCFG &= ~(EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK | EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK);
864 base->INT_MASK |= EMVSIM_INT_MASK_GPCNT0_IM_MASK;
865 smartcard_emvsim_CompleteReceiveData(base, context);
866 }
867 if (kSMARTCARD_ReceivingState == context->transferState)
868 { /* Stop initial character (TS) detection timer and disable ATR duration timer to reset it */
869 base->CLKCFG &= ~(EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK | EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK);
870 /* Start ATR duration counter (restart GPCNT) */
871 base->CLKCFG |= EMVSIM_CLKCFG_GPCNT1_CLK_SEL(kEMVSIM_GPCTxClock);
872 /* Start ATR duration counter, Disable counter 0 interrupt and Enable counter 1 interrupt */
873 base->INT_MASK = (base->INT_MASK & ~EMVSIM_INT_MASK_GPCNT1_IM_MASK) | EMVSIM_INT_MASK_GPCNT0_IM_MASK;
874 /* Complete receive transfer */
875 smartcard_emvsim_CompleteReceiveData(base, context);
876 }
877 /* Return anyway */
878 return;
879 }
880
881 while (((base->RX_STATUS & EMVSIM_RX_STATUS_RX_CNT_MASK) != 0u) && ((context->xSize) > 0u))
882 {
883 /* Get data and put into receive buffer */
884 *context->xBuff = (uint8_t)(base->RX_BUF);
885 ++context->xBuff;
886 --context->xSize;
887 }
888
889 /* Check if the last byte was received */
890 if (context->xSize == 0u)
891 {
892 smartcard_emvsim_CompleteReceiveData(base, context);
893 }
894 else
895 {
896 /* If the count of remaining bytes to receive is less than depth of fifo, update the value of the receiver
897 * data threshold */
898 if (context->xSize < context->rxFifoThreshold)
899 {
900 /* Set receiver data threshold value to count of remaining bytes */
901 uint32_t rx_thd;
902 rx_thd = (base->RX_THD & ~EMVSIM_RX_THD_RDT_MASK);
903 rx_thd |= context->xSize;
904 base->RX_THD = rx_thd;
905 }
906 }
907 }
908
909 /* ETC IRQ - all data from fifo is transmitted */
910 if (((base->INT_MASK & EMVSIM_INT_MASK_ETC_IM_MASK) == 0u) &&
911 ((base->TX_STATUS & EMVSIM_TX_STATUS_ETCF_MASK) != 0u))
912 {
913 smartcard_emvsim_CompleteSendData(base, context);
914 }
915
916 /* TDT IRQ - tx fifo is empty */
917 if (((base->INT_MASK & EMVSIM_INT_MASK_TDT_IM_MASK) == 0u) &&
918 ((base->TX_STATUS & EMVSIM_TX_STATUS_TDTF_MASK) != 0u))
919 {
920 if (context->xSize == 0u)
921 {
922 smartcard_emvsim_CompleteSendData(base, context);
923 }
924
925 if (context->xSize == 1u)
926 {
927 /* Disable TDT interrupt */
928 base->INT_MASK |= EMVSIM_INT_MASK_TDT_IM_MASK;
929 /* When the TX_GETU is not zero while sending last byte, the transmitter sends one byte more */
930 base->TX_GETU = 0;
931
932 /* Write data to fifo */
933 base->TX_BUF = *(context->xBuff);
934 ++context->xBuff;
935 --context->xSize;
936
937 /* Last byte was written to fifo - wait for ETC interrupt */
938 /* Clear ETC flag and enable ETC interrupt */
939 base->TX_STATUS |= EMVSIM_TX_STATUS_ETCF_MASK;
940 base->INT_MASK &= ~EMVSIM_INT_MASK_ETC_IM_MASK;
941 }
942 else
943 {
944 /* To fifo will be written 2 or more bytes */
945 size_t getu_tail = (size_t)(base->TX_GETU > 0u);
946 while (((context->txFifoEntryCount - (uint8_t)((base->TX_STATUS & EMVSIM_TX_STATUS_TX_CNT_MASK) >>
947 EMVSIM_TX_STATUS_TX_CNT_SHIFT)) > 0u) &&
948 (context->xSize > getu_tail))
949 {
950 /* Write data to fifo */
951 base->TX_BUF = *(context->xBuff);
952 ++context->xBuff;
953 --context->xSize;
954 }
955
956 if (context->xSize == 0u)
957 {
958 /* Disable TDT interrupt */
959 base->INT_MASK |= EMVSIM_INT_MASK_TDT_IM_MASK;
960
961 /* Clear ETC flag and enable ETC interrupt */
962 base->TX_STATUS |= EMVSIM_TX_STATUS_ETCF_MASK;
963 base->INT_MASK &= ~EMVSIM_INT_MASK_ETC_IM_MASK;
964 }
965 }
966 }
967 SDK_ISR_EXIT_BARRIER;
968 }
969
970 /*!
971 * brief Controls the EMVSIM module per different user request.
972 *
973 * param base The EMVSIM peripheral base address.
974 * param context A pointer to a smart card driver context structure.
975 * param control Control type.
976 * param param Integer value of specific to control command.
977 *
978 * return kStatus_SMARTCARD_Success in success.
979 * return kStatus_SMARTCARD_OtherError in case of error.
980 */
SMARTCARD_EMVSIM_Control(EMVSIM_Type * base,smartcard_context_t * context,smartcard_control_t control,uint32_t param)981 status_t SMARTCARD_EMVSIM_Control(EMVSIM_Type *base,
982 smartcard_context_t *context,
983 smartcard_control_t control,
984 uint32_t param)
985 {
986 if ((NULL == context))
987 {
988 return kStatus_SMARTCARD_InvalidInput;
989 }
990
991 status_t status = kStatus_SMARTCARD_Success;
992 uint32_t temp32 = 0u;
993
994 switch (control)
995 {
996 case kSMARTCARD_EnableADT:
997 /* Do nothing, ADT counter has been loaded and started after reset
998 * and during starting TS delay counter only. This is because, once
999 * TS counter has been triggered with RCV_EN down-up, we should not
1000 * trigger again after TS is received(to avoid missing next character to
1001 * TS. Rather, after TS is received, the ATR duration counter should just
1002 * be restarted w/o re-triggering the counter. */
1003 break;
1004 case kSMARTCARD_DisableADT:
1005 base->CTRL &= ~EMVSIM_CTRL_RCV_EN_MASK;
1006 /* Stop ADT specific counter and it's interrupt to occur */
1007 base->CLKCFG &= ~EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK;
1008 base->TX_STATUS = EMVSIM_TX_STATUS_GPCNT1_TO_MASK;
1009 base->INT_MASK |= EMVSIM_INT_MASK_GPCNT1_IM_MASK;
1010 break;
1011 case kSMARTCARD_EnableGTV:
1012 /* Enable GTV specific interrupt */
1013 base->INT_MASK &= ~EMVSIM_INT_MASK_BGT_ERR_IM_MASK;
1014 break;
1015 case kSMARTCARD_DisableGTV:
1016 /* Disable GTV specific interrupt */
1017 base->INT_MASK |= EMVSIM_INT_MASK_BGT_ERR_IM_MASK;
1018 break;
1019 case kSMARTCARD_ResetWWT:
1020 /* Reset WWT Timer */
1021 base->CTRL &= ~(EMVSIM_CTRL_CWT_EN_MASK | EMVSIM_CTRL_BWT_EN_MASK);
1022 base->CTRL |= (EMVSIM_CTRL_CWT_EN_MASK | EMVSIM_CTRL_BWT_EN_MASK);
1023 break;
1024 case kSMARTCARD_EnableWWT:
1025 /* BGT must be masked */
1026 base->INT_MASK |= EMVSIM_INT_MASK_BGT_ERR_IM_MASK;
1027 /* Enable WWT Timer interrupt to occur */
1028 base->INT_MASK &= (~EMVSIM_INT_MASK_CWT_ERR_IM_MASK & ~EMVSIM_INT_MASK_BWT_ERR_IM_MASK);
1029 break;
1030 case kSMARTCARD_DisableWWT:
1031 /* Disable WWT Timer interrupt to occur */
1032 base->INT_MASK |= (EMVSIM_INT_MASK_CWT_ERR_IM_MASK | EMVSIM_INT_MASK_BWT_ERR_IM_MASK);
1033 break;
1034 case kSMARTCARD_ResetCWT:
1035 /* Reset CWT Timer */
1036 base->CTRL &= ~EMVSIM_CTRL_CWT_EN_MASK;
1037 base->CTRL |= EMVSIM_CTRL_CWT_EN_MASK;
1038 break;
1039 case kSMARTCARD_EnableCWT:
1040 base->CTRL |= EMVSIM_CTRL_CWT_EN_MASK;
1041 /* Enable CWT Timer interrupt to occur */
1042 base->INT_MASK &= ~EMVSIM_INT_MASK_CWT_ERR_IM_MASK;
1043 break;
1044 case kSMARTCARD_DisableCWT:
1045 /* CWT counter is for receive mode only */
1046 base->CTRL &= ~EMVSIM_CTRL_CWT_EN_MASK;
1047 /* Disable CWT Timer interrupt to occur */
1048 base->INT_MASK |= EMVSIM_INT_MASK_CWT_ERR_IM_MASK;
1049 break;
1050 case kSMARTCARD_ResetBWT:
1051 /* Reset BWT Timer */
1052 base->CTRL &= ~EMVSIM_CTRL_BWT_EN_MASK;
1053 base->CTRL |= EMVSIM_CTRL_BWT_EN_MASK;
1054 break;
1055 case kSMARTCARD_EnableBWT:
1056 base->CTRL |= EMVSIM_CTRL_BWT_EN_MASK;
1057 /* Enable BWT Timer interrupt to occur */
1058 base->INT_MASK &= ~EMVSIM_INT_MASK_BWT_ERR_IM_MASK;
1059 break;
1060 case kSMARTCARD_DisableBWT:
1061 /* Disable BWT Timer interrupt to occur */
1062 base->INT_MASK |= EMVSIM_INT_MASK_BWT_ERR_IM_MASK;
1063 break;
1064 case kSMARTCARD_EnableInitDetect:
1065 /* Clear all ISO7816 interrupt flags */
1066 base->RX_STATUS = 0xFFFFFFFFu;
1067 /* Enable initial character detection : hardware method */
1068 context->transferState = kSMARTCARD_WaitingForTSState;
1069 /* Enable initial character detection */
1070 base->CTRL |= EMVSIM_CTRL_ICM_MASK;
1071 base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK;
1072 break;
1073 case kSMARTCARD_EnableAnack:
1074 /* Enable NACK-on-error interrupt to occur */
1075 base->CTRL |= EMVSIM_CTRL_ANACK_MASK;
1076 break;
1077 case kSMARTCARD_DisableAnack:
1078 /* Disable NACK-on-error interrupt to occur */
1079 base->CTRL &= ~EMVSIM_CTRL_ANACK_MASK;
1080 break;
1081 case kSMARTCARD_ConfigureBaudrate:
1082 /* Set default baudrate/ETU time based on EMV parameters and card clock */
1083 base->DIVISOR = (((uint32_t)context->cardParams.Fi / context->cardParams.currentD) & 0x1FFu);
1084 break;
1085 case kSMARTCARD_SetupATRMode:
1086 /* Set in default ATR mode */
1087 smartcard_emvsim_SetTransferType(base, context, kSMARTCARD_SetupATRMode);
1088 break;
1089 case kSMARTCARD_SetupT0Mode:
1090 /* Set transport protocol type to T=0 */
1091 smartcard_emvsim_SetTransferType(base, context, kSMARTCARD_SetupT0Mode);
1092 break;
1093 case kSMARTCARD_SetupT1Mode:
1094 /* Set transport protocol type to T=1 */
1095 smartcard_emvsim_SetTransferType(base, context, kSMARTCARD_SetupT1Mode);
1096 break;
1097 case kSMARTCARD_EnableReceiverMode:
1098 /* Enable receiver mode and switch to receive direction */
1099 base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK;
1100 /* Set receiver threshold value to 1 */
1101 base->RX_THD = ((base->RX_THD & ~EMVSIM_RX_THD_RDT_MASK) | 1u);
1102 /* Enable RDT interrupt */
1103 base->INT_MASK &= ~EMVSIM_INT_MASK_RDT_IM_MASK;
1104 break;
1105 case kSMARTCARD_DisableReceiverMode:
1106 /* Disable receiver */
1107 base->CTRL &= ~EMVSIM_CTRL_RCV_EN_MASK;
1108 break;
1109 case kSMARTCARD_EnableTransmitterMode:
1110 /* Enable transmitter mode and switch to transmit direction */
1111 base->CTRL |= EMVSIM_CTRL_XMT_EN_MASK;
1112 break;
1113 case kSMARTCARD_DisableTransmitterMode:
1114 /* Disable transmitter */
1115 base->CTRL &= ~EMVSIM_CTRL_XMT_EN_MASK;
1116 break;
1117 case kSMARTCARD_ResetWaitTimeMultiplier:
1118 base->CTRL &= ~EMVSIM_CTRL_BWT_EN_MASK;
1119 /* Reset Wait Timer Multiplier
1120 * EMV Formula : WTX x (11 + ((2^BWI + 1) x 960 x D)) */
1121 temp32 = ((uint8_t)param) *
1122 (11u + ((((uint32_t)1u << context->cardParams.BWI) + 1u) * 960u * context->cardParams.currentD));
1123 #ifdef CARDSIM_EXTRADELAY_USED
1124 temp32 += context->cardParams.currentD * 50;
1125 #endif
1126 base->BWT_VAL = temp32;
1127 /* Set flag to SMARTCARD context accordingly */
1128 if (param > 1u)
1129 {
1130 context->wtxRequested = true;
1131 }
1132 else
1133 {
1134 context->wtxRequested = false;
1135 }
1136 base->CTRL |= EMVSIM_CTRL_BWT_EN_MASK;
1137 break;
1138 default:
1139 status = kStatus_SMARTCARD_InvalidInput;
1140 break;
1141 }
1142 return status;
1143 }
1144