How to derive CRC polynomial ?

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

How to derive CRC polynomial ?

跳至解决方案
10,852 次查看
s32k146_ige
Contributor IV

How do i calculate the polynomial for CRC? i am looking to use CRC feature, i have existing code and polynomial expression but dont know how to convert to polynomial value required for CRC peripheral

here is following CRC related functions and expression

// ITU_T polynomial: x^16 + x^15 + x^2 + 1
uint16 CRC16(BYTE *pBuf, int nLen) {
wCRC2 = 0xFFFF;
//printConsole("CRCOUT = \t");
for (crc16_i = 0; crc16_i < nLen; crc16_i++) {
//printConsole("%02x ",*pBuf);
wCRC2 ^= (*pBuf++) & 0x00FF;
wCRC2 = crc16_table[wCRC2 & 0x00FF] ^ (wCRC2 >> 8);
    }
//printConsole("\n\r");

return wCRC2;
}
 
 
标记 (1)
0 项奖励
回复
1 解答
10,676 次查看
VaneB
NXP TechSupport
NXP TechSupport

Hi @s32k146_ige 

I am going to explain the theory of the CRC-16-MODBUS algorithm.

For example, if your input data is 01 10 C0 03 00 01 and this algorithm has an initial value that is not zero and has RefIn and RefOut as true.

To compute the CRC-16-MODBUS on your data, you exclusive the first 16 bits of your data and make an OR with the Init value = 0xFFFF. That gives FE EF C0 03 00 01.Now you apply the init value.

The next step is dealing with RefIn and RefOut as true. RefIn means that we reflect the bits in each byte of input. RefOut means that we reflect the bits in bytes and bytes of the remainder. The input message is then: 7F F7 03 C0 00 80. Divide by the polynomial and you get the remainder 0xB393. Reflect those bits in bytes and bytes and we get 0xC9CD.

You can verify the provided result with this CRC calculator.

在原帖中查看解决方案

9 回复数
10,836 次查看
VaneB
NXP TechSupport
NXP TechSupport

Hi @s32k146_ige 

As you know the CRC Polynomial register (GPOLY) is a 32-bit register witch receives the desired polynomial.

If for example, you want to use x^16 + x^15 + x^2 + 1 as you mention the power to which x is raised will be the position where you will set the bit to 1. In this case, the polynomial would be 0001 1000 0000 0000 0101 = 0x018005.

Please let me know if this clarifies your doubt.

 

B.R.

VaneB

0 项奖励
回复
10,824 次查看
s32k146_ige
Contributor IV

little deep dive from my end it showed the CRC is similar for MODBUS CRC calculation,

so i set the crc setting as follows,

/*! @brief Configuration structure crc1_InitConfig0 */
const crc_user_config_t crc1_InitConfig0 = {
.crcWidth = CRC_BITS_16,
.seed = 0xFFFFU,
.polynomial = 0x8005U,
.writeTranspose = CRC_TRANSPOSE_NONE,
.readTranspose = CRC_TRANSPOSE_NONE,
.complementChecksum = false
};

following is data byte, 0x80, 0x00, 0x02, 0x15, 0x0b and expected CRC value is 0xCB49

but some how i am unable to get this CRC result using crc peripheral

can you help?

0 项奖励
回复
10,818 次查看
VaneB
NXP TechSupport
NXP TechSupport

Hi @s32k146_ige 

Just to ensure, did you change the polynomial value at the crc_Cfg0 struct?

It needs to be as the following:

const crc_user_config_t crc_Cfg0 = {
.crcWidth = CRC_BITS_16,
.readTranspose = CRC_TRANSPOSE_NONE,
.writeTranspose = CRC_TRANSPOSE_NONE,
.complementChecksum = false,
.polynomial = 32773UL,
.seed = 65535UL
};
0 项奖励
回复
10,798 次查看
s32k146_ige
Contributor IV

This doesnt work its the same config that i have shared

0 项奖励
回复
10,751 次查看
VaneB
NXP TechSupport
NXP TechSupport

Hi @s32k146_ige 

With the configurations, you made it is not possible to obtain the desired result, it is necessary to take the necessary considerations depending on the algorithm you want to use.

