File indexing completed on 2025-05-11 08:23:01
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "fsl_smartcard_emvsim.h"
0010 #include "fsl_smartcard_phy.h"
0011
0012
0013 #ifndef FSL_COMPONENT_ID
0014 #define FSL_COMPONENT_ID "platform.drivers.smartcard_phy_emvsim"
0015 #endif
0016
0017
0018
0019
0020
0021
0022
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
0030
0031
0032
0033
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
0045 emvsimClkMhz = srcClock_Hz / 1000000u;
0046
0047 emvsimPRSCValue = (uint8_t)((emvsimClkMhz * 1000u) / (config->smartCardClock / 1000u));
0048
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
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
0074 (void)smartcard_phy_emvsim_InterfaceClockInit(emvsimBase, config, srcClock_Hz);
0075
0076
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
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
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
0112 emvsimBase->CTRL &= ~EMVSIM_CTRL_RCV_EN_MASK;
0113 if (resetType == kSMARTCARD_ColdReset)
0114 {
0115 emvsimBase->PCSR =
0116 (emvsimBase->PCSR & ~EMVSIM_PCSR_VCCENP_MASK) | (EMVSIM_PCSR_SVCC_EN_MASK | EMVSIM_PCSR_SCEN_MASK);
0117
0118 emvsimBase->CTRL &= ~EMVSIM_CTRL_IC_MASK;
0119 }
0120 else if (resetType == kSMARTCARD_WarmReset)
0121 {
0122 if (!context->cardParams.active)
0123 {
0124 return kStatus_SMARTCARD_CardNotActivated;
0125 }
0126 }
0127 else
0128 {
0129 return kStatus_SMARTCARD_InvalidInput;
0130 }
0131
0132 emvsimBase->PCSR &= ~EMVSIM_PCSR_SRST_MASK;
0133
0134 uint32_t temp =
0135 ((((uint32_t)10000u * context->interfaceConfig.clockToResetDelay) / context->interfaceConfig.smartCardClock) *
0136 100u) +
0137 1u;
0138 context->timeDelay(temp);
0139
0140 emvsimBase->PCSR |= EMVSIM_PCSR_SRST_MASK;
0141
0142 emvsimBase->CLKCFG &= ~(EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK | EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK);
0143
0144 emvsimBase->TX_STATUS = EMVSIM_TX_STATUS_GPCNT1_TO_MASK | EMVSIM_TX_STATUS_GPCNT0_TO_MASK;
0145
0146 emvsimBase->GPCNT0_VAL = (SMARTCARD_INIT_DELAY_CLOCK_CYCLES + SMARTCARD_INIT_DELAY_CLOCK_CYCLES_ADJUSTMENT);
0147
0148 emvsimBase->GPCNT1_VAL = (SMARTCARD_EMV_ATR_DURATION_ETU + SMARTCARD_ATR_DURATION_ADJUSTMENT);
0149
0150 emvsimBase->CLKCFG |=
0151 (EMVSIM_CLKCFG_GPCNT0_CLK_SEL(kEMVSIM_GPCCardClock) | EMVSIM_CLKCFG_GPCNT1_CLK_SEL(kEMVSIM_GPCTxClock));
0152
0153 emvsimBase->CTRL |= (EMVSIM_CTRL_ICM_MASK | EMVSIM_CTRL_FLSH_RX_MASK);
0154
0155 emvsimBase->INT_MASK &= ~EMVSIM_INT_MASK_GPCNT0_IM_MASK;
0156
0157 emvsimBase->RX_STATUS = 0xFFFFFFFFu;
0158
0159 emvsimBase->CTRL |= EMVSIM_CTRL_RCV_EN_MASK;
0160
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
0176 emvsimBase->PCSR &= ~EMVSIM_PCSR_SRST_MASK;
0177
0178 emvsimBase->PCSR &= ~EMVSIM_PCSR_SCEN_MASK;
0179
0180 emvsimBase->PCSR &= ~EMVSIM_PCSR_SVCC_EN_MASK;
0181
0182
0183
0184
0185 context->timeDelay(100 * 1000);
0186
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
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
0213 context->interfaceConfig.clockToResetDelay = param;
0214 break;
0215 case kSMARTCARD_InterfaceReadStatus:
0216
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 }