Kevin Kadooka / mbed-dev

Fork of mbed-dev by mbed official

Committer:
kkado
Date:
Tue Jun 20 11:06:37 2017 +0000
Revision:
167:356ef919c855
Parent:
154:37f96f9d4de2
Build 137 with reduced HSE timeout

Who changed what in which revision?

UserRevisionLine numberNew 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 }