Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: Hobbyking_Cheetah_Compact Hobbyking_Cheetah_Compact_DRV8323_14bit Hobbyking_Cheetah_Compact_DRV8323_V51_201907 HKC_MiniCheetah ... more
Fork of mbed-dev by
targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_K82F/drivers/fsl_smartcard_phy_emvsim.c@181:36facd806e4a, 2018-07-30 (annotated)
- Committer:
- benkatz
- Date:
- Mon Jul 30 20:31:44 2018 +0000
- Revision:
- 181:36facd806e4a
- Parent:
- 154:37f96f9d4de2
going on the robot. fixed a dumb bug in float_to_uint
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| <> | 154:37f96f9d4de2 | 1 | /* |
| <> | 154:37f96f9d4de2 | 2 | * Copyright (c) 2015-2016, Freescale Semiconductor, Inc. |
| <> | 154:37f96f9d4de2 | 3 | * All rights reserved. |
| <> | 154:37f96f9d4de2 | 4 | * |
| <> | 154:37f96f9d4de2 | 5 | * Redistribution and use in source and binary forms, with or without modification, |
| <> | 154:37f96f9d4de2 | 6 | * are permitted provided that the following conditions are met: |
| <> | 154:37f96f9d4de2 | 7 | * |
| <> | 154:37f96f9d4de2 | 8 | * o Redistributions of source code must retain the above copyright notice, this list |
| <> | 154:37f96f9d4de2 | 9 | * of conditions and the following disclaimer. |
| <> | 154:37f96f9d4de2 | 10 | * |
| <> | 154:37f96f9d4de2 | 11 | * o Redistributions in binary form must reproduce the above copyright notice, this |
| <> | 154:37f96f9d4de2 | 12 | * list of conditions and the following disclaimer in the documentation and/or |
| <> | 154:37f96f9d4de2 | 13 | * other materials provided with the distribution. |
| <> | 154:37f96f9d4de2 | 14 | * |
| <> | 154:37f96f9d4de2 | 15 | * o Neither the name of Freescale Semiconductor, Inc. nor the names of its |
| <> | 154:37f96f9d4de2 | 16 | * contributors may be used to endorse or promote products derived from this |
| <> | 154:37f96f9d4de2 | 17 | * software without specific prior written permission. |
| <> | 154:37f96f9d4de2 | 18 | * |
| <> | 154:37f96f9d4de2 | 19 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND |
| <> | 154:37f96f9d4de2 | 20 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
| <> | 154:37f96f9d4de2 | 21 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
| <> | 154:37f96f9d4de2 | 22 | * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR |
| <> | 154:37f96f9d4de2 | 23 | * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
| <> | 154:37f96f9d4de2 | 24 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
| <> | 154:37f96f9d4de2 | 25 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
| <> | 154:37f96f9d4de2 | 26 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| <> | 154:37f96f9d4de2 | 27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
| <> | 154:37f96f9d4de2 | 28 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| <> | 154:37f96f9d4de2 | 29 | */ |
| <> | 154:37f96f9d4de2 | 30 | |
| <> | 154:37f96f9d4de2 | 31 | #include "fsl_smartcard_emvsim.h" |
| <> | 154:37f96f9d4de2 | 32 | #include "fsl_smartcard_phy_emvsim.h" |
| <> | 154:37f96f9d4de2 | 33 | |
| <> | 154:37f96f9d4de2 | 34 | /******************************************************************************* |
| <> | 154:37f96f9d4de2 | 35 | * Variables |
| <> | 154:37f96f9d4de2 | 36 | ******************************************************************************/ |
| <> | 154:37f96f9d4de2 | 37 | |
| <> | 154:37f96f9d4de2 | 38 | /******************************************************************************* |
| <> | 154:37f96f9d4de2 | 39 | * Private Functions |
| <> | 154:37f96f9d4de2 | 40 | ******************************************************************************/ |
| <> | 154:37f96f9d4de2 | 41 | static uint32_t smartcard_phy_emvsim_InterfaceClockInit(EMVSIM_Type *base, |
| <> | 154:37f96f9d4de2 | 42 | const smartcard_interface_config_t *config, |
| <> | 154:37f96f9d4de2 | 43 | uint32_t srcClock_Hz); |
| <> | 154:37f96f9d4de2 | 44 | |
| <> | 154:37f96f9d4de2 | 45 | /******************************************************************************* |
| <> | 154:37f96f9d4de2 | 46 | * Code |
| <> | 154:37f96f9d4de2 | 47 | ******************************************************************************/ |
| <> | 154:37f96f9d4de2 | 48 | |
| <> | 154:37f96f9d4de2 | 49 | /*! |
| <> | 154:37f96f9d4de2 | 50 | * @brief This function initializes clock module used for card clock generation |
| <> | 154:37f96f9d4de2 | 51 | */ |
| <> | 154:37f96f9d4de2 | 52 | static uint32_t smartcard_phy_emvsim_InterfaceClockInit(EMVSIM_Type *base, |
| <> | 154:37f96f9d4de2 | 53 | const smartcard_interface_config_t *config, |
| <> | 154:37f96f9d4de2 | 54 | uint32_t srcClock_Hz) |
| <> | 154:37f96f9d4de2 | 55 | { |
| <> | 154:37f96f9d4de2 | 56 | assert((NULL != config) && (0u != srcClock_Hz)); |
| <> | 154:37f96f9d4de2 | 57 | |
| <> | 154:37f96f9d4de2 | 58 | uint32_t emvsimClkMhz = 0u; |
| <> | 154:37f96f9d4de2 | 59 | uint8_t emvsimPRSCValue; |
| <> | 154:37f96f9d4de2 | 60 | |
| <> | 154:37f96f9d4de2 | 61 | /* Retrieve EMV SIM clock */ |
| <> | 154:37f96f9d4de2 | 62 | emvsimClkMhz = srcClock_Hz / 1000000u; |
| <> | 154:37f96f9d4de2 | 63 | /* Calculate MOD value */ |
| <> | 154:37f96f9d4de2 | 64 | emvsimPRSCValue = (emvsimClkMhz * 1000u) / (config->smartCardClock / 1000u); |
| <> | 154:37f96f9d4de2 | 65 | /* Set clock prescaler */ |
| <> | 154:37f96f9d4de2 | 66 | base->CLKCFG = (base->CLKCFG & ~EMVSIM_CLKCFG_CLK_PRSC_MASK) | EMVSIM_CLKCFG_CLK_PRSC(emvsimPRSCValue); |
| <> | 154:37f96f9d4de2 | 67 | |
| <> | 154:37f96f9d4de2 | 68 | return config->smartCardClock; |
| <> | 154:37f96f9d4de2 | 69 | } |
| <> | 154:37f96f9d4de2 | 70 | |
| <> | 154:37f96f9d4de2 | 71 | void SMARTCARD_PHY_EMVSIM_GetDefaultConfig(smartcard_interface_config_t *config) |
| <> | 154:37f96f9d4de2 | 72 | { |
| <> | 154:37f96f9d4de2 | 73 | assert((NULL != config)); |
| <> | 154:37f96f9d4de2 | 74 | |
| <> | 154:37f96f9d4de2 | 75 | config->clockToResetDelay = SMARTCARD_INIT_DELAY_CLOCK_CYCLES; |
| <> | 154:37f96f9d4de2 | 76 | config->vcc = kSMARTCARD_VoltageClassB3_3V; |
| <> | 154:37f96f9d4de2 | 77 | } |
| <> | 154:37f96f9d4de2 | 78 | |
| <> | 154:37f96f9d4de2 | 79 | status_t SMARTCARD_PHY_EMVSIM_Init(EMVSIM_Type *base, smartcard_interface_config_t const *config, uint32_t srcClock_Hz) |
| <> | 154:37f96f9d4de2 | 80 | { |
| <> | 154:37f96f9d4de2 | 81 | if ((NULL == config) || (0u == srcClock_Hz)) |
| <> | 154:37f96f9d4de2 | 82 | { |
| <> | 154:37f96f9d4de2 | 83 | return kStatus_SMARTCARD_InvalidInput; |
| <> | 154:37f96f9d4de2 | 84 | } |
| <> | 154:37f96f9d4de2 | 85 | |
| <> | 154:37f96f9d4de2 | 86 | /* SMARTCARD clock initialization. Clock is still not active after this call */ |
| <> | 154:37f96f9d4de2 | 87 | if (config->smartCardClock != smartcard_phy_emvsim_InterfaceClockInit(base, config, srcClock_Hz)) |
| <> | 154:37f96f9d4de2 | 88 | { |
| <> | 154:37f96f9d4de2 | 89 | return kStatus_SMARTCARD_OtherError; |
| <> | 154:37f96f9d4de2 | 90 | } |
| <> | 154:37f96f9d4de2 | 91 | /* Configure EMVSIM direct interface driver interrupt occur according card presence */ |
| <> | 154:37f96f9d4de2 | 92 | if (base->PCSR & EMVSIM_PCSR_SPDP_MASK) |
| <> | 154:37f96f9d4de2 | 93 | { |
| <> | 154:37f96f9d4de2 | 94 | base->PCSR &= ~EMVSIM_PCSR_SPDES_MASK; |
| <> | 154:37f96f9d4de2 | 95 | } |
| <> | 154:37f96f9d4de2 | 96 | else |
| <> | 154:37f96f9d4de2 | 97 | { |
| <> | 154:37f96f9d4de2 | 98 | base->PCSR |= EMVSIM_PCSR_SPDES_MASK; |
| <> | 154:37f96f9d4de2 | 99 | } |
| <> | 154:37f96f9d4de2 | 100 | /* Un-mask presence detect interrupt flag */ |
| <> | 154:37f96f9d4de2 | 101 | base->PCSR &= ~EMVSIM_PCSR_SPDIM_MASK; |
| <> | 154:37f96f9d4de2 | 102 | |
| <> | 154:37f96f9d4de2 | 103 | return kStatus_SMARTCARD_Success; |
| <> | 154:37f96f9d4de2 | 104 | } |
| <> | 154:37f96f9d4de2 | 105 | |
| <> | 154:37f96f9d4de2 | 106 | void SMARTCARD_PHY_EMVSIM_Deinit(EMVSIM_Type *base, const smartcard_interface_config_t *config) |
| <> | 154:37f96f9d4de2 | 107 | { |
| <> | 154:37f96f9d4de2 | 108 | assert((NULL != config)); |
| <> | 154:37f96f9d4de2 | 109 | /* Deactivate VCC, CLOCK */ |
| <> | 154:37f96f9d4de2 | 110 | base->PCSR &= ~(EMVSIM_PCSR_SCEN_MASK | EMVSIM_PCSR_SVCC_EN_MASK); |
| <> | 154:37f96f9d4de2 | 111 | } |
| <> | 154:37f96f9d4de2 | 112 | |
| <> | 154:37f96f9d4de2 | 113 | status_t SMARTCARD_PHY_EMVSIM_Activate(EMVSIM_Type *base, |
| <> | 154:37f96f9d4de2 | 114 | smartcard_context_t *context, |
| <> | 154:37f96f9d4de2 | 115 | smartcard_reset_type_t resetType) |
| <> | 154:37f96f9d4de2 | 116 | { |
| <> | 154:37f96f9d4de2 | 117 | if ((NULL == context) || (NULL == context->timeDelay)) |
| <> | 154:37f96f9d4de2 | 118 | { |
| <> | 154:37f96f9d4de2 | 119 | return kStatus_SMARTCARD_InvalidInput; |
| <> | 154:37f96f9d4de2 | 120 | } |
| <> | 154:37f96f9d4de2 | 121 | assert(context->interfaceConfig.vcc == kSMARTCARD_VoltageClassB3_3V); |
| <> | 154:37f96f9d4de2 | 122 | |
| <> | 154:37f96f9d4de2 | 123 | context->timersState.initCharTimerExpired = false; |
| <> | 154:37f96f9d4de2 | 124 | context->resetType = resetType; |
| <> | 154:37f96f9d4de2 | 125 | |
| <> | 154:37f96f9d4de2 | 126 | /* Disable receiver to deactivate GPC timers trigger */ |
| <> | 154:37f96f9d4de2 | 127 | base->CTRL &= ~EMVSIM_CTRL_RCV_EN_MASK; |
| <> | 154:37f96f9d4de2 | 128 | if (resetType == kSMARTCARD_ColdReset) |
| <> | 154:37f96f9d4de2 | 129 | { /* Set polarity of VCC to active high, Enable VCC for SMARTCARD, Enable smart card clock */ |
| <> | 154:37f96f9d4de2 | 130 | base->PCSR = (base->PCSR & ~EMVSIM_PCSR_VCCENP_MASK) | (EMVSIM_PCSR_SVCC_EN_MASK | EMVSIM_PCSR_SCEN_MASK); |
| <> | 154:37f96f9d4de2 | 131 | /* Set transfer inversion to default(direct) value */ |
| <> | 154:37f96f9d4de2 | 132 | base->CTRL &= ~EMVSIM_CTRL_IC_MASK; |
| <> | 154:37f96f9d4de2 | 133 | } |
| <> | 154:37f96f9d4de2 | 134 | else if (resetType == kSMARTCARD_WarmReset) |
| <> | 154:37f96f9d4de2 | 135 | { /* Ensure that card is already active */ |
| <> | 154:37f96f9d4de2 | 136 | if (!context->cardParams.active) |
| <> | 154:37f96f9d4de2 | 137 | { /* Card is not active;hence return */ |
| <> | 154:37f96f9d4de2 | 138 | return kStatus_SMARTCARD_CardNotActivated; |
| <> | 154:37f96f9d4de2 | 139 | } |
| <> | 154:37f96f9d4de2 | 140 | } |
| <> | 154:37f96f9d4de2 | 141 | else |
| <> | 154:37f96f9d4de2 | 142 | { |
| <> | 154:37f96f9d4de2 | 143 | return kStatus_SMARTCARD_InvalidInput; |
| <> | 154:37f96f9d4de2 | 144 | } |
| <> | 154:37f96f9d4de2 | 145 | /* Set Reset low */ |
| <> | 154:37f96f9d4de2 | 146 | base->PCSR &= ~EMVSIM_PCSR_SRST_MASK; |
| <> | 154:37f96f9d4de2 | 147 | /* Calculate time delay needed for reset */ |
| <> | 154:37f96f9d4de2 | 148 | uint32_t temp = (uint32_t)((float)(1 + (float)(((float)(1000u * context->interfaceConfig.clockToResetDelay)) / |
| <> | 154:37f96f9d4de2 | 149 | ((float)context->interfaceConfig.smartCardClock / 1000)))); |
| <> | 154:37f96f9d4de2 | 150 | context->timeDelay(temp); |
| <> | 154:37f96f9d4de2 | 151 | /* Pull reset HIGH Now to mark the end of Activation sequence */ |
| <> | 154:37f96f9d4de2 | 152 | base->PCSR |= EMVSIM_PCSR_SRST_MASK; |
| <> | 154:37f96f9d4de2 | 153 | /* Disable GPC timers input clock */ |
| <> | 154:37f96f9d4de2 | 154 | base->CLKCFG &= ~(EMVSIM_CLKCFG_GPCNT0_CLK_SEL_MASK | EMVSIM_CLKCFG_GPCNT1_CLK_SEL_MASK); |
| <> | 154:37f96f9d4de2 | 155 | /* Down counter trigger, and clear any pending counter status flag */ |
| <> | 154:37f96f9d4de2 | 156 | base->TX_STATUS = EMVSIM_TX_STATUS_GPCNT1_TO_MASK | EMVSIM_TX_STATUS_GPCNT0_TO_MASK; |
| <> | 154:37f96f9d4de2 | 157 | /* Set counter value for TS detection delay */ |
| <> | 154:37f96f9d4de2 | 158 | base->GPCNT0_VAL = (SMARTCARD_INIT_DELAY_CLOCK_CYCLES + SMARTCARD_INIT_DELAY_CLOCK_CYCLES_ADJUSTMENT); |
| <> | 154:37f96f9d4de2 | 159 | /* Pre-load counter value for ATR duration delay */ |
| <> | 154:37f96f9d4de2 | 160 | base->GPCNT1_VAL = (SMARTCARD_EMV_ATR_DURATION_ETU + SMARTCARD_ATR_DURATION_ADJUSTMENT); |
| <> | 154:37f96f9d4de2 | 161 | /* Select the clock for GPCNT for both TS detection and early start of ATR duration counter */ |
| <> | 154:37f96f9d4de2 | 162 | base->CLKCFG |= |
| <> | 154:37f96f9d4de2 | 163 | (EMVSIM_CLKCFG_GPCNT0_CLK_SEL(kEMVSIM_GPCCardClock) | EMVSIM_CLKCFG_GPCNT1_CLK_SEL(kEMVSIM_GPCTxClock)); |
| <> | 154:37f96f9d4de2 | 164 | /* Set receiver to ICM mode, Flush RX FIFO */ |
| <> | 154:37f96f9d4de2 | 165 | base->CTRL |= (EMVSIM_CTRL_ICM_MASK | EMVSIM_CTRL_FLSH_RX_MASK); |
| <> | 154:37f96f9d4de2 | 166 | /* Enable counter interrupt for TS detection */ |
| <> | 154:37f96f9d4de2 | 167 | base->INT_MASK &= ~EMVSIM_INT_MASK_GPCNT0_IM_MASK; |
| <> | 154:37f96f9d4de2 | 168 | /* Clear any pending status flags */ |
| <> | 154:37f96f9d4de2 | 169 | base->RX_STATUS = 0xFFFFFFFFu; |
| <> | 154:37f96f9d4de2 | 170 | /* Enable receiver */ |
| <> | 154:37f96f9d4de2 | 171 | base->CTRL |= EMVSIM_CTRL_RCV_EN_MASK; |
| <> | 154:37f96f9d4de2 | 172 | /* Here the card was activated */ |
| <> | 154:37f96f9d4de2 | 173 | context->cardParams.active = true; |
| <> | 154:37f96f9d4de2 | 174 | |
| <> | 154:37f96f9d4de2 | 175 | return kStatus_SMARTCARD_Success; |
| <> | 154:37f96f9d4de2 | 176 | } |
| <> | 154:37f96f9d4de2 | 177 | |
| <> | 154:37f96f9d4de2 | 178 | status_t SMARTCARD_PHY_EMVSIM_Deactivate(EMVSIM_Type *base, smartcard_context_t *context) |
| <> | 154:37f96f9d4de2 | 179 | { |
| <> | 154:37f96f9d4de2 | 180 | if ((NULL == context)) |
| <> | 154:37f96f9d4de2 | 181 | { |
| <> | 154:37f96f9d4de2 | 182 | return kStatus_SMARTCARD_InvalidInput; |
| <> | 154:37f96f9d4de2 | 183 | } |
| <> | 154:37f96f9d4de2 | 184 | |
| <> | 154:37f96f9d4de2 | 185 | /* Assert Reset */ |
| <> | 154:37f96f9d4de2 | 186 | base->PCSR &= ~EMVSIM_PCSR_SRST_MASK; |
| <> | 154:37f96f9d4de2 | 187 | /* Stop SMARTCARD clock generation */ |
| <> | 154:37f96f9d4de2 | 188 | base->PCSR &= ~EMVSIM_PCSR_SCEN_MASK; |
| <> | 154:37f96f9d4de2 | 189 | /* Deactivate card by disabling VCC */ |
| <> | 154:37f96f9d4de2 | 190 | base->PCSR &= ~EMVSIM_PCSR_SVCC_EN_MASK; |
| <> | 154:37f96f9d4de2 | 191 | /* According EMV 4.3 specification deactivation sequence should be done within 100ms. |
| <> | 154:37f96f9d4de2 | 192 | * The period is measured from the time that RST is set to state L to the time that Vcc |
| <> | 154:37f96f9d4de2 | 193 | * reaches 0.4 V or less. |
| <> | 154:37f96f9d4de2 | 194 | */ |
| <> | 154:37f96f9d4de2 | 195 | context->timeDelay(100 * 1000); |
| <> | 154:37f96f9d4de2 | 196 | /* Here the card was deactivated */ |
| <> | 154:37f96f9d4de2 | 197 | context->cardParams.active = false; |
| <> | 154:37f96f9d4de2 | 198 | |
| <> | 154:37f96f9d4de2 | 199 | return kStatus_SMARTCARD_Success; |
| <> | 154:37f96f9d4de2 | 200 | } |
| <> | 154:37f96f9d4de2 | 201 | |
| <> | 154:37f96f9d4de2 | 202 | status_t SMARTCARD_PHY_EMVSIM_Control(EMVSIM_Type *base, |
| <> | 154:37f96f9d4de2 | 203 | smartcard_context_t *context, |
| <> | 154:37f96f9d4de2 | 204 | smartcard_interface_control_t control, |
| <> | 154:37f96f9d4de2 | 205 | uint32_t param) |
| <> | 154:37f96f9d4de2 | 206 | { |
| <> | 154:37f96f9d4de2 | 207 | if ((NULL == context)) |
| <> | 154:37f96f9d4de2 | 208 | { |
| <> | 154:37f96f9d4de2 | 209 | return kStatus_SMARTCARD_InvalidInput; |
| <> | 154:37f96f9d4de2 | 210 | } |
| <> | 154:37f96f9d4de2 | 211 | |
| <> | 154:37f96f9d4de2 | 212 | switch (control) |
| <> | 154:37f96f9d4de2 | 213 | { |
| <> | 154:37f96f9d4de2 | 214 | case kSMARTCARD_InterfaceSetVcc: |
| <> | 154:37f96f9d4de2 | 215 | /* Only 3.3V interface supported by the direct interface */ |
| <> | 154:37f96f9d4de2 | 216 | assert((smartcard_card_voltage_class_t)param == kSMARTCARD_VoltageClassB3_3V); |
| <> | 154:37f96f9d4de2 | 217 | context->interfaceConfig.vcc = (smartcard_card_voltage_class_t)param; |
| <> | 154:37f96f9d4de2 | 218 | break; |
| <> | 154:37f96f9d4de2 | 219 | case kSMARTCARD_InterfaceSetClockToResetDelay: |
| <> | 154:37f96f9d4de2 | 220 | /* Set interface clock to Reset delay set by caller */ |
| <> | 154:37f96f9d4de2 | 221 | context->interfaceConfig.clockToResetDelay = param; |
| <> | 154:37f96f9d4de2 | 222 | break; |
| <> | 154:37f96f9d4de2 | 223 | case kSMARTCARD_InterfaceReadStatus: |
| <> | 154:37f96f9d4de2 | 224 | /* Expecting active low present detect */ |
| <> | 154:37f96f9d4de2 | 225 | context->cardParams.present = |
| <> | 154:37f96f9d4de2 | 226 | (emvsim_presence_detect_status_t)((base->PCSR & EMVSIM_PCSR_SPDP_MASK) >> EMVSIM_PCSR_SPDP_SHIFT) == |
| <> | 154:37f96f9d4de2 | 227 | kEMVSIM_DetectPinIsLow; |
| <> | 154:37f96f9d4de2 | 228 | break; |
| <> | 154:37f96f9d4de2 | 229 | default: |
| <> | 154:37f96f9d4de2 | 230 | return kStatus_SMARTCARD_InvalidInput; |
| <> | 154:37f96f9d4de2 | 231 | } |
| <> | 154:37f96f9d4de2 | 232 | |
| <> | 154:37f96f9d4de2 | 233 | return kStatus_SMARTCARD_Success; |
| <> | 154:37f96f9d4de2 | 234 | } |
