429 lines
9.2 KiB
C
429 lines
9.2 KiB
C
#include "crc_lib.h"
|
|
|
|
static uint8_t CRC_4_ITU(uint8_t *data, uint8_t len);
|
|
static uint8_t CRC_5_EPC(uint8_t *data, uint8_t len);
|
|
static uint8_t CRC_5_ITU(uint8_t *data, uint8_t len);
|
|
static uint8_t CRC_5_USB(uint8_t *data, uint8_t len);
|
|
static uint8_t CRC_6_ITU(uint8_t *data, uint8_t len);
|
|
static uint8_t CRC_7_MMC(uint8_t *data, uint8_t len);
|
|
static uint8_t CRC_8(uint8_t *data, uint8_t len);
|
|
static uint8_t CRC_8_ITU(uint8_t *data, uint8_t len);
|
|
static uint8_t CRCC_8_ROHC(uint8_t *data, uint8_t len);
|
|
static uint8_t CRC_8_MAXIM(uint8_t *data, uint8_t len);
|
|
static uint16_t CRC_16_IBM(uint8_t *data, uint8_t len);
|
|
static uint16_t CRC_16_MAXIM(uint8_t *data, uint8_t len);
|
|
static uint16_t CRC_16_USB(uint8_t *data, uint8_t len);
|
|
static uint16_t CRC_16_MODBUS(uint8_t *data, uint8_t len);
|
|
static uint16_t CRC_16_CCITT(uint8_t *data, uint8_t len);
|
|
static uint16_t CRC_16_CCITT_FALSE(uint8_t *data, uint8_t len);
|
|
static uint16_t CRC_16_X25(uint8_t *data, uint8_t len);
|
|
static uint16_t CRC_16_XMODEM(uint8_t *data, uint8_t len);
|
|
static uint16_t CRC_16_DNP(uint8_t *data, uint8_t len);
|
|
static uint32_t CRC_32(uint8_t *data, uint8_t len);
|
|
static uint32_t CRC_32_MPEG_2(uint8_t *data, uint8_t len);
|
|
|
|
FuncionTable crc_list = {
|
|
.CRC_4_ITU = CRC_4_ITU,
|
|
.CRC_5_EPC = CRC_5_EPC,
|
|
.CRC_5_ITU = CRC_5_ITU,
|
|
.CRC_5_USB = CRC_5_USB,
|
|
.CRC_6_ITU = CRC_6_ITU,
|
|
.CRC_7_MMC = CRC_7_MMC,
|
|
.CRC_8 = CRC_8,
|
|
.CRC_8_ITU = CRC_8_ITU,
|
|
.CRCC_8_ROHC = CRCC_8_ROHC,
|
|
.CRC_8_MAXIM = CRC_8_MAXIM,
|
|
.CRC_16_IBM = CRC_16_IBM,
|
|
.CRC_16_MAXIM = CRC_16_MAXIM,
|
|
.CRC_16_USB = CRC_16_USB,
|
|
.CRC_16_MODBUS = CRC_16_MODBUS,
|
|
.CRC_16_CCITT = CRC_16_CCITT,
|
|
.CRC_16_CCITT_FALSE = CRC_16_CCITT_FALSE,
|
|
.CRC_16_X25 = CRC_16_X25,
|
|
.CRC_16_XMODEM = CRC_16_XMODEM,
|
|
.CRC_16_DNP = CRC_16_DNP,
|
|
.CRC_32 = CRC_32,
|
|
.CRC_32_MPEG_2 = CRC_32_MPEG_2,
|
|
};
|
|
|
|
static uint8_t CRC_4_ITU(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint8_t crc = 0;
|
|
while(len--)
|
|
{
|
|
crc ^= *data++;
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
if (crc & 1)
|
|
crc = (crc >> 1) ^ 0x0C;
|
|
else
|
|
crc = (crc >> 1);
|
|
}
|
|
}
|
|
return crc & 0x0F;
|
|
}
|
|
|
|
static uint8_t CRC_5_EPC(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint8_t crc = 0x48;
|
|
while(len--)
|
|
{
|
|
crc ^= *data++;
|
|
for ( i = 0; i < 8; i++ )
|
|
{
|
|
if ( crc & 0x80 )
|
|
crc = (crc << 1) ^ 0x48;
|
|
else
|
|
crc <<= 1;
|
|
}
|
|
}
|
|
return (crc >> 3) & 0x1F;
|
|
}
|
|
|
|
static uint8_t CRC_5_ITU(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint8_t crc = 0;
|
|
while(len--)
|
|
{
|
|
crc ^= *data++;
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
if (crc & 1)
|
|
crc = (crc >> 1) ^ 0x15;
|
|
else
|
|
crc = (crc >> 1);
|
|
}
|
|
}
|
|
return crc & 0x1F;
|
|
}
|
|
|
|
static uint8_t CRC_5_USB(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint8_t crc = 0x1F;
|
|
while(len--)
|
|
{
|
|
crc ^= *data++;
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
if (crc & 1)
|
|
crc = (crc >> 1) ^ 0x14;
|
|
else
|
|
crc = (crc >> 1);
|
|
}
|
|
}
|
|
return crc ^ 0x1F;
|
|
}
|
|
|
|
static uint8_t CRC_6_ITU(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint8_t crc = 0;
|
|
while(len--)
|
|
{
|
|
crc ^= *data++;
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
if (crc & 1)
|
|
crc = (crc >> 1) ^ 0x30;
|
|
else
|
|
crc = (crc >> 1);
|
|
}
|
|
}
|
|
return crc & 0x3F;
|
|
}
|
|
|
|
static uint8_t CRC_7_MMC(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint8_t crc = 0;
|
|
while(len--)
|
|
{
|
|
crc ^= *data++;
|
|
for ( i = 0; i < 8; i++ )
|
|
{
|
|
if ( crc & 0x80 )
|
|
crc = (crc << 1) ^ 0x12;
|
|
else
|
|
crc <<= 1;
|
|
}
|
|
}
|
|
return (crc >> 1) & 0x7F;
|
|
}
|
|
|
|
static uint8_t CRC_8(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint8_t crc = 0;
|
|
while(len--)
|
|
{
|
|
crc ^= *data++;
|
|
for ( i = 0; i < 8; i++ )
|
|
{
|
|
if ( crc & 0x80 )
|
|
crc = (crc << 1) ^ 0x07;
|
|
else
|
|
crc <<= 1;
|
|
}
|
|
}
|
|
return crc;
|
|
}
|
|
|
|
static uint8_t CRC_8_ITU(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint8_t crc = 0;
|
|
while(len--)
|
|
{
|
|
crc ^= *data++;
|
|
for ( i = 0; i < 8; i++ )
|
|
{
|
|
if ( crc & 0x80 )
|
|
crc = (crc << 1) ^ 0x07;
|
|
else
|
|
crc <<= 1;
|
|
}
|
|
}
|
|
return crc ^ 0x55;
|
|
}
|
|
|
|
static uint8_t CRCC_8_ROHC(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint8_t crc = 0xFF;
|
|
while(len--)
|
|
{
|
|
crc ^= *data++;
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
if (crc & 1)
|
|
crc = (crc >> 1) ^ 0xE0;
|
|
else
|
|
crc = (crc >> 1);
|
|
}
|
|
}
|
|
return crc;
|
|
}
|
|
|
|
static uint8_t CRC_8_MAXIM(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint8_t crc = 0;
|
|
while(len--)
|
|
{
|
|
crc ^= *data++;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
if (crc & 1)
|
|
crc = (crc >> 1) ^ 0x8C;
|
|
else
|
|
crc >>= 1;
|
|
}
|
|
}
|
|
return crc;
|
|
}
|
|
|
|
static uint16_t CRC_16_IBM(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint16_t crc = 0;
|
|
while(len--)
|
|
{
|
|
crc ^= *data++;
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
if (crc & 1)
|
|
crc = (crc >> 1) ^ 0xA001;
|
|
else
|
|
crc = (crc >> 1);
|
|
}
|
|
}
|
|
return crc;
|
|
}
|
|
|
|
static uint16_t CRC_16_MAXIM(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint16_t crc = 0;
|
|
while(len--)
|
|
{
|
|
crc ^= *data++;
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
if (crc & 1)
|
|
crc = (crc >> 1) ^ 0xA001;
|
|
else
|
|
crc = (crc >> 1);
|
|
}
|
|
}
|
|
return ~crc;
|
|
}
|
|
|
|
static uint16_t CRC_16_USB(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint16_t crc = 0xffff;
|
|
while(len--)
|
|
{
|
|
crc ^= *data++;
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
if (crc & 1)
|
|
crc = (crc >> 1) ^ 0xA001;
|
|
else
|
|
crc = (crc >> 1);
|
|
}
|
|
}
|
|
return ~crc;
|
|
}
|
|
|
|
static uint16_t CRC_16_MODBUS(uint8_t *data, uint8_t len)
|
|
{
|
|
uint16_t crc = 0xFFFF;
|
|
uint8_t i, j;
|
|
for (j=0; j < len; j++)
|
|
{
|
|
crc=crc ^* data++;
|
|
for (i = 0; i < 8; i++)
|
|
{
|
|
if((crc & 0x0001) > 0)
|
|
{
|
|
crc = crc >> 1;
|
|
crc = crc ^ 0xa001;
|
|
}else
|
|
{
|
|
crc = crc >> 1;
|
|
}
|
|
}
|
|
}
|
|
return crc;
|
|
}
|
|
|
|
static uint16_t CRC_16_CCITT(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint16_t crc = 0;
|
|
while(len--)
|
|
{
|
|
crc ^= *data++;
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
if (crc & 1)
|
|
crc = (crc >> 1) ^ 0x8408;
|
|
else
|
|
crc = (crc >> 1);
|
|
}
|
|
}
|
|
return crc;
|
|
}
|
|
|
|
static uint16_t CRC_16_CCITT_FALSE(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint16_t crc = 0xffff;
|
|
while(len--)
|
|
{
|
|
crc ^= (uint16_t)(*data++) << 8;
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
if ( crc & 0x8000 )
|
|
crc = (crc << 1) ^ 0x1021;
|
|
else
|
|
crc <<= 1;
|
|
}
|
|
}
|
|
return crc;
|
|
}
|
|
|
|
static uint16_t CRC_16_X25(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint16_t crc = 0xffff;
|
|
while(len--)
|
|
{
|
|
crc ^= *data++;
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
if (crc & 1)
|
|
crc = (crc >> 1) ^ 0x8408;
|
|
else
|
|
crc = (crc >> 1);
|
|
}
|
|
}
|
|
return ~crc;
|
|
}
|
|
|
|
static uint16_t CRC_16_XMODEM(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint16_t crc = 0;
|
|
while(len--)
|
|
{
|
|
crc ^= (uint16_t)(*data++) << 8;
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
if ( crc & 0x8000 )
|
|
crc = (crc << 1) ^ 0x1021;
|
|
else
|
|
crc <<= 1;
|
|
}
|
|
}
|
|
return crc;
|
|
}
|
|
|
|
static uint16_t CRC_16_DNP(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint16_t crc = 0;
|
|
while(len--)
|
|
{
|
|
crc ^= *data++;
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
if (crc & 1)
|
|
crc = (crc >> 1) ^ 0xA6BC;
|
|
else
|
|
crc = (crc >> 1);
|
|
}
|
|
}
|
|
return ~crc;
|
|
}
|
|
|
|
static uint32_t CRC_32(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint32_t crc = 0xffffffff;
|
|
while(len--)
|
|
{
|
|
crc ^= *data++;
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
if (crc & 1)
|
|
crc = (crc >> 1) ^ 0xEDB88320;
|
|
else
|
|
crc = (crc >> 1);
|
|
}
|
|
}
|
|
return ~crc;
|
|
}
|
|
|
|
static uint32_t CRC_32_MPEG_2(uint8_t *data, uint8_t len)
|
|
{
|
|
uint8_t i;
|
|
uint32_t crc = 0xffffffff;
|
|
while(len--)
|
|
{
|
|
crc ^= (uint32_t)(*data++) << 24;
|
|
for (i = 0; i < 8; ++i)
|
|
{
|
|
if ( crc & 0x80000000 )
|
|
crc = (crc << 1) ^ 0x04C11DB7;
|
|
else
|
|
crc <<= 1;
|
|
}
|
|
}
|
|
return crc;
|
|
} |