1 /*
2 * Copyright (c) 2015-2016, Freescale Semiconductor, Inc.
3 * Copyright 2016-2017 NXP
4 * All rights reserved.
5 *
6 * SPDX-License-Identifier: BSD-3-Clause
7 */
8
9 #include "fsl_smartcard_emvsim.h"
10 #include "fsl_smartcard_phy.h"
11
12 /* Component ID definition, used by tools. */
13 #ifndef FSL_COMPONENT_ID
14 #define FSL_COMPONENT_ID "platform.drivers.smartcard_phy_emvsim"
15 #endif
16
17 /*******************************************************************************
18 * Variables
19 ******************************************************************************/
20
21 /*******************************************************************************
22 * Private Functions
23 ******************************************************************************/
24 static uint32_t smartcard_phy_emvsim_InterfaceClockInit(EMVSIM_Type *base,
25 const smartcard_interface_config_t *config,
26 uint32_t srcClock_Hz);
27
28 /*******************************************************************************
29 * Code
30 ******************************************************************************/
31
32 /*!
33 * @brief This function initializes clock module used for card clock generation
34 */
smartcard_phy_emvsim_InterfaceClockInit(EMVSIM_Type * base,const smartcard_interface_config_t * config,uint32_t srcClock_Hz)35 static uint32_t smartcard_phy_emvsim_InterfaceClockInit(EMVSIM_Type *base,
36 const smartcard_interface_config_t *config,
37 uint32_t srcClock_Hz)
38 {
39 assert((NULL != config) && (0u != srcClock_Hz));
40
41 uint32_t emvsimClkMhz = 0u;
42 uint8_t emvsimPRSCValue;
43
44 /* Retrieve EMV SIM clock */
45 emvsimClkMhz = srcClock_Hz / 1000000u;
46 /* Calculate MOD value */
47 emvsimPRSCValue = (uint8_t)((emvsimClkMhz * 1000u) / (config->smartCardClock / 1000u));
48 /* Set clock prescaler */
49 base->CLKCFG = (base->CLKCFG & ~EMVSIM_CLKCFG_CLK_PRSC_MASK) | EMVSIM_CLKCFG_CLK_PRSC(emvsimPRSCValue);
50
51 return config->smartCardClock;
52 }
53
SMARTCARD_PHY_GetDefaultConfig(smartcard_interface_config_t * config)54 void SMARTCARD_PHY_GetDefaultConfig(smartcard_interface_config_t *config)
55 {
56 assert((NULL != config));
57
58 /* Initializes the configure structure to zero. */
59 (void)memset(config, 0, sizeof(*config));
60
61 config->clockToResetDelay = SMARTCARD_INIT_DELAY_CLOCK_CYCLES;
62 config->vcc = kSMARTCARD_VoltageClassB3_3V;
63 }
64
SMARTCARD_PHY_Init(void * base,smartcard_interface_config_t const * config,uint32_t srcClock_Hz)65 status_t SMARTCARD_PHY_Init(void *base, smartcard_interface_config_t const *config, uint32_t srcClock_Hz)
66 {
67 if ((NULL == config) || (0u == srcClock_Hz))
68 {
69 return kStatus_SMARTCARD_InvalidInput;
70 }
71 EMVSIM_Type *emvsimBase = (EMVSIM_Type *)base;
72
73 /* SMARTCARD clock initialization. Clock is still not active after this call */
74 (void)smartcard_phy_emvsim_InterfaceClockInit(emvsimBase, config, srcClock_Hz);
75
76 /* Configure EMVSIM direct interface driver interrupt occur according card presence */
77 if ((emvsimBase->PCSR & EMVSIM_PCSR_SPDP_MASK) != 0u)
78 {
79 emvsimBase->PCSR &= ~EMVSIM_PCSR_SPDES_MASK;
80 }
81 else
82 {
83 emvsimBase->PCSR |= EMVSIM_PCSR_SPDES_MASK;
84 }
85 /* Un-mask presence detect interrupt flag */
86 emvsimBase->PCSR &= ~EMVSIM_PCSR_SPDIM_MASK;
87
88 return kStatus_SMARTCARD_Success;
89 }
90
SMARTCARD_PHY_Deinit(void * base,smartcard_interface_config_t const * config)91 void SMARTCARD_PHY_Deinit(void *base, smartcard_interface_config_t const *config)
92 {
93 assert((NULL != config));
94 /* Deactivate VCC, CLOCK */
95 ((EMVSIM_Type *)base)->PCSR &= ~(EMVSIM_PCSR_SCEN_MASK | EMVSIM_PCSR_SVCC_EN_MASK);
96 }
97
SMARTCARD_PHY_Activate(void * base,smartcard_context_t * context,smartcard_reset_type_t resetType)98 status_t SMARTCARD_PHY_Activate(void *base, smartcard_context_t *context, smartcard_reset_type_t resetType)
99 {
100 if ((NULL == context) || (NULL == context->timeDelay))
101 {
102 return kStatus_SMARTCARD_InvalidInput;
103 }
104 assert(context->interfaceConfig.vcc == kSMARTCARD_VoltageClassB3_3V);
105
106 EMVSIM_Type *emvsimBase = (EMVSIM_Type *)base;
107
108 context->timersState.initCharTimerExpired = false;
109 context->resetType = resetType;
110
111 /* Disable receiver to deactivate GPC timers trigger */
112 emvsimBase->CTRL &= ~EMVSIM_CTRL_RCV_EN_MASK;
113 if (resetType == kSMARTCARD_ColdReset)
114 { /* Set polarity of VCC to active high, Enable VCC for SMARTCARD, Enable smart card clock */
115 emvsimBase->PCSR =
116 (emvsimBase->PCSR & ~EMVSIM_PCSR_VCCENP_MASK) | (EMVSIM_PCSR_SVCC_EN_MASK | EMVSIM_PCSR_SCEN_MASK);
117 /* Set transfer inversion to default(direct) value */
118 emvsimBase->CTRL &= ~EMVSIM_CTRL_IC_MASK;
119 }
120 else if (resetType == kSMARTCARD_WarmReset)
121 { /* Ensure that card is already active */
122 if (!context->cardParams.active)
123 { /* Card is not active;hence return */
124 return kStatus_SMARTCARD_CardNotActivated;
125 }
126 }
127 else
128 {
129 return kStatus_SMARTCARD_InvalidInput;
130 }
131 /* Set Reset low */
132 emvsimBase->PCSR &= ~EMVSIM_PCSR_SRST_MASK;
133 /* Calculate time delay needed for reset */
134 uint32_t temp =
135 ((((uint32_t)10000u * context->interfaceConfig.clockToResetDelay) / context->interfaceConfig.smartCardClock) *
136 100u) +
137 1u;
138 context->timeDelay(temp);
139 /* Pull reset HIGH Now to mark the end of Activation sequence */
140 emvsimBase->PCSR |= EMVSIM_PCSR_SRST_MASK;
141 /* Disable GPC timers input clock */
142 emvsimBase->CLKCFG &= ~(EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK | EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK);
143 /* Down counter trigger, and clear any pending counter status flag */
144 emvsimBase->TX_STATUS = EMVSIM_TX_STATUS_GPCNT1_TO_MASK | EMVSIM_TX_STATUS_GPCNT0_TO_MASK;
145 /* Set counter value for TS detection delay */
146 emvsimBase->GPCNT0_VAL = (SMARTCARD_INIT_DELAY_CLOCK_CYCLES + SMARTCARD_INIT_DELAY_CLOCK_CYCLES_ADJUSTMENT);
147 /* Pre-load counter value for ATR duration delay */
148 emvsimBase->GPCNT1_VAL = (SMARTCARD_EMV_ATR_DURATION_ETU + SMARTCARD_ATR_DURATION_ADJUSTMENT);
149 /* Select the clock for GPCNT for both TS detection and early start of ATR duration counter */
150 emvsimBase->CLKCFG |=
151 (EMVSIM_CLKCFG_GPCNT0_CLK_SEL(kEMVSIM_GPCCardClock) | EMVSIM_CLKCFG_GPCNT1_CLK_SEL(kEMVSIM_GPCTxClock));
152 /* Set receiver to ICM mode, Flush RX FIFO */
153 emvsimBase->CTRL |= (EMVSIM_CTRL_ICM_MASK | EMVSIM_CTRL_FLSH_RX_MASK);
154 /* Enable counter interrupt for TS detection */
155 emvsimBase->INT_MASK &= ~EMVSIM_INT_MASK_GPCNT0_IM_MASK;
156 /* Clear any pending status flags */
157 emvsimBase->RX_STATUS = 0xFFFFFFFFu;
158 /* Enable receiver */
159 emvsimBase->CTRL |= EMVSIM_CTRL_RCV_EN_MASK;
160 /* Here the card was activated */
161 context->cardParams.active = true;
162
163 return kStatus_SMARTCARD_Success;
164 }
165
SMARTCARD_PHY_Deactivate(void * base,smartcard_context_t * context)166 status_t SMARTCARD_PHY_Deactivate(void *base, smartcard_context_t *context)
167 {
168 if ((NULL == context))
169 {
170 return kStatus_SMARTCARD_InvalidInput;
171 }
172
173 EMVSIM_Type *emvsimBase = (EMVSIM_Type *)base;
174
175 /* Assert Reset */
176 emvsimBase->PCSR &= ~EMVSIM_PCSR_SRST_MASK;
177 /* Stop SMARTCARD clock generation */
178 emvsimBase->PCSR &= ~EMVSIM_PCSR_SCEN_MASK;
179 /* Deactivate card by disabling VCC */
180 emvsimBase->PCSR &= ~EMVSIM_PCSR_SVCC_EN_MASK;
181 /* According EMV 4.3 specification deactivation sequence should be done within 100ms.
182 * The period is measured from the time that RST is set to state L to the time that Vcc
183 * reaches 0.4 V or less.
184 */
185 context->timeDelay(100 * 1000);
186 /* Here the card was deactivated */
187 context->cardParams.active = false;
188
189 return kStatus_SMARTCARD_Success;
190 }
191
SMARTCARD_PHY_Control(void * base,smartcard_context_t * context,smartcard_interface_control_t control,uint32_t param)192 status_t SMARTCARD_PHY_Control(void *base,
193 smartcard_context_t *context,
194 smartcard_interface_control_t control,
195 uint32_t param)
196 {
197 if ((NULL == context))
198 {
199 return kStatus_SMARTCARD_InvalidInput;
200 }
201
202 status_t status = kStatus_SMARTCARD_Success;
203
204 switch (control)
205 {
206 case kSMARTCARD_InterfaceSetVcc:
207 /* Only 3.3V interface supported by the direct interface */
208 assert((smartcard_card_voltage_class_t)param == kSMARTCARD_VoltageClassB3_3V);
209 context->interfaceConfig.vcc = (smartcard_card_voltage_class_t)param;
210 break;
211 case kSMARTCARD_InterfaceSetClockToResetDelay:
212 /* Set interface clock to Reset delay set by caller */
213 context->interfaceConfig.clockToResetDelay = param;
214 break;
215 case kSMARTCARD_InterfaceReadStatus:
216 /* Expecting active low present detect */
217 context->cardParams.present = (bool)((emvsim_presence_detect_status_t)(uint32_t)(
218 (((EMVSIM_Type *)base)->PCSR & EMVSIM_PCSR_SPDP_MASK) >>
219 EMVSIM_PCSR_SPDP_SHIFT) == kEMVSIM_DetectPinIsLow);
220 break;
221 default:
222 status = kStatus_SMARTCARD_InvalidInput;
223 break;
224 }
225
226 return status;
227 }
228