745 lines
21 KiB
Plaintext
745 lines
21 KiB
Plaintext
/*----------------------------------------------------------------------------*/
|
|
/* Copyright 2009,2020,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
|
|
* Generic Tools Component of Reader Library Framework.
|
|
* $Author$
|
|
* $Revision$ (v07.10.00)
|
|
* $Date$
|
|
*
|
|
* History:
|
|
* CHu: Generated 19. May 2009
|
|
*
|
|
*/
|
|
|
|
#include <phTools.h>
|
|
#include <ph_RefDefs.h>
|
|
#include <NxpNfcRdLib_Ver.h>
|
|
|
|
#ifdef _WIN32
|
|
#pragma warning(push) /* PRQA S 3116 */
|
|
#pragma warning(disable:4001) /* PRQA S 3116 */
|
|
#include <stdlib.h>
|
|
#include <string.h> /* memcpy */
|
|
#pragma warning(pop) /* PRQA S 3116 */
|
|
#else
|
|
#include <string.h> /* memcpy */
|
|
#endif
|
|
|
|
static uint8_t phTools_CalcParity(uint8_t bDataByte, uint8_t bOption);
|
|
|
|
phStatus_t phTools_EncodeParity(
|
|
uint8_t bOption,
|
|
uint8_t * pInBuffer,
|
|
uint16_t wInBufferLength,
|
|
uint8_t bInBufferBits,
|
|
uint16_t wOutBufferSize,
|
|
uint8_t * pOutBuffer,
|
|
uint16_t * pOutBufferLength,
|
|
uint8_t * pOutBufferBits
|
|
)
|
|
{
|
|
uint16_t PH_MEMLOC_REM wByteIndexIn;
|
|
uint16_t PH_MEMLOC_REM wByteIndexOut;
|
|
uint8_t PH_MEMLOC_REM bBitPosition;
|
|
uint16_t PH_MEMLOC_REM wInByteCount;
|
|
|
|
/* Parameter check */
|
|
if (((bOption != PH_TOOLS_PARITY_OPTION_EVEN) && (bOption != PH_TOOLS_PARITY_OPTION_ODD)) || (bInBufferBits > 7U))
|
|
{
|
|
return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_TOOLS);
|
|
}
|
|
|
|
/* Retrieve full input byte count */
|
|
if (bInBufferBits == 0U)
|
|
{
|
|
wInByteCount = wInBufferLength;
|
|
}
|
|
else
|
|
{
|
|
wInByteCount = wInBufferLength - 1u;
|
|
}
|
|
|
|
/* Retrieve number of (additional) full bytes */
|
|
(*pOutBufferLength) = (uint16_t)((uint16_t)(wInByteCount + bInBufferBits) >> 3U);
|
|
|
|
/* Retrieve output bits */
|
|
*pOutBufferBits = (uint8_t)((uint16_t)(wInByteCount + bInBufferBits) % 8U);
|
|
|
|
/* Increment output length in case of incomplete byte */
|
|
if (*pOutBufferBits > 0U)
|
|
{
|
|
++(*pOutBufferLength);
|
|
}
|
|
|
|
/* Overflow check */
|
|
if ((*pOutBufferLength) > (0xFFFFU - wInByteCount))
|
|
{
|
|
return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_TOOLS);
|
|
}
|
|
|
|
/* Calculate number of output bytes */
|
|
(*pOutBufferLength) = wInByteCount + (*pOutBufferLength);
|
|
|
|
/* Buffer overflow check*/
|
|
if (wOutBufferSize < (*pOutBufferLength))
|
|
{
|
|
(*pOutBufferLength) = 0;
|
|
return PH_ADD_COMPCODE_FIXED(PH_ERR_BUFFER_OVERFLOW, PH_COMP_TOOLS);
|
|
}
|
|
|
|
/* Prepare output buffer */
|
|
pOutBuffer[0] = 0x00;
|
|
|
|
/* Prepare loop vars */
|
|
wByteIndexIn = 0;
|
|
wByteIndexOut = 0;
|
|
bBitPosition = 7;
|
|
|
|
/* Do for each byte */
|
|
for (; wByteIndexIn < wInBufferLength; ++wByteIndexIn )
|
|
{
|
|
/* Append source bits to output */
|
|
pOutBuffer[wByteIndexOut] |= (uint8_t)(pInBuffer[wByteIndexIn] << (7U - bBitPosition));
|
|
|
|
/* If there is more data bits in the sourcebyte append it to next data byte */
|
|
if ((wByteIndexOut + 1U) < (*pOutBufferLength))
|
|
{
|
|
if(bBitPosition == 7U)
|
|
{
|
|
pOutBuffer[wByteIndexOut + 1U] = 0;
|
|
}
|
|
else
|
|
{
|
|
pOutBuffer[wByteIndexOut + 1U] = (uint8_t)(pInBuffer[wByteIndexIn] >> (1u + bBitPosition));
|
|
}
|
|
|
|
/* Perform parity appending if this isn't an incomplete byte */
|
|
if ((bInBufferBits == 0U) || ((wByteIndexIn + 1U) < wInBufferLength))
|
|
{
|
|
pOutBuffer[wByteIndexOut + 1U] |= (uint8_t)(phTools_CalcParity(pInBuffer[wByteIndexIn], bOption) << (7U - bBitPosition));
|
|
}
|
|
}
|
|
|
|
/* We have reached the 8th parity bit, the output buffer index is now one ahead */
|
|
if (bBitPosition == 0U)
|
|
{
|
|
if ((wByteIndexOut + 2U) < (*pOutBufferLength))
|
|
{
|
|
bBitPosition = 8;
|
|
pOutBuffer[++wByteIndexOut + 1U] = 0x00;
|
|
}
|
|
}
|
|
|
|
++wByteIndexOut;
|
|
--bBitPosition;
|
|
}
|
|
|
|
/* Mask out invalid bits of last byte */
|
|
if (*pOutBufferBits > 0U)
|
|
{
|
|
pOutBuffer[(*pOutBufferLength) - 1U] &= (uint8_t)(0xFFU >> (8U - *pOutBufferBits));
|
|
}
|
|
|
|
return PH_ERR_SUCCESS;
|
|
}
|
|
|
|
phStatus_t phTools_DecodeParity(
|
|
uint8_t bOption,
|
|
uint8_t * pInBuffer,
|
|
uint16_t wInBufferLength,
|
|
uint8_t bInBufferBits,
|
|
uint16_t wOutBufferSize,
|
|
uint8_t * pOutBuffer,
|
|
uint16_t * pOutBufferLength,
|
|
uint8_t * pOutBufferBits
|
|
)
|
|
{
|
|
uint16_t PH_MEMLOC_REM wByteIndexIn;
|
|
uint16_t PH_MEMLOC_REM wByteIndexOut;
|
|
uint8_t PH_MEMLOC_REM bBitPosition;
|
|
uint16_t PH_MEMLOC_REM wDiv;
|
|
uint8_t PH_MEMLOC_REM bMod;
|
|
uint8_t PH_MEMLOC_REM bParity;
|
|
|
|
/* Parameter check */
|
|
if (((bOption != PH_TOOLS_PARITY_OPTION_EVEN) && (bOption != PH_TOOLS_PARITY_OPTION_ODD)) || (bInBufferBits > 7U))
|
|
{
|
|
return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_TOOLS);
|
|
}
|
|
|
|
/* Parameter check */
|
|
if (wInBufferLength == 0U)
|
|
{
|
|
/* Zero input length is simply passed through */
|
|
if (bInBufferBits == 0U)
|
|
{
|
|
(*pOutBufferLength) = 0;
|
|
*pOutBufferBits = 0;
|
|
return PH_ERR_SUCCESS;
|
|
}
|
|
/* Invalid parameter */
|
|
else
|
|
{
|
|
return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_TOOLS);
|
|
}
|
|
}
|
|
|
|
/* Retrieve DIV and MOD */
|
|
if (bInBufferBits == 0U)
|
|
{
|
|
wDiv = (uint16_t)(wInBufferLength / 9U);
|
|
bMod = (uint8_t)(wInBufferLength % 9U);
|
|
}
|
|
else
|
|
{
|
|
wDiv = (uint16_t)((wInBufferLength - 1U) / 9U);
|
|
bMod = (uint8_t)((wInBufferLength - 1U) % 9U);
|
|
}
|
|
|
|
/* Calculate number of output bytes */
|
|
(*pOutBufferLength) = (uint16_t)((wDiv << 3U) + bMod);
|
|
if (bMod > bInBufferBits)
|
|
{
|
|
--(*pOutBufferLength);
|
|
}
|
|
|
|
/* Calculate number of rest-bits of output */
|
|
*pOutBufferBits = (uint8_t)((8U - (((8U + ((*pOutBufferLength) % 8U)) - bInBufferBits) % 8U)) % 8U);
|
|
|
|
/* Increment output length in case of incomplete byte */
|
|
if (*pOutBufferBits > 0U)
|
|
{
|
|
++(*pOutBufferLength);
|
|
}
|
|
|
|
/* Buffer overflow check*/
|
|
if (wOutBufferSize < (*pOutBufferLength))
|
|
{
|
|
(*pOutBufferLength) = 0;
|
|
return PH_ADD_COMPCODE_FIXED(PH_ERR_BUFFER_OVERFLOW, PH_COMP_TOOLS);
|
|
}
|
|
|
|
/* Prepare loop vars */
|
|
wByteIndexIn = 0U;
|
|
wByteIndexOut = 0U;
|
|
bBitPosition = 7U;
|
|
|
|
/* Do for each byte */
|
|
for (; wByteIndexOut < (*pOutBufferLength); ++wByteIndexOut, ++wByteIndexIn, --bBitPosition)
|
|
{
|
|
/* Append source bits to output */
|
|
pOutBuffer[wByteIndexOut] = (uint8_t)(pInBuffer[wByteIndexIn] >> (7U - bBitPosition));
|
|
|
|
/* If there is more data bits in the sourcebyte append it to next data byte */
|
|
if ((wByteIndexIn + /* */ 1U) < wInBufferLength)
|
|
{
|
|
/* Append remaining bits to output */
|
|
pOutBuffer[wByteIndexOut] |= (uint8_t)(pInBuffer[wByteIndexIn + 1U] << (1U + bBitPosition));
|
|
|
|
/* Perform parity checking if this isn't an incomplete byte */
|
|
if ((*pOutBufferBits == 0U)
|
|
|| ((wByteIndexOut + /* */ 1U) < (*pOutBufferLength)))
|
|
{
|
|
bParity = phTools_CalcParity(pOutBuffer[wByteIndexOut], bOption);
|
|
if ((pInBuffer[wByteIndexIn + 1U] & (uint8_t)(1U << (7U - bBitPosition))) != (bParity << (7U - bBitPosition)))
|
|
{
|
|
return PH_ADD_COMPCODE_FIXED(PH_ERR_INTEGRITY_ERROR, PH_COMP_TOOLS);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* We have reached the 8th parity bit, the input buffer index is now one ahead */
|
|
if (bBitPosition == 0U)
|
|
{
|
|
bBitPosition = 8;
|
|
++wByteIndexIn;
|
|
}
|
|
}
|
|
|
|
/* Mask out invalid bits of last byte */
|
|
if (*pOutBufferBits > 0U)
|
|
{
|
|
pOutBuffer[(*pOutBufferLength) - 1U] &= (uint8_t)(0xFFU >> (8U - *pOutBufferBits));
|
|
}
|
|
|
|
return PH_ERR_SUCCESS;
|
|
}
|
|
|
|
phStatus_t phTools_CalculateCrc5(
|
|
uint8_t bOption,
|
|
uint8_t bPreset,
|
|
uint8_t bPolynom,
|
|
uint8_t * pData,
|
|
uint16_t wDataLength,
|
|
uint8_t * pCrc
|
|
)
|
|
{
|
|
uint16_t PH_MEMLOC_REM wDataIndex = 0;
|
|
uint8_t PH_MEMLOC_REM bBitIndex;
|
|
uint8_t PH_MEMLOC_REM bBitMax;
|
|
|
|
if (0u != (bOption & (uint8_t)~(uint8_t)PH_TOOLS_CRC_OPTION_MASK))
|
|
{
|
|
return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_TOOLS);
|
|
}
|
|
|
|
*pCrc = bPreset;
|
|
|
|
if (0U != (bOption & PH_TOOLS_CRC_OPTION_MSB_FIRST))
|
|
{
|
|
/* Shift 5bit preset to 8bit (data) alignment */
|
|
*pCrc <<= 3U;
|
|
|
|
/* Shift 5bit polinom to 8bit (data) alignment */
|
|
bPolynom <<= 3U;
|
|
}
|
|
|
|
/* Loop through all data bytes */
|
|
while (0U != wDataLength)
|
|
{
|
|
/* XOR input data */
|
|
if (0U != (bOption & PH_TOOLS_CRC_OPTION_BITWISE))
|
|
{
|
|
if (wDataLength < 8U)
|
|
{
|
|
bBitMax = (uint8_t)wDataLength;
|
|
wDataLength = 0;
|
|
}
|
|
else
|
|
{
|
|
bBitMax = 8;
|
|
wDataLength -= 8u;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bBitMax = 8;
|
|
/* Decrement DataLen */
|
|
--wDataLength;
|
|
}
|
|
|
|
/* CRC polynom (MSB first) */
|
|
if (0U != (bOption & PH_TOOLS_CRC_OPTION_MSB_FIRST))
|
|
{
|
|
*pCrc ^= pData[wDataIndex++] & (0xFFU << (8U - bBitMax));
|
|
|
|
for (bBitIndex = 0; bBitIndex < bBitMax; ++bBitIndex)
|
|
{
|
|
if (0u != ((*pCrc) & 0x80U))
|
|
{
|
|
*pCrc = (uint8_t)(((*pCrc) << 1U) ^ bPolynom);
|
|
}
|
|
else
|
|
{
|
|
*pCrc = (*pCrc) << 1U;
|
|
}
|
|
}
|
|
}
|
|
/* CRC polynom (LSB first) */
|
|
else
|
|
{
|
|
*pCrc ^= pData[wDataIndex++] & (0xFFU >> (8U - bBitMax));
|
|
|
|
for (bBitIndex = 0; bBitIndex < bBitMax; ++bBitIndex)
|
|
{
|
|
if (0u != ((*pCrc) & 0x01U))
|
|
{
|
|
*pCrc = (uint8_t)(((*pCrc) >> 1U) ^ bPolynom);
|
|
}
|
|
else
|
|
{
|
|
*pCrc = ((*pCrc) >> 1U);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (0U != (bOption & PH_TOOLS_CRC_OPTION_MSB_FIRST))
|
|
{
|
|
/* Shift back for 5bit alignment */
|
|
*pCrc >>= 3U;
|
|
}
|
|
|
|
/* Invert CRC if requested */
|
|
if (0U != (bOption & PH_TOOLS_CRC_OPTION_OUPUT_INVERTED))
|
|
{
|
|
*pCrc ^= 0x1FU;
|
|
}
|
|
|
|
return PH_ERR_SUCCESS;
|
|
}
|
|
|
|
phStatus_t phTools_CalculateCrc8(
|
|
uint8_t bOption,
|
|
uint8_t bPreset,
|
|
uint8_t bPolynom,
|
|
uint8_t * pData,
|
|
uint16_t wDataLength,
|
|
uint8_t * pCrc
|
|
)
|
|
{
|
|
uint16_t PH_MEMLOC_REM wDataIndex = 0;
|
|
uint8_t PH_MEMLOC_REM bBitIndex;
|
|
uint8_t PH_MEMLOC_REM bBitMax;
|
|
|
|
if (0u != (bOption & (uint8_t)~(uint8_t)PH_TOOLS_CRC_OPTION_MASK))
|
|
{
|
|
return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_TOOLS);
|
|
}
|
|
|
|
*pCrc = bPreset;
|
|
|
|
/* Loop through all data bytes */
|
|
while (0U != wDataLength)
|
|
{
|
|
/* XOR input data */
|
|
if (0U != (bOption & PH_TOOLS_CRC_OPTION_BITWISE))
|
|
{
|
|
if (wDataLength < 8U)
|
|
{
|
|
bBitMax = (uint8_t)wDataLength;
|
|
wDataLength = 0;
|
|
}
|
|
else
|
|
{
|
|
bBitMax = 8;
|
|
wDataLength -= 8u;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bBitMax = 8;
|
|
/* Decrement DataLen */
|
|
--wDataLength;
|
|
}
|
|
|
|
/* CRC polynom (MSB first) */
|
|
if (0U != (bOption & PH_TOOLS_CRC_OPTION_MSB_FIRST))
|
|
{
|
|
*pCrc ^= pData[wDataIndex++] & (0xFFU << (8U - bBitMax));
|
|
|
|
for (bBitIndex = 0; bBitIndex < bBitMax; ++bBitIndex)
|
|
{
|
|
if (0U != ((*pCrc) & 0x80U))
|
|
{
|
|
*pCrc = (uint8_t)(((*pCrc) << 1U) ^ bPolynom);
|
|
}
|
|
else
|
|
{
|
|
*pCrc = ((*pCrc) << 1U);
|
|
}
|
|
}
|
|
}
|
|
/* CRC polynom (LSB first) */
|
|
else
|
|
{
|
|
*pCrc ^= pData[wDataIndex++] & (0xFFU >> (8U - bBitMax));
|
|
|
|
for (bBitIndex = 0; bBitIndex < bBitMax; ++bBitIndex)
|
|
{
|
|
if (0u != ((*pCrc) & 0x01U))
|
|
{
|
|
*pCrc = (uint8_t)(((*pCrc) >> 1U) ^ bPolynom);
|
|
}
|
|
else
|
|
{
|
|
*pCrc = ((*pCrc) >> 1U);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Invert CRC if requested */
|
|
if (0U != (bOption & PH_TOOLS_CRC_OPTION_OUPUT_INVERTED))
|
|
{
|
|
*pCrc ^= 0xFFU;
|
|
}
|
|
|
|
return PH_ERR_SUCCESS;
|
|
}
|
|
|
|
phStatus_t phTools_CalculateCrc16(
|
|
uint8_t bOption,
|
|
uint16_t wPreset,
|
|
uint16_t wPolynom,
|
|
uint8_t * pData,
|
|
uint16_t wDataLength,
|
|
uint16_t * pCrc
|
|
)
|
|
{
|
|
uint16_t PH_MEMLOC_REM wDataIndex = 0;
|
|
uint8_t PH_MEMLOC_REM bBitIndex;
|
|
uint8_t PH_MEMLOC_REM bBitMax;
|
|
|
|
if (0u != (bOption & (uint8_t)~(uint8_t)PH_TOOLS_CRC_OPTION_MASK))
|
|
{
|
|
return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_TOOLS);
|
|
}
|
|
|
|
*pCrc = wPreset;
|
|
|
|
/* Loop through all data bytes */
|
|
while (0U != wDataLength)
|
|
{
|
|
/* XOR input data */
|
|
if (0U != (bOption & PH_TOOLS_CRC_OPTION_BITWISE))
|
|
{
|
|
if (wDataLength < 8U)
|
|
{
|
|
bBitMax = (uint8_t)wDataLength;
|
|
wDataLength = 0;
|
|
}
|
|
else
|
|
{
|
|
bBitMax = 8;
|
|
wDataLength -= 8u;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bBitMax = 8;
|
|
/* Decrement DataLen */
|
|
--wDataLength;
|
|
}
|
|
|
|
/* CRC polynom (MSB first) */
|
|
if (0U != (bOption & PH_TOOLS_CRC_OPTION_MSB_FIRST))
|
|
{
|
|
*pCrc ^= (uint16_t)pData[wDataIndex++] << 8U;
|
|
|
|
for (bBitIndex = 0; bBitIndex < bBitMax; ++bBitIndex)
|
|
{
|
|
if (0u != ((*pCrc) & 0x8000U))
|
|
{
|
|
*pCrc = (uint16_t)(((*pCrc) << 1U) ^ wPolynom);
|
|
}
|
|
else
|
|
{
|
|
*pCrc = ((*pCrc) << 1U);
|
|
}
|
|
}
|
|
}
|
|
/* CRC polynom (LSB first) */
|
|
else
|
|
{
|
|
*pCrc ^= pData[wDataIndex++];
|
|
|
|
for (bBitIndex = 0; bBitIndex < bBitMax; ++bBitIndex)
|
|
{
|
|
if (0U != ((*pCrc) & 0x0001U))
|
|
{
|
|
*pCrc = (uint16_t)(((*pCrc) >> 1U) ^ wPolynom);
|
|
}
|
|
else
|
|
{
|
|
*pCrc = ((*pCrc) >> 1U);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Invert CRC if requested */
|
|
if (0U != (bOption & PH_TOOLS_CRC_OPTION_OUPUT_INVERTED))
|
|
{
|
|
*pCrc ^= 0xFFFFU;
|
|
}
|
|
|
|
return PH_ERR_SUCCESS;
|
|
}
|
|
|
|
phStatus_t phTools_CalculateCrc32(
|
|
uint8_t bOption,
|
|
uint32_t dwPreset,
|
|
uint32_t dwPolynom,
|
|
uint8_t * pData,
|
|
uint32_t dwDataLength,
|
|
uint32_t * pCrc
|
|
)
|
|
{
|
|
uint32_t PH_MEMLOC_REM dwDataIndex = 0;
|
|
uint8_t PH_MEMLOC_REM bBitIndex;
|
|
uint8_t PH_MEMLOC_REM bBitMax;
|
|
|
|
if (0u != (bOption & (uint8_t)~(uint8_t)PH_TOOLS_CRC_OPTION_MASK))
|
|
{
|
|
return PH_ADD_COMPCODE_FIXED(PH_ERR_INVALID_PARAMETER, PH_COMP_TOOLS);
|
|
}
|
|
|
|
*pCrc = dwPreset;
|
|
|
|
/* Loop through all data bytes */
|
|
while (0U != dwDataLength)
|
|
{
|
|
/* XOR input data */
|
|
if (0U != (bOption & PH_TOOLS_CRC_OPTION_BITWISE))
|
|
{
|
|
if (dwDataLength < 8U)
|
|
{
|
|
bBitMax = (uint8_t)dwDataLength;
|
|
dwDataLength = 0;
|
|
}
|
|
else
|
|
{
|
|
bBitMax = 8;
|
|
dwDataLength -= 8u;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
bBitMax = 8;
|
|
/* Decrement DataLen */
|
|
--dwDataLength;
|
|
}
|
|
|
|
/* CRC polynom (MSB first) */
|
|
if (0U != (bOption & PH_TOOLS_CRC_OPTION_MSB_FIRST))
|
|
{
|
|
*pCrc ^= (uint32_t)pData[dwDataIndex++] << 24U;
|
|
|
|
for (bBitIndex = 0; bBitIndex < bBitMax; ++bBitIndex)
|
|
{
|
|
if (0u != ((*pCrc) & 0x80000000U))
|
|
{
|
|
*pCrc = (uint32_t)(((*pCrc) << 1U) ^ dwPolynom);
|
|
}
|
|
else
|
|
{
|
|
*pCrc = ((*pCrc) << 1U);
|
|
}
|
|
}
|
|
}
|
|
/* CRC polynom (LSB first) */
|
|
else
|
|
{
|
|
*pCrc ^= pData[dwDataIndex++];
|
|
|
|
for (bBitIndex = 0; bBitIndex < bBitMax; ++bBitIndex)
|
|
{
|
|
if (0u != ((*pCrc) & 0x00000001U))
|
|
{
|
|
*pCrc = (uint32_t)(((*pCrc) >> 1U) ^ dwPolynom);
|
|
}
|
|
else
|
|
{
|
|
*pCrc = ((*pCrc) >> 1U);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Invert CRC if requested */
|
|
if (0U != (bOption & PH_TOOLS_CRC_OPTION_OUPUT_INVERTED))
|
|
{
|
|
*pCrc ^= 0xFFFFFFFFU;
|
|
}
|
|
|
|
return PH_ERR_SUCCESS;
|
|
}
|
|
|
|
static uint8_t phTools_CalcParity(
|
|
uint8_t bDataByte,
|
|
uint8_t bOption
|
|
)
|
|
{
|
|
uint8_t PH_MEMLOC_REM bBit;
|
|
uint8_t PH_MEMLOC_REM bParity;
|
|
|
|
if (bOption == PH_TOOLS_PARITY_OPTION_EVEN)
|
|
{
|
|
bParity = 0x00;
|
|
}
|
|
else
|
|
{
|
|
bParity = 0x01;
|
|
}
|
|
|
|
for (bBit = 0; bBit < 8U; ++bBit)
|
|
{
|
|
if (0U != (bDataByte & (uint8_t)(1U << bBit)))
|
|
{
|
|
++bParity;
|
|
}
|
|
}
|
|
return bParity & 0x01U;
|
|
}
|
|
|
|
static void phTools_UpdateCrc_B(uint8_t bCh, uint16_t *pLpwCrc)
|
|
{
|
|
bCh = (bCh^(uint8_t)((*pLpwCrc)&0x00FFU));
|
|
bCh = (bCh ^ (bCh<<4U));
|
|
*pLpwCrc = (*pLpwCrc >> 8U) ^ ((uint16_t)bCh << 8U) ^ ((uint16_t)bCh << 3U) ^ ((uint16_t)bCh>>4U);
|
|
}
|
|
|
|
phStatus_t phTools_ComputeCrc_B(
|
|
uint8_t *pData,
|
|
uint32_t dwLength,
|
|
uint8_t *pCrc)
|
|
{
|
|
uint8_t PH_MEMLOC_REM bChBlock = 0;
|
|
uint16_t PH_MEMLOC_REM wCrc = 0xFFFF;
|
|
|
|
do
|
|
{
|
|
bChBlock = *pData++;
|
|
phTools_UpdateCrc_B(bChBlock, &wCrc);
|
|
} while (0u != (--dwLength));
|
|
|
|
wCrc = ~wCrc;
|
|
|
|
pCrc[0] = (uint8_t) (wCrc & 0xFFU);
|
|
pCrc[1] = (uint8_t) ( (wCrc>>8U) & 0xFFU);
|
|
|
|
return PH_ERR_SUCCESS;
|
|
}
|
|
|
|
#ifndef __min
|
|
# define __min(X,Y) (((X) < (Y)) ? (X) : (Y))
|
|
#endif
|
|
|
|
phStatus_t phTools_GetVersion(
|
|
uint8_t * pProductVer,
|
|
uint16_t * pMajor,
|
|
uint8_t * pMinor,
|
|
uint16_t * pPatch_Dev,
|
|
uint8_t * pVersionString,
|
|
uint16_t * pVersionStringLen)
|
|
{
|
|
uint16_t PH_MEMLOC_REM wCopyLen = 0;
|
|
const char szNxpNfcRdLib_VER_FILEDESCRIPTION[] = NxpNfcRdLib_VER_FILEDESCRIPTION;
|
|
|
|
PH_UNUSED_VARIABLE(pProductVer);
|
|
|
|
/* *pProductVer = ; ankur update it when there ir product version */
|
|
*pMajor = NxpNfcRdLib_VER_MAJOR;
|
|
*pMinor = NxpNfcRdLib_VER_MINOR;
|
|
*pPatch_Dev = NxpNfcRdLib_VER_DEV;
|
|
|
|
wCopyLen = (uint16_t)(sizeof(szNxpNfcRdLib_VER_FILEDESCRIPTION)/sizeof(szNxpNfcRdLib_VER_FILEDESCRIPTION[0]));
|
|
|
|
if(*pVersionStringLen < (wCopyLen - 1u))
|
|
{
|
|
return PH_ADD_COMPCODE_FIXED(PH_ERR_LENGTH_ERROR, PH_COMP_TOOLS);
|
|
}
|
|
else
|
|
{
|
|
wCopyLen = __min(wCopyLen,(*pVersionStringLen));
|
|
|
|
(void)memcpy(pVersionString, szNxpNfcRdLib_VER_FILEDESCRIPTION, wCopyLen);
|
|
|
|
*pVersionStringLen = wCopyLen - 1u;
|
|
}
|
|
|
|
return PH_ERR_SUCCESS;
|
|
}
|