fsl_smartcard_phy_emvsim.c 8.6 KB

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