phStatus_t phKeyStore_Rc632_WriteE2_Int( phKeyStore_Rc632_DataParams_t * pDataParams, uint8_t *pData, uint16_t DataLength ) { phStatus_t PH_MEMLOC_REM statusTmp; uint8_t PH_MEMLOC_REM bCmdReg; uint16_t PH_MEMLOC_COUNT i; /* disable all interrupt */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_WriteRegister( pDataParams->pHalDataParams, PH_KEYSTORE_RC632_REG_INT_EN, 0x7F )); /* Stop an eventual previous Command (enter Idle state) */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_WriteRegister( pDataParams->pHalDataParams, PH_KEYSTORE_RC632_REG_COMMAND, PH_KEYSTORE_RC632_CMD_IDLE )); /* Flush Rc632 fifo */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_WriteRegister( pDataParams->pHalDataParams, PH_KEYSTORE_RC632_REG_CONTROL, PH_KEYSTORE_RC632_BIT_FLUSHFIFO )); /* Fill up Rc632 fifo with data associated to WriteE2 command */ for (i = 0; i < DataLength; ++i) { PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_WriteRegister( pDataParams->pHalDataParams, PH_KEYSTORE_RC632_REG_FIFO_DATA, *pData++ )); } /* Execute Rc632 WriteE2 command */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_WriteRegister( pDataParams->pHalDataParams, PH_KEYSTORE_RC632_REG_COMMAND, PH_KEYSTORE_RC632_CMD_WRITE_E2 )); /* Wait end of execution of Rc632 WriteE2 command */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_Wait( pDataParams->pHalDataParams, PHHAL_HW_TIME_MILLISECONDS, PH_KEYSTORE_RC632_EEP_WR_TO_MS )); /* Check if eeprom is ready */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_ReadRegister( pDataParams->pHalDataParams, PH_KEYSTORE_RC632_REG_SECONDARY_STATUS, &bCmdReg )); /* Command has to be stopped manually to get back to Idle */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_WriteRegister( pDataParams->pHalDataParams, PH_KEYSTORE_RC632_REG_COMMAND, PH_KEYSTORE_RC632_CMD_IDLE )); /* Check for write error */ if (!(bCmdReg & PH_KEYSTORE_RC632_BIT_E2READY)) { return PH_ADD_COMPCODE(PH_ERR_READ_WRITE_ERROR, PH_COMP_KEYSTORE); } return PH_ADD_COMPCODE(PH_ERR_SUCCESS, PH_COMP_KEYSTORE); }
phStatus_t phpalI14443p4a_Sw_Rats( phpalI14443p4a_Sw_DataParams_t * pDataParams, uint8_t bFsdi, uint8_t bCid, uint8_t * pAts ) { phStatus_t PH_MEMLOC_REM status; phStatus_t PH_MEMLOC_REM statusTmp; uint8_t PH_MEMLOC_REM cmd[2]; uint8_t PH_MEMLOC_REM bAtsIndex; uint8_t PH_MEMLOC_REM bSfgi; uint32_t PH_MEMLOC_REM dwSfgt; uint32_t PH_MEMLOC_REM dwFwt; uint8_t * PH_MEMLOC_REM pResp; uint16_t PH_MEMLOC_REM wRespLength; /* Parameter check */ if ((bFsdi > 8) || (bCid > 14)) { return PH_ADD_COMPCODE(PH_ERR_INVALID_PARAMETER, PH_COMP_PAL_ISO14443P4A); } /* Set Activation timeout */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_TIMEOUT_VALUE_US, PHPAL_I14443P4A_SW_FWT_ACTIVATION_US + PHPAL_I14443P4A_SW_EXT_TIME_US)); /* Send Rats command */ cmd[0] = PHPAL_I14443P4A_SW_RATS; cmd[1] = (uint8_t)(((bFsdi << 4) & 0xF0) | (bCid & 0x0F)); status = phhalHw_Exchange( pDataParams->pHalDataParams, PH_EXCHANGE_DEFAULT, cmd, 2, &pResp, &wRespLength); if ((status & PH_ERR_MASK) == PH_ERR_SUCCESS) { /* Check for protocol error */ if (((uint8_t)wRespLength != pResp[0]) || (wRespLength < 1)) { return PH_ADD_COMPCODE(PH_ERR_PROTOCOL_ERROR, PH_COMP_PAL_ISO14443P4A); } /* Copy ATS buffer */ memcpy(pAts, pResp, wRespLength); /* PRQA S 3200 */ /* Set default values */ /* */ pDataParams->bCidSupported = PH_OFF; pDataParams->bCid = 0x00; pDataParams->bNadSupported = PH_OFF; pDataParams->bBitRateCaps = 0x00; pDataParams->bFwi = PHPAL_I14443P4A_SW_FWI_DEFAULT; pDataParams->bFsdi = bFsdi; pDataParams->bFsci = PHPAL_I14443P4A_SW_FSCI_DEFAULT; pDataParams->bDri = 0x00; pDataParams->bDsi = 0x00; bSfgi = PHPAL_I14443P4A_SW_SFGI_DEFAULT; /* Retrieve ATS information */ /* Start parsing with T0 byte */ bAtsIndex = PHPAL_I14443P4A_SW_ATS_T0; /* Parse T0/TA/TB/TC */ if (wRespLength > 1) { /* Parse T0 */ pDataParams->bFsci = pAts[bAtsIndex] & 0x0F; if (pDataParams->bFsci > 8) { pDataParams->bFsci = 8; } bAtsIndex++; /* Parse TA(1) */ if (pAts[PHPAL_I14443P4A_SW_ATS_T0] & PHPAL_I14443P4A_SW_ATS_TA1_PRESENT) { /* Check for protocol error */ if (wRespLength <= bAtsIndex) { return PH_ADD_COMPCODE(PH_ERR_PROTOCOL_ERROR, PH_COMP_PAL_ISO14443P4A); } else { /* Store Bitrate capabilities */ pDataParams->bBitRateCaps = pAts[bAtsIndex]; bAtsIndex++; } } /* Parse TB(1) */ if (pAts[PHPAL_I14443P4A_SW_ATS_T0] & PHPAL_I14443P4A_SW_ATS_TB1_PRESENT) { /* Check for protocol error */ if (wRespLength <= bAtsIndex) { return PH_ADD_COMPCODE(PH_ERR_PROTOCOL_ERROR, PH_COMP_PAL_ISO14443P4A); } else { /* Store Sfgi */ bSfgi = pAts[bAtsIndex] & 0x0F; if (bSfgi == 0x0F) { bSfgi = PHPAL_I14443P4A_SW_SFGI_DEFAULT; } /* Store Fwi */ pDataParams->bFwi = (pAts[bAtsIndex] >> 4) & 0x0F; if (pDataParams->bFwi == 0x0F) { pDataParams->bFwi = PHPAL_I14443P4A_SW_FWI_DEFAULT; } bAtsIndex++; } } /* Parse TC(1) */ if (pAts[PHPAL_I14443P4A_SW_ATS_T0] & PHPAL_I14443P4A_SW_ATS_TC1_PRESENT) { /* Check for protocol error */ if (wRespLength <= bAtsIndex) { return PH_ADD_COMPCODE(PH_ERR_PROTOCOL_ERROR, PH_COMP_PAL_ISO14443P4A); } else { /* Check NAD Support */ if (pAts[bAtsIndex] & PHPAL_I14443P4A_SW_ATS_TC1_NAD_SUPPORT) { pDataParams->bNadSupported = 1; } /* Check CID Support */ if (pAts[bAtsIndex] & PHPAL_I14443P4A_SW_ATS_TC1_CID_SUPPORT) { pDataParams->bCidSupported = 1; pDataParams->bCid = bCid; } } } } /* Calculate SFGT in Microseconds */ dwSfgt = (uint32_t)(PHPAL_I14443P4A_SW_FWT_MIN_US * (1 << bSfgi)); /* Perform SFGT Wait */ if (dwSfgt > 0xFFFF) { PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_Wait( pDataParams->pHalDataParams, PHHAL_HW_TIME_MILLISECONDS, (uint16_t)(dwSfgt / 1000))); } else { PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_Wait( pDataParams->pHalDataParams, PHHAL_HW_TIME_MICROSECONDS, (uint16_t)dwSfgt)); } /* Calculate FWT timeout */ dwFwt = (uint32_t)(PHPAL_I14443P4A_SW_FWT_MIN_US * (1 << pDataParams->bFwi)); /* Add extension time */ dwFwt = dwFwt + PHPAL_I14443P4A_SW_EXT_TIME_US; /* Set FWT timeout */ if (dwFwt > 0xFFFF) { /* +1 is added to the timeout in millisecond to compensate the * fractional microseconds lost in division by 1000 */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_TIMEOUT_VALUE_MS, (uint16_t)((dwFwt / 1000) + 1))); } else { PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_TIMEOUT_VALUE_US, (uint16_t)dwFwt)); } }