#include "crc.h"
//计算机存储最小单位是字节,存储顺序(小端模式)为低位字节在前,高位在后
#define MSB_MODE 1 //大端模式
#define LSB_MODE 0
static void _InvertU8(uint8_t *dBuf, uint8_t *srcBuf);
static void _InvertU16(uint16_t *dBuf, uint16_t *srcBuf);
static void _InvertU32(uint32_t *dBuf, uint32_t *srcBuf);
typedef bool (*pFunc)();
typedef struct{
uint16_t initVal;
uint16_t POLY;
uint16_t sub;
uint8_t bits;
char *funcName;
}crc16_Table_TypeDef;
static const crc16_Table_TypeDef CRC16_Table[] = {
{0x0000, 0x1021, 0x0000, LSB_MODE, "CRC16_CCITT"},
{0xFFFF, 0x1021, 0x0000, MSB_MODE, "CRC16_CCITT_FLASE"},
{0x0000, 0x1021, 0x0000, MSB_MODE, "CRC16_XMODEM"},
{0xFFFF, 0x1021, 0xFFFF, LSB_MODE, "CRC16_X25"},
{0xFFFF, 0x8005, 0x0000, LSB_MODE, "CRC16_MODBUS"},
{0x0000, 0x8005, 0x0000, LSB_MODE, "CRC16_IBM"},
{0x0000, 0x8005, 0xFFFF, LSB_MODE, "CRC16_MAXIM"},
{0xFFFF, 0x8005, 0xFFFF, LSB_MODE, "CRC16_USB"},
};
typedef struct{
uint8_t initVal;
uint8_t POLY;
uint8_t sub;
uint8_t bits;
char *funcName;
}crc8_Table_TypeDef;
static const crc8_Table_TypeDef CRC8_Table[] = {
{0x00, 0x07, 0x00, MSB_MODE, "CRC8"},
{0x00, 0x07, 0x55, MSB_MODE, "CRC8_ITU"},
{0xFF, 0x07, 0x00, LSB_MODE, "CRC8_ROHC"},
{0x00, 0x31, 0x00, LSB_MODE, "CRC8_MAXIM"},
};
typedef struct{
uint32_t initVal;
uint32_t POLY;
uint32_t sub;
uint8_t bits;
char *funcName;
}crc32_Table_TypeDef;
static const crc32_Table_TypeDef CRC32_Table[]={
{0xFFFFFFFF, 0x04C11DB7, 0xFFFFFFFF, LSB_MODE, "CRC32"},
{0xFFFFFFFF, 0x04C11DB7, 0x00000000, MSB_MODE, "CRC32_MPEG-2"}
};
uint16_t calc_crc16(uint8_t Mode, uint8_t *pMsg, uint16_t Len){
// printf(" %d \n", sizeof(Table)/sizeof(funcTable_TypeDef));
if(Mode > sizeof(CRC16_Table)/sizeof(crc16_Table_TypeDef))
return 0;
uint16_t CRCin = CRC16_Table[Mode].initVal;
uint8_t tmp = 0;
printf("CRC_Mode: %s\n", CRC16_Table[Mode].funcName);
for(uint16_t i=0;i<Len;i++){
tmp = *(pMsg++);
if(CRC16_Table[Mode].bits == LSB_MODE){
_InvertU8(&tmp, &tmp);
}
CRCin ^= (tmp << 8);
for(uint8_t j=0;j<8;j++){
if(CRCin & 0x8000){
CRCin = (CRCin << 1) ^ CRC16_Table[Mode].POLY;
}else{
CRCin = CRCin << 1;
}
}
}
if(CRC16_Table[Mode].bits == LSB_MODE){
_InvertU16(&CRCin, &CRCin);
}
return (CRCin ^ CRC16_Table[Mode].sub);
}
uint8_t calc_crc8(uint8_t Mode, uint8_t*pMsg, uint16_t Len){
if(Mode > sizeof(CRC8_Table)/sizeof(crc8_Table_TypeDef))
return 0;
uint8_t CRCin = CRC8_Table[Mode].initVal;
uint8_t tmp = 0;
printf("CRC_Mode: %s\n", CRC8_Table[Mode].funcName);
for(uint16_t i=0;i<Len;i++){
tmp = *(pMsg++);
if(CRC8_Table[Mode].bits == LSB_MODE){
_InvertU8(&tmp, &tmp);
}
CRCin ^= tmp;
for(uint8_t j=0;j<8;j++){
if(CRCin & 0x80){
CRCin = (CRCin << 1) ^ CRC8_Table[Mode].POLY;
}else{
CRCin <<= 1;
}
}
}
if(CRC8_Table[Mode].bits == LSB_MODE){
_InvertU8(&CRCin, &CRCin);
}
return (CRCin ^ CRC8_Table[Mode].sub);
}
uint32_t calc_crc32(uint8_t Mode, uint8_t *pMsg, uint16_t Len){
if(Mode > sizeof(CRC32_Table)/sizeof(crc32_Table_TypeDef))
return 0;
uint32_t CRCin = CRC32_Table[Mode].initVal;
uint32_t tmp = 0;
printf("CRC_Mode: %s\n", CRC32_Table[Mode].funcName);
for(uint16_t i=0;i<Len;i++){
tmp = *(pMsg++);
if(CRC32_Table[Mode].bits == LSB_MODE){
_InvertU8((uint8_t*)&tmp, (uint8_t*)&tmp);
}
CRCin ^= (tmp <<24);
for(uint8_t j=0;j<8;j++){
if(CRCin & 0x80000000){
CRCin = (CRCin << 1) ^ CRC32_Table[Mode].POLY;
}else{
CRCin <<= 1;
}
}
}
if(CRC32_Table[Mode].bits == LSB_MODE){
_InvertU32(&CRCin, &CRCin);
}
return (CRCin ^ CRC32_Table[Mode].sub);
}
static void _InvertU8(uint8_t *dBuf, uint8_t *srcBuf){
uint8_t tmp[4] = {0};
for(uint8_t i=0;i<8;i++){
if(srcBuf[0] & (1<<i)){
tmp[0] |= 1<<(7-i);
}
}
dBuf[0] = tmp[0];
}
static void _InvertU16(uint16_t *dBuf, uint16_t *srcBuf){
uint16_t tmp[4] = {0};
for(uint8_t i=0;i<16;i++){
if(srcBuf[0] & (1<<i)){
tmp[0] |= 1<<(15-i);
}
}
dBuf[0] = tmp[0];
}
static void _InvertU32(uint32_t *dBuf, uint32_t *srcBuf){
uint32_t tmp[4] = {0};
for(uint8_t i=0;i<32;i++){
if(srcBuf[0] & (1<<i)){
tmp[0] |= 1<<(31-i);
}
}
dBuf[0] = tmp[0];
}