Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:23:01

0001 /*
0002  * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
0003  * Copyright 2016-2019 NXP
0004  * All rights reserved.
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 
0009 #include "fsl_smartcard_emvsim.h"
0010 
0011 /* Component ID definition, used by tools. */
0012 #ifndef FSL_COMPONENT_ID
0013 #define FSL_COMPONENT_ID "platform.drivers.smartcard_emvsim"
0014 #endif
0015 
0016 /*******************************************************************************
0017  * Variables
0018  ******************************************************************************/
0019 /*! @brief Pointers to emvsim bases for each instance. */
0020 static EMVSIM_Type *const s_emvsimBases[] = EMVSIM_BASE_PTRS;
0021 
0022 /*! @brief Pointers to emvsim IRQ number for each instance. */
0023 static const IRQn_Type s_emvsimIRQ[] = EMVSIM_IRQS;
0024 
0025 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0026 /*! @brief Pointers to emvsim clocks for each instance. */
0027 static const clock_ip_name_t s_emvsimClock[] = EMVSIM_CLOCKS;
0028 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0029 
0030 /* #define CARDSIM_EXTRADELAY_USED */
0031 
0032 /*******************************************************************************
0033  * Private Functions
0034  ******************************************************************************/
0035 static void smartcard_emvsim_CompleteSendData(EMVSIM_Type *base, smartcard_context_t *context);
0036 static void smartcard_emvsim_StartSendData(EMVSIM_Type *base, smartcard_context_t *context);
0037 static void smartcard_emvsim_CompleteReceiveData(EMVSIM_Type *base, smartcard_context_t *context);
0038 static void smartcard_emvsim_StartReceiveData(EMVSIM_Type *base, smartcard_context_t *context);
0039 static void smartcard_emvsim_SetTransferType(EMVSIM_Type *base,
0040                                              smartcard_context_t *context,
0041                                              smartcard_control_t control);
0042 static uint32_t smartcard_emvsim_GetInstance(EMVSIM_Type *base);
0043 
0044 /*******************************************************************************
0045  * Code
0046  ******************************************************************************/
0047 /*!
0048  * @brief Get the UART instance from peripheral base address.
0049  *
0050  * @param base UART peripheral base address.
0051  * @return UART instance.
0052  */
0053 static uint32_t smartcard_emvsim_GetInstance(EMVSIM_Type *base)
0054 {
0055     uint8_t instance          = 0;
0056     uint32_t emvsimArrayCount = (sizeof(s_emvsimBases) / sizeof(s_emvsimBases[0]));
0057 
0058     /* Find the instance index from base address mappings. */
0059     for (instance = 0; instance < emvsimArrayCount; instance++)
0060     {
0061         if (s_emvsimBases[instance] == base)
0062         {
0063             break;
0064         }
0065     }
0066 
0067     assert(instance < emvsimArrayCount);
0068 
0069     return instance;
0070 }
0071 /*!
0072  * @brief Finish up a transmit by completing the process of sending data and disabling the interrupt.
0073  *
0074  * @param base The EMVSIM peripheral base address.
0075  * @param context A pointer to a SMARTCARD driver context structure.
0076  */
0077 static void smartcard_emvsim_CompleteSendData(EMVSIM_Type *base, smartcard_context_t *context)
0078 {
0079     assert((NULL != context));
0080 
0081     /* Disable ETC and TDT interrupt */
0082     base->INT_MASK |= (EMVSIM_INT_MASK_ETC_IM_MASK | EMVSIM_INT_MASK_TDT_IM_MASK);
0083 
0084     /* Disable transmitter */
0085     base->CTRL &= ~EMVSIM_CTRL_XMT_EN_MASK;
0086     /* Clear receive status flag */
0087     base->RX_STATUS = EMVSIM_RX_STATUS_RX_DATA_MASK;
0088     /* Enable Receiver */
0089     base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK;
0090     /* Update the information of the module driver context */
0091     context->xIsBusy       = false;
0092     context->transferState = kSMARTCARD_IdleState;
0093     /* Clear txSize to avoid any spurious transmit from ISR */
0094     context->xSize = 0u;
0095     /* Invoke user call-back */
0096     if (NULL != context->transferCallback)
0097     {
0098         context->transferCallback(context, context->transferCallbackParam);
0099     }
0100 }
0101 
0102 /*!
0103  * @brief Finish up a receive by completing the process of receiving data and disabling the interrupt.
0104  *
0105  * @param base The EMVSIM peripheral base address.
0106  * @param context A pointer to a SMARTCARD driver context structure.
0107  */
0108 static void smartcard_emvsim_CompleteReceiveData(EMVSIM_Type *base, smartcard_context_t *context)
0109 {
0110     assert((NULL != context));
0111 
0112     /* Disable RDT and RX_DATA interrupt */
0113     base->INT_MASK |= (EMVSIM_INT_MASK_RDT_IM_MASK | EMVSIM_INT_MASK_RX_DATA_IM_MASK);
0114 
0115     /* Read data from fifo */
0116     while (((base->RX_STATUS & EMVSIM_RX_STATUS_RX_CNT_MASK) != 0u) && ((context->xSize) > 0u))
0117     {
0118         /* Get data and put into receive buffer */
0119         *context->xBuff = (uint8_t)(base->RX_BUF);
0120         ++context->xBuff;
0121         --context->xSize;
0122     }
0123 
0124     /* Update the information of the module driver context */
0125     context->xIsBusy = false;
0126     /* Invoke user call-back */
0127     if (NULL != context->transferCallback)
0128     {
0129         context->transferCallback(context, context->transferCallbackParam);
0130     }
0131 }
0132 
0133 /*!
0134  * @brief Initiate (start) a transmit by beginning the process of sending data and enabling the interrupt.
0135  *
0136  * @param base The EMVSIM peripheral base address.
0137  * @param context A pointer to a SMARTCARD driver context structure.
0138  */
0139 static void smartcard_emvsim_StartSendData(EMVSIM_Type *base, smartcard_context_t *context)
0140 {
0141     assert((NULL != context));
0142 
0143     uint32_t delay   = 0u;
0144     uint32_t control = 0u;
0145 
0146     /* Block guard time */
0147     /* 22 etus (16 Receiver Clocks == 1 etu) */
0148     delay = 22u * 16u;
0149     /* Disable all functionality like protocol timers, NACK generation */
0150     control       = base->CTRL;
0151     base->CTRL    = 0u;
0152     base->TX_GETU = context->cardParams.GTN;
0153     /* Clear Global counter time-out flag */
0154     base->TX_STATUS = EMVSIM_TX_STATUS_GPCNT1_TO_MASK;
0155     /* Disable counter interrupt */
0156     base->INT_MASK |= EMVSIM_INT_MASK_GPCNT1_IM_MASK;
0157     /* Set counter value */
0158     base->GPCNT1_VAL = delay;
0159     /* Select the clock for GPCNT */
0160     base->CLKCFG =
0161         (base->CLKCFG & ~EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK) | EMVSIM_CLKCFG_GPCNT1_CLK_SEL(kEMVSIM_GPCRxClock);
0162     /* Trigger the counter */
0163     base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK;
0164     /* Wait until counter overflow event occur */
0165     while ((base->TX_STATUS & EMVSIM_TX_STATUS_GPCNT1_TO_MASK) == 0u)
0166     {
0167     }
0168     /* Clear status flag and disable GPCNT1 clock */
0169     base->TX_STATUS = EMVSIM_TX_STATUS_GPCNT1_TO_MASK;
0170     base->CLKCFG &= ~EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK;
0171     /* Restore Control register */
0172     base->CTRL = control & ~(EMVSIM_CTRL_XMT_EN_MASK | EMVSIM_CTRL_RCV_EN_MASK);
0173     /* Update transferState */
0174     context->transferState = kSMARTCARD_TransmittingState;
0175     context->xIsBusy       = true;
0176 
0177     /* Flush transmitter */
0178     base->CTRL |= EMVSIM_CTRL_FLSH_TX_MASK;
0179 
0180     /* Enable transmitter */
0181     base->CTRL |= EMVSIM_CTRL_XMT_EN_MASK;
0182 
0183     /* Set transmitter data threshold value to 0 - TDTF is set when the fifo is empty */
0184     base->TX_THD &= ~EMVSIM_TX_THD_TDT_MASK;
0185 
0186     /* Enable TDT interrupt */
0187     base->INT_MASK &= ~EMVSIM_INT_MASK_TDT_IM_MASK;
0188 }
0189 
0190 /*!
0191  * @brief Initiate (start) a receive by beginning the process of receiving data and enabling the interrupt.
0192  *
0193  * @param base The EMVSIM peripheral base address.
0194  * @param context A pointer to a SMARTCARD driver context structure.
0195  */
0196 static void smartcard_emvsim_StartReceiveData(EMVSIM_Type *base, smartcard_context_t *context)
0197 {
0198     assert((NULL != context));
0199 
0200     /* Initialize the module driver context structure to indicate transfer in progress */
0201     context->xIsBusy = true;
0202     /* Enable BWT Timer interrupt to occur */
0203     base->INT_MASK &= ~EMVSIM_INT_MASK_BWT_ERR_IM_MASK;
0204     /* Disable transmitter */
0205     base->CTRL &= ~EMVSIM_CTRL_XMT_EN_MASK;
0206     /* Enable receiver and switch to receive direction */
0207     base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK;
0208 
0209     /* Set rx threshold value - number of bytes that must exist in the Receive FIFO to trigger the receive data
0210      * threshold interrupt flag (RDTF).*/
0211     if (context->xSize < context->rxFifoThreshold)
0212     {
0213         uint32_t rx_thd;
0214         rx_thd = (base->RX_THD & ~EMVSIM_RX_THD_RDT_MASK);
0215         rx_thd |= context->xSize;
0216         base->RX_THD = rx_thd;
0217     }
0218     else
0219     {
0220         base->RX_THD = ((base->RX_THD & ~EMVSIM_RX_THD_RDT_MASK) | context->rxFifoThreshold);
0221     }
0222 
0223     /* Enable RDT interrupt - count of bytes in rx fifo is equal or greater than threshold RX_THD[RDT] */
0224     base->INT_MASK &= ~EMVSIM_INT_MASK_RDT_IM_MASK;
0225 
0226     if (context->tType == kSMARTCARD_T1Transport)
0227     {
0228         /* Enable interrupt when new byte is received - in T=1 is necessary to disable BWT interrupt and enable CWT
0229          * interrupt after receiving the first byte */
0230         base->INT_MASK &= ~EMVSIM_INT_MASK_RX_DATA_IM_MASK;
0231     }
0232 }
0233 
0234 /*!
0235  * @brief Sets up the EMVSIM hardware for T=0 or T=1 protocol data exchange and initialize timer values.
0236  *
0237  * @param base The EMVSIM peripheral base address.
0238  * @param context A pointer to a SMARTCARD driver context structure.
0239  */
0240 static void smartcard_emvsim_SetTransferType(EMVSIM_Type *base,
0241                                              smartcard_context_t *context,
0242                                              smartcard_control_t control)
0243 {
0244     assert((NULL != context));
0245     assert((control == kSMARTCARD_SetupATRMode) || (control == kSMARTCARD_SetupT0Mode) ||
0246            (control == kSMARTCARD_SetupT1Mode));
0247 
0248     uint16_t temp16 = 0u;
0249     uint32_t bwiVal = 0u;
0250     uint8_t tdt     = 0u;
0251 
0252     if (control == kSMARTCARD_SetupATRMode)
0253     {
0254         /* Disable all functionality at first */
0255         base->CTRL &= ~(EMVSIM_CTRL_RCVR_11_MASK | EMVSIM_CTRL_XMT_CRC_LRC_MASK | EMVSIM_CTRL_LRC_EN_MASK |
0256                         EMVSIM_CTRL_ANACK_MASK | EMVSIM_CTRL_ONACK_MASK | EMVSIM_CTRL_RCV_EN_MASK);
0257         /* Set default values as per EMV specification */
0258         context->cardParams.Fi       = 372u;
0259         context->cardParams.Di       = 1u;
0260         context->cardParams.currentD = 1u;
0261         context->cardParams.WI       = 0x0Au;
0262         context->cardParams.GTN      = 0x00u;
0263         /* Set default baudrate/ETU time based on EMV parameters and card clock */
0264         base->DIVISOR = (((uint32_t)context->cardParams.Fi / context->cardParams.currentD) & 0x1FFu);
0265         /* EMV expectation: WWT = (960 x D x WI) + (D x 480)
0266          * EMVSIM formula: BWT_VAL[15:0] = CWT_VAL[15:0] */
0267         temp16 = (960u * context->cardParams.currentD * context->cardParams.WI) +
0268                  (context->cardParams.currentD * 480u) + SMARTCARD_WWT_ADJUSTMENT;
0269         base->CWT_VAL = temp16;
0270         base->BWT_VAL = temp16;
0271         /* Set Extended Guard Timer value
0272          * EMV expectation: GT = GTN not equal to 255 -> 12 + GTN = GTN equal to 255 -> 12
0273          * EMVSIM formula: same as above */
0274         base->TX_GETU = context->cardParams.GTN;
0275         /* Setting Rx threshold so that an interrupt is generated when a NACK is
0276            sent either due to parity error or wrong INIT char*/
0277         base->RX_THD = EMVSIM_RX_THD_RDT(1);
0278         /* Setting up Tx NACK threshold */
0279         tdt = (uint8_t)(((base->PARAM & EMVSIM_PARAM_TX_FIFO_DEPTH_MASK) >> EMVSIM_PARAM_TX_FIFO_DEPTH_SHIFT) - 1u);
0280         base->TX_THD = (EMVSIM_TX_THD_TNCK_THD(SMARTCARD_EMV_TX_NACK_THRESHOLD) | EMVSIM_TX_THD_TDT(tdt));
0281         /* Clear all pending interrupts */
0282         base->RX_STATUS = 0xFFFFFFFFu;
0283         /* Enable Tx NACK threshold interrupt to occur */
0284         base->INT_MASK &= ~EMVSIM_INT_MASK_TNACK_IM_MASK;
0285         /* Set transport type to T=0 in SMARTCARD context structure */
0286         context->tType = kSMARTCARD_T0Transport;
0287     }
0288     else if (control == kSMARTCARD_SetupT0Mode)
0289     {
0290         /* Disable receiver at first if it's not, Disable T=0 mode counters 1st,
0291          * Setup for single wire ISO7816 mode (setup 12 etu mode).
0292          * Set transport protocol type to T=0, Disable initial character detection.*/
0293         base->CTRL &=
0294             ~(EMVSIM_CTRL_RCV_EN_MASK | EMVSIM_CTRL_CWT_EN_MASK | EMVSIM_CTRL_BWT_EN_MASK | EMVSIM_CTRL_RCVR_11_MASK |
0295               EMVSIM_CTRL_XMT_CRC_LRC_MASK | EMVSIM_CTRL_LRC_EN_MASK | EMVSIM_CTRL_ICM_MASK);
0296         /* EMV expectation: WWT = (960 x D x WI) + (D x 480)
0297          * EMVSIM formula: BWT_VAL[15:0] = CWT_VAL[15:0]  */
0298         temp16 = (960u * context->cardParams.currentD * context->cardParams.WI) +
0299                  (context->cardParams.currentD * 480u) + SMARTCARD_WWT_ADJUSTMENT;
0300         base->CWT_VAL = temp16;
0301         base->BWT_VAL = temp16;
0302         /* Set Extended Guard Timer value
0303          * EMV expectation: GT = GTN not equal to 255 -> 12 + GTN = GTN equal to 255 -> 12
0304          * EMVSIM formula: same as above for range [0:254]
0305          * Fix for EMV. If TX_GETU == 0 in T0 mode, 3 stop bits are inserted. */
0306         context->cardParams.GTN = (context->cardParams.GTN == 0xFFu) ? 0x00u : context->cardParams.GTN;
0307         base->TX_GETU           = context->cardParams.GTN;
0308         /* Setting Rx threshold so that an interrupt is generated when a NACK is
0309         sent either due to parity error or wrong INIT char */
0310         base->RX_THD = (EMVSIM_RX_THD_RNCK_THD(SMARTCARD_EMV_RX_NACK_THRESHOLD) | EMVSIM_RX_THD_RDT(1));
0311         /* Setting up Tx NACK threshold */
0312         tdt = (uint8_t)(((base->PARAM & EMVSIM_PARAM_TX_FIFO_DEPTH_MASK) >> EMVSIM_PARAM_TX_FIFO_DEPTH_SHIFT) - 1u);
0313         base->TX_THD = (EMVSIM_TX_THD_TNCK_THD(SMARTCARD_EMV_TX_NACK_THRESHOLD) | EMVSIM_TX_THD_TDT(tdt));
0314         /* Enable Tx NACK threshold interrupt to occur */
0315         base->INT_MASK &= ~EMVSIM_INT_MASK_TNACK_IM_MASK;
0316         /* Enable T=0 mode counters, Enable NACK on error interrupt and NACK on overflow interrupt */
0317         base->CTRL |=
0318             (EMVSIM_CTRL_CWT_EN_MASK | EMVSIM_CTRL_BWT_EN_MASK | EMVSIM_CTRL_ANACK_MASK | EMVSIM_CTRL_ONACK_MASK);
0319         /* Set transport type to T=0 in SMARTCARD context structure */
0320         context->tType = kSMARTCARD_T0Transport;
0321     }
0322     else
0323     { /* Disable T=1 mode counters 1st, Disable NACK on error interrupt, Disable NACK on overflow interrupt */
0324         base->CTRL &= ~(EMVSIM_CTRL_CWT_EN_MASK | EMVSIM_CTRL_BWT_EN_MASK | EMVSIM_CTRL_ANACK_MASK |
0325                         EMVSIM_CTRL_ONACK_MASK | EMVSIM_CTRL_XMT_CRC_LRC_MASK | EMVSIM_CTRL_LRC_EN_MASK);
0326         /* Calculate and set Block Wait Timer (BWT) value
0327          * EMV expectation: BWT = 11 + (2^BWI x 960 x D) + (D x 960) = 11 + (2^BWI + 1) x 960 x D
0328          * EMVSIM formula: BWT = Same */
0329         bwiVal = 11u + ((((uint32_t)1u << context->cardParams.BWI) + 1u) * 960u * context->cardParams.currentD);
0330 #ifdef CARDSIM_EXTRADELAY_USED
0331         base->BWT_VAL = bwiVal + 100u;
0332 #else
0333         base->BWT_VAL = bwiVal;
0334 #endif
0335         /* Calculate and set Character Wait Timer (CWT) value
0336          * EMV expectation: CWT = ((2^CWI + 11) + 4)
0337          * EMVSIM formula: CWT = Same */
0338         if (context->cardParams.currentD == 1u)
0339         {
0340 #ifdef CARDSIM_EXTRADELAY_USED
0341             temp16 = ((uint16_t)1u << context->cardParams.CWI) + 16u;
0342 #else
0343             temp16 = ((uint16_t)1u << context->cardParams.CWI) + 15u;
0344 #endif
0345         }
0346         else
0347         {
0348 #ifdef CARDSIM_EXTRADELAY_USED
0349             temp16 = ((uint16_t)1u << context->cardParams.CWI) + 20u + SMARTCARD_CWT_ADJUSTMENT;
0350 #else
0351             temp16 = ((uint16_t)1u << context->cardParams.CWI) + 15u + SMARTCARD_CWT_ADJUSTMENT;
0352 #endif
0353         }
0354         /* EMV = 15, ISO = 11,
0355          * EMV expectation: BGT = 22
0356          * EMVSIM formula: BGT = Same */
0357         base->CWT_VAL           = temp16;
0358         context->cardParams.BGI = 22u;
0359         base->BGT_VAL           = context->cardParams.BGI;
0360         /* Set Extended Guard Timer value
0361          * EMV expectation: GT = GTN not equal to 255 -> 12 + GTN = GTN equal to 255 -> 11
0362          * EMVSIM formula: same as above */
0363         base->TX_GETU = context->cardParams.GTN;
0364         /* Setup for single wire ISO7816 mode,
0365          * Set transport protocol type to T=1, Enable T=0 mode counters */
0366         base->CTRL |= (EMVSIM_CTRL_RCVR_11_MASK | EMVSIM_CTRL_CWT_EN_MASK | EMVSIM_CTRL_BWT_EN_MASK);
0367         /* Setting Rx threshold */
0368         base->RX_THD = (EMVSIM_RX_THD_RNCK_THD(SMARTCARD_EMV_RX_NACK_THRESHOLD) | EMVSIM_RX_THD_RDT(1));
0369         /* Setting up Tx threshold */
0370         tdt = (uint8_t)(((base->PARAM & EMVSIM_PARAM_TX_FIFO_DEPTH_MASK) >> EMVSIM_PARAM_TX_FIFO_DEPTH_SHIFT) - 1u);
0371         base->TX_THD = (EMVSIM_TX_THD_TDT(tdt) | EMVSIM_TX_THD_TNCK_THD(SMARTCARD_EMV_TX_NACK_THRESHOLD));
0372         /* Set transport type to T=1 in SMARTCARD context structure */
0373         context->tType = kSMARTCARD_T1Transport;
0374     }
0375 }
0376 
0377 /*!
0378  * brief Fills in the smartcard_card_params structure with default values according to the EMV 4.3 specification.
0379  *
0380  * param cardParams The configuration structure of type smartcard_interface_config_t.
0381  * Function fill in members:
0382  *        Fi = 372;
0383  *        Di = 1;
0384  *        currentD = 1;
0385  *        WI = 0x0A;
0386  *        GTN = 0x00;
0387  * with default values.
0388  */
0389 void SMARTCARD_EMVSIM_GetDefaultConfig(smartcard_card_params_t *cardParams)
0390 {
0391     /* Initializes the configure structure to zero. */
0392     (void)memset(cardParams, 0, sizeof(*cardParams));
0393 
0394     /* EMV default values */
0395     cardParams->Fi       = 372u;
0396     cardParams->Di       = 1u;
0397     cardParams->currentD = 1u;
0398     cardParams->WI       = 0x0Au;
0399     cardParams->GTN      = 0x00u;
0400 }
0401 
0402 /*!
0403  * brief Initializes an EMVSIM peripheral for the Smart card/ISO-7816 operation.
0404  *
0405  * This function un-gates the EMVSIM clock, initializes the module to EMV default settings,
0406  * configures the IRQ, enables the module-level interrupt to the core and, initializes the driver context.
0407  *
0408  * param base The EMVSIM peripheral base address.
0409  * param context A pointer to the smart card driver context structure.
0410  * param srcClock_Hz Smart card clock generation module source clock.
0411  *
0412  * return An error code or kStatus_SMARTCARD_Success.
0413  */
0414 status_t SMARTCARD_EMVSIM_Init(EMVSIM_Type *base, smartcard_context_t *context, uint32_t srcClock_Hz)
0415 {
0416     assert((NULL != base));
0417 
0418     if ((NULL == context) || (srcClock_Hz == 0u))
0419     {
0420         return kStatus_SMARTCARD_InvalidInput;
0421     }
0422 
0423     uint32_t instance = smartcard_emvsim_GetInstance(base);
0424 /* Set source clock for EMVSIM MCGPLLCLK */
0425 #if (defined(FSL_FEATURE_SOC_MCG_COUNT) && FSL_FEATURE_SOC_MCG_COUNT)
0426     CLOCK_SetEmvsimClock(1u);
0427 #endif
0428 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0429     /* Enable emvsim clock */
0430     CLOCK_EnableClock(s_emvsimClock[instance]);
0431 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0432     context->base = base;
0433     /* Initialize EMVSIM to a known context. */
0434     base->CLKCFG     = 0u;
0435     base->DIVISOR    = 372u;
0436     base->CTRL       = 0x300u;
0437     base->INT_MASK   = 0x7FFFu;
0438     base->RX_THD     = 1u;
0439     base->TX_THD     = 0u;
0440     base->PCSR       = 0x1000000u;
0441     base->TX_GETU    = 0u;
0442     base->CWT_VAL    = 0xFFFFu;
0443     base->BWT_VAL    = 0xFFFFFFFFu;
0444     base->BGT_VAL    = 0u;
0445     base->GPCNT0_VAL = 0xFFFFu;
0446     base->GPCNT1_VAL = 0xFFFFu;
0447     /* Initialize EMVSIM module for SMARTCARD mode of default operation */
0448     smartcard_emvsim_SetTransferType(base, context, kSMARTCARD_SetupATRMode);
0449     /* Store information about tx fifo depth */
0450     context->txFifoEntryCount =
0451         (uint8_t)((base->PARAM & EMVSIM_PARAM_TX_FIFO_DEPTH_MASK) >> EMVSIM_PARAM_TX_FIFO_DEPTH_SHIFT);
0452     /* Compute max value of rx fifo threshold */
0453     context->rxFifoThreshold =
0454         (uint8_t)((base->PARAM & EMVSIM_PARAM_RX_FIFO_DEPTH_MASK) >> EMVSIM_PARAM_RX_FIFO_DEPTH_SHIFT);
0455     if ((EMVSIM_RX_THD_RDT_MASK >> EMVSIM_RX_THD_RDT_SHIFT) < context->rxFifoThreshold)
0456     {
0457         context->rxFifoThreshold = (EMVSIM_RX_THD_RDT_MASK >> EMVSIM_RX_THD_RDT_SHIFT);
0458     }
0459 /* Enable EMVSIM interrupt on NVIC level. */
0460 #if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && FSL_FEATURE_SOC_INTMUX_COUNT
0461     if ((uint32_t)s_emvsimIRQ[instance] < (uint32_t)FSL_FEATURE_INTMUX_IRQ_START_INDEX)
0462     {
0463         NVIC_EnableIRQ(s_emvsimIRQ[instance]);
0464     }
0465 #else
0466     NVIC_EnableIRQ(s_emvsimIRQ[instance]);
0467 #endif
0468     /* Finally, disable the EMVSIM receiver and transmitter */
0469     base->CTRL &= ~EMVSIM_CTRL_XMT_EN_MASK & ~EMVSIM_CTRL_RCV_EN_MASK;
0470 
0471     return kStatus_SMARTCARD_Success;
0472 }
0473 
0474 /*!
0475  * brief This function disables the EMVSIM interrupts, disables the transmitter and receiver,
0476  * flushes the FIFOs, and gates EMVSIM clock in SIM.
0477  *
0478  * param base The EMVSIM module base address.
0479  */
0480 void SMARTCARD_EMVSIM_Deinit(EMVSIM_Type *base)
0481 {
0482     uint32_t instance = 0u;
0483     /* In case there is still data in the TX FIFO or shift register that is
0484      * being transmitted wait till transmit is complete.
0485      * Wait until the data is completely shifted out of shift register */
0486     if ((base->TX_STATUS & EMVSIM_TX_STATUS_TX_CNT_MASK) != 0u)
0487     {
0488         while ((base->TX_STATUS & EMVSIM_TX_STATUS_ETCF_MASK) == 0u)
0489         {
0490         }
0491     }
0492     instance = smartcard_emvsim_GetInstance(base);
0493     /* Disable TX and RX */
0494     base->CTRL &= ~EMVSIM_CTRL_XMT_EN_MASK & ~EMVSIM_CTRL_RCV_EN_MASK;
0495 #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
0496     /* Gate EMVSIM module clock */
0497     CLOCK_DisableClock(s_emvsimClock[instance]);
0498 #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
0499 /* Disable emvsim interrupt in NVIC */
0500 #if defined(FSL_FEATURE_SOC_INTMUX_COUNT) && FSL_FEATURE_SOC_INTMUX_COUNT
0501     if ((uint32_t)s_emvsimIRQ[instance] < (uint32_t)FSL_FEATURE_INTMUX_IRQ_START_INDEX)
0502     {
0503         NVIC_DisableIRQ(s_emvsimIRQ[instance]);
0504     }
0505 #else
0506     NVIC_DisableIRQ(s_emvsimIRQ[instance]);
0507 #endif
0508 }
0509 
0510 /*!
0511  * brief Transfer data using interrupts.
0512  *
0513  * A non-blocking (also known as asynchronous) function means that the function returns
0514  * immediately after initiating the transfer function. The application has to get the
0515  * transfer status to see when the transfer is complete. In other words, after calling the non-blocking
0516  * (asynchronous) transfer function, the application must get the transfer status to check if the transmit
0517  * is completed or not.
0518  *
0519  * param base The EMVSIM peripheral base address.
0520  * param context A pointer to a smart card driver context structure.
0521  * param xfer A pointer to the smart card transfer structure where the linked buffers and sizes are stored.
0522  *
0523  * return An error code or kStatus_SMARTCARD_Success.
0524  */
0525 status_t SMARTCARD_EMVSIM_TransferNonBlocking(EMVSIM_Type *base, smartcard_context_t *context, smartcard_xfer_t *xfer)
0526 {
0527     if ((NULL == context) || (NULL == xfer) || (xfer->buff == NULL))
0528     {
0529         return kStatus_SMARTCARD_InvalidInput;
0530     }
0531 
0532     /* Check input parameters */
0533     if ((0u == xfer->size))
0534     {
0535         return kStatus_SMARTCARD_Success;
0536     }
0537     /* Check if some transfer is in progress */
0538     if (0 != SMARTCARD_EMVSIM_GetTransferRemainingBytes(base, context))
0539     {
0540         if (kSMARTCARD_Receive == context->direction)
0541         {
0542             return kStatus_SMARTCARD_RxBusy;
0543         }
0544         else
0545         {
0546             return kStatus_SMARTCARD_TxBusy;
0547         }
0548     }
0549     /* Initialize error check flags */
0550     context->rxtCrossed  = false;
0551     context->txtCrossed  = false;
0552     context->parityError = false;
0553     /* Initialize SMARTCARD context structure to start transfer */
0554     context->xBuff = xfer->buff;
0555     context->xSize = xfer->size;
0556 
0557     if (kSMARTCARD_Receive == xfer->direction)
0558     {
0559         context->direction     = xfer->direction;
0560         context->transferState = kSMARTCARD_ReceivingState;
0561         /* Start transfer */
0562         smartcard_emvsim_StartReceiveData(base, context);
0563     }
0564     else if (kSMARTCARD_Transmit == xfer->direction)
0565     {
0566         context->direction     = xfer->direction;
0567         context->transferState = kSMARTCARD_TransmittingState;
0568         /* Start transfer */
0569         smartcard_emvsim_StartSendData(base, context);
0570     }
0571     else
0572     {
0573         return kStatus_SMARTCARD_InvalidInput;
0574     }
0575 
0576     return kStatus_SMARTCARD_Success;
0577 }
0578 
0579 /*!
0580  * brief Returns whether the previous EMVSIM transfer has finished.
0581  *
0582  * When performing an async transfer, call this function to ascertain the context of the
0583  * current transfer: in progress (or busy) or complete (success). If the
0584  * transfer is still in progress, the user can obtain the number of words that have not been
0585  * transferred.
0586  *
0587  * param base The EMVSIM module base address.
0588  * param context A pointer to a smart card driver context structure.
0589  *
0590  * return The number of bytes not transferred.
0591  */
0592 int32_t SMARTCARD_EMVSIM_GetTransferRemainingBytes(EMVSIM_Type *base, smartcard_context_t *context)
0593 {
0594     if ((NULL == context))
0595     {
0596         return -1;
0597     }
0598     if (context->xIsBusy)
0599     {
0600         if (context->direction == kSMARTCARD_Transmit)
0601         {
0602             /* Count of bytes in buffer + data in fifo */
0603             uint32_t count;
0604             count = context->xSize;
0605             count += ((base->TX_STATUS & EMVSIM_TX_STATUS_TX_CNT_MASK) >> EMVSIM_TX_STATUS_TX_CNT_SHIFT);
0606             return (int32_t)count;
0607         }
0608         return (int32_t)context->xSize;
0609     }
0610 
0611     return 0;
0612 }
0613 
0614 /*!
0615  * brief Terminates an asynchronous EMVSIM transfer early.
0616  *
0617  * During an async EMVSIM transfer, the user can terminate the transfer early
0618  * if the transfer is still in progress.
0619  *
0620  * param base The EMVSIM peripheral address.
0621  * param context A pointer to a smart card driver context structure.
0622  * retval kStatus_SMARTCARD_Success The transmit abort was successful.
0623  * retval kStatus_SMARTCARD_NoTransmitInProgress No transmission is currently in progress.
0624  */
0625 status_t SMARTCARD_EMVSIM_AbortTransfer(EMVSIM_Type *base, smartcard_context_t *context)
0626 {
0627     if ((NULL == context))
0628     {
0629         return kStatus_SMARTCARD_InvalidInput;
0630     }
0631 
0632     context->abortTransfer = true;
0633 
0634     /* Check if a transfer is running. */
0635     if ((!context->xIsBusy))
0636     {
0637         return kStatus_SMARTCARD_NoTransferInProgress;
0638     }
0639     /* Call transfer complete to abort transfer */
0640     if (kSMARTCARD_Receive == context->direction)
0641     { /* Stop the running transfer. */
0642         smartcard_emvsim_CompleteReceiveData(base, context);
0643     }
0644     else if (kSMARTCARD_Transmit == context->direction)
0645     { /* Stop the running transfer. */
0646         smartcard_emvsim_CompleteSendData(base, context);
0647     }
0648     else
0649     {
0650         return kStatus_SMARTCARD_InvalidInput;
0651     }
0652 
0653     return kStatus_SMARTCARD_Success;
0654 }
0655 
0656 /*!
0657  * brief Handles EMVSIM module interrupts.
0658  *
0659  * param base The EMVSIM peripheral base address.
0660  * param context A pointer to a smart card driver context structure.
0661  */
0662 void SMARTCARD_EMVSIM_IRQHandler(EMVSIM_Type *base, smartcard_context_t *context)
0663 {
0664     if (NULL == context)
0665     {
0666         return;
0667     }
0668 
0669     /* Check card insertion/removal interrupt occurs, only EMVSIM DIRECT interface driver using enables this interrupt
0670      * to occur */
0671     if (((base->PCSR & EMVSIM_PCSR_SPDIM_MASK) == 0u) && ((base->PCSR & EMVSIM_PCSR_SPDIF_MASK) != 0u))
0672     {
0673         /* Clear card presence interrupt status */
0674         base->PCSR |= EMVSIM_PCSR_SPDIF_MASK;
0675         /* Set PD signal edge behaviour */
0676         if (((emvsim_presence_detect_edge_t)(uint32_t)((base->PCSR & EMVSIM_PCSR_SPDES_MASK) >>
0677                                                        EMVSIM_PCSR_SPDES_SHIFT) == kEMVSIM_DetectOnFallingEdge) &&
0678             ((emvsim_presence_detect_status_t)(uint32_t)((base->PCSR & EMVSIM_PCSR_SPDP_MASK) >>
0679                                                          EMVSIM_PCSR_SPDP_SHIFT) == kEMVSIM_DetectPinIsLow))
0680         { /* Set rising edge interrupt */
0681             base->PCSR |= EMVSIM_PCSR_SPDES_MASK;
0682         }
0683         if (((emvsim_presence_detect_edge_t)(uint32_t)((base->PCSR & EMVSIM_PCSR_SPDES_MASK) >>
0684                                                        EMVSIM_PCSR_SPDES_SHIFT) == kEMVSIM_DetectOnRisingEdge) &&
0685             ((emvsim_presence_detect_status_t)(uint32_t)((base->PCSR & EMVSIM_PCSR_SPDP_MASK) >>
0686                                                          EMVSIM_PCSR_SPDP_SHIFT) == kEMVSIM_DetectPinIsHigh))
0687         { /* Set falling edge interrupt */
0688             base->PCSR &= ~EMVSIM_PCSR_SPDES_MASK;
0689         }
0690         /* Card presence(insertion)/removal detected */
0691         /* Invoke callback if there is one */
0692         if (NULL != context->interfaceCallback)
0693         {
0694             context->interfaceCallback(context, context->interfaceCallbackParam);
0695         }
0696         return;
0697     }
0698     /* Check if timer for initial character (TS) detection has expired */
0699     if (((base->INT_MASK & EMVSIM_INT_MASK_GPCNT0_IM_MASK) >> EMVSIM_INT_MASK_GPCNT0_IM_SHIFT == 0u) &&
0700         ((base->TX_STATUS & EMVSIM_TX_STATUS_GPCNT0_TO_MASK) != 0u))
0701     {
0702         /* Disable TS and ADT timers by clearing source clock to 0 */
0703         base->CLKCFG &= ~(EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK | EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK);
0704         context->timersState.initCharTimerExpired = true;
0705         /* Disable and clear GPCNT interrupt */
0706         base->INT_MASK |= EMVSIM_INT_MASK_GPCNT0_IM_MASK;
0707         base->TX_STATUS = EMVSIM_TX_STATUS_GPCNT0_TO_MASK;
0708         /* Down counter trigger, and clear any pending counter status flag */
0709         base->CTRL &= ~EMVSIM_CTRL_RCV_EN_MASK;
0710         base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK;
0711         context->transferState = kSMARTCARD_IdleState;
0712         /* Unblock the caller */
0713         smartcard_emvsim_CompleteReceiveData(base, context);
0714         return;
0715     }
0716     /* Check if timer for ATR duration timer has expired */
0717     if (((base->INT_MASK & EMVSIM_INT_MASK_GPCNT1_IM_MASK) == 0u) &&
0718         ((base->TX_STATUS & EMVSIM_TX_STATUS_GPCNT1_TO_MASK) != 0u))
0719     { /* Disable clock counter by clearing source clock to 0 */
0720         base->CLKCFG &= ~EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK;
0721         /* Disable and clear GPCNT interrupt */
0722         base->INT_MASK |= EMVSIM_INT_MASK_GPCNT1_IM_MASK;
0723         base->TX_STATUS                 = EMVSIM_TX_STATUS_GPCNT1_TO_MASK;
0724         context->timersState.adtExpired = true;
0725         /* Unblock the caller */
0726         smartcard_emvsim_CompleteReceiveData(base, context);
0727         return;
0728     }
0729     /*
0730      * Check if a parity error was indicated.
0731      * A parity error will cause transmission of NACK if ANACK bit is set in
0732      * CTRL register and PEF bit will not be asserted. When ANACK is not set,
0733      * PEF will be asserted.
0734      */
0735     if ((base->RX_STATUS & EMVSIM_RX_STATUS_PEF_MASK) != 0u)
0736     {
0737         context->parityError = true;
0738         /* Clear parity error indication */
0739         base->RX_STATUS = EMVSIM_RX_STATUS_PEF_MASK;
0740     }
0741     /* Check if transmit NACK generation threshold was reached */
0742     if ((base->TX_STATUS & EMVSIM_TX_STATUS_TNTE_MASK) != 0u)
0743     {
0744         context->txtCrossed = true;
0745         /* Disable transmit NACK threshold interrupt */
0746         base->INT_MASK |= EMVSIM_INT_MASK_TNACK_IM_MASK;
0747         /* Clear transmit NACK threshold error flag */
0748         base->TX_STATUS = EMVSIM_TX_STATUS_TNTE_MASK;
0749         /* Unblock the caller */
0750         smartcard_emvsim_CompleteSendData(base, context);
0751         return;
0752     }
0753     /* Check if receive NACK generation threshold was reached */
0754     if ((base->RX_STATUS & EMVSIM_RX_STATUS_RTE_MASK) != 0u)
0755     {
0756         context->rxtCrossed = true;
0757         /* Clear receiver NACK threshold interrupt status */
0758         base->RX_STATUS = EMVSIM_RX_STATUS_RTE_MASK;
0759         if (context->xIsBusy)
0760         { /* Unblock the caller */
0761             smartcard_emvsim_CompleteReceiveData(base, context);
0762         }
0763     }
0764     /* Check if a Character Wait Timer expired */
0765     if (((base->INT_MASK & EMVSIM_INT_MASK_CWT_ERR_IM_MASK) == 0u) &&
0766         ((base->RX_STATUS & EMVSIM_RX_STATUS_CWT_ERR_MASK) != 0u))
0767     { /* Disable Character Wait Timer interrupt */
0768         base->INT_MASK |= EMVSIM_INT_MASK_CWT_ERR_IM_MASK;
0769         /* Reset the counter */
0770         base->CTRL &= ~EMVSIM_CTRL_CWT_EN_MASK;
0771         /* Clear interrupt status */
0772         base->RX_STATUS = EMVSIM_RX_STATUS_CWT_ERR_MASK;
0773         /* Enable CWT timer */
0774         base->CTRL |= EMVSIM_CTRL_CWT_EN_MASK;
0775         context->transferState = kSMARTCARD_IdleState;
0776 
0777         if (kSMARTCARD_T0Transport == context->tType)
0778         { /* Indicate WWT expired */
0779             context->timersState.wwtExpired = true;
0780         }
0781         else
0782         { /* Indicate CWT expired */
0783             context->timersState.cwtExpired = true;
0784         }
0785         if (context->xIsBusy)
0786         { /* Terminate and unblock any caller */
0787             smartcard_emvsim_CompleteReceiveData(base, context);
0788         }
0789     }
0790     /* Check if a Block Wait Timer expired */
0791     if (((base->INT_MASK & EMVSIM_INT_MASK_BWT_ERR_IM_MASK) == 0u) &&
0792         ((base->RX_STATUS & EMVSIM_RX_STATUS_BWT_ERR_MASK) != 0u))
0793     { /* Disable Block Wait Timer interrupt */
0794         base->INT_MASK |= EMVSIM_INT_MASK_BWT_ERR_IM_MASK;
0795         /* Clear interrupt status flag */
0796         base->CTRL &= ~EMVSIM_CTRL_BWT_EN_MASK;
0797         /* Clear error */
0798         base->RX_STATUS = EMVSIM_RX_STATUS_BWT_ERR_MASK;
0799         /* Enable BWT timer */
0800         base->CTRL |= EMVSIM_CTRL_BWT_EN_MASK;
0801 
0802         if (kSMARTCARD_T0Transport == context->tType)
0803         { /* Indicate WWT expired */
0804             context->timersState.wwtExpired = true;
0805         }
0806         else
0807         { /* Indicate BWT expired */
0808             context->timersState.bwtExpired = true;
0809         }
0810         /* Check if Wait Time Extension(WTX) was requested */
0811         if (context->wtxRequested)
0812         { /* Reset WTX to default */
0813             (void)SMARTCARD_EMVSIM_Control(base, context, kSMARTCARD_ResetWaitTimeMultiplier, 1u);
0814         }
0815         if (context->xIsBusy)
0816         { /* Terminate and unblock any caller */
0817             smartcard_emvsim_CompleteReceiveData(base, context);
0818         }
0819     }
0820 
0821     /* RX_DATA IRQ */
0822     /* Used in T=1 after receive 1st byte - disable BWT and enable CWT interrupt */
0823     if (((base->INT_MASK & EMVSIM_INT_MASK_RX_DATA_IM_MASK) == 0u) &&
0824         ((base->RX_STATUS & EMVSIM_RX_STATUS_RX_DATA_MASK) != 0u))
0825     {
0826         if ((context->tType == kSMARTCARD_T1Transport) && (context->xSize > 0u) &&
0827             ((base->INT_MASK & EMVSIM_INT_MASK_BWT_ERR_IM_MASK) == 0u))
0828         {
0829             context->timersState.cwtExpired = false;
0830             /* Clear CWT error flag */
0831             base->RX_STATUS = EMVSIM_RX_STATUS_CWT_ERR_MASK;
0832             /* Enable CWT */
0833             base->CTRL |= EMVSIM_CTRL_CWT_EN_MASK;
0834             /* Only the 1st byte has been received, now time to disable BWT interrupt and enable CWT interrupt */
0835             base->INT_MASK = (base->INT_MASK & ~EMVSIM_INT_MASK_CWT_ERR_IM_MASK) | EMVSIM_INT_MASK_BWT_ERR_IM_MASK;
0836         }
0837         /* Disable interrupt when is received new byte */
0838         base->INT_MASK |= EMVSIM_INT_MASK_RX_DATA_IM_MASK;
0839     }
0840 
0841     /* RDT IRQ - count of bytes in rx fifo reached the rx threshold value RX_THD[RDT] */
0842     if (((base->INT_MASK & EMVSIM_INT_MASK_RDT_IM_MASK) == 0u) &&
0843         ((base->RX_STATUS & EMVSIM_RX_STATUS_RDTF_MASK) != 0u))
0844     {
0845         if (kSMARTCARD_WaitingForTSState == context->transferState)
0846         {
0847             /* Read byte */
0848             (void)(base->RX_BUF);
0849 
0850             if ((base->CTRL & EMVSIM_CTRL_ICM_MASK) != 0u)
0851             { /* ICM mode still enabled, this is due to parity error */
0852                 context->transferState = kSMARTCARD_InvalidTSDetecetedState;
0853             }
0854             else
0855             { /* Received valid TS */
0856                 context->transferState = kSMARTCARD_ReceivingState;
0857                 /* Get Data Convention form by reading IC bit of EMVSIM_CTRL register */
0858                 context->cardParams.convention =
0859                     (smartcard_card_convention_t)(uint32_t)((base->CTRL & EMVSIM_CTRL_IC_MASK) >> EMVSIM_CTRL_IC_SHIFT);
0860             }
0861             if (kSMARTCARD_InvalidTSDetecetedState == context->transferState)
0862             { /* Stop initial character (TS) detection timer, ADT timer and it's interrupt to occur */
0863                 base->CLKCFG &= ~(EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK | EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK);
0864                 base->INT_MASK |= EMVSIM_INT_MASK_GPCNT0_IM_MASK;
0865                 smartcard_emvsim_CompleteReceiveData(base, context);
0866             }
0867             if (kSMARTCARD_ReceivingState == context->transferState)
0868             { /* Stop initial character (TS) detection timer and disable ATR duration timer to reset it */
0869                 base->CLKCFG &= ~(EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK | EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK);
0870                 /* Start ATR duration counter (restart GPCNT) */
0871                 base->CLKCFG |= EMVSIM_CLKCFG_GPCNT1_CLK_SEL(kEMVSIM_GPCTxClock);
0872                 /* Start ATR duration counter, Disable counter 0 interrupt and Enable counter 1 interrupt */
0873                 base->INT_MASK = (base->INT_MASK & ~EMVSIM_INT_MASK_GPCNT1_IM_MASK) | EMVSIM_INT_MASK_GPCNT0_IM_MASK;
0874                 /* Complete receive transfer */
0875                 smartcard_emvsim_CompleteReceiveData(base, context);
0876             }
0877             /* Return anyway */
0878             return;
0879         }
0880 
0881         while (((base->RX_STATUS & EMVSIM_RX_STATUS_RX_CNT_MASK) != 0u) && ((context->xSize) > 0u))
0882         {
0883             /* Get data and put into receive buffer */
0884             *context->xBuff = (uint8_t)(base->RX_BUF);
0885             ++context->xBuff;
0886             --context->xSize;
0887         }
0888 
0889         /* Check if the last byte was received */
0890         if (context->xSize == 0u)
0891         {
0892             smartcard_emvsim_CompleteReceiveData(base, context);
0893         }
0894         else
0895         {
0896             /* If the count of remaining bytes to receive is less than depth of fifo, update the value of the receiver
0897              * data threshold */
0898             if (context->xSize < context->rxFifoThreshold)
0899             {
0900                 /* Set receiver data threshold value to count of remaining bytes */
0901                 uint32_t rx_thd;
0902                 rx_thd = (base->RX_THD & ~EMVSIM_RX_THD_RDT_MASK);
0903                 rx_thd |= context->xSize;
0904                 base->RX_THD = rx_thd;
0905             }
0906         }
0907     }
0908 
0909     /* ETC IRQ - all data from fifo is transmitted */
0910     if (((base->INT_MASK & EMVSIM_INT_MASK_ETC_IM_MASK) == 0u) &&
0911         ((base->TX_STATUS & EMVSIM_TX_STATUS_ETCF_MASK) != 0u))
0912     {
0913         smartcard_emvsim_CompleteSendData(base, context);
0914     }
0915 
0916     /* TDT IRQ - tx fifo is empty */
0917     if (((base->INT_MASK & EMVSIM_INT_MASK_TDT_IM_MASK) == 0u) &&
0918         ((base->TX_STATUS & EMVSIM_TX_STATUS_TDTF_MASK) != 0u))
0919     {
0920         if (context->xSize == 0u)
0921         {
0922             smartcard_emvsim_CompleteSendData(base, context);
0923         }
0924 
0925         if (context->xSize == 1u)
0926         {
0927             /* Disable TDT interrupt */
0928             base->INT_MASK |= EMVSIM_INT_MASK_TDT_IM_MASK;
0929             /* When the TX_GETU is not zero while sending last byte, the transmitter sends one byte more */
0930             base->TX_GETU = 0;
0931 
0932             /* Write data to fifo */
0933             base->TX_BUF = *(context->xBuff);
0934             ++context->xBuff;
0935             --context->xSize;
0936 
0937             /* Last byte was written to fifo - wait for ETC interrupt */
0938             /* Clear ETC flag and enable ETC interrupt */
0939             base->TX_STATUS |= EMVSIM_TX_STATUS_ETCF_MASK;
0940             base->INT_MASK &= ~EMVSIM_INT_MASK_ETC_IM_MASK;
0941         }
0942         else
0943         {
0944             /* To fifo will be written 2 or more bytes */
0945             size_t getu_tail = (size_t)(base->TX_GETU > 0u);
0946             while (((context->txFifoEntryCount - (uint8_t)((base->TX_STATUS & EMVSIM_TX_STATUS_TX_CNT_MASK) >>
0947                                                            EMVSIM_TX_STATUS_TX_CNT_SHIFT)) > 0u) &&
0948                    (context->xSize > getu_tail))
0949             {
0950                 /* Write data to fifo */
0951                 base->TX_BUF = *(context->xBuff);
0952                 ++context->xBuff;
0953                 --context->xSize;
0954             }
0955 
0956             if (context->xSize == 0u)
0957             {
0958                 /* Disable TDT interrupt */
0959                 base->INT_MASK |= EMVSIM_INT_MASK_TDT_IM_MASK;
0960 
0961                 /* Clear ETC flag and enable ETC interrupt */
0962                 base->TX_STATUS |= EMVSIM_TX_STATUS_ETCF_MASK;
0963                 base->INT_MASK &= ~EMVSIM_INT_MASK_ETC_IM_MASK;
0964             }
0965         }
0966     }
0967     SDK_ISR_EXIT_BARRIER;
0968 }
0969 
0970 /*!
0971  * brief Controls the EMVSIM module per different user request.
0972  *
0973  * param base The EMVSIM peripheral base address.
0974  * param context A pointer to a smart card driver context structure.
0975  * param control Control type.
0976  * param param Integer value of specific to control command.
0977  *
0978  * return kStatus_SMARTCARD_Success in success.
0979  * return kStatus_SMARTCARD_OtherError in case of error.
0980  */
0981 status_t SMARTCARD_EMVSIM_Control(EMVSIM_Type *base,
0982                                   smartcard_context_t *context,
0983                                   smartcard_control_t control,
0984                                   uint32_t param)
0985 {
0986     if ((NULL == context))
0987     {
0988         return kStatus_SMARTCARD_InvalidInput;
0989     }
0990 
0991     status_t status = kStatus_SMARTCARD_Success;
0992     uint32_t temp32 = 0u;
0993 
0994     switch (control)
0995     {
0996         case kSMARTCARD_EnableADT:
0997             /* Do nothing, ADT counter has been loaded and started after reset
0998              * and during starting TS delay counter only. This is because, once
0999              * 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 }