Files
NxpNfcRdLib/.svn/pristine/61/6167c574436492300169527be30ab67d69b25422.svn-base
2024-07-08 21:03:06 +08:00

1005 lines
43 KiB
Plaintext

/*----------------------------------------------------------------------------*/
/* Copyright 2016-2022 NXP */
/* */
/* NXP Confidential. This software is owned or controlled by NXP and may only */
/* be used strictly in accordance with the applicable license terms. */
/* By expressly accepting such terms or by downloading, installing, */
/* activating and/or otherwise using the software, you are agreeing that you */
/* have read, and that you agree to comply with and are bound by, such */
/* license terms. If you do not agree to be bound by the applicable license */
/* terms, then you may not retain, install, activate or otherwise use the */
/* software. */
/*----------------------------------------------------------------------------*/
/** \file
* NFC Library Top Level API of Reader Library Framework.
* $Author: jenkins_ cm (nxp92197) $
* $Revision: 4184 $ (v07.10.00)
* $Date: 2016-08-30 18:04:59 +0530 (Fri, 30 Aug 2016) $
*
* History:
* KK: Generated 30. Aug 2016
*/
#include <ph_Status.h>
#ifdef NXPBUILD__PH_NFCLIB_ISO_18000
#include "phNfcLib_Initialization.h"
#include "phNfcLib_Int.h"
#define PH_NFCLIB_18000P3M3_CMD_REQ_RN 0xC1U /**< ReqRn command code. */
#define PH_NFCLIB_18000P3M3_CMD_READ 0xC2U /**< Read command code. */
#define PH_NFCLIB_18000P3M3_CMD_WRITE 0xC3U /**< Write command code. */
#define PH_NFCLIB_18000P3M3_CMD_KILL 0xC4U /**< Kill command code. */
#define PH_NFCLIB_18000P3M3_CMD_LOCK 0xC5U /**< Lock command code. */
#define PH_NFCLIB_18000P3M3_CMD_ACCESS 0xC6U /**< Access command code. */
#define PH_NFCLIB_18000P3M3_CMD_BLOCKWRITE 0xC7U /**< BlockWrite command code. */
#define PH_NFCLIB_18000P3M3_CMD_BLOCKERASE 0xC8U /**< BlockErase command code. */
#define PH_NFCLIB_18000P3M3_CMD_BLOCKPERMALOCK 0xC9U /**< BlockPermaLock command code. */
#define PH_NFCLIB_18000P3M3_CMD_ACK 0x01U /**< ACK command code. */
#define PH_NFCLIB_18000P3M3_SW_T2_MIN_US 151U /* T2 Time for 18000p3m3 */
#define PH_NFCLIB_18000P3M3_SW_TIMEOUT 113U /* Timeout for 18000p3m3 */
#define PH_NFCLIB_18000P3M3_SKIP_COMMAND 0xFFU /**< Skip the command */
static phStatus_t phNfcLib_18000p3m3_ReqRN(void);
static phStatus_t phNfcLib_18000p3m3_Exchange(uint8_t bSymbol, uint8_t bTxLastBits, uint16_t wTimeout, uint8_t* pCmd, uint16_t wCmdLength, uint16_t *pRxLastBits);
phStatus_t phNfcLib_ISO18000_Transmit(void * const pTxBuffer, uint16_t wTxBufferLength)
{
uint8_t bCmd[10] = {0};
uint16_t wCmdLength = 0;
phStatus_t statusTmp = PH_ERR_INVALID_PARAMETER;
phStatus_t wStatus = PH_ERR_INVALID_PARAMETER;
uint8_t bIndex;
uint8_t bUiiMaskBytes = 0;
uint8_t bHandle[2] = {0};
uint16_t wRxLastBits = 0;
uint8_t aSelectCmd[39] = {0};
uint8_t wSelectCmdLen;
uint8_t bSelectCmdValidBits;
uint8_t aBeginRoundCmd[3] = {0};
uint8_t bUiiStartAddress = 0x20;
if ((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.wUiiMaskLength % 8U) != 0U)
{
bUiiMaskBytes = (((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.wUiiMaskLength)/8U) + 1U);
}
else
{
bUiiMaskBytes = (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.wUiiMaskLength)/8U;
}
#if 0
((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.wUiiMaskLength % 8U) != 0U) ? (bUiiMaskBytes = (((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.wUiiMaskLength)/8U) + 1U)) : (bUiiMaskBytes = (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.wUiiMaskLength)/8U);
/* Since truncation option is not set thus logically the chance of it getting non complete bytes is very rare */
bUiiMaskBytes = ((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.wUiiMaskLength % 8U) ?
((((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.wUiiMaskLength)/8U) + 1U)) :
((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.wUiiMaskLength)/8U));
#endif
if(0 != (memcmp(gphNfcLib_State.pActivatedUid, ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pUii, bUiiMaskBytes)))
{
/* Create select command frame (with selected UII in mask) */
PH_CHECK_SUCCESS_FCT(statusTmp, phpalI18000p3m3_CreateSelectCmd(
gphNfcLib_Params.sDiscLoop.pPal18000p3m3DataParams,
PHPAL_I18000P3M3_TARGET_INVENTORIED_S0,
0,
PHPAL_I18000P3M3_MEMBANK_UII,
&bUiiStartAddress,
0,
((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pUii,
(uint8_t)((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.wUiiMaskLength,
0,
aSelectCmd,
&wSelectCmdLen,
&bSelectCmdValidBits));
/* Create BeginRound command frame */
PH_CHECK_SUCCESS_FCT(statusTmp, phpalI18000p3m3_CreateBeginRoundCmd(
gphNfcLib_Params.sDiscLoop.pPal18000p3m3DataParams,
gphNfcLib_Params.sDiscLoop.sI18000p3m3TargetInfo.bDr,
gphNfcLib_Params.sDiscLoop.sI18000p3m3TargetInfo.bM,
(uint8_t)PH_OFF,
PHPAL_I18000P3M3_SEL_ALL_00,
PHPAL_I18000P3M3_SESSION_S0,
0,
0,
aBeginRoundCmd));
/* Activate tag with specified UII */
PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_I18000p3m3Inventory(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
aSelectCmd,
(uint8_t)wSelectCmdLen,
bSelectCmdValidBits,
aBeginRoundCmd,
PHHAL_HW_I18000P3M3_GET_TAG_HANDLE,
&gphNfcLib_State.pRxBuffer,
&gphNfcLib_State.wRxLength));
/* Update handle */
/* Update the activated UII here */
gphNfcLib_State.pActivatedUid = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pUii;
(void)memcpy(&gphNfcLib_Params.salI18000p3m3.abHandle[0], &gphNfcLib_State.pRxBuffer[gphNfcLib_State.wRxLength - 2u], 2);
gphNfcLib_Params.salI18000p3m3.bHandleValid = PH_ON;
}
/* TODO: If ever the handle concept changes the check has to be performed here */
/* Valid Handle is mandatory */
if (gphNfcLib_Params.salI18000p3m3.bHandleValid == PH_OFF)
{
return PH_ERR_USE_CONDITION;
}
switch(((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bCommand)
{
case ISO18000_Ack:
/* Build Command frame */
bCmd[0] = (PH_NFCLIB_18000P3M3_CMD_ACK << 6U) | (gphNfcLib_Params.salI18000p3m3.abHandle[0] >> 2U); /* 0 bits left */
bCmd[1] = (gphNfcLib_Params.salI18000p3m3.abHandle[0] << 6U) | (gphNfcLib_Params.salI18000p3m3.abHandle[1] >> 2U); /* 0 bits left */
bCmd[2] = (gphNfcLib_Params.salI18000p3m3.abHandle[1] << 6U); /* 6 bits left */
/* Set frame-sync as start symbol */
PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SetConfig(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PHHAL_HW_CONFIG_SYMBOL_START,
PHHAL_HW_SYMBOL_I18000P3M3_FSYNC));
/* Set TxWait to T2 */
PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SetConfig(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PHHAL_HW_CONFIG_TXWAIT_US,
PH_NFCLIB_18000P3M3_SW_T2_MIN_US));
/* Set T1+T3 Timeout */
PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SetConfig(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PHHAL_HW_CONFIG_TIMEOUT_VALUE_US,
PH_NFCLIB_18000P3M3_SW_TIMEOUT));
/* Switch off HAL-CRC */
PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SetConfig(gphNfcLib_Params.sDiscLoop.pHalDataParams, PHHAL_HW_CONFIG_TXCRC, PH_OFF));
PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SetConfig(gphNfcLib_Params.sDiscLoop.pHalDataParams, PHHAL_HW_CONFIG_RXCRC, PH_OFF));
statusTmp = phNfcLib_18000p3m3_Exchange(PH_NFCLIB_18000P3M3_SKIP_COMMAND, 0x02, PH_NFCLIB_18000P3M3_SKIP_COMMAND, &bCmd[0], 3, &wRxLastBits);
/* Switch on HAL-CRC from now on */
PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SetConfig(gphNfcLib_Params.sDiscLoop.pHalDataParams, PHHAL_HW_CONFIG_TXCRC, PH_ON));
PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SetConfig(gphNfcLib_Params.sDiscLoop.pHalDataParams, PHHAL_HW_CONFIG_RXCRC, PH_ON));
/* set Tx-CRC as CRC16 */
PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SetConfig(gphNfcLib_Params.sDiscLoop.pHalDataParams, PHHAL_HW_CONFIG_CRCTYPE, PHHAL_HW_CRCTYPE_CRC16|PHHAL_HW_CRCOPTION_INVERTED));
if(statusTmp == PH_ERR_SUCCESS)
{
/* Get bit length */
if (0U != (wRxLastBits & 0x07U))
{
--gphNfcLib_State.wRxLength;
}
wRxLastBits = (uint16_t)((gphNfcLib_State.wRxLength << 3U) + wRxLastBits);
/* Check response length */
if ((wRxLastBits < 5U) || (wRxLastBits > 528U))
{
return PH_ERR_PROTOCOL_ERROR;
}
}
break;
case ISO18000_ReqRn:
statusTmp = phNfcLib_18000p3m3_ReqRN();
break;
case ISO18000_Read:
/* Parameter check */
if ((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bMemBank > 0x03U) || (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordPtrLength > 3U))
{
return PH_ERR_INVALID_PARAMETER;
}
PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SetConfig(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PHHAL_HW_CONFIG_TIMEOUT_VALUE_US,
(uint16_t)0x158));
/* prepare command header */
bCmd[wCmdLength++] = PH_NFCLIB_18000P3M3_CMD_READ;
bCmd[wCmdLength] = (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bMemBank << 6U) | (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordPtrLength << 4U); /* 4 bits left */
/* append pointer */
for (bIndex = 0; bIndex < (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordPtrLength + 1U); ++bIndex)
{
bCmd[wCmdLength++] |= (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pWordPtr[bIndex]) >> 4U;
bCmd[wCmdLength] = (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pWordPtr[bIndex]) << 4U;
}
/* 4 bits left */
/* append word-count */
bCmd[wCmdLength++] |= ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordCount >> 4U; /* 0 bits left */
bCmd[wCmdLength] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordCount << 4U; /* 4 bits left */
/* TODO: if ever the handle concept changes the change has to be done here */
/* append handle */
bCmd[wCmdLength++] |= gphNfcLib_Params.salI18000p3m3.abHandle[0] >> 4U; /* 0 bits left */
bCmd[wCmdLength] = gphNfcLib_Params.salI18000p3m3.abHandle[0] << 4U; /* 4 bits left */
bCmd[wCmdLength++] |= gphNfcLib_Params.salI18000p3m3.abHandle[1] >> 4U; /* 0 bits left */
bCmd[wCmdLength++] = gphNfcLib_Params.salI18000p3m3.abHandle[1] << 4U; /* 4 bits left */
PH_CHECK_SUCCESS_FCT(statusTmp, phNfcLib_18000p3m3_Exchange(PH_OFF, 0x04, PH_NFCLIB_18000P3M3_SKIP_COMMAND, &bCmd[0], wCmdLength, &wRxLastBits));
/* Check received length and header bit */
if (((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordCount != 0x00U) &&
(gphNfcLib_State.wRxLength != ((((uint16_t)(((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordCount)) << 1U) + 3U))) ||
(wRxLastBits != 1U) || ((gphNfcLib_State.pRxBuffer[0] & 0x80U) != 0U))
{
return PH_ERR_PROTOCOL_ERROR;
}
for (bIndex = 0; bIndex < (gphNfcLib_State.wRxLength - 1U); bIndex++)
{
gphNfcLib_State.pRxBuffer[bIndex] = (gphNfcLib_State.pRxBuffer[bIndex] << 1U) |
(gphNfcLib_State.pRxBuffer[bIndex + 1U] >> 7U);
}
/* Status byte is removed */
gphNfcLib_State.wRxLength--;
/* TODO: if ever the handle concept changes the change has to be done here */
/* Check Handle */
if ((gphNfcLib_State.pRxBuffer[gphNfcLib_State.wRxLength - 2u] != gphNfcLib_Params.salI18000p3m3.abHandle[0]) ||
(gphNfcLib_State.pRxBuffer[gphNfcLib_State.wRxLength - 1u] != gphNfcLib_Params.salI18000p3m3.abHandle[1]))
{
return PH_ERR_PROTOCOL_ERROR;
}
/* Handle is not part of data */
gphNfcLib_State.wRxLength -= 2u;
break;
case ISO18000_Write:
/* Parameter check */
if ((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bMemBank > 0x03U) ||
(((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordPtrLength > 3U) ||
((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bOption != PH_NFCLIB_18000P3M3_AC_NO_COVER_CODING) &&
(((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bOption != PH_NFCLIB_18000P3M3_AC_USE_COVER_CODING)))
{
return PH_ERR_INVALID_PARAMETER;
}
/* prepare command header */
wCmdLength = 0;
bCmd[wCmdLength++] = PH_NFCLIB_18000P3M3_CMD_WRITE;
bCmd[wCmdLength] = (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bMemBank << 6U) |
(((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordPtrLength << 4U); /* 4 bits left */
/* append pointer */
for (bIndex = 0; bIndex < (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordPtrLength + 1U); ++bIndex)
{
bCmd[wCmdLength++] |= (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pWordPtr[bIndex]) >> 4U;
bCmd[wCmdLength] = (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pWordPtr[bIndex]) << 4U;
}
/* 4 bits left */
/* append data */
bCmd[wCmdLength++] |= ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pBuffer[0] >> 4U; /* 0 bits left */
bCmd[wCmdLength++] = (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pBuffer[0] << 4U) |
(((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pBuffer[1] >> 4U); /* 0 bits left */
bCmd[wCmdLength] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pBuffer[1] << 4U; /* 4 bits left */
/* perform cover-coding if neccessary */
if (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bOption == PH_NFCLIB_18000P3M3_AC_USE_COVER_CODING)
{
/* New RN16 needs to be obtained for cover coding */
(void)phNfcLib_18000p3m3_ReqRN();
/* perform XOR operation */
bCmd[wCmdLength - 2u] ^= gphNfcLib_State.pRxBuffer[0] >> 4U;
bCmd[wCmdLength - 1u] ^= (gphNfcLib_State.pRxBuffer[0] << 4U) | (gphNfcLib_State.pRxBuffer[1] >> 4U);
bCmd[wCmdLength] ^= gphNfcLib_State.pRxBuffer[1] << 4U;
}
/* append handle */
bCmd[wCmdLength++] |= gphNfcLib_Params.salI18000p3m3.abHandle[0] >> 4U; /* 0 bits left */
bCmd[wCmdLength] = gphNfcLib_Params.salI18000p3m3.abHandle[0] << 4U; /* 4 bits left */
bCmd[wCmdLength++] |= gphNfcLib_Params.salI18000p3m3.abHandle[1] >> 4U; /* 0 bits left */
bCmd[wCmdLength++] = gphNfcLib_Params.salI18000p3m3.abHandle[1] << 4U; /* 4 bits left */
PH_CHECK_SUCCESS_FCT(statusTmp, phNfcLib_18000p3m3_Exchange(PH_OFF, 0x04, 5, &bCmd[0], wCmdLength, &wRxLastBits));
/* Check header bit */
if ((gphNfcLib_State.wRxLength != 3U) || (wRxLastBits != 1U) || ((gphNfcLib_State.pRxBuffer[0] & 0x80U) != 0U))
{
return PH_ERR_PROTOCOL_ERROR;
}
/* Check Handle */
bHandle[0] = (uint8_t)((gphNfcLib_State.pRxBuffer[0] << 1U) | (gphNfcLib_State.pRxBuffer[1] >> 7U));
bHandle[1] = (uint8_t)((gphNfcLib_State.pRxBuffer[1] << 1U) | (gphNfcLib_State.pRxBuffer[2] >> 7U));
if ((bHandle[0] != gphNfcLib_Params.salI18000p3m3.abHandle[0]) ||
(bHandle[1] != gphNfcLib_Params.salI18000p3m3.abHandle[1]))
{
return PH_ERR_PROTOCOL_ERROR;
}
/* Making Received length as 0 since no user data has been received */
gphNfcLib_State.wRxLength = 0;
break;
case ISO18000_Kill:
/* Parameter check */
if (((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bOption != PH_NFCLIB_18000P3M3_AC_NO_COVER_CODING) &&
(((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bOption != PH_NFCLIB_18000P3M3_AC_USE_COVER_CODING)) ||
(((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bRecom > 0x07U))
{
return PH_ERR_INVALID_PARAMETER;
}
/* */
/* Perform FIRST PART of KILL command */
/* */
/* prepare command header */
bCmd[0] = PH_NFCLIB_18000P3M3_CMD_KILL;
bCmd[1] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pPassword[0];
bCmd[2] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pPassword[1];
/* perform cover-coding if necessary */
if (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bOption == PHAL_I18000P3M3_AC_USE_COVER_CODING)
{
/* retrieve RN16 */
PH_CHECK_SUCCESS_FCT(statusTmp,phNfcLib_18000p3m3_ReqRN());
/* perform XOR operation */
bCmd[1] ^= gphNfcLib_State.pRxBuffer[0];
bCmd[2] ^= gphNfcLib_State.pRxBuffer[1];
}
/* append RFU/Recom bits (000) and handle */
bCmd[3] = 0x00; /* 5 bits left */
bCmd[3] |= gphNfcLib_Params.salI18000p3m3.abHandle[0] >> 3U; /* 0 bits left */
bCmd[4] = gphNfcLib_Params.salI18000p3m3.abHandle[0] << 5U; /* 5 bits left */
bCmd[4] |= gphNfcLib_Params.salI18000p3m3.abHandle[1] >> 3U; /* 0 bits left */
bCmd[5] = gphNfcLib_Params.salI18000p3m3.abHandle[1] << 5U; /* 5 bits left */
PH_CHECK_SUCCESS_FCT(statusTmp, phNfcLib_18000p3m3_Exchange(PH_OFF, 0x03, 500, &bCmd[0], 6, NULL));
/* Check received length */
if (gphNfcLib_State.wRxLength != 2U)
{
return PH_ERR_PROTOCOL_ERROR;
}
/* Check Handle */
if ((gphNfcLib_State.pRxBuffer[0] != gphNfcLib_Params.salI18000p3m3.abHandle[0]) ||
(gphNfcLib_State.pRxBuffer[1] != gphNfcLib_Params.salI18000p3m3.abHandle[1]))
{
return PH_ERR_PROTOCOL_ERROR;
}
/*
* Perform second part of kill command
*/
/* prepare command header */
bCmd[0] = PH_NFCLIB_18000P3M3_CMD_KILL;
bCmd[1] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pPassword[2];
bCmd[2] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pPassword[3];
/* perform cover-coding if neccessary */
if (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bOption == PHAL_I18000P3M3_AC_USE_COVER_CODING)
{
/* retrieve RN16 */
/* retrieve RN16 */
PH_CHECK_SUCCESS_FCT(statusTmp,phNfcLib_18000p3m3_ReqRN());
/* perform XOR operation */
bCmd[1] ^= gphNfcLib_State.pRxBuffer[0];
bCmd[2] ^= gphNfcLib_State.pRxBuffer[1];
}
/* append RFU/Recom bits (000) and handle */
bCmd[3] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bRecom << 5U; /* 5 bits left */
bCmd[3] |= gphNfcLib_Params.salI18000p3m3.abHandle[0] >> 3U; /* 0 bits left */
bCmd[4] = gphNfcLib_Params.salI18000p3m3.abHandle[0] << 5U; /* 5 bits left */
bCmd[4] |= gphNfcLib_Params.salI18000p3m3.abHandle[1] >> 3U; /* 0 bits left */
bCmd[5] = gphNfcLib_Params.salI18000p3m3.abHandle[1] << 5U; /* 5 bits left */
PH_CHECK_SUCCESS_FCT(statusTmp, phNfcLib_18000p3m3_Exchange(PH_OFF, 0x03, PH_NFCLIB_18000P3M3_SKIP_COMMAND, &bCmd[0], 6, &wRxLastBits));
/* Check received length and header */
if ((gphNfcLib_State.wRxLength != 3U) ||
(wRxLastBits != 1U) ||
((gphNfcLib_State.pRxBuffer[0] & 0x80U) != 0U))
{
return PH_ERR_PROTOCOL_ERROR;
}
/* Check Handle */
bHandle[0] = (uint8_t)((gphNfcLib_State.pRxBuffer[0] << 1U) | (gphNfcLib_State.pRxBuffer[1] >> 7U));
bHandle[1] = (uint8_t)((gphNfcLib_State.pRxBuffer[1] << 1U) | (gphNfcLib_State.pRxBuffer[2] >> 7U));
if ((bHandle[0] != gphNfcLib_Params.salI18000p3m3.abHandle[0]) ||
(bHandle[1] != gphNfcLib_Params.salI18000p3m3.abHandle[1]))
{
return PH_ERR_PROTOCOL_ERROR;
}
/* Making Received length as 0 since no user data has been received */
gphNfcLib_State.wRxLength = 0;
break;
case ISO18000_Lock:
/* prepare command header */
bCmd[0] = PH_NFCLIB_18000P3M3_CMD_LOCK; /* 0 bits left */
bCmd[1] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pMask[0]; /* 0 bits left */
bCmd[2] = (uint8_t)((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pMask[1] & 0xC0U) | (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pAction[0] >> 2U)); /* 0 bits left */
bCmd[3] = (uint8_t)((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pAction[0] << 6U) | ((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pAction[1] & 0xC0U) >> 2U)); /* 4 bits left */
/* append handle */
bCmd[3] |= gphNfcLib_Params.salI18000p3m3.abHandle[0] >> 4U; /* 0 bits left */
bCmd[4] = gphNfcLib_Params.salI18000p3m3.abHandle[0] << 4U; /* 4 bits left */
bCmd[4] |= gphNfcLib_Params.salI18000p3m3.abHandle[1] >> 4U; /* 0 bits left */
bCmd[5] = gphNfcLib_Params.salI18000p3m3.abHandle[1] << 4U; /* 4 bits left */
PH_CHECK_SUCCESS_FCT(statusTmp, phNfcLib_18000p3m3_Exchange(PH_OFF, 0x04, 5, &bCmd[0], 6, &wRxLastBits));
/* Check received length and header */
if ((gphNfcLib_State.wRxLength != 3U) ||
(wRxLastBits != 1U) ||
((gphNfcLib_State.pRxBuffer[0] & 0x80U) != 0U))
{
return PH_ERR_PROTOCOL_ERROR;
}
/* Check Handle */
bHandle[0] = (uint8_t)((gphNfcLib_State.pRxBuffer[0] << 1U) | (gphNfcLib_State.pRxBuffer[1] >> 7U));
bHandle[1] = (uint8_t)((gphNfcLib_State.pRxBuffer[1] << 1U) | (gphNfcLib_State.pRxBuffer[2] >> 7U));
if ((bHandle[0] != gphNfcLib_Params.salI18000p3m3.abHandle[0]) ||
(bHandle[1] != gphNfcLib_Params.salI18000p3m3.abHandle[1]))
{
return PH_ERR_PROTOCOL_ERROR;
}
/* Making Received length as 0 since no user data has been received */
gphNfcLib_State.wRxLength = 0;
break;
case ISO18000_Access:
/* Parameter check */
if ((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bOption != PH_NFCLIB_18000P3M3_AC_NO_COVER_CODING) &&
(((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bOption != PH_NFCLIB_18000P3M3_AC_USE_COVER_CODING))
{
return PH_ERR_INVALID_PARAMETER;
}
/* */
/* Perform FIRST PART of ACCESS command */
/* */
/* prepare command header */
bCmd[0] = PH_NFCLIB_18000P3M3_CMD_ACCESS;
bCmd[1] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pPassword[0];
bCmd[2] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pPassword[1];
/* perform cover-coding if neccessary */
if (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bOption == PH_NFCLIB_18000P3M3_AC_USE_COVER_CODING)
{
/* New RN16 needs to be obtained for cover coding */
(void)phNfcLib_18000p3m3_ReqRN();
/* perform XOR operation */
bCmd[1] ^= gphNfcLib_State.pRxBuffer[0];
bCmd[2] ^= gphNfcLib_State.pRxBuffer[1];
}
/* append handle */
bCmd[3] = gphNfcLib_Params.salI18000p3m3.abHandle[0];
bCmd[4] = gphNfcLib_Params.salI18000p3m3.abHandle[1];
PH_CHECK_SUCCESS_FCT(statusTmp, phNfcLib_18000p3m3_Exchange(PH_OFF, PH_NFCLIB_18000P3M3_SKIP_COMMAND, PH_NFCLIB_18000P3M3_SKIP_COMMAND, &bCmd[0], 5, NULL));
/* Check received length */
if (gphNfcLib_State.wRxLength != 2U)
{
return PH_ERR_PROTOCOL_ERROR;
}
/* Check Handle */
if ((gphNfcLib_State.pRxBuffer[0] != gphNfcLib_Params.salI18000p3m3.abHandle[0]) ||
(gphNfcLib_State.pRxBuffer[1] != gphNfcLib_Params.salI18000p3m3.abHandle[1]))
{
return PH_ERR_PROTOCOL_ERROR;
}
/* */
/* Perform SECOND PART of ACCESS command */
/* */
/* prepare command header */
bCmd[0] = PH_NFCLIB_18000P3M3_CMD_ACCESS;
bCmd[1] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pPassword[2];
bCmd[2] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pPassword[3];
/* perform cover-coding if neccessary */
if (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bOption == PH_NFCLIB_18000P3M3_AC_USE_COVER_CODING)
{
/* New RN16 needs to be obtained for cover coding */
(void)phNfcLib_18000p3m3_ReqRN();
/* perform XOR operation */
bCmd[1] ^= gphNfcLib_State.pRxBuffer[0];
bCmd[2] ^= gphNfcLib_State.pRxBuffer[1];
}
/* append handle */
bCmd[3] = gphNfcLib_Params.salI18000p3m3.abHandle[0];
bCmd[4] = gphNfcLib_Params.salI18000p3m3.abHandle[1];
/* perform the exchange */
PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_Exchange(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PH_EXCHANGE_DEFAULT,
bCmd,
5,
&gphNfcLib_State.pRxBuffer,
&gphNfcLib_State.wRxLength));
/* Check received length */
if (gphNfcLib_State.wRxLength != 2U)
{
return PH_ERR_PROTOCOL_ERROR;
}
/* Check Handle */
if ((gphNfcLib_State.pRxBuffer[0] != gphNfcLib_Params.salI18000p3m3.abHandle[0]) ||
(gphNfcLib_State.pRxBuffer[1] != gphNfcLib_Params.salI18000p3m3.abHandle[1]))
{
return PH_ERR_PROTOCOL_ERROR;
}
/* Making Received length as 0 since no user data has been received */
gphNfcLib_State.wRxLength = 0;
break;
case ISO18000_BlockWrite:
/* Parameter check */
if ((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bMemBank > 0x03U) || (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordPtrLength > 3U))
{
return PH_ERR_INVALID_PARAMETER;
}
/* prepare command header */
bCmd[wCmdLength++] = PH_NFCLIB_18000P3M3_CMD_BLOCKWRITE;
bCmd[wCmdLength] = (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bMemBank << 6U) | (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordPtrLength << 4U); /* 4 bits left */
/* append pointer */
for (bIndex = 0; bIndex < (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordPtrLength + 1U); ++bIndex)
{
bCmd[wCmdLength++] |= (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pWordPtr[bIndex]) >> 4U;
bCmd[wCmdLength] = (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pWordPtr[bIndex]) << 4U;
}
/* 4 bits left */
/* append (4bits) of Word-Count */
bCmd[wCmdLength++] |= ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordCount >> 4U; /* 0 bits left */
(void)phNfcLib_18000p3m3_Exchange(PH_OFF, 0x04, 20, NULL, PH_NFCLIB_18000P3M3_SKIP_COMMAND, NULL);
/* buffer the current contents */
statusTmp = phhalHw_Exchange(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PH_EXCHANGE_BUFFER_FIRST,
bCmd,
wCmdLength,
&gphNfcLib_State.pRxBuffer,
&gphNfcLib_State.wRxLength);
/* reset command length*/
wCmdLength = 0;
/* append the rest bits of block-range*/
bCmd[wCmdLength] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordCount << 4U; /* 4 bits left */
/* append data */
for (bIndex = 0; bIndex < (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordCount << 1U); ++bIndex)
{
bCmd[wCmdLength++] |= ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pBuffer[bIndex] >> 4U; /* 0 bits left */
/* buffer the current contents if command buffer is full */
if (wCmdLength == 7U)
{
/* buffer the current contents */
statusTmp = phhalHw_Exchange(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PH_EXCHANGE_BUFFER_CONT,
bCmd,
wCmdLength,
&gphNfcLib_State.pRxBuffer,
&gphNfcLib_State.wRxLength);
/* reset command length*/
wCmdLength = 0;
}
bCmd[wCmdLength] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pBuffer[bIndex] << 4U; /* 4 bits left */
}
/* append handle */
bCmd[wCmdLength++] |= gphNfcLib_Params.salI18000p3m3.abHandle[0] >> 4U; /* 0 bits left */
/* buffer the current contents if command buffer is full */
if (wCmdLength == 7U)
{
statusTmp = phhalHw_Exchange(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PH_EXCHANGE_BUFFER_CONT,
bCmd,
wCmdLength,
&gphNfcLib_State.pRxBuffer,
&gphNfcLib_State.wRxLength);
/* reset command length*/
wCmdLength = 0;
}
bCmd[wCmdLength] = gphNfcLib_Params.salI18000p3m3.abHandle[0] << 4U; /* 4 bits left */
bCmd[wCmdLength++] |= gphNfcLib_Params.salI18000p3m3.abHandle[1] >> 4U; /* 0 bits left */
bCmd[wCmdLength++] = gphNfcLib_Params.salI18000p3m3.abHandle[1] << 4U; /* 4 bits left */
/* perform the exchange */
statusTmp = phhalHw_Exchange(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PH_EXCHANGE_BUFFER_LAST,
bCmd,
wCmdLength,
&gphNfcLib_State.pRxBuffer,
&gphNfcLib_State.wRxLength);
/* Ignore incomplete byte status, bail out on error */
if ((statusTmp & PH_ERR_MASK) == PH_ERR_SUCCESS_INCOMPLETE_BYTE)
{
PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_GetConfig(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PHHAL_HW_CONFIG_RXLASTBITS,
&wRxLastBits));
statusTmp = PH_ERR_SUCCESS;
}
if(statusTmp == PH_ERR_SUCCESS)
{
/* Check header bit */
if ((gphNfcLib_State.wRxLength != 3U) || (wRxLastBits != 1U) || ((gphNfcLib_State.pRxBuffer[0] & 0x80U) != 0U))
{
return PH_ERR_PROTOCOL_ERROR;
}
/* Check Handle */
bHandle[0] = (uint8_t)((gphNfcLib_State.pRxBuffer[0] << 1U) | (gphNfcLib_State.pRxBuffer[1] >> 7U));
bHandle[1] = (uint8_t)((gphNfcLib_State.pRxBuffer[1] << 1U) | (gphNfcLib_State.pRxBuffer[2] >> 7U));
if ((bHandle[0] != gphNfcLib_Params.salI18000p3m3.abHandle[0]) ||
(bHandle[1] != gphNfcLib_Params.salI18000p3m3.abHandle[1]))
{
return PH_ERR_PROTOCOL_ERROR;
}
/* Making Received length as 0 since no user data has been received */
gphNfcLib_State.wRxLength = 0;
}
break;
case ISO18000_BlockErase:
/* Parameter check */
if ((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bMemBank > 0x03U) || (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordPtrLength > 3U))
{
return PH_ERR_INVALID_PARAMETER;
}
/* prepare command header */
wCmdLength = 0;
bCmd[wCmdLength++] = PH_NFCLIB_18000P3M3_CMD_BLOCKERASE;
bCmd[wCmdLength] = (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bMemBank << 6U) | (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordPtrLength << 4U); /* 4 bits left */
/* append pointer */
for (bIndex = 0; bIndex < (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordPtrLength + 1U); ++bIndex)
{
bCmd[wCmdLength++] |= (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pWordPtr[bIndex]) >> 4U;
bCmd[wCmdLength] = (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pWordPtr[bIndex]) << 4U;
}
/* 4 bits left */
/* append word-count */
bCmd[wCmdLength++] |= ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordCount >> 4U; /* 0 bits left */
bCmd[wCmdLength] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bWordCount << 4U; /* 4 bits left */
/* append handle */
bCmd[wCmdLength++] |= gphNfcLib_Params.salI18000p3m3.abHandle[0] >> 4U; /* 0 bits left */
bCmd[wCmdLength] = gphNfcLib_Params.salI18000p3m3.abHandle[0] << 4U; /* 4 bits left */
bCmd[wCmdLength++] |= gphNfcLib_Params.salI18000p3m3.abHandle[1] >> 4U; /* 0 bits left */
bCmd[wCmdLength++] = gphNfcLib_Params.salI18000p3m3.abHandle[1] << 4U; /* 4 bits left */
PH_CHECK_SUCCESS_FCT(statusTmp, phNfcLib_18000p3m3_Exchange(PH_ON, 0x04, 20, &bCmd[0], wCmdLength, &wRxLastBits));
/* Check received length and header bit */
if ((gphNfcLib_State.wRxLength != 3U) || (wRxLastBits != 1U) || ((gphNfcLib_State.pRxBuffer[0] & 0x80U) != 0U))
{
return PH_ERR_PROTOCOL_ERROR;
}
/* Check Handle */
bHandle[0] = (uint8_t)((gphNfcLib_State.pRxBuffer[0] << 1U) | (gphNfcLib_State.pRxBuffer[1] >> 7U));
bHandle[1] = (uint8_t)((gphNfcLib_State.pRxBuffer[1] << 1U) | (gphNfcLib_State.pRxBuffer[2] >> 7U));
if ((bHandle[0] != gphNfcLib_Params.salI18000p3m3.abHandle[0]) ||
(bHandle[1] != gphNfcLib_Params.salI18000p3m3.abHandle[1]))
{
return PH_ERR_PROTOCOL_ERROR;
}
/* Making Received length as 0 since no user data has been received */
gphNfcLib_State.wRxLength = 0;
break;
case ISO18000_BlockPermaLock:
/* Parameter check */
if ((((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bReadLock > 0x01U) || (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bMemBank > 0x03U) || (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bBlockPtrLength > 3U))
{
return PH_ERR_INVALID_PARAMETER;
}
/* prepare command header */
wCmdLength = 0;
bCmd[wCmdLength++] = PH_NFCLIB_18000P3M3_CMD_BLOCKPERMALOCK;
bCmd[wCmdLength++] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bRFU;
bCmd[wCmdLength] = (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bReadLock << 7U) | (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bMemBank << 5U) | (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bBlockPtrLength << 3U); /* 3 bits left */
/* append pointer */
for (bIndex = 0; bIndex < (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bBlockPtrLength + 1U); ++bIndex)
{
bCmd[wCmdLength++] |= (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pBlockPtr[bIndex]) >> 5U;
bCmd[wCmdLength] = (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pBlockPtr[bIndex]) << 3U;
}
/* 3 bits left */
/* append (3bits) of block-range */
bCmd[wCmdLength++] |= ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bBlockRange >> 5U; /* 0 bits left */
/* buffer the current contents */
statusTmp = phhalHw_Exchange(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PH_EXCHANGE_BUFFER_FIRST,
bCmd,
wCmdLength,
&gphNfcLib_State.pRxBuffer,
&gphNfcLib_State.wRxLength);
/* reset command length*/
wCmdLength = 0;
/* append the rest bits of block-range*/
bCmd[wCmdLength] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bBlockRange << 3U; /* 3 bits left */
/* append mask */
if (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bReadLock == 0x01U)
{
for (bIndex = 0; bIndex < (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bBlockRange << 1U); ++bIndex)
{
bCmd[wCmdLength++] |= ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pMask[bIndex] >> 5U; /* 0 bits left */
/* buffer the current contents if command buffer is full */
if (wCmdLength == 7U)
{
/* buffer the current contents */
statusTmp = phhalHw_Exchange(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PH_EXCHANGE_BUFFER_CONT,
bCmd,
wCmdLength,
&gphNfcLib_State.pRxBuffer,
&gphNfcLib_State.wRxLength);
/* reset command length*/
wCmdLength = 0;
}
bCmd[wCmdLength] = ((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pMask[bIndex] << 3U; /* 3 bits left */
}
}
/* append handle */
bCmd[wCmdLength++] |= gphNfcLib_Params.salI18000p3m3.abHandle[0] >> 5U; /* 0 bits left */
/* buffer the current contents if command buffer is full */
if (wCmdLength == 7U)
{
statusTmp = phhalHw_Exchange(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PH_EXCHANGE_BUFFER_CONT,
bCmd,
wCmdLength,
&gphNfcLib_State.pRxBuffer,
&gphNfcLib_State.wRxLength);
/* reset command length*/
wCmdLength = 0;
}
bCmd[wCmdLength] = gphNfcLib_Params.salI18000p3m3.abHandle[0] << 3U; /* 3 bits left */
bCmd[wCmdLength++] |= gphNfcLib_Params.salI18000p3m3.abHandle[1] >> 5U; /* 0 bits left */
bCmd[wCmdLength++] = gphNfcLib_Params.salI18000p3m3.abHandle[1] << 3U; /* 3 bits left */
(void)phNfcLib_18000p3m3_Exchange(PH_OFF, 0x05, 500, NULL, PH_NFCLIB_18000P3M3_SKIP_COMMAND, NULL);
/* perform the exchange */
statusTmp = phhalHw_Exchange(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PH_EXCHANGE_BUFFER_LAST,
bCmd,
wCmdLength,
&gphNfcLib_State.pRxBuffer,
&gphNfcLib_State.wRxLength);
/* Ignore incomplete byte status, bail out on error */
if ((statusTmp & PH_ERR_MASK) == PH_ERR_SUCCESS_INCOMPLETE_BYTE)
{
PH_CHECK_SUCCESS_FCT(statusTmp, phhalHw_GetConfig(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PHHAL_HW_CONFIG_RXLASTBITS,
&wRxLastBits));
statusTmp = PH_ERR_SUCCESS;
}
if(statusTmp == PH_ERR_SUCCESS)
{
/* Check header bit */
if ((gphNfcLib_State.wRxLength < 3U) || (wRxLastBits != 1U) || ((gphNfcLib_State.pRxBuffer[0] & 0x80U) != 0U))
{
return PH_ERR_PROTOCOL_ERROR;
}
/* Check data length */
if (((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bReadLock == 0x00U)
{
if (gphNfcLib_State.wRxLength != (3u + (((uint16_t)(((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.bBlockRange)) << 1U)))
{
return PH_ERR_PROTOCOL_ERROR;
}
}
else
{
if (gphNfcLib_State.wRxLength != 3U)
{
return PH_ERR_PROTOCOL_ERROR;
}
}
for (bIndex = 0; bIndex < (gphNfcLib_State.wRxLength - 1U); bIndex++)
{
gphNfcLib_State.pRxBuffer[bIndex] = (gphNfcLib_State.pRxBuffer[bIndex] << 1U) | (gphNfcLib_State.pRxBuffer[bIndex + 1U] >> 7U);
}
/* Status byte is removed */
gphNfcLib_State.wRxLength--;
/* Check Handle */
if ((gphNfcLib_State.pRxBuffer[gphNfcLib_State.wRxLength - 2u] != gphNfcLib_Params.salI18000p3m3.abHandle[0]) ||
(gphNfcLib_State.pRxBuffer[gphNfcLib_State.wRxLength - 1u] != gphNfcLib_Params.salI18000p3m3.abHandle[1]))
{
return PH_ERR_PROTOCOL_ERROR;
}
/* Handle is not part of data */
gphNfcLib_State.wRxLength -= 2u;
}
break;
case ISO18000_SetHandle:
(void)memcpy(&gphNfcLib_Params.salI18000p3m3.abHandle[0], &((phNfcLib_Transmit_t *)pTxBuffer)->phNfcLib_ISO18000.pHandle[0], 2);
gphNfcLib_Params.salI18000p3m3.bHandleValid = PH_ON;
statusTmp = PH_ERR_SUCCESS;
break;
default:
break;
}
PH_UNUSED_VARIABLE(wTxBufferLength);
return statusTmp;
}
static phStatus_t phNfcLib_18000p3m3_ReqRN(void)
{
phStatus_t statusTmp;
uint8_t bCmd[3] = {0};
/* Prepare and buffer command header */
bCmd[0] = PH_NFCLIB_18000P3M3_CMD_REQ_RN;
bCmd[1] = gphNfcLib_Params.salI18000p3m3.abHandle[0];
bCmd[2] = gphNfcLib_Params.salI18000p3m3.abHandle[1];
statusTmp = phhalHw_Exchange(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PH_EXCHANGE_DEFAULT,
bCmd,
3,
&gphNfcLib_State.pRxBuffer,
&gphNfcLib_State.wRxLength);
return statusTmp;
}
static phStatus_t phNfcLib_18000p3m3_Exchange(uint8_t bSymbol, uint8_t bTxLastBits, uint16_t wTimeout, uint8_t* pCmd, uint16_t wCmdLength, uint16_t *pRxLastBits)
{
phStatus_t statusTmp = PH_ERR_SUCCESS;
phStatus_t wStatus = PH_ERR_INVALID_PARAMETER;
if(bSymbol != PH_NFCLIB_18000P3M3_SKIP_COMMAND)
{
/* Setting the Symbol send. */
PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SetConfig(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PHHAL_HW_CONFIG_SET_SYMBOL_SEND,
(uint16_t)bSymbol));
}
if(bTxLastBits != PH_NFCLIB_18000P3M3_SKIP_COMMAND)
{
/* Setting the TxLastbits. */
PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SetConfig(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PHHAL_HW_CONFIG_TXLASTBITS,
(uint16_t)bTxLastBits));
}
if(wTimeout != PH_NFCLIB_18000P3M3_SKIP_COMMAND)
{
/* Set config for timeout */
PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_SetConfig(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PHHAL_HW_CONFIG_TIMEOUT_VALUE_MS,
(uint16_t)wTimeout));
}
if(wCmdLength != PH_NFCLIB_18000P3M3_SKIP_COMMAND)
{
/* Perform HAL exchange. */
statusTmp = phhalHw_Exchange(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PH_EXCHANGE_DEFAULT,
pCmd,
wCmdLength,
&gphNfcLib_State.pRxBuffer,
&gphNfcLib_State.wRxLength);
}
if(pRxLastBits != NULL)
{
/* Ignore incomplete byte status, bail out on error */
if ((statusTmp & PH_ERR_MASK) == PH_ERR_SUCCESS_INCOMPLETE_BYTE)
{
PH_CHECK_SUCCESS_FCT(wStatus, phhalHw_GetConfig(
gphNfcLib_Params.sDiscLoop.pHalDataParams,
PHHAL_HW_CONFIG_RXLASTBITS,
pRxLastBits));
statusTmp = PH_ERR_SUCCESS;
}
}
return statusTmp;
}
#endif /* NXPBUILD__PH_NFCLIB_ISO_18000 */