355 lines
8.7 KiB
C
355 lines
8.7 KiB
C
/**
|
||
******************************************************************************
|
||
* @file
|
||
* @author
|
||
* @version
|
||
* @date
|
||
* @brief
|
||
* @function List:
|
||
******************************************************************************
|
||
* @attention
|
||
*
|
||
*
|
||
* <h2><center>© COPYRIGHT 2021 </center></h2>
|
||
******************************************************************************
|
||
* @History:
|
||
* @Author:
|
||
* @Data:
|
||
* @Version:
|
||
*/
|
||
|
||
#include "crc.h"
|
||
#include "common_types.h"
|
||
|
||
|
||
#ifdef CRC_USE_TABLE
|
||
#define CRC8_BIT(x) (1u << (x))
|
||
|
||
#ifdef CRC_TABLE_IS_CONST
|
||
|
||
MEMORY_MAP_ROM_DATA_FOR_ASIL const u8 crc8_table[CRC8_ID_MAX][256]=
|
||
{
|
||
{ //多项式 1D 初始化值 FF 异或值 FF
|
||
0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53, 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB,
|
||
0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E, 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76,
|
||
0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4, 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C,
|
||
0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19, 0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1,
|
||
0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40, 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8,
|
||
0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D, 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65,
|
||
0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7, 0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F,
|
||
0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A, 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2,
|
||
0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75, 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D,
|
||
0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8, 0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50,
|
||
0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2, 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A,
|
||
0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F, 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7,
|
||
0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66, 0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E,
|
||
0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB, 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43,
|
||
0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1, 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09,
|
||
0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C, 0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4
|
||
},
|
||
{ //多项式 1D 初始化值 00 异或值 00
|
||
0x00, 0x1D, 0x3A, 0x27, 0x74, 0x69, 0x4E, 0x53, 0xE8, 0xF5, 0xD2, 0xCF, 0x9C, 0x81, 0xA6, 0xBB,
|
||
0xCD, 0xD0, 0xF7, 0xEA, 0xB9, 0xA4, 0x83, 0x9E, 0x25, 0x38, 0x1F, 0x02, 0x51, 0x4C, 0x6B, 0x76,
|
||
0x87, 0x9A, 0xBD, 0xA0, 0xF3, 0xEE, 0xC9, 0xD4, 0x6F, 0x72, 0x55, 0x48, 0x1B, 0x06, 0x21, 0x3C,
|
||
0x4A, 0x57, 0x70, 0x6D, 0x3E, 0x23, 0x04, 0x19, 0xA2, 0xBF, 0x98, 0x85, 0xD6, 0xCB, 0xEC, 0xF1,
|
||
0x13, 0x0E, 0x29, 0x34, 0x67, 0x7A, 0x5D, 0x40, 0xFB, 0xE6, 0xC1, 0xDC, 0x8F, 0x92, 0xB5, 0xA8,
|
||
0xDE, 0xC3, 0xE4, 0xF9, 0xAA, 0xB7, 0x90, 0x8D, 0x36, 0x2B, 0x0C, 0x11, 0x42, 0x5F, 0x78, 0x65,
|
||
0x94, 0x89, 0xAE, 0xB3, 0xE0, 0xFD, 0xDA, 0xC7, 0x7C, 0x61, 0x46, 0x5B, 0x08, 0x15, 0x32, 0x2F,
|
||
0x59, 0x44, 0x63, 0x7E, 0x2D, 0x30, 0x17, 0x0A, 0xB1, 0xAC, 0x8B, 0x96, 0xC5, 0xD8, 0xFF, 0xE2,
|
||
0x26, 0x3B, 0x1C, 0x01, 0x52, 0x4F, 0x68, 0x75, 0xCE, 0xD3, 0xF4, 0xE9, 0xBA, 0xA7, 0x80, 0x9D,
|
||
0xEB, 0xF6, 0xD1, 0xCC, 0x9F, 0x82, 0xA5, 0xB8, 0x03, 0x1E, 0x39, 0x24, 0x77, 0x6A, 0x4D, 0x50,
|
||
0xA1, 0xBC, 0x9B, 0x86, 0xD5, 0xC8, 0xEF, 0xF2, 0x49, 0x54, 0x73, 0x6E, 0x3D, 0x20, 0x07, 0x1A,
|
||
0x6C, 0x71, 0x56, 0x4B, 0x18, 0x05, 0x22, 0x3F, 0x84, 0x99, 0xBE, 0xA3, 0xF0, 0xED, 0xCA, 0xD7,
|
||
0x35, 0x28, 0x0F, 0x12, 0x41, 0x5C, 0x7B, 0x66, 0xDD, 0xC0, 0xE7, 0xFA, 0xA9, 0xB4, 0x93, 0x8E,
|
||
0xF8, 0xE5, 0xC2, 0xDF, 0x8C, 0x91, 0xB6, 0xAB, 0x10, 0x0D, 0x2A, 0x37, 0x64, 0x79, 0x5E, 0x43,
|
||
0xB2, 0xAF, 0x88, 0x95, 0xC6, 0xDB, 0xFC, 0xE1, 0x5A, 0x47, 0x60, 0x7D, 0x2E, 0x33, 0x14, 0x09,
|
||
0x7F, 0x62, 0x45, 0x58, 0x0B, 0x16, 0x31, 0x2C, 0x97, 0x8A, 0xAD, 0xB0, 0xE3, 0xFE, 0xD9, 0xC4
|
||
}
|
||
};
|
||
|
||
#else
|
||
|
||
MEMORY_MAP_RAM_FOR_ASIL ENABLE_STATIC_FOR_ASIL u8 crc8_table[CRC8_ID_MAX][256] = {0u};
|
||
|
||
#endif
|
||
|
||
typedef struct
|
||
{
|
||
u8 width;
|
||
u8 poly;
|
||
u8 init;
|
||
u8 refin;
|
||
u8 refout;
|
||
u8 xorout;
|
||
}crc8_info_s;
|
||
|
||
MEMORY_MAP_RAM_FOR_ASIL ENABLE_STATIC_FOR_ASIL crc8_info_s crc_struct[CRC8_ID_MAX] =
|
||
{
|
||
{8, CRC8_L1_POLY_VALUE, CRC8_L1_INIT_VALUE, 0, 0, CRC8_L1_XOR_VALUE}, //CRC8_SAE J1850
|
||
{8, CRC8_L2_POLY_VALUE, CRC8_L2_INIT_VALUE, 0, 0, CRC8_L2_XOR_VALUE}, //CRC8_SAE J1850
|
||
};
|
||
|
||
|
||
//位逆转
|
||
MEMORY_MAP_ROM_FOR_ASIL u8 crc8_reflected(u8 input_value, u8 bits)
|
||
{
|
||
u8 var = 0u;
|
||
u8 l_bits = bits;
|
||
while(l_bits)
|
||
{
|
||
l_bits -= 1u;
|
||
var <<= 1;
|
||
if (input_value & 0x01u)
|
||
{
|
||
var |= 1u;
|
||
}
|
||
input_value >>= 1u;
|
||
}
|
||
return var;
|
||
}
|
||
|
||
MEMORY_MAP_ROM_FOR_ASIL void crc8_table_init(u8 id) /*PRQA S 3206*/ /*CRC_TABLE_IS_CONST开着引起的*/
|
||
{
|
||
#ifdef CRC_TABLE_IS_CONST
|
||
|
||
#else
|
||
|
||
u16 i;
|
||
u8 j;
|
||
u8 poly, value;
|
||
u8 valid_bits;
|
||
u8 l_bit ;
|
||
|
||
if(id<CRC8_ID_MAX)
|
||
{
|
||
valid_bits = (2u << (crc_struct[id].width - 1u)) - 1u;
|
||
//逆序LSB输入
|
||
if (crc_struct[id].refin)
|
||
{
|
||
//poly 以及init 都要先逆序, crc8_table 的 init = 0;
|
||
poly = crc8_reflected(crc_struct[id].poly, crc_struct[id].width);
|
||
|
||
for (i = 0u; i < 256u; i++)
|
||
{
|
||
value = i;
|
||
for (j = 0u; j < 8u; j++)
|
||
{
|
||
if (value & 1u)
|
||
{
|
||
value = (value >> 1u) ^ poly;
|
||
}
|
||
else
|
||
{
|
||
value = (value >> 1u);
|
||
}
|
||
}
|
||
crc8_table[id][i] = value & valid_bits;
|
||
}
|
||
}
|
||
//正序MSB输入
|
||
else
|
||
{
|
||
//如果位数小于8,poly要左移到最高位
|
||
poly = crc_struct[id].width < 8u ? crc_struct[id].poly << (8u - crc_struct[id].width) : crc_struct[id].poly;
|
||
l_bit = crc_struct[id].width > 8u ? CRC8_BIT(crc_struct[id].width - 1u) : 0x80u;
|
||
|
||
for (i = 0u; i < 256u; i++)
|
||
{
|
||
value = crc_struct[id].width > 8u ? i << (crc_struct[id].width - 8u) : i;
|
||
for (j = 0u; j < 8u; j++)
|
||
{
|
||
if (value & l_bit)
|
||
{
|
||
value = (value << 1) ^ poly;
|
||
}
|
||
else
|
||
{
|
||
value = (value << 1);
|
||
}
|
||
}
|
||
//如果width < 8,那么实际上,crc是在高width位的,需要右移 8 - width
|
||
//但是为了方便后续异或(还是要移位到最高位与*ptr的bit7对齐),所以不处理
|
||
// if (info->width < 8)
|
||
// value >>= 8 - info->width;
|
||
// crc8_table[id][i] = value & (2 << (info->width - 1)) - 1);
|
||
|
||
[id][i] = value & (crc_struct[id].width < 8u ? 0xff : valid_bits);
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
|
||
|
||
|
||
MEMORY_MAP_ROM_FOR_ASIL u8 crc8_table_set_init_value(u8 id,u8 value)
|
||
{
|
||
if(id<CRC8_ID_MAX)
|
||
{
|
||
crc_struct[id].init = value;
|
||
}
|
||
return 1u;
|
||
}
|
||
|
||
MEMORY_MAP_ROM_FOR_ASIL u8 crc8_make_by_table(u8 id,u8 *p_data,u8 len)
|
||
{
|
||
//正序
|
||
u8 crc8=0u;
|
||
u8 i;
|
||
if(id<CRC8_ID_MAX)
|
||
{
|
||
crc8 = crc_struct[id].init;
|
||
for(i=0u; i<len;i++)
|
||
{
|
||
crc8 = crc8_table[id][crc8^*p_data];
|
||
p_data++;
|
||
}
|
||
crc8 ^= crc_struct[id].xorout;
|
||
}
|
||
return(crc8);
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
#endif
|
||
|
||
|
||
MEMORY_MAP_ROM_FOR_ASIL u8 crc_8_make_l1(u8 *u8_data,u8 u8_len)
|
||
{
|
||
u8 i, j;
|
||
u8 u8_crc8;
|
||
u8 u8_poly;
|
||
|
||
u8_crc8 = CRC8_L1_INIT_VALUE;
|
||
u8_poly = CRC8_L1_POLY_VALUE;
|
||
|
||
for (i = 0; i < u8_len; i++)
|
||
{
|
||
u8_crc8 ^= u8_data[i];
|
||
|
||
for (j = 0u; j < 8u; j++)
|
||
{
|
||
if (u8_crc8 & 0x80u)
|
||
{
|
||
u8_crc8 = (u8)(u8_crc8 << 1) ^ u8_poly; /*PRQA S 4571*/
|
||
}
|
||
else
|
||
{
|
||
u8_crc8 <<= 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
u8_crc8 ^= (u8)CRC8_L1_XOR_VALUE;
|
||
return u8_crc8;
|
||
|
||
}
|
||
|
||
|
||
MEMORY_MAP_ROM_FOR_ASIL u8 crc_8_make_l2(u8 *u8_data,u8 u8_len)
|
||
{
|
||
u8 i, j;
|
||
u8 u8_crc8;
|
||
u8 u8_poly;
|
||
|
||
u8_crc8 = CRC8_L2_INIT_VALUE;
|
||
u8_poly = CRC8_L2_POLY_VALUE;
|
||
|
||
for (i = 0; i < u8_len; i++)
|
||
{
|
||
u8_crc8 ^= u8_data[i];
|
||
|
||
for (j = 0u; j < 8u; j++)
|
||
{
|
||
if (u8_crc8 & 0x80u)
|
||
{
|
||
u8_crc8 = (u8)(u8_crc8 << 1) ^ u8_poly; /*PRQA S 4571*/
|
||
}
|
||
else
|
||
{
|
||
u8_crc8 <<= 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
u8_crc8 ^= (u8)CRC8_L2_XOR_VALUE; /*PRQA S 2985*/
|
||
return u8_crc8;
|
||
|
||
}
|
||
|
||
|
||
/*
|
||
举例: 00 00 00 00 结果为0X59
|
||
|
||
ff ff ff ff 结果为0X74
|
||
|
||
F2 01 83 结果为 0X37
|
||
*/
|
||
u8 crc_8_for_sa3f(u8 *p_data,u8 len)
|
||
{
|
||
u8 i;
|
||
u8 l_result=0u;
|
||
for(i=0;i<len;i++)
|
||
{
|
||
l_result += p_data[i];
|
||
}
|
||
l_result = l_result^0xffu;
|
||
return l_result;
|
||
}
|
||
#ifdef ASIL_EN
|
||
|
||
#define CRC_L1_CHECKSUM_CHECK 0xb4u
|
||
#define CRC_L2_CHECKSUM_CHECK 0x5du
|
||
u8 g_crc_check[4] = {0u};
|
||
void crc_init(void)
|
||
{
|
||
u8 i;
|
||
u8 l_buf[8];
|
||
u8 l_checksum[2];
|
||
//检验CRC的结果是否正确
|
||
#ifdef CRC_USE_TABLE
|
||
crc8_table_init(CRC8_ID_FOR_E2E_L1);
|
||
crc8_table_init(CRC8_ID_FOR_E2E_L2);
|
||
#endif
|
||
|
||
for(i = 0u; i < 8u; i++)
|
||
{
|
||
/* code */
|
||
l_buf[i] = 0x01u+i;
|
||
}
|
||
|
||
#ifdef CRC_USE_TABLE
|
||
l_checksum[0] = crc8_make_by_table(CRC8_ID_FOR_E2E_L1,&l_buf[0],8u);
|
||
l_checksum[1] = crc8_make_by_table(CRC8_ID_FOR_E2E_L2,&l_buf[0],8u);
|
||
#else
|
||
l_checksum[0] = crc_8_make_l1(&l_buf[0],8u);
|
||
l_checksum[1] = crc_8_make_l2(&l_buf[0],8u);
|
||
#endif
|
||
|
||
if(l_checksum[0]==CRC_L1_CHECKSUM_CHECK)
|
||
{
|
||
g_crc_check[0]++;
|
||
}
|
||
else
|
||
{
|
||
g_crc_check[1]++;
|
||
}
|
||
|
||
if(l_checksum[1]==CRC_L2_CHECKSUM_CHECK)
|
||
{
|
||
g_crc_check[2]++;
|
||
}
|
||
else
|
||
{
|
||
g_crc_check[3]++;
|
||
}
|
||
}
|
||
|
||
|
||
#endif
|
||
/*END LINE*/
|