2025-04-26 16:03:23 +08:00

355 lines
8.7 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
******************************************************************************
* @file
* @author
* @version
* @date
* @brief
* @function List:
******************************************************************************
* @attention
*
*
* <h2><center>&copy; 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
{
//如果位数小于8poly要左移到最高位
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*/