AnsweredAssumed Answered

STM32F07x CRC-16 MODBUS HAL Configuration

Question asked by botha.antonie on Jan 27, 2017
Latest reply on Jan 30, 2017 by Clive One

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 0x8180. On-line CRC calculation and free library 

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

Software Call: 

uwCRCValue = CRC16_2(commsBuffer, 0x02);

 

Peripheral Call:

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

 

The Software Implementation 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?

Outcomes