1 /*
2 * Copyright 2021-2022 NXP
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7 #include "fsl_smartcard_usim.h"
8 #include "fsl_smartcard_phy.h"
9
10 /* Component ID definition, used by tools. */
11 #ifndef FSL_COMPONENT_ID
12 #define FSL_COMPONENT_ID "platform.drivers.smartcard_phy_usim"
13 #endif
14
15 /*******************************************************************************
16 * Variables
17 ******************************************************************************/
18
19 /*******************************************************************************
20 * Private Functions
21 ******************************************************************************/
22 static void SMARTCARD_PHY_USIM_InterfaceClockInit(USIM_Type *base,
23 const smartcard_interface_config_t *config,
24 uint32_t srcClock_Hz);
25
26 /*******************************************************************************
27 * Code
28 ******************************************************************************/
29
30 /*!
31 * @brief This function initializes clock module used for card clock generation
32 */
SMARTCARD_PHY_USIM_InterfaceClockInit(USIM_Type * base,const smartcard_interface_config_t * config,uint32_t srcClock_Hz)33 static void SMARTCARD_PHY_USIM_InterfaceClockInit(USIM_Type *base,
34 const smartcard_interface_config_t *config,
35 uint32_t srcClock_Hz)
36 {
37 assert((NULL != config) && (0u != srcClock_Hz));
38
39 uint32_t usimClkMhz = 0u;
40 uint8_t usimPRSCValue;
41
42 /* Retrieve USIM clock */
43 usimClkMhz = srcClock_Hz / 1000000u;
44 /* Calculate MOD value */
45 usimPRSCValue = (uint8_t)((usimClkMhz * 1000u) / (config->smartCardClock / 1000u) / 2U);
46 while (0UL != (base->CLKR & USIM_CLKR_RQST_MASK))
47 {
48 }
49 /* Set clock prescaler */
50 base->CLKR = (base->CLKR & ~USIM_CLKR_DIVISOR_MASK) | USIM_CLKR_DIVISOR(usimPRSCValue);
51 }
52
SMARTCARD_PHY_GetDefaultConfig(smartcard_interface_config_t * config)53 void SMARTCARD_PHY_GetDefaultConfig(smartcard_interface_config_t *config)
54 {
55 assert((NULL != config));
56
57 /* Initializes the configure structure to zero. */
58 (void)memset(config, 0, sizeof(*config));
59
60 config->clockToResetDelay = SMARTCARD_INIT_DELAY_CLOCK_CYCLES;
61 config->vcc = kSMARTCARD_VoltageClassB3_3V;
62 }
63
SMARTCARD_PHY_Init(void * base,smartcard_interface_config_t const * config,uint32_t srcClock_Hz)64 status_t SMARTCARD_PHY_Init(void *base, smartcard_interface_config_t const *config, uint32_t srcClock_Hz)
65 {
66 if ((NULL == config) || (0u == srcClock_Hz))
67 {
68 return kStatus_SMARTCARD_InvalidInput;
69 }
70 USIM_Type *usimBase = (USIM_Type *)base;
71
72 /* SMARTCARD clock initialization. Clock is still not active after this call */
73 SMARTCARD_PHY_USIM_InterfaceClockInit(usimBase, config, srcClock_Hz);
74
75 return kStatus_SMARTCARD_Success;
76 }
77
SMARTCARD_PHY_Deinit(void * base,smartcard_interface_config_t const * config)78 void SMARTCARD_PHY_Deinit(void *base, smartcard_interface_config_t const *config)
79 {
80 assert((NULL != config));
81 /* Stop CARD CLOCK */
82 while (0U != (((USIM_Type *)base)->CLKR & USIM_CLKR_RQST_MASK))
83 {
84 }
85 ((USIM_Type *)base)->CLKR |= USIM_CLKR_STOP_UCLK_MASK;
86 /* Deactivate VCC */
87 ((USIM_Type *)base)->USCCR &= ~USIM_USCCR_VCC_MASK;
88 }
89
SMARTCARD_PHY_Activate(void * base,smartcard_context_t * context,smartcard_reset_type_t resetType)90 status_t SMARTCARD_PHY_Activate(void *base, smartcard_context_t *context, smartcard_reset_type_t resetType)
91 {
92 if ((NULL == context) || (NULL == context->timeDelay))
93 {
94 return kStatus_SMARTCARD_InvalidInput;
95 }
96 assert(context->interfaceConfig.vcc == kSMARTCARD_VoltageClassB3_3V);
97
98 USIM_Type *usimBase = (USIM_Type *)base;
99
100 context->timersState.initCharTimerExpired = false;
101 context->resetType = resetType;
102
103 /* Hold Transmission. */
104 usimBase->FCR |= USIM_FCR_TX_HOLD_MASK;
105 if (resetType == kSMARTCARD_ColdReset)
106 {
107 /* Set Reset low */
108 usimBase->USCCR &= ~USIM_USCCR_RST_CARD_N_MASK;
109 /* Enable VCC for SMARTCARD, Enable smart card clock */
110 usimBase->USCCR = (usimBase->USCCR & ~USIM_USCCR_VCC_MASK) | USIM_USCCR_VCC(1);
111 usimBase->USCCR &= ~USIM_USCCR_TXD_FORCE_MASK;
112 usimBase->CLKR &= ~USIM_CLKR_STOP_UCLK_MASK;
113 /* Set transfer mode to default(direct convention) */
114 usimBase->LCR &= ~(USIM_LCR_ORDER_MASK | USIM_LCR_INVERSE_MASK);
115 }
116 else if (resetType == kSMARTCARD_WarmReset)
117 {
118 /* Ensure that card is already active */
119 if (!context->cardParams.active)
120 { /* Card is not active;hence return */
121 return kStatus_SMARTCARD_CardNotActivated;
122 }
123 /* Set Reset low */
124 usimBase->USCCR &= ~USIM_USCCR_RST_CARD_N_MASK;
125 }
126 else
127 {
128 return kStatus_SMARTCARD_InvalidInput;
129 }
130 /* Calculate time delay needed for reset */
131 uint32_t temp =
132 ((((uint32_t)10000u * context->interfaceConfig.clockToResetDelay) / context->interfaceConfig.smartCardClock) *
133 100u) +
134 1u;
135 context->timeDelay(temp);
136 /* Pull reset HIGH Now to mark the end of Activation sequence */
137 usimBase->USCCR |= USIM_USCCR_RST_CARD_N_MASK;
138
139 /* Enable external timer for TS detection time-out */
140 SMARTCARD_USIM_TimerStart((SMARTCARD_INIT_DELAY_CLOCK_CYCLES + SMARTCARD_INIT_DELAY_CLOCK_CYCLES_ADJUSTMENT) *
141 (SystemCoreClock / context->interfaceConfig.smartCardClock));
142 /* Here the card was activated */
143 context->cardParams.active = true;
144
145 return kStatus_SMARTCARD_Success;
146 }
147
SMARTCARD_PHY_Deactivate(void * base,smartcard_context_t * context)148 status_t SMARTCARD_PHY_Deactivate(void *base, smartcard_context_t *context)
149 {
150 if ((NULL == context))
151 {
152 return kStatus_SMARTCARD_InvalidInput;
153 }
154
155 USIM_Type *usimBase = (USIM_Type *)base;
156
157 /* Set Reset low */
158 usimBase->USCCR &= ~USIM_USCCR_RST_CARD_N_MASK;
159 /* Stop SMARTCARD clock generation */
160 while (0UL != (usimBase->CLKR & USIM_CLKR_RQST_MASK))
161 {
162 }
163 usimBase->CLKR &= ~USIM_CLKR_STOP_LEVEL_MASK;
164 usimBase->CLKR |= USIM_CLKR_STOP_UCLK_MASK;
165 /* Force the I/O line to ground level. */
166 usimBase->USCCR |= USIM_USCCR_TXD_FORCE_MASK;
167 /* Turn the VCC voltage to ground level. */
168 usimBase->USCCR &= ~USIM_USCCR_VCC_MASK;
169 /* According EMV 4.3 specification deactivation sequence should be done within 100ms.
170 * The period is measured from the time that RST is set to state L to the time that Vcc
171 * reaches 0.4 V or less.
172 */
173 context->timeDelay(100 * 1000);
174 /* Here the card was deactivated */
175 context->cardParams.active = false;
176
177 return kStatus_SMARTCARD_Success;
178 }
179
SMARTCARD_PHY_Control(void * base,smartcard_context_t * context,smartcard_interface_control_t control,uint32_t param)180 status_t SMARTCARD_PHY_Control(void *base,
181 smartcard_context_t *context,
182 smartcard_interface_control_t control,
183 uint32_t param)
184 {
185 if ((NULL == context))
186 {
187 return kStatus_SMARTCARD_InvalidInput;
188 }
189
190 status_t status = kStatus_SMARTCARD_Success;
191
192 switch (control)
193 {
194 case kSMARTCARD_InterfaceSetVcc:
195 /* Only 3.3V interface supported by the interface */
196 assert((smartcard_card_voltage_class_t)param == kSMARTCARD_VoltageClassB3_3V);
197 context->interfaceConfig.vcc = (smartcard_card_voltage_class_t)param;
198 break;
199 case kSMARTCARD_InterfaceSetClockToResetDelay:
200 /* Set interface clock to Reset delay set by caller */
201 context->interfaceConfig.clockToResetDelay = param;
202 break;
203 case kSMARTCARD_InterfaceReadStatus:
204 /* Workaround, RW610 board no Card detect PIN */
205 context->cardParams.present = true;
206 break;
207 default:
208 status = kStatus_SMARTCARD_InvalidInput;
209 break;
210 }
211
212 return status;
213 }
214