/* * Copyright (c), NXP Semiconductors Gratkorn / Austria * * (C)NXP Semiconductors * All rights are reserved. Reproduction in whole or in part is * prohibited without the written consent of the copyright owner. * NXP reserves the right to make changes without notice at any time. * NXP makes no warranty, expressed, implied or statutory, including but * not limited to any implied warranty of merchantability or fitness for any *particular purpose, or that the use will not infringe any third party patent, * copyright or trademark. NXP must not be liable for any loss or damage * arising from its use. */ /** \file * Software ICode EPC/UID Component of Reader Library Framework. * $Author$ * $Revision$ (v07.10.00) * $Date$ * * History: * CHu: Generated 8. September 2009 * */ #include #include #include #include #include #ifdef NXPBUILD__PHPAL_EPCUID_SW #include "phpalEpcUid_Sw.h" #include "phpalEpcUid_Sw_Int.h" phStatus_t phpalEpcUid_Sw_Init( phpalEpcUid_Sw_DataParams_t * pDataParams, uint16_t wSizeOfDataParams, void * pHalDataParams ) { /* Dataparam check */ if (sizeof(phpalEpcUid_Sw_DataParams_t) != wSizeOfDataParams) { return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_DATA_PARAMS, PH_COMP_PAL_EPCUID); } /* Pointer check */ PH_ASSERT_NULL (pDataParams); PH_ASSERT_NULL (pHalDataParams); /* init private data */ pDataParams->wId = PH_COMP_PAL_EPCUID | PHPAL_EPCUID_SW_ID; pDataParams->pHalDataParams = pHalDataParams; pDataParams->bUidValid = PH_OFF; return PH_ERR_SUCCESS; } phStatus_t phpalEpcUid_Sw_ActivateCard( phpalEpcUid_Sw_DataParams_t * pDataParams, uint8_t bTagType, uint8_t bNumSlots, uint8_t * pMask, uint8_t bMaskBitLength, uint8_t bHash, uint8_t * pRxBuffer, uint8_t * pRxLength, uint8_t * pMoreCardsAvailable ) { phStatus_t PH_MEMLOC_REM status; phStatus_t PH_MEMLOC_REM statusTmp; phStatus_t PH_MEMLOC_REM statusReturned; uint8_t PH_MEMLOC_REM bNumSlotsTmp; uint16_t PH_MEMLOC_REM wNumSlotsDec; uint8_t PH_MEMLOC_REM bCardsPresent; /* reset pMoreCardsAvailable flag */ *pMoreCardsAvailable = PH_OFF; /* init. return status */ statusReturned = PH_ERR_SUCCESS; do { /* Reset card present state */ bCardsPresent = PH_OFF; /* Start a new Response Round and scan slot 0 */ status = phpalEpcUid_Sw_BeginRound( pDataParams, bTagType, bNumSlots, pMask, bMaskBitLength, bHash, pRxBuffer, pRxLength); /* Return on parameter error */ if ((status & PH_ERR_MASK) == PH_ERR_INVALID_PARAMETER) { return status; } /* Calculate number of slots in decimal */ wNumSlotsDec = 0x01; if (bNumSlots > PHPAL_EPCUID_NUMSLOTS_1) { bNumSlotsTmp = bNumSlots; do { bNumSlotsTmp >>= 1U; wNumSlotsDec <<= 1U; } while (0U != bNumSlotsTmp); wNumSlotsDec <<= 1U; } bNumSlotsTmp = bNumSlots; /* Do for all further requested slots */ while (0U != (wNumSlotsDec--)) { /* Multiple labels found in current slot */ if (((status & PH_ERR_MASK) == PH_ERR_COLLISION_ERROR) || ((status & PH_ERR_MASK) == PH_ERR_INTEGRITY_ERROR)) { bCardsPresent = PH_ON; *pMoreCardsAvailable = PH_ON; /* Store collision error in case it can't be resolved */ if ((statusReturned & PH_ERR_MASK) == PH_ERR_SUCCESS) { statusReturned = status; } } else { /* Store timeout error if integrity / collision error has not happened */ if ((status & PH_ERR_MASK) == PH_ERR_IO_TIMEOUT) { if ((statusReturned & PH_ERR_MASK) == PH_ERR_SUCCESS) { statusReturned = status; } } /* Return on success or other errors */ else { return status; } } /* Last slot -> send CloseSlotLast */ if (wNumSlotsDec == 0U) { /* Send CloseSlot command */ PH_CHECK_SUCCESS_FCT(statusTmp, phpalEpcUid_Sw_CloseSlot( pDataParams, PHPAL_EPCUID_CLOSESLOT_LAST, pRxBuffer, pRxLength)); } else { /* Send CloseSlot command */ status = phpalEpcUid_Sw_CloseSlot( pDataParams, PHPAL_EPCUID_CLOSESLOT_NONLAST, pRxBuffer, pRxLength); } } /* Increment number of slots */ bNumSlots = (bNumSlots << 1U) | 0x01U; } while ((bCardsPresent != PH_OFF) && (bNumSlotsTmp < PHPAL_EPCUID_NUMSLOTS_512)); /* return error */ return statusReturned; } phStatus_t phpalEpcUid_Sw_BeginRound( phpalEpcUid_Sw_DataParams_t * pDataParams, uint8_t bTagType, uint8_t bNumSlots, uint8_t * pMask, uint8_t bMaskBitLength, uint8_t bHash, uint8_t * pRxBuffer, uint8_t * pRxLength ) { phStatus_t PH_MEMLOC_REM statusTmp; uint8_t PH_MEMLOC_REM bCrc8; uint8_t PH_MEMLOC_REM bBitCount; uint8_t PH_MEMLOC_REM aCommand[PHPAL_EPCUID_IDD_LENGTH + 4U]; uint16_t PH_MEMLOC_REM wCommandLen = 0; uint16_t PH_MEMLOC_REM wCommandBitLen = 0; uint8_t * PH_MEMLOC_REM pResponse = NULL; uint16_t PH_MEMLOC_REM wResponseLen = 0; /* Parameter check */ switch (bNumSlots) { case PHPAL_EPCUID_NUMSLOTS_1: case PHPAL_EPCUID_NUMSLOTS_4: case PHPAL_EPCUID_NUMSLOTS_8: case PHPAL_EPCUID_NUMSLOTS_16: case PHPAL_EPCUID_NUMSLOTS_32: case PHPAL_EPCUID_NUMSLOTS_64: case PHPAL_EPCUID_NUMSLOTS_128: case PHPAL_EPCUID_NUMSLOTS_256: case PHPAL_EPCUID_NUMSLOTS_512: break; default: return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_PAL_EPCUID); } /* checks for EPC */ if (bTagType == PHPAL_EPCUID_LABEL_EPC) { if (bMaskBitLength > (PHPAL_EPCUID_EPC_LENGTH << 3U)) { return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_PAL_EPCUID); } /* Copy EPC mask */ (void)memcpy(pDataParams->LabelInfo.bEpc, pMask, (size_t)(((uint32_t)bMaskBitLength) >> 3U)); } /* checks for UID */ else if (bTagType == PHPAL_EPCUID_LABEL_UID) { if (bMaskBitLength > (PHPAL_EPCUID_IDD_LENGTH << 3U)) { return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_PAL_EPCUID); } /* Copy IDD mask */ (void)memcpy(pDataParams->LabelInfo.bIdd, pMask, (((uint32_t)bMaskBitLength) >> 3U)); } else { return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_PAL_EPCUID); } /* reset label data */ pDataParams->bLabelType = bTagType; pDataParams->bMaskBitLength = bMaskBitLength; pDataParams->bUidValid = PH_OFF; /* Build first part of frame */ aCommand[0] = PHPAL_EPCUID_SW_CMD_BEGINROUND; aCommand[1] = bMaskBitLength; /* Evaluate command length and copy mask */ bBitCount = bMaskBitLength & 0x07U; wCommandLen = (bBitCount == 0U) ? (((uint16_t)bMaskBitLength) >> 3U) : ((((uint16_t)bMaskBitLength) >> 3U) + 1U); (void)memcpy(&aCommand[2], pMask, wCommandLen); wCommandLen = wCommandLen + 2U; /* append number of slots */ if (0U != (bBitCount)) { /* clear the last invalid bits of the mask */ aCommand[wCommandLen - 1u] &= (uint8_t) (0xFFU << (8U - bBitCount)); /* append number of slots */ aCommand[wCommandLen - 1u] |= (uint8_t) (bNumSlots >> bBitCount); aCommand[wCommandLen++] = (uint8_t) (bNumSlots << (8U - bBitCount)); } else { aCommand[wCommandLen++] = bNumSlots; } /* Calculate full bit-length */ wCommandBitLen = (bBitCount == 0U) ? (wCommandLen << 3U) : (((uint16_t)(wCommandLen - 1u) << 3U) + bBitCount); /* Calculate CRC for Epc */ if (bTagType == PHPAL_EPCUID_LABEL_EPC) { PH_CHECK_SUCCESS_FCT(statusTmp, phTools_CalculateCrc8( PH_TOOLS_CRC_OPTION_MSB_FIRST | PH_TOOLS_CRC_OPTION_BITWISE, PH_TOOLS_CRC8_PRESET_EPC, PH_TOOLS_CRC8_POLY_EPCUID, aCommand, wCommandBitLen, &bCrc8)); } /* calculate CRC for Uid */ else { PH_CHECK_SUCCESS_FCT(statusTmp, phTools_CalculateCrc8( PH_TOOLS_CRC_OPTION_MSB_FIRST | PH_TOOLS_CRC_OPTION_BITWISE, PH_TOOLS_CRC8_PRESET_UID, PH_TOOLS_CRC8_POLY_EPCUID, aCommand, wCommandBitLen, &bCrc8)); } /* Insert CRC & Hashvalue if applicable */ if (0U != (bBitCount)) { /* Insert the crc */ aCommand[wCommandLen - 1u] |= bCrc8 >> bBitCount; aCommand[wCommandLen++] = bCrc8 << (8U - bBitCount); if (bTagType == PHPAL_EPCUID_LABEL_EPC) { /* Insert the hash value */ aCommand[wCommandLen - 1u] |= bHash >> bBitCount; aCommand[wCommandLen++] = bHash << (8U - bBitCount); } } else { /* Insert the crc */ aCommand[wCommandLen++] = bCrc8; if (bTagType == PHPAL_EPCUID_LABEL_EPC) { /* Insert the hash value */ aCommand[wCommandLen++] = bHash; } } /* Set TxLastBits to bBitCount */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_TXLASTBITS, bBitCount)); /* set SSOF as start symbol */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_SYMBOL_START, PHHAL_HW_SYMBOL_ICODEEPCUID_SSOF) ); /* set CEOF as end symbol */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_SYMBOL_END, PHHAL_HW_SYMBOL_ICODEEPCUID_CEOF) ); /* Set RxWait */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_RXWAIT_US, PHPAL_EPCUID_SW_BEGINROUND_DEAFTIME)); /* Set the RxTimeout */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_TIMEOUT_VALUE_US, PHPAL_EPCUID_SW_TIMEOUT_ANTICOLL_US)); /* Exchange command */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_Exchange( pDataParams->pHalDataParams, PH_EXCHANGE_DEFAULT, aCommand, wCommandLen, &pResponse, &wResponseLen)); /* Parse response */ PH_CHECK_SUCCESS_FCT(statusTmp, phpalEpcUid_Sw_ParseResponse(pDataParams, pResponse, wResponseLen)); /* Return response */ if (pDataParams->bLabelType == PHPAL_EPCUID_LABEL_EPC) { *pRxLength = PHPAL_EPCUID_EPC_LENGTH; (void)memcpy(pRxBuffer, pDataParams->LabelInfo.bEpc, *pRxLength); } else { *pRxLength = PHPAL_EPCUID_IDD_LENGTH; (void)memcpy(pRxBuffer, pDataParams->LabelInfo.bIdd, *pRxLength); } return PH_ERR_SUCCESS; } phStatus_t phpalEpcUid_Sw_CloseSlot( phpalEpcUid_Sw_DataParams_t * pDataParams, uint8_t bOption, uint8_t * pRxBuffer, uint8_t * pRxLength ) { phStatus_t PH_MEMLOC_REM status; phStatus_t PH_MEMLOC_REM statusTmp; uint8_t PH_MEMLOC_REM aCommand[1]; uint8_t * PH_MEMLOC_REM pResponse = NULL; uint16_t PH_MEMLOC_REM wResponseLen = 0; /* Set closeslot timeout*/ if (bOption == PHPAL_EPCUID_CLOSESLOT_NONLAST) { PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_TIMEOUT_VALUE_US, PHPAL_EPCUID_SW_TIMEOUT_ANTICOLL_US)); } /* Set minimum timeout */ else if (bOption == PHPAL_EPCUID_CLOSESLOT_LAST) { PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_TIMEOUT_VALUE_US, 1)); } else { return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_PAL_EPCUID); } /* set CS as start symbol */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_SYMBOL_START, PHHAL_HW_SYMBOL_ICODEEPCUID_CS)); /* no stop symbol */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_SYMBOL_END, PHHAL_HW_SYMBOL_ICODEEPCUID_CEOF)); /* Set RxWait */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_RXWAIT_US, PHPAL_EPCUID_SW_DEAFTIME_DEFAULT)); /* Exchange command */ status = phhalHw_Exchange( pDataParams->pHalDataParams, PH_EXCHANGE_DEFAULT, aCommand, 0, &pResponse, &wResponseLen); if (bOption == PHPAL_EPCUID_CLOSESLOT_NONLAST) { /* Return on error */ PH_CHECK_SUCCESS(status); /* Parse response */ PH_CHECK_SUCCESS_FCT(statusTmp, phpalEpcUid_Sw_ParseResponse(pDataParams, pResponse, wResponseLen)); /* Return response */ if (pDataParams->bLabelType == PHPAL_EPCUID_LABEL_EPC) { *pRxLength = PHPAL_EPCUID_EPC_LENGTH; (void)memcpy(pRxBuffer, pDataParams->LabelInfo.bEpc, *pRxLength); } else { *pRxLength = PHPAL_EPCUID_IDD_LENGTH; (void)memcpy(pRxBuffer, pDataParams->LabelInfo.bIdd, *pRxLength); } } else { /* Reset received length */ if (NULL != (pRxLength)) { *pRxLength = 0; } /* Timeout is the correct behaviour */ if ((status & PH_ERR_MASK) != PH_ERR_IO_TIMEOUT) { if ((status & PH_ERR_MASK) == PH_ERR_SUCCESS) { /* if data was received return an error */ return PH_ADD_COMPCODE_FIXED(PH_ERR_PROTOCOL_ERROR, PH_COMP_PAL_EPCUID); } else { /* Return the received error */ return status; } } } return PH_ERR_SUCCESS; } phStatus_t phpalEpcUid_Sw_FixSlot( phpalEpcUid_Sw_DataParams_t * pDataParams, uint8_t bTagType, uint8_t * pMask, uint8_t bMaskBitLength ) { phStatus_t PH_MEMLOC_REM status; phStatus_t PH_MEMLOC_REM statusTmp; uint8_t PH_MEMLOC_REM aCommand[2]; uint8_t * PH_MEMLOC_REM pResponse = NULL; uint16_t PH_MEMLOC_REM wResponseLen = 0; uint8_t PH_MEMLOC_REM bResponseLen; uint16_t PH_MEMLOC_REM wCrc16; /* checks for EPC */ if (bTagType == PHPAL_EPCUID_LABEL_EPC) { if (bMaskBitLength != (PHPAL_EPCUID_EPC_LENGTH << 3U)) { return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_PAL_EPCUID); } } /* checks for UID */ else if (bTagType == PHPAL_EPCUID_LABEL_UID) { if (bMaskBitLength != (PHPAL_EPCUID_IDD_LENGTH << 3U)) { return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_PAL_EPCUID); } } else { return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_PAL_EPCUID); } /* Set TxWait */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_TXWAIT_US, PHPAL_EPCUID_SW_T1_MIN_US)); /* Execute Begin-Round with only 1 slot */ PH_CHECK_SUCCESS_FCT(statusTmp, phpalEpcUid_Sw_BeginRound( pDataParams, bTagType, PHPAL_EPCUID_NUMSLOTS_1, pMask, bMaskBitLength, 0x00, pDataParams->LabelInfo.bIdd, &bResponseLen)); /* Calculate CRC */ if (pDataParams->bLabelType == PHPAL_EPCUID_LABEL_EPC) { PH_CHECK_SUCCESS_FCT(statusTmp, phTools_CalculateCrc16( PH_TOOLS_CRC_OPTION_MSB_FIRST | PH_TOOLS_CRC_OPTION_OUPUT_INVERTED, PH_TOOLS_CRC16_PRESET_EPCUID, PH_TOOLS_CRC16_POLY_EPCUID, pDataParams->LabelInfo.bEpc, PHPAL_EPCUID_EPC_LENGTH, &wCrc16)); } else { PH_CHECK_SUCCESS_FCT(statusTmp, phTools_CalculateCrc16( PH_TOOLS_CRC_OPTION_MSB_FIRST | PH_TOOLS_CRC_OPTION_OUPUT_INVERTED, PH_TOOLS_CRC16_PRESET_EPCUID, PH_TOOLS_CRC16_POLY_EPCUID, &pDataParams->LabelInfo.bIdd[PHPAL_EPCUID_EPC_LENGTH + 2U], PHPAL_EPCUID_IDD_LENGTH - (PHPAL_EPCUID_EPC_LENGTH + 2U), &wCrc16)); } /* Build fix-slot command (2 crc bytes) */ aCommand[0] = (uint8_t)(wCrc16 >> 8U); aCommand[1] = (uint8_t)wCrc16; /* set LSOF as start symbol */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_SYMBOL_START, PHHAL_HW_SYMBOL_ICODEEPCUID_LSOF)); /* set CEOF as end symbol */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_SYMBOL_END, PHHAL_HW_SYMBOL_ICODEEPCUID_CEOF)); /* Set RxWait */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_RXWAIT_US, PHPAL_EPCUID_SW_DEAFTIME_DEFAULT)); /* Set fix-slot timeout */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_TIMEOUT_VALUE_US, 1)); /* Send the command */ status = phhalHw_Exchange( pDataParams->pHalDataParams, PH_EXCHANGE_DEFAULT, aCommand, 2, &pResponse, &wResponseLen); /* Timeout is the correct behaviour */ if ((status & PH_ERR_MASK) != PH_ERR_IO_TIMEOUT) { if ((status & PH_ERR_MASK) == PH_ERR_SUCCESS) { /* if data was received return an error */ return PH_ADD_COMPCODE_FIXED(PH_ERR_PROTOCOL_ERROR, PH_COMP_PAL_EPCUID); } else { /* Return the received error */ return status; } } return PH_ERR_SUCCESS; } phStatus_t phpalEpcUid_Sw_Write( phpalEpcUid_Sw_DataParams_t * pDataParams, uint8_t bTagType, uint8_t bBlockNo, uint8_t bData ) { phStatus_t PH_MEMLOC_REM status; phStatus_t PH_MEMLOC_REM statusTmp; uint8_t PH_MEMLOC_REM aCommand[4]; uint8_t * PH_MEMLOC_REM pResponse = NULL; uint16_t PH_MEMLOC_REM wResponseLen = 0; /* checks for EPC */ if (bTagType == PHPAL_EPCUID_LABEL_EPC) { if (bBlockNo > PHPAL_EPCUID_EPC_MAXBLOCKNUMBER) { return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_PAL_EPCUID); } } /* checks for UID */ else if (bTagType == PHPAL_EPCUID_LABEL_UID) { if (bBlockNo > PHPAL_EPCUID_UID_MAXBLOCKNUMBER) { return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_PAL_EPCUID); } } else { return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_PAL_EPCUID); } /* set SSOF as start symbol */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_SYMBOL_START, PHHAL_HW_SYMBOL_ICODEEPCUID_SSOF) ); /* set CEOF as end symbol */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_SYMBOL_END, PHHAL_HW_SYMBOL_ICODEEPCUID_CEOF) ); /* Set timeout to 6.4ms */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_TIMEOUT_VALUE_US, PHPAL_EPCUID_SW_TIMEOUT_DEFAULT_US)); /* Build command frame */ aCommand[0] = PHPAL_EPCUID_SW_CMD_WRITE; aCommand[1] = bBlockNo; aCommand[2] = bData; /* Calculate CRC */ if (bTagType == PHPAL_EPCUID_LABEL_EPC) { PH_CHECK_SUCCESS_FCT(statusTmp, phTools_CalculateCrc8( PH_TOOLS_CRC_OPTION_MSB_FIRST, PH_TOOLS_CRC8_PRESET_EPC, PH_TOOLS_CRC8_POLY_EPCUID, aCommand, 3, &aCommand[3])); } else { PH_CHECK_SUCCESS_FCT(statusTmp, phTools_CalculateCrc8( PH_TOOLS_CRC_OPTION_MSB_FIRST, PH_TOOLS_CRC8_PRESET_UID, PH_TOOLS_CRC8_POLY_EPCUID, aCommand, 3, &aCommand[3])); } /* Send the command */ status = phhalHw_Exchange( pDataParams->pHalDataParams, PH_EXCHANGE_DEFAULT, aCommand, 4, &pResponse, &wResponseLen); /* Timeout is the correct behaviour */ if ((status & PH_ERR_MASK) != PH_ERR_IO_TIMEOUT) { if ((status & PH_ERR_MASK) == PH_ERR_SUCCESS) { /* if data was received return an error */ return PH_ADD_COMPCODE_FIXED(PH_ERR_PROTOCOL_ERROR, PH_COMP_PAL_EPCUID); } else { /* Return the received error */ return status; } } return PH_ERR_SUCCESS; } phStatus_t phpalEpcUid_Sw_Destroy( phpalEpcUid_Sw_DataParams_t * pDataParams, uint8_t bTagType, uint8_t * pData, uint8_t bDataLength, uint8_t * pDestroyCode ) { phStatus_t PH_MEMLOC_REM status; phStatus_t PH_MEMLOC_REM statusTmp; uint8_t PH_MEMLOC_REM bCrc8; uint8_t PH_MEMLOC_REM aCommand[1]; uint8_t * PH_MEMLOC_REM pResponse = NULL; uint16_t PH_MEMLOC_REM wResponseLen = 0; /* checks for EPC */ if (bTagType == PHPAL_EPCUID_LABEL_EPC) { if (bDataLength != PHPAL_EPCUID_EPC_LENGTH) { return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_PAL_EPCUID); } } /* checks for UID */ else if (bTagType == PHPAL_EPCUID_LABEL_UID) { if (bDataLength != PHPAL_EPCUID_IDD_LENGTH) { return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_PAL_EPCUID); } } else { return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_PAL_EPCUID); } /* set SSOF as start symbol */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_SYMBOL_START, PHHAL_HW_SYMBOL_ICODEEPCUID_SSOF) ); /* set CEOF as end symbol */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_SYMBOL_END, PHHAL_HW_SYMBOL_ICODEEPCUID_CEOF) ); /* Set timeout to 6.4ms */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_SetConfig( pDataParams->pHalDataParams, PHHAL_HW_CONFIG_TIMEOUT_VALUE_US, PHPAL_EPCUID_SW_TIMEOUT_DEFAULT_US)); /* Set command code */ aCommand[0] = PHPAL_EPCUID_SW_CMD_DESTROY; PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_Exchange( pDataParams->pHalDataParams, PH_EXCHANGE_BUFFER_FIRST, aCommand, 1, NULL, NULL)); /* Append EPC/IDD */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_Exchange( pDataParams->pHalDataParams, PH_EXCHANGE_BUFFER_CONT, pData, (uint16_t)bDataLength, NULL, NULL)); /* Append Destroy Code */ PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_Exchange( pDataParams->pHalDataParams, PH_EXCHANGE_BUFFER_CONT, pDestroyCode, PHPAL_EPCUID_DESTROYCODE_LENGTH, NULL, NULL)); /* Calculate CRC over command */ if (bTagType == PHPAL_EPCUID_LABEL_EPC) { PH_CHECK_SUCCESS_FCT(statusTmp, phTools_CalculateCrc8( PH_TOOLS_CRC_OPTION_MSB_FIRST, PH_TOOLS_CRC8_PRESET_EPC, PH_TOOLS_CRC8_POLY_EPCUID, aCommand, 1, &bCrc8)); } else { PH_CHECK_SUCCESS_FCT(statusTmp, phTools_CalculateCrc8( PH_TOOLS_CRC_OPTION_MSB_FIRST, PH_TOOLS_CRC8_PRESET_UID, PH_TOOLS_CRC8_POLY_EPCUID, aCommand, 1, &bCrc8)); } /* Calculate CRC over data */ PH_CHECK_SUCCESS_FCT(statusTmp, phTools_CalculateCrc8( PH_TOOLS_CRC_OPTION_MSB_FIRST, bCrc8, PH_TOOLS_CRC8_POLY_EPCUID, pData, (uint16_t)bDataLength, &bCrc8)); /* Calculate CRC over destroy-code */ PH_CHECK_SUCCESS_FCT(statusTmp, phTools_CalculateCrc8( PH_TOOLS_CRC_OPTION_MSB_FIRST, bCrc8, PH_TOOLS_CRC8_POLY_EPCUID, pDestroyCode, PHPAL_EPCUID_DESTROYCODE_LENGTH, &bCrc8)); /* Append CRC and perform exchange */ aCommand[0] = bCrc8; status = phhalHw_Exchange( pDataParams->pHalDataParams, PH_EXCHANGE_BUFFER_LAST, aCommand, 1, &pResponse, &wResponseLen); /* Timeout is the correct behaviour */ if ((status & PH_ERR_MASK) != PH_ERR_IO_TIMEOUT) { if ((status & PH_ERR_MASK) == PH_ERR_SUCCESS) { /* if data was received return an error */ return PH_ADD_COMPCODE_FIXED(PH_ERR_PROTOCOL_ERROR, PH_COMP_PAL_EPCUID); } else { /* Return the received error */ return status; } } return PH_ERR_SUCCESS; } phStatus_t phpalEpcUid_Sw_GetSerialNo( phpalEpcUid_Sw_DataParams_t * pDataParams, uint8_t * pUidOut, uint8_t * pLenUidOut ) { if (pDataParams->bUidValid != PH_OFF) { if (pDataParams->bLabelType == PHPAL_EPCUID_LABEL_EPC) { *pLenUidOut = PHPAL_EPCUID_EPC_LENGTH; (void)memcpy(pUidOut, pDataParams->LabelInfo.bEpc, *pLenUidOut); } else { *pLenUidOut = PHPAL_EPCUID_IDD_LENGTH; (void)memcpy(pUidOut, pDataParams->LabelInfo.bIdd, *pLenUidOut); } return PH_ERR_SUCCESS; } else { return PH_ADD_COMPCODE_FIXED(PH_ERR_USE_CONDITION, PH_COMP_PAL_EPCUID); } } phStatus_t phpalEpcUid_Sw_ParseResponse( phpalEpcUid_Sw_DataParams_t * pDataParams, uint8_t * pRxBuffer, uint16_t wRxLength ) { phStatus_t PH_MEMLOC_REM statusTmp; uint8_t * PH_MEMLOC_REM pEpcIddStorage = NULL; uint16_t PH_MEMLOC_REM wCrc16; uint16_t PH_MEMLOC_REM wLabelLenght; /* Response check */ if (( (pDataParams->bLabelType == PHPAL_EPCUID_LABEL_EPC) && (wRxLength != (PHPAL_EPCUID_EPC_LENGTH + 2U - (((uint16_t)pDataParams->bMaskBitLength) >> 3U))) ) || ( (pDataParams->bLabelType == PHPAL_EPCUID_LABEL_UID) && (wRxLength != (PHPAL_EPCUID_IDD_LENGTH + 2U - (((uint16_t)pDataParams->bMaskBitLength) >> 3U))) )) { pDataParams->bUidValid = PH_OFF; return PH_ADD_COMPCODE_FIXED(PH_ERR_PROTOCOL_ERROR, PH_COMP_PAL_EPCUID); } /* Check where to store EPC/IDD */ if (pDataParams->bLabelType == PHPAL_EPCUID_LABEL_EPC) { /* Copy EPC */ (void)memcpy(&pDataParams->LabelInfo.bEpc[pDataParams->bMaskBitLength >> 3U], pRxBuffer, (((uint32_t)(wRxLength)) - 2u)); /* Set data paramters for CRC calculation */ pEpcIddStorage = pDataParams->LabelInfo.bEpc; wLabelLenght = PHPAL_EPCUID_EPC_LENGTH; } else { /* Copy IDD */ (void)memcpy(&pDataParams->LabelInfo.bIdd[pDataParams->bMaskBitLength >> 3U], pRxBuffer, (((uint32_t)(wRxLength)) - 2u)); /* Set data paramters for CRC calculation */ pEpcIddStorage = &pDataParams->LabelInfo.bIdd[PHPAL_EPCUID_EPC_LENGTH + 2U]; wLabelLenght = PHPAL_EPCUID_IDD_LENGTH - (PHPAL_EPCUID_EPC_LENGTH + 2U); } /* Calculate CRC */ PH_CHECK_SUCCESS_FCT(statusTmp, phTools_CalculateCrc16( PH_TOOLS_CRC_OPTION_MSB_FIRST | PH_TOOLS_CRC_OPTION_OUPUT_INVERTED, PH_TOOLS_CRC16_PRESET_EPCUID, PH_TOOLS_CRC16_POLY_EPCUID, pEpcIddStorage, wLabelLenght, &wCrc16)); /* Check CRC */ if (((uint8_t)(wCrc16 >> 8U) != pRxBuffer[wRxLength-2u]) || ((uint8_t)(wCrc16) != pRxBuffer[wRxLength-1u])) { pDataParams->bUidValid = PH_OFF; return PH_ADD_COMPCODE_FIXED(PH_ERR_INTEGRITY_ERROR, PH_COMP_PAL_EPCUID); } pDataParams->bUidValid = PH_ON; return PH_ERR_SUCCESS; } #endif /* NXPBUILD__PHPAL_EPCUID_SW */