Files
tc264smart/libraries/infineon_libraries/Service/CpuGeneric/SysSe/Math/Ifx_Crc.c
T
32343 843447835d Initial commit: TC264 smart car project with IPS200 menu system
- IPS200 display menu with real-time status and parameter settings
- Camera image processing and line tracking
- IMU attitude solution and PID control
- WiFi SPI oscilloscope data transmission
2026-05-10 21:38:49 +08:00

657 lines
17 KiB
C

/**
* \file Ifx_Crc.c
* \brief CRC algorithm
*
* \version disabled
* \copyright Copyright (c) 2013 Infineon Technologies AG. All rights reserved.
*
*
* IMPORTANT NOTICE
*
*
* Use of this file is subject to the terms of use agreed between (i) you or
* the company in which ordinary course of business you are acting and (ii)
* Infineon Technologies AG or its licensees. If and as long as no such
* terms of use are agreed, use of this file is subject to following:
* Boost Software License - Version 1.0 - August 17th, 2003
* Permission is hereby granted, free of charge, to any person or
* organization obtaining a copy of the software and accompanying
* documentation covered by this license (the "Software") to use, reproduce,
* display, distribute, execute, and transmit the Software, and to prepare
* derivative works of the Software, and to permit third-parties to whom the
* Software is furnished to do so, all subject to the following:
* The copyright notices in the Software and this entire statement, including
* the above license grant, this restriction and the following disclaimer, must
* be included in all copies of the Software, in whole or in part, and all
* derivative works of the Software, unless such copies or derivative works are
* solely in the form of machine-executable object code generated by a source
* language processor.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
* SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
* FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
*/
#include "Ifx_Crc.h"
uint32 Ifx_Crc_reflect(uint32 crc, sint32 bitnum);
boolean Ifx_Crc_init(Ifc_Crc *driver, const Ifc_Crc_Table *table, sint32 direct, sint32 refout, uint32 crcinit, uint32 crcxor)
{
sint32 i;
uint32 bit, crc;
if (crcinit != (crcinit & table->crcmask))
{
//IfxStdIf_DPipe_print(io,"ERROR, invalid crcinit."ENDL);
return FALSE;
}
if (crcxor != (crcxor & table->crcmask))
{
//IfxStdIf_DPipe_print(io,"ERROR, invalid crcxor."ENDL);
return FALSE;
}
driver->table = table;
driver->crcxor = crcxor;
driver->refout = refout;
// compute missing initial CRC value
if (!direct)
{
driver->crcinit_nondirect = crcinit;
crc = crcinit;
for (i = 0; i < table->order; i++)
{
bit = crc & table->crchighbit;
crc <<= 1;
if (bit)
{
crc ^= table->polynom;
}
}
crc &= table->crcmask;
driver->crcinit_direct = crc;
}
else
{
driver->crcinit_direct = crcinit;
crc = crcinit;
for (i = 0; i < table->order; i++)
{
bit = crc & 1;
if (bit)
{
crc ^= table->polynom;
}
crc >>= 1;
if (bit)
{
crc |= table->crchighbit;
}
}
driver->crcinit_nondirect = crc;
}
return TRUE;
}
boolean Ifx_Crc_createTable(Ifc_Crc_Table *table, sint32 order, uint32 polynom, sint32 refin)
{
uint32 crcmask;
// at first, compute constant bit masks for whole CRC and CRC high bit
crcmask = ((((uint32)1 << (order - 1)) - 1) << 1) | 1;
// check parameters
if ((order < 1) || (order > 32))
{
//IfxStdIf_DPipe_print(io,"ERROR, invalid order, it must be between 1..32."ENDL);
return FALSE;
}
if (polynom != (polynom & crcmask))
{
//IfxStdIf_DPipe_print(io,"ERROR, invalid polynom."ENDL);
return FALSE;
}
table->order = order;
table->polynom = polynom;
table->refin = refin;
table->crchighbit = (uint32)1 << (order - 1);
table->crcmask = crcmask;
// generate lookup table
// make CRC lookup table used by table algorithms
{
sint32 i, j;
uint32 bit, crc;
for (i = 0; i < 256; i++)
{
crc = (uint32)i;
if (refin)
{
crc = Ifx_Crc_reflect(crc, 8);
}
crc <<= order - 8;
for (j = 0; j < 8; j++)
{
bit = crc & table->crchighbit;
crc <<= 1;
if (bit)
{
crc ^= polynom;
}
}
if (refin)
{
crc = Ifx_Crc_reflect(crc, order);
}
crc &= crcmask;
if (order <= 8)
{
uint8 *crctab = (uint8 *)((uint32)table + sizeof(Ifc_Crc_Table));
crctab[i] = (uint8)crc;
}
else if (order <= 16)
{
uint16 *crctab = (uint16 *)((uint32)table + sizeof(Ifc_Crc_Table));
crctab[i] = (uint16)crc;
}
else
{
uint32 *crctab = (uint32 *)((uint32)table + sizeof(Ifc_Crc_Table));
crctab[i] = crc;
}
}
}
return TRUE;
}
// subroutines
uint32 Ifx_Crc_reflect(uint32 crc, sint32 bitnum)
{
// reflects the lower 'bitnum' bits of 'crc'
uint32 i, j = 1, crcout = 0;
for (i = (uint32)1 << (bitnum - 1); i; i >>= 1)
{
if (crc & i)
{
crcout |= j;
}
j <<= 1;
}
return crcout;
}
uint32 Ifx_Crc_tableFast(Ifc_Crc *driver, uint8 *p, uint32 len)
{
// fast lookup table algorithm without augmented zero bytes, e.g. used in pkzip.
// only usable with polynom orders of 8, 16, 24 or 32.
uint32 crc = driver->crcinit_direct;
sint32 orderMinusHeight = driver->table->order - 8;
if (driver->table->refin)
{
crc = Ifx_Crc_reflect(crc, driver->table->order);
}
if (driver->table->order <= 8)
{
uint8 *crctab = (uint8 *)((uint32)driver->table + sizeof(Ifc_Crc_Table));
if (!driver->table->refin)
{
while (len--)
{
crc = (crc << 8) ^ crctab[((crc >> (orderMinusHeight)) & 0xff) ^ *p++];
}
}
else
{
while (len--)
{
crc = (crc >> 8) ^ crctab[(crc & 0xff) ^ *p++];
}
}
}
else if (driver->table->order <= 16)
{
uint16 *crctab = (uint16 *)((uint32)driver->table + sizeof(Ifc_Crc_Table));
if (!driver->table->refin)
{
while (len--)
{
crc = (crc << 8) ^ crctab[((crc >> (orderMinusHeight)) & 0xff) ^ *p++];
}
}
else
{
while (len--)
{
crc = (crc >> 8) ^ crctab[(crc & 0xff) ^ *p++];
}
}
}
else
{
uint32 *crctab = (uint32 *)((uint32)driver->table + sizeof(Ifc_Crc_Table));
if (!driver->table->refin)
{
while (len--)
{
crc = (crc << 8) ^ crctab[((crc >> (orderMinusHeight)) & 0xff) ^ *p++];
}
}
else
{
while (len--)
{
crc = (crc >> 8) ^ crctab[(crc & 0xff) ^ *p++];
}
}
}
if (driver->refout ^ driver->table->refin)
{
crc = Ifx_Crc_reflect(crc, driver->table->order);
}
crc ^= driver->crcxor;
crc &= driver->table->crcmask;
return crc;
}
uint32 Ifx_Crc_table(Ifc_Crc *driver, uint8 *p, uint32 len)
{
// normal lookup table algorithm with augmented zero bytes.
// only usable with polynom orders of 8, 16, 24 or 32.
uint32 crc = driver->crcinit_nondirect;
sint32 orderMinusHeight = driver->table->order - 8;
if (driver->table->refin)
{
crc = Ifx_Crc_reflect(crc, driver->table->order);
}
if (driver->table->order <= 8)
{
uint8 *crctab = (uint8 *)((uint32)driver->table + sizeof(Ifc_Crc_Table));
if (!driver->table->refin)
{
while (len--)
{
crc = ((crc << 8) | *p++) ^ crctab[(crc >> (orderMinusHeight)) & 0xff];
}
}
else
{
while (len--)
{
crc = ((crc >> 8) | (*p++ << (orderMinusHeight))) ^ crctab[crc & 0xff];
}
}
if (!driver->table->refin)
{
while (++len < (driver->table->order >> 3))
{
crc = (crc << 8) ^ crctab[(crc >> (orderMinusHeight)) & 0xff];
}
}
else
{
while (++len < (driver->table->order >> 3))
{
crc = (crc >> 8) ^ crctab[crc & 0xff];
}
}
}
else if (driver->table->order <= 16)
{
uint16 *crctab = (uint16 *)((uint32)driver->table + sizeof(Ifc_Crc_Table));
if (!driver->table->refin)
{
while (len--)
{
crc = ((crc << 8) | *p++) ^ crctab[(crc >> (orderMinusHeight)) & 0xff];
}
}
else
{
while (len--)
{
crc = ((crc >> 8) | (*p++ << (orderMinusHeight))) ^ crctab[crc & 0xff];
}
}
if (!driver->table->refin)
{
while (++len < (driver->table->order >> 3))
{
crc = (crc << 8) ^ crctab[(crc >> (orderMinusHeight)) & 0xff];
}
}
else
{
while (++len < (driver->table->order >> 3))
{
crc = (crc >> 8) ^ crctab[crc & 0xff];
}
}
}
else if (driver->table->order <= 32)
{
uint32 *crctab = (uint32 *)((uint32)driver->table + sizeof(Ifc_Crc_Table));
if (!driver->table->refin)
{
while (len--)
{
crc = ((crc << 8) | *p++) ^ crctab[(crc >> (orderMinusHeight)) & 0xff];
}
}
else
{
while (len--)
{
crc = ((crc >> 8) | (*p++ << (orderMinusHeight))) ^ crctab[crc & 0xff];
}
}
if (!driver->table->refin)
{
while (++len < (driver->table->order >> 3))
{
crc = (crc << 8) ^ crctab[(crc >> (orderMinusHeight)) & 0xff];
}
}
else
{
while (++len < (driver->table->order >> 3))
{
crc = (crc >> 8) ^ crctab[crc & 0xff];
}
}
}
if (driver->refout ^ driver->table->refin)
{
crc = Ifx_Crc_reflect(crc, driver->table->order);
}
crc ^= driver->crcxor;
crc &= driver->table->crcmask;
return crc;
}
uint32 Ifx_Crc_bitByBit(Ifc_Crc *driver, uint8 *p, uint32 len)
{
// bit by bit algorithm with augmented zero bytes.
// does not use lookup table, suited for polynom driver->table->orders between 1...32.
uint32 i, j, c, bit;
uint32 crc = driver->crcinit_nondirect;
for (i = 0; i < len; i++)
{
c = (uint32)*p++;
if (driver->table->refin)
{
c = Ifx_Crc_reflect(c, 8);
}
for (j = 0x80; j; j >>= 1)
{
bit = crc & driver->table->crchighbit;
crc <<= 1;
if (c & j)
{
crc |= 1;
}
if (bit)
{
crc ^= driver->table->polynom;
}
}
}
for (i = 0; i < driver->table->order; i++)
{
bit = crc & driver->table->crchighbit;
crc <<= 1;
if (bit)
{
crc ^= driver->table->polynom;
}
}
if (driver->refout)
{
crc = Ifx_Crc_reflect(crc, driver->table->order);
}
crc ^= driver->crcxor;
crc &= driver->table->crcmask;
return crc;
}
uint32 Ifx_Crc_bitByBitFast(Ifc_Crc *driver, uint8 *p, uint32 len)
{
// fast bit by bit algorithm without augmented zero bytes.
// does not use lookup table, suited for polynom driver->table->orders between 1...32.
uint32 i, j, c, bit;
uint32 crc = driver->crcinit_direct;
for (i = 0; i < len; i++)
{
c = (uint32)*p++;
if (driver->table->refin)
{
c = Ifx_Crc_reflect(c, 8);
}
for (j = 0x80; j; j >>= 1)
{
bit = crc & driver->table->crchighbit;
crc <<= 1;
if (c & j)
{
bit ^= driver->table->crchighbit;
}
if (bit)
{
crc ^= driver->table->polynom;
}
}
}
if (driver->refout)
{
crc = Ifx_Crc_reflect(crc, driver->table->order);
}
crc ^= driver->crcxor;
crc &= driver->table->crcmask;
return crc;
}
#if CRC_ENABLE_DPIPE
void Ifx_Crc_printTable(Ifc_Crc_Table *table, IfxStdIf_DPipe *io)
{
sint32 i = 0;
uint32 typeSize;
if (table->order <= 8)
{
typeSize = 8;
}
else if (table->order <= 16)
{
typeSize = 16;
}
else
{
typeSize = 32;
}
IfxStdIf_DPipe_print(io, ENDL "Ifc_Crc_Table%d <tabe name> = {"ENDL, typeSize);
IfxStdIf_DPipe_print(io, " .data.order=%d,"ENDL, table->order);
IfxStdIf_DPipe_print(io, " .data.polynom=0x%X,"ENDL, table->polynom);
IfxStdIf_DPipe_print(io, " .data.refin=%d,"ENDL, table->refin);
IfxStdIf_DPipe_print(io, " .data.crchighbit=%d,"ENDL, table->crchighbit);
IfxStdIf_DPipe_print(io, " .data.crcmask=0x%X,"ENDL, table->crcmask);
IfxStdIf_DPipe_print(io, " .crctab={"ENDL);
IfxStdIf_DPipe_print(io, " ");
while (i < 256)
{
if (table->order <= 4)
{
uint8 *crctab = (uint8 *)((uint32)table + sizeof(Ifc_Crc_Table));
IfxStdIf_DPipe_print(io, "0x%01X, ", crctab[i]);
}
else if (table->order <= 8)
{
uint8 *crctab = (uint8 *)((uint32)table + sizeof(Ifc_Crc_Table));
IfxStdIf_DPipe_print(io, "0x%02X, ", crctab[i]);
}
else if (table->order <= 16)
{
uint16 *crctab = (uint16 *)((uint32)table + sizeof(Ifc_Crc_Table));
IfxStdIf_DPipe_print(io, "0x%04X, ", crctab[i]);
}
else if (table->order <= 24)
{
uint32 *crctab = (uint32 *)((uint32)table + sizeof(Ifc_Crc_Table));
IfxStdIf_DPipe_print(io, "0x%06X, ", crctab[i]);
}
else
{
uint32 *crctab = (uint32 *)((uint32)table + sizeof(Ifc_Crc_Table));
IfxStdIf_DPipe_print(io, "0x%08X, ", crctab[i]);
}
i++;
if ((i % 16) == 0)
{
IfxStdIf_DPipe_print(io, ENDL " ");
}
}
IfxStdIf_DPipe_print(io, " }"ENDL);
IfxStdIf_DPipe_print(io, "};"ENDL);
}
boolean Ifx_Crc_Test(Ifc_Crc *driver, uint8 *string, uint32 length, IfxStdIf_DPipe *io)
{
IfxStdIf_DPipe_print(io, ""ENDL);
IfxStdIf_DPipe_print(io, "CRC tester v1.1 written on 13/01/2003 by Sven Reifegerste (zorc/reflex)"ENDL);
IfxStdIf_DPipe_print(io, "-----------------------------------------------------------------------"ENDL);
IfxStdIf_DPipe_print(io, ""ENDL);
IfxStdIf_DPipe_print(io, "Parameters:"ENDL);
IfxStdIf_DPipe_print(io, ""ENDL);
IfxStdIf_DPipe_print(io, " polynom : 0x%x"ENDL, driver->table->polynom);
IfxStdIf_DPipe_print(io, " order : %d"ENDL, driver->table->order);
IfxStdIf_DPipe_print(io, " crcinit : 0x%x direct, 0x%x nondirect"ENDL, driver->crcinit_direct, driver->crcinit_nondirect);
IfxStdIf_DPipe_print(io, " crcxor : 0x%x"ENDL, driver->crcxor);
IfxStdIf_DPipe_print(io, " refin : %d"ENDL, driver->table->refin);
IfxStdIf_DPipe_print(io, " refout : %d"ENDL, driver->refout);
IfxStdIf_DPipe_print(io, ""ENDL);
// IfxStdIf_DPipe_print(io," data string : '%s' (%d bytes)"ENDL, string, stringLength);
IfxStdIf_DPipe_print(io, ""ENDL);
IfxStdIf_DPipe_print(io, "Results:"ENDL);
IfxStdIf_DPipe_print(io, ""ENDL);
#if 0
IfxCpu_Perf perf;
uint32 result;
IfxCpu_resetAndStartCounters(IfxCpu_CounterMode_normal);
result = Ifx_Crc_bitByBit(driver, (uint8 *)string, length);
perf = IfxCpu_stopCounters();
IfxStdIf_DPipe_print(io, " crc bit by bit : 0x%X, %d cycles"ENDL, result, perf.clock.counter);
IfxCpu_resetAndStartCounters(IfxCpu_CounterMode_normal);
result = Ifx_Crc_bitByBitFast(driver, (uint8 *)string, length);
perf = IfxCpu_stopCounters();
IfxStdIf_DPipe_print(io, " crc bit by bit fast : 0x%X, %d cycles"ENDL, result, perf.clock.counter);
IfxCpu_resetAndStartCounters(IfxCpu_CounterMode_normal);
result = Ifx_Crc_table(driver, (uint8 *)string, length);
perf = IfxCpu_stopCounters();
IfxStdIf_DPipe_print(io, " crc table : 0x%X, %d cycles"ENDL, result, perf.clock.counter);
IfxCpu_resetAndStartCounters(IfxCpu_CounterMode_normal);
result = Ifx_Crc_tableFast(driver, (uint8 *)string, length);
perf = IfxCpu_stopCounters();
IfxStdIf_DPipe_print(io, " crc table fast : 0x%X, %d cycles"ENDL, result, perf.clock.counter);
#endif
return TRUE;
}
#endif