cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F07x CRC-16 MODBUS HAL Configuration

abotha
Associate III
Posted on January 27, 2017 at 08:25

I am trying to use the hardware peripheral on the STM32F072 to calculate a 16-bit CRC for a modbus RTU application.

The hardware peripheral offers twice the speed compared to my software implementation. I am getting the incorrect CRC back and cannot figure out where I am doing what wrong.

/* USER CODE BEGIN 0 */
#define MODBUS_CRC_POLY 0xA001
/* USER CODE END 0 */
CRC_HandleTypeDef hcrc;
/* CRC init function */
void MX_CRC_Init(void)
{
 hcrc.Instance = CRC;
 hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE;
 hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE;
 hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
 hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
hcrc.Init.GeneratingPolynomial = MODBUS_CRC_POLY;
hcrc.Init.CRCLength = CRC_POLYLENGTH_16B;
hcrc.Init.InitValue = 0xFFFF;
 hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
 if (HAL_CRC_Init(&hcrc) != HAL_OK)
 {
 Error_Handler();
 }
}
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

The buffer that holds the comms from Uart:

 unsigned char commsBuffer[150]; �?

If I send two bytes, 0x03 and 0x02 I expect a CRC of 0x8

https://www.lammertbies.nl/comm/info/crc-calculation.html

I get this CRC when I run it through the software implementation, from the hardware peripheral I get 0x9

Software Call:

uwCRCValue = CRC16_2(commsBuffer, 0x02);�?

Peripheral Call:

uwCRCValue = HAL_CRC_Calculate(&hcrc, (uint32_t *)&commsBuffer, 0x02);�?

The SoftwareImplementation function was from this forum:

unsigned int CRC16_2(unsigned char *buf, int len)
 { 
 unsigned int crc = 0xFFFF;
 for (int pos = 0; pos < len; pos++)
 {
 crc ^= (unsigned int)buf[pos]; // XOR byte into least sig. byte of crc
for (int i = 8; i != 0; i--) { // Loop over each bit
 if ((crc & 0x0001) != 0) { // If the LSB is set
 crc >>= 1; // Shift right and XOR 0xA001
 crc ^= 0xA001;
 }
 else // Else LSB is not set
 crc >>= 1; // Just shift right
 }
 }
return crc;
 }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

Can anyone spot what I am doing wrong please?

#crc #rtu #crc-16 #modbus
1 ACCEPTED SOLUTION

Accepted Solutions
Guenael Cadier
ST Employee

Posted on January 27, 2017 at 18:46

Hi

Botha.Antonie

,

Differences might exist in CRC computations provided by different online calculators, depending on implementation, endianess management, final xor, ...

For CRC16 modbus computation, some are using : 0x8005 polynomial (reversal of 0xA001), input reversed, output reversed.

Could you check if applying below modifications in your HAL CRC configuration, helps reaching expected values ?

&sharpdefine MODBUS_CRC_POLY 0x8005 
hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE; >hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE; 

View solution in original post

3 REPLIES 3
Guenael Cadier
ST Employee

Posted on January 27, 2017 at 18:46

Hi

Botha.Antonie

,

Differences might exist in CRC computations provided by different online calculators, depending on implementation, endianess management, final xor, ...

For CRC16 modbus computation, some are using : 0x8005 polynomial (reversal of 0xA001), input reversed, output reversed.

Could you check if applying below modifications in your HAL CRC configuration, helps reaching expected values ?

&sharpdefine MODBUS_CRC_POLY 0x8005 
hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE; >hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE; 

Posted on January 30, 2017 at 07:22

Thank you very much, this solves my incorrect output! Appreciated - very much.

Posted on January 30, 2017 at 14:44

Your software method is the least efficient one, there are faster software methods.

https://community.st.com/0D50X00009XkgXtSAJ

 

Watch for thread-safe implementations using hardware.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..