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-2017 NXP
0004  * All rights reserved.
0005  *
0006  * SPDX-License-Identifier: BSD-3-Clause
0007  */
0008 
0009 #include "fsl_smartcard_emvsim.h"
0010 #include "fsl_smartcard_phy.h"
0011 
0012 /* Component ID definition, used by tools. */
0013 #ifndef FSL_COMPONENT_ID
0014 #define FSL_COMPONENT_ID "platform.drivers.smartcard_phy_emvsim"
0015 #endif
0016 
0017 /*******************************************************************************
0018  * Variables
0019  ******************************************************************************/
0020 
0021 /*******************************************************************************
0022  * Private Functions
0023  ******************************************************************************/
0024 static uint32_t smartcard_phy_emvsim_InterfaceClockInit(EMVSIM_Type *base,
0025                                                         const smartcard_interface_config_t *config,
0026                                                         uint32_t srcClock_Hz);
0027 
0028 /*******************************************************************************
0029  * Code
0030  ******************************************************************************/
0031 
0032 /*!
0033  * @brief This function initializes clock module used for card clock generation
0034  */
0035 static uint32_t smartcard_phy_emvsim_InterfaceClockInit(EMVSIM_Type *base,
0036                                                         const smartcard_interface_config_t *config,
0037                                                         uint32_t srcClock_Hz)
0038 {
0039     assert((NULL != config) && (0u != srcClock_Hz));
0040 
0041     uint32_t emvsimClkMhz = 0u;
0042     uint8_t emvsimPRSCValue;
0043 
0044     /* Retrieve EMV SIM clock */
0045     emvsimClkMhz = srcClock_Hz / 1000000u;
0046     /* Calculate MOD value */
0047     emvsimPRSCValue = (uint8_t)((emvsimClkMhz * 1000u) / (config->smartCardClock / 1000u));
0048     /* Set clock prescaler */
0049     base->CLKCFG = (base->CLKCFG & ~EMVSIM_CLKCFG_CLK_PRSC_MASK) | EMVSIM_CLKCFG_CLK_PRSC(emvsimPRSCValue);
0050 
0051     return config->smartCardClock;
0052 }
0053 
0054 void SMARTCARD_PHY_GetDefaultConfig(smartcard_interface_config_t *config)
0055 {
0056     assert((NULL != config));
0057 
0058     /* Initializes the configure structure to zero. */
0059     (void)memset(config, 0, sizeof(*config));
0060 
0061     config->clockToResetDelay = SMARTCARD_INIT_DELAY_CLOCK_CYCLES;
0062     config->vcc               = kSMARTCARD_VoltageClassB3_3V;
0063 }
0064 
0065 status_t SMARTCARD_PHY_Init(void *base, smartcard_interface_config_t const *config, uint32_t srcClock_Hz)
0066 {
0067     if ((NULL == config) || (0u == srcClock_Hz))
0068     {
0069         return kStatus_SMARTCARD_InvalidInput;
0070     }
0071     EMVSIM_Type *emvsimBase = (EMVSIM_Type *)base;
0072 
0073     /* SMARTCARD clock initialization. Clock is still not active after this call */
0074     (void)smartcard_phy_emvsim_InterfaceClockInit(emvsimBase, config, srcClock_Hz);
0075 
0076     /* Configure EMVSIM direct interface driver interrupt occur according card presence */
0077     if ((emvsimBase->PCSR & EMVSIM_PCSR_SPDP_MASK) != 0u)
0078     {
0079         emvsimBase->PCSR &= ~EMVSIM_PCSR_SPDES_MASK;
0080     }
0081     else
0082     {
0083         emvsimBase->PCSR |= EMVSIM_PCSR_SPDES_MASK;
0084     }
0085     /* Un-mask presence detect interrupt flag */
0086     emvsimBase->PCSR &= ~EMVSIM_PCSR_SPDIM_MASK;
0087 
0088     return kStatus_SMARTCARD_Success;
0089 }
0090 
0091 void SMARTCARD_PHY_Deinit(void *base, smartcard_interface_config_t const *config)
0092 {
0093     assert((NULL != config));
0094     /* Deactivate VCC, CLOCK */
0095     ((EMVSIM_Type *)base)->PCSR &= ~(EMVSIM_PCSR_SCEN_MASK | EMVSIM_PCSR_SVCC_EN_MASK);
0096 }
0097 
0098 status_t SMARTCARD_PHY_Activate(void *base, smartcard_context_t *context, smartcard_reset_type_t resetType)
0099 {
0100     if ((NULL == context) || (NULL == context->timeDelay))
0101     {
0102         return kStatus_SMARTCARD_InvalidInput;
0103     }
0104     assert(context->interfaceConfig.vcc == kSMARTCARD_VoltageClassB3_3V);
0105 
0106     EMVSIM_Type *emvsimBase = (EMVSIM_Type *)base;
0107 
0108     context->timersState.initCharTimerExpired = false;
0109     context->resetType                        = resetType;
0110 
0111     /* Disable receiver to deactivate GPC timers trigger */
0112     emvsimBase->CTRL &= ~EMVSIM_CTRL_RCV_EN_MASK;
0113     if (resetType == kSMARTCARD_ColdReset)
0114     { /* Set polarity of VCC to active high, Enable VCC for SMARTCARD, Enable smart card clock */
0115         emvsimBase->PCSR =
0116             (emvsimBase->PCSR & ~EMVSIM_PCSR_VCCENP_MASK) | (EMVSIM_PCSR_SVCC_EN_MASK | EMVSIM_PCSR_SCEN_MASK);
0117         /* Set transfer inversion to default(direct) value */
0118         emvsimBase->CTRL &= ~EMVSIM_CTRL_IC_MASK;
0119     }
0120     else if (resetType == kSMARTCARD_WarmReset)
0121     { /* Ensure that card is already active */
0122         if (!context->cardParams.active)
0123         { /* Card is not active;hence return */
0124             return kStatus_SMARTCARD_CardNotActivated;
0125         }
0126     }
0127     else
0128     {
0129         return kStatus_SMARTCARD_InvalidInput;
0130     }
0131     /* Set Reset low */
0132     emvsimBase->PCSR &= ~EMVSIM_PCSR_SRST_MASK;
0133     /* Calculate time delay needed for reset */
0134     uint32_t temp =
0135         ((((uint32_t)10000u * context->interfaceConfig.clockToResetDelay) / context->interfaceConfig.smartCardClock) *
0136          100u) +
0137         1u;
0138     context->timeDelay(temp);
0139     /* Pull reset HIGH Now to mark the end of Activation sequence */
0140     emvsimBase->PCSR |= EMVSIM_PCSR_SRST_MASK;
0141     /* Disable GPC timers input clock */
0142     emvsimBase->CLKCFG &= ~(EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK | EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK);
0143     /* Down counter trigger, and clear any pending counter status flag */
0144     emvsimBase->TX_STATUS = EMVSIM_TX_STATUS_GPCNT1_TO_MASK | EMVSIM_TX_STATUS_GPCNT0_TO_MASK;
0145     /* Set counter value for TS detection delay */
0146     emvsimBase->GPCNT0_VAL = (SMARTCARD_INIT_DELAY_CLOCK_CYCLES + SMARTCARD_INIT_DELAY_CLOCK_CYCLES_ADJUSTMENT);
0147     /* Pre-load counter value for ATR duration delay */
0148     emvsimBase->GPCNT1_VAL = (SMARTCARD_EMV_ATR_DURATION_ETU + SMARTCARD_ATR_DURATION_ADJUSTMENT);
0149     /* Select the clock for GPCNT for both TS detection and early start of ATR duration counter */
0150     emvsimBase->CLKCFG |=
0151         (EMVSIM_CLKCFG_GPCNT0_CLK_SEL(kEMVSIM_GPCCardClock) | EMVSIM_CLKCFG_GPCNT1_CLK_SEL(kEMVSIM_GPCTxClock));
0152     /* Set receiver to ICM mode, Flush RX FIFO */
0153     emvsimBase->CTRL |= (EMVSIM_CTRL_ICM_MASK | EMVSIM_CTRL_FLSH_RX_MASK);
0154     /* Enable counter interrupt for TS detection */
0155     emvsimBase->INT_MASK &= ~EMVSIM_INT_MASK_GPCNT0_IM_MASK;
0156     /* Clear any pending status flags */
0157     emvsimBase->RX_STATUS = 0xFFFFFFFFu;
0158     /* Enable receiver */
0159     emvsimBase->CTRL |= EMVSIM_CTRL_RCV_EN_MASK;
0160     /* Here the card was activated */
0161     context->cardParams.active = true;
0162 
0163     return kStatus_SMARTCARD_Success;
0164 }
0165 
0166 status_t SMARTCARD_PHY_Deactivate(void *base, smartcard_context_t *context)
0167 {
0168     if ((NULL == context))
0169     {
0170         return kStatus_SMARTCARD_InvalidInput;
0171     }
0172 
0173     EMVSIM_Type *emvsimBase = (EMVSIM_Type *)base;
0174 
0175     /* Assert Reset */
0176     emvsimBase->PCSR &= ~EMVSIM_PCSR_SRST_MASK;
0177     /* Stop SMARTCARD clock generation */
0178     emvsimBase->PCSR &= ~EMVSIM_PCSR_SCEN_MASK;
0179     /* Deactivate card by disabling VCC */
0180     emvsimBase->PCSR &= ~EMVSIM_PCSR_SVCC_EN_MASK;
0181     /* According EMV 4.3 specification deactivation sequence should be done within 100ms.
0182      * The period is measured from the time that RST is set to state L to the time that Vcc
0183      * reaches 0.4 V or less.
0184      */
0185     context->timeDelay(100 * 1000);
0186     /* Here the card was deactivated */
0187     context->cardParams.active = false;
0188 
0189     return kStatus_SMARTCARD_Success;
0190 }
0191 
0192 status_t SMARTCARD_PHY_Control(void *base,
0193                                smartcard_context_t *context,
0194                                smartcard_interface_control_t control,
0195                                uint32_t param)
0196 {
0197     if ((NULL == context))
0198     {
0199         return kStatus_SMARTCARD_InvalidInput;
0200     }
0201 
0202     status_t status = kStatus_SMARTCARD_Success;
0203 
0204     switch (control)
0205     {
0206         case kSMARTCARD_InterfaceSetVcc:
0207             /* Only 3.3V interface supported by the direct interface */
0208             assert((smartcard_card_voltage_class_t)param == kSMARTCARD_VoltageClassB3_3V);
0209             context->interfaceConfig.vcc = (smartcard_card_voltage_class_t)param;
0210             break;
0211         case kSMARTCARD_InterfaceSetClockToResetDelay:
0212             /* Set interface clock to Reset delay set by caller */
0213             context->interfaceConfig.clockToResetDelay = param;
0214             break;
0215         case kSMARTCARD_InterfaceReadStatus:
0216             /* Expecting active low present detect */
0217             context->cardParams.present = (bool)((emvsim_presence_detect_status_t)(uint32_t)(
0218                                                      (((EMVSIM_Type *)base)->PCSR & EMVSIM_PCSR_SPDP_MASK) >>
0219                                                      EMVSIM_PCSR_SPDP_SHIFT) == kEMVSIM_DetectPinIsLow);
0220             break;
0221         default:
0222             status = kStatus_SMARTCARD_InvalidInput;
0223             break;
0224     }
0225 
0226     return status;
0227 }