Files
NxpNfcRdLib/.svn/pristine/1a/1a8251d717ea095c7325db2ab45afd48efb22883.svn-base
2024-07-08 21:03:06 +08:00

982 lines
30 KiB
Plaintext

/*
* 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 <ph_Status.h>
#include <phTools.h>
#include <phhalHw.h>
#include <phpalEpcUid.h>
#include <ph_RefDefs.h>
#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 */