The CRC module provides several types of transpose functions to flip the bits and/or bytes, for both writing input data and reading the CRC result. This feature significantly impacts the results that can be obtained.

Could you tell me how you calculated the desired result so that I can help you if it is possible to obtain it with the CRC example?

0 项奖励
回复
10,728 次查看
s32k146_ige
Contributor IV

Its MODBUS CRC

following is the available code

// CRC16 TABLE
// ITU_T polynomial: x^16 + x^15 + x^2 + 1
const uint16 crc16_table[256] = { 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301,
		0x03C0, 0x0280, 0xC241, 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1,
		0xC481, 0x0440, 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81,
		0x0E40, 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841,
		0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 0x1E00,
		0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 0x1400, 0xD4C1,
		0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 0xD201, 0x12C0, 0x1380,
		0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 0xF001, 0x30C0, 0x3180, 0xF141,
		0x3300, 0xF3C1, 0xF281, 0x3240, 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501,
		0x35C0, 0x3480, 0xF441, 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0,
		0x3E80, 0xFE41, 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881,
		0x3840, 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41,
		0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 0xE401,
		0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 0x2200, 0xE2C1,
		0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 0xA001, 0x60C0, 0x6180,
		0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 0x6600, 0xA6C1, 0xA781, 0x6740,
		0xA501, 0x65C0, 0x6480, 0xA441, 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01,
		0x6FC0, 0x6E80, 0xAE41, 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1,
		0xA881, 0x6840, 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80,
		0xBA41, 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40,
		0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 0x7200,
		0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 0x5000, 0x90C1,
		0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 0x9601, 0x56C0, 0x5780,
		0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 0x9C01, 0x5CC0, 0x5D80, 0x9D41,
		0x5F00, 0x9FC1, 0x9E81, 0x5E40, 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901,
		0x59C0, 0x5880, 0x9841, 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1,
		0x8A81, 0x4A40, 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80,
		0x8C41, 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641,
		0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 };

uint16 CRC16(BYTE *pBuf, int nLen) {
    wCRC2 = 0xFFFF;
    //printConsole("CRCOUT = \t");
    for (crc16_i = 0; crc16_i < nLen; crc16_i++) {
        //printConsole("%02x ",*pBuf);
        wCRC2 ^= (*pBuf++) & 0x00FF;
        wCRC2 = crc16_table[wCRC2 & 0x00FF] ^ (wCRC2 >> 8);
    }
    //printConsole("\n\r");

    return wCRC2;
}
0 项奖励
回复
10,677 次查看
VaneB
NXP TechSupport
NXP TechSupport

Hi @s32k146_ige 

I am going to explain the theory of the CRC-16-MODBUS algorithm.

For example, if your input data is 01 10 C0 03 00 01 and this algorithm has an initial value that is not zero and has RefIn and RefOut as true.

To compute the CRC-16-MODBUS on your data, you exclusive the first 16 bits of your data and make an OR with the Init value = 0xFFFF. That gives FE EF C0 03 00 01.Now you apply the init value.

The next step is dealing with RefIn and RefOut as true. RefIn means that we reflect the bits in each byte of input. RefOut means that we reflect the bits in bytes and bytes of the remainder. The input message is then: 7F F7 03 C0 00 80. Divide by the polynomial and you get the remainder 0xB393. Reflect those bits in bytes and bytes and we get 0xC9CD.

You can verify the provided result with this CRC calculator.

10,648 次查看
s32k146_ige
Contributor IV

Thanks for making this understand it properly, so i got the output with following config,

 

const crc_user_config_t crc1_InitConfig0 = {
    .crcWidth = CRC_BITS_16,
    .seed = 0xFFFFU,
    .polynomial = 0x8005U,
    .writeTranspose = CRC_TRANSPOSE_BITS,
    .readTranspose = CRC_TRANSPOSE_BITS,
    .complementChecksum = false
};

 

 

标记 (3)
0 项奖励
回复
10,826 次查看
s32k146_ige
Contributor IV
i am getting error Value is above admissible range
0 项奖励
回复