495 lines
8.8 KiB
C
495 lines
8.8 KiB
C
#include "check.h"
|
|
|
|
//获取校验长度
|
|
uint8_t check_size(uint8_t type)
|
|
{
|
|
uint8_t size = 0;
|
|
|
|
switch(type)
|
|
{
|
|
case CHECK_SUM8:
|
|
case CHECK_XOR8:
|
|
case CHECK_CRC8_MAXIM:
|
|
size = 1;
|
|
break;
|
|
case CHECK_CRC16_MODBUS:
|
|
size = 2;
|
|
break;
|
|
}
|
|
|
|
return size;
|
|
}
|
|
|
|
//获取校验值
|
|
uint32_t check_value(check_t check, uint8_t *data)
|
|
{
|
|
uint32_t value = 0; //校验值
|
|
|
|
switch(check.type)
|
|
{
|
|
case CHECK_SUM8:
|
|
value = CHECKSUM8(data+check.start, check.length);
|
|
break;
|
|
case CHECK_XOR8:
|
|
value = XOR8(data+check.start, check.length);
|
|
break;
|
|
case CHECK_CRC8_MAXIM:
|
|
value = CRC8_MAXIM(data+check.start, check.length);
|
|
break;
|
|
case CHECK_CRC16_MODBUS:
|
|
value = CRC16_MODBUS(data+check.start, check.length);
|
|
break;
|
|
}
|
|
|
|
return value;
|
|
}
|
|
|
|
//计算并比较校验
|
|
uint8_t check_cmp(check_t check, uint8_t *data)
|
|
{
|
|
if(check.length > 0)
|
|
{
|
|
uint8_t size = check_size(check.type); //校验长度
|
|
uint32_t value = check_value(check, data); //校验值
|
|
|
|
switch(size)
|
|
{
|
|
case 1: //1字节校验
|
|
if(data[check.index] == (value&0xFF))
|
|
{
|
|
return 1;
|
|
}
|
|
break;
|
|
case 2: //2字节校验
|
|
if((data[check.index] == (value&0xFF)) && (data[check.index+1] == ((value>>8)&0xFF)))
|
|
{
|
|
return 1;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
//计算并添加校验
|
|
void check_add(check_t check, uint8_t *data)
|
|
{
|
|
if(check.length > 0)
|
|
{
|
|
uint8_t size = check_size(check.type); //校验长度
|
|
uint32_t value = check_value(check, data); //校验值
|
|
|
|
switch(size)
|
|
{
|
|
case 1: //1字节校验
|
|
data[check.index] = value & 0xFF;
|
|
break;
|
|
case 2: //2字节校验
|
|
data[check.index] = value & 0xFF;
|
|
data[check.index+1] = (value>>8) & 0xFF;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//校验和
|
|
uint8_t CHECKSUM8(const uint8_t *data, uint16_t length)
|
|
{
|
|
uint8_t sum = 0;
|
|
while(length--)
|
|
{
|
|
sum += *data++;
|
|
}
|
|
return (sum);
|
|
}
|
|
|
|
//异或校验
|
|
uint8_t XOR8(const uint8_t *data, uint16_t length)
|
|
{
|
|
uint8_t x = 0;
|
|
while(length--)
|
|
{
|
|
x ^= *data++;
|
|
}
|
|
return (x);
|
|
}
|
|
|
|
/*************************************************
|
|
* CRC-8: X8+X2+X+1
|
|
* POLY: 0x07
|
|
* INIT: 0x00
|
|
* REFIN: FALSE
|
|
* REFOUT: FALSE
|
|
* XOROUT: 0x00
|
|
**************************************************/
|
|
uint8_t CRC8(const uint8_t *data, uint16_t length)
|
|
{
|
|
uint8_t crc = 0x00;
|
|
uint8_t poly = 0x07;
|
|
|
|
while(length--)
|
|
{
|
|
crc ^= *data++;
|
|
for(uint8_t i = 0; i < 8; i++)
|
|
{
|
|
if(crc & 0x80)
|
|
crc = (crc << 1) ^ poly;
|
|
else
|
|
crc = crc << 1;
|
|
}
|
|
}
|
|
return (crc);
|
|
}
|
|
|
|
/*************************************************
|
|
* CRC-8/ITU: X8+X2+X+1
|
|
* POLY: 0x07
|
|
* INIT: 0x00
|
|
* REFIN: FALSE
|
|
* REFOUT: FALSE
|
|
* XOROUT: 0x55
|
|
**************************************************/
|
|
uint8_t CRC8_ITU(const uint8_t *data, uint16_t length)
|
|
{
|
|
uint8_t crc = 0x00;
|
|
uint8_t poly = 0x07;
|
|
|
|
while(length--)
|
|
{
|
|
crc ^= *data++;
|
|
for(uint8_t i = 0; i < 8; i++)
|
|
{
|
|
if(crc & 0x80)
|
|
crc = (crc << 1) ^ poly;
|
|
else
|
|
crc = crc << 1;
|
|
}
|
|
}
|
|
return (crc ^ 0x55);
|
|
}
|
|
|
|
/*************************************************
|
|
* CRC-8/ROHC: X8+X2+X+1
|
|
* POLY: 0x07
|
|
* INIT: 0xFF
|
|
* REFIN: TRUE
|
|
* REFOUT: TRUE
|
|
* XOROUT: 0x00
|
|
**************************************************/
|
|
uint8_t CRC8_ROHC(const uint8_t *data, uint16_t length)
|
|
{
|
|
uint8_t crc = 0xFF;
|
|
uint8_t poly = 0xE0; //0x07字节颠倒后为0xE0
|
|
|
|
while(length--)
|
|
{
|
|
crc ^= *data++;
|
|
for(uint8_t i = 0; i < 8; i++)
|
|
{
|
|
if(crc & 0x01)
|
|
crc = (crc >> 1) ^ poly;
|
|
else
|
|
crc = crc >> 1;
|
|
}
|
|
}
|
|
return (crc);
|
|
}
|
|
|
|
/*************************************************
|
|
* CRC-8/MAXIM: X8+X2+X+1
|
|
* POLY: 0x31
|
|
* INIT: 0x00
|
|
* REFIN: TRUE
|
|
* REFOUT: TRUE
|
|
* XOROUT: 0x00
|
|
**************************************************/
|
|
uint8_t CRC8_MAXIM(const uint8_t *data, uint16_t length)
|
|
{
|
|
uint8_t crc = 0x00;
|
|
uint8_t poly = 0x8C; //0x31字节颠倒后为0x8C
|
|
|
|
while(length--)
|
|
{
|
|
crc ^= *data++;
|
|
for(uint8_t i = 0; i < 8; i++)
|
|
{
|
|
if(crc & 0x01)
|
|
crc = (crc >> 1) ^ poly;
|
|
else
|
|
crc = crc >> 1;
|
|
}
|
|
}
|
|
return (crc);
|
|
}
|
|
|
|
/*************************************************
|
|
* CRC-8: X8+X4+X3+X2+1
|
|
* POLY: 0x1D
|
|
* INIT: 0x00
|
|
* REFIN: FALSE
|
|
* REFOUT: FALSE
|
|
* XOROUT: 0x00
|
|
**************************************************/
|
|
uint8_t CRC8_SAE(const uint8_t *data, uint16_t length)
|
|
{
|
|
uint8_t crc = 0x00;
|
|
uint8_t poly = 0x1D;
|
|
|
|
while(length--)
|
|
{
|
|
crc ^= *data++;
|
|
for(uint8_t i = 0; i < 8; i++)
|
|
{
|
|
if(crc & 0x80)
|
|
crc = (crc << 1) ^ poly;
|
|
else
|
|
crc = crc << 1;
|
|
}
|
|
}
|
|
return (crc);
|
|
}
|
|
|
|
/*************************************************
|
|
* CRC-16/CCITT: X16+X12+X5+1
|
|
* POLY: 0x1021
|
|
* INIT: 0x0000
|
|
* REFIN: TRUE
|
|
* REFOUT: TRUE
|
|
* XOROUT: 0x0000
|
|
**************************************************/
|
|
uint16_t CRC16_CCITT(const uint8_t *data, uint16_t length)
|
|
{
|
|
uint16_t crc = 0x0000;
|
|
uint16_t poly = 0x8408; //0x1021字节颠倒后为0x8408
|
|
|
|
while(length--)
|
|
{
|
|
crc ^= *data++;
|
|
for(uint8_t i = 0; i < 8; i++)
|
|
{
|
|
if(crc & 0x01)
|
|
crc = (crc >> 1) ^ poly;
|
|
else
|
|
crc = crc >> 1;
|
|
}
|
|
}
|
|
return (crc);
|
|
}
|
|
|
|
/*************************************************
|
|
* CRC-16/CCITT-FALSE: X16+X12+X5+1
|
|
* POLY: 0x1021
|
|
* INIT: 0xFFFF
|
|
* REFIN: FALSE
|
|
* REFOUT: FALSE
|
|
* XOROUT: 0x0000
|
|
**************************************************/
|
|
uint16_t CRC16_CCITT_FALSE(const uint8_t *data, uint16_t length)
|
|
{
|
|
uint16_t crc = 0xFFFF;
|
|
uint16_t poly = 0x1021;
|
|
|
|
while(length--)
|
|
{
|
|
crc ^= ((*data++) << 8);
|
|
for(uint8_t i = 0; i < 8; i++)
|
|
{
|
|
if(crc & 0x8000)
|
|
crc = (crc << 1) ^ poly;
|
|
else
|
|
crc = crc << 1;
|
|
}
|
|
}
|
|
return (crc);
|
|
}
|
|
|
|
/*************************************************
|
|
* CRC-16/XMODEM: X16+X12+X5+1
|
|
* POLY: 0x1021
|
|
* INIT: 0x0000
|
|
* REFIN: FALSE
|
|
* REFOUT: FALSE
|
|
* XOROUT: 0x0000
|
|
**************************************************/
|
|
uint16_t CRC16_XMODEM(const uint8_t *data, uint16_t length)
|
|
{
|
|
uint16_t crc = 0x0000;
|
|
uint16_t poly = 0x1021;
|
|
|
|
while(length--)
|
|
{
|
|
crc ^= ((*data++) << 8);
|
|
for(uint8_t i = 0; i < 8; i++)
|
|
{
|
|
if(crc & 0x8000)
|
|
crc = (crc << 1) ^ poly;
|
|
else
|
|
crc = crc << 1;
|
|
}
|
|
}
|
|
return (crc);
|
|
}
|
|
|
|
/*************************************************
|
|
* CRC-16/X25: X16+X12+X5+1
|
|
* POLY: 0x1021
|
|
* INIT: 0xFFFF
|
|
* REFIN: TRUE
|
|
* REFOUT: TRUE
|
|
* XOROUT: 0xFFFF
|
|
**************************************************/
|
|
uint16_t CRC16_X25(const uint8_t *data, uint16_t length)
|
|
{
|
|
uint16_t crc = 0xFFFF;
|
|
uint16_t poly = 0x8408; //0x1021字节颠倒后为0x8408
|
|
|
|
while(length--)
|
|
{
|
|
crc ^= *data++;
|
|
for(uint8_t i = 0; i < 8; i++)
|
|
{
|
|
if(crc & 0x01)
|
|
crc = (crc >> 1) ^ poly;
|
|
else
|
|
crc = crc >> 1;
|
|
}
|
|
}
|
|
return (crc^0xFFFF);
|
|
}
|
|
|
|
/*************************************************
|
|
* CRC-16/MODBUS: X16+X12+X5+1
|
|
* POLY: 0x8005
|
|
* INIT: 0xFFFF
|
|
* REFIN: TRUE
|
|
* REFOUT: TRUE
|
|
* XOROUT: 0x0000
|
|
**************************************************/
|
|
uint16_t CRC16_MODBUS(const uint8_t *data, uint16_t length)
|
|
{
|
|
uint16_t crc = 0xFFFF;
|
|
uint16_t poly = 0xA001; //0x8005字节颠倒后为0xA001
|
|
|
|
while(length--)
|
|
{
|
|
crc ^= *data++;
|
|
for(uint8_t i = 0; i < 8; i++)
|
|
{
|
|
if(crc & 0x01)
|
|
crc = (crc >> 1) ^ poly;
|
|
else
|
|
crc = crc >> 1;
|
|
}
|
|
}
|
|
return (crc);
|
|
}
|
|
|
|
/*************************************************
|
|
* CRC-16/IBM: X16+X12+X5+1
|
|
* POLY: 0x8005
|
|
* INIT: 0x0000
|
|
* REFIN: TRUE
|
|
* REFOUT: TRUE
|
|
* XOROUT: 0x0000
|
|
**************************************************/
|
|
uint16_t CRC16_IBM(const uint8_t *data, uint16_t length)
|
|
{
|
|
uint16_t crc = 0x0000;
|
|
uint16_t poly = 0xA001; //0x8005字节颠倒后为0xA001
|
|
|
|
while(length--)
|
|
{
|
|
crc ^= *data++;
|
|
for(uint8_t i = 0; i < 8; i++)
|
|
{
|
|
if(crc & 0x01)
|
|
crc = (crc >> 1) ^ poly;
|
|
else
|
|
crc = crc >> 1;
|
|
}
|
|
}
|
|
return (crc);
|
|
}
|
|
|
|
/*************************************************
|
|
* CRC-16/MAXIM: X16+X12+X5+1
|
|
* POLY: 0x8005
|
|
* INIT: 0x0000
|
|
* REFIN: TRUE
|
|
* REFOUT: TRUE
|
|
* XOROUT: 0xFFFF
|
|
**************************************************/
|
|
uint16_t CRC16_MAXIM(const uint8_t *data, uint16_t length)
|
|
{
|
|
uint16_t crc = 0x0000;
|
|
uint16_t poly = 0xA001; //0x8005字节颠倒后为0xA001
|
|
|
|
while(length--)
|
|
{
|
|
crc ^= *data++;
|
|
for(uint8_t i = 0; i < 8; i++)
|
|
{
|
|
if(crc & 0x01)
|
|
crc = (crc >> 1) ^ poly;
|
|
else
|
|
crc = crc >> 1;
|
|
}
|
|
}
|
|
return (crc^0xFFFF);
|
|
}
|
|
|
|
/*************************************************
|
|
* CRC-16/USB: X16+X12+X5+1
|
|
* POLY: 0x8005
|
|
* INIT: 0xFFFF
|
|
* REFIN: TRUE
|
|
* REFOUT: TRUE
|
|
* XOROUT: 0xFFFF
|
|
**************************************************/
|
|
uint16_t CRC16_USB(const uint8_t *data, uint16_t length)
|
|
{
|
|
uint16_t crc = 0xFFFF;
|
|
uint16_t poly = 0xA001; //0x8005字节颠倒后为0xA001
|
|
|
|
while(length--)
|
|
{
|
|
crc ^= *data++;
|
|
for(uint8_t i = 0; i < 8; i++)
|
|
{
|
|
if(crc & 0x01)
|
|
crc = (crc >> 1) ^ poly;
|
|
else
|
|
crc = crc >> 1;
|
|
}
|
|
}
|
|
return (crc^0xFFFF);
|
|
}
|
|
|
|
/*************************************************
|
|
* CRC-16/NDP: X16+X12+X5+1
|
|
* POLY: 0x3D65
|
|
* INIT: 0x0000
|
|
* REFIN: TRUE
|
|
* REFOUT: TRUE
|
|
* XOROUT: 0xFFFF
|
|
**************************************************/
|
|
uint16_t CRC16_NDP(const uint8_t *data, uint16_t length)
|
|
{
|
|
uint16_t crc = 0x0000;
|
|
uint16_t poly = 0xA6BC; //0x3D65字节颠倒后为0xA6BC
|
|
|
|
while(length--)
|
|
{
|
|
crc ^= *data++;
|
|
for(uint8_t i = 0; i < 8; i++)
|
|
{
|
|
if(crc & 0x01)
|
|
crc = (crc >> 1) ^ poly;
|
|
else
|
|
crc = crc >> 1;
|
|
}
|
|
}
|
|
return (crc^0xFFFF);
|
|
}
|