Skip to main content
RPG
Associate III
June 14, 2022
Solved

CRC8 with HAL for Stm32 and Python

  • June 14, 2022
  • 7 replies
  • 5407 views

I am quite new with embedded programming. I must implement CRC8 with HAL and have tried to implement the CRC8 in python at the other end. Have used the crc8 library but both results don’t match. Is there anybody who could give me a hand to implement it correctly?

This topic has been closed for replies.
Best answer by Tesla DeLorean

uint32_t data[5] = { 0x28, 0x4f, 0x4c, 0x43, 0x29 };

I'd expect the STM32 to return 0x97

Being fed bytes, this is then a byte count

uint8_t data[5] = { 0x28, 0x4f, 0x4c, 0x43, 0x29 };

uint8_t crc = HAL_CRC_Calculate(&hcrc, (void *)data, 5);

I'd expect the STM32 to return 0xF3 (0xCA if the initialization is 0xFF)

7 replies

waclawek.jan
Super User
June 14, 2022

Wh​ich STM32? What are the details of CRC? Show the Python code and example data+result.

JW​

RPG
RPGAuthor
Associate III
June 14, 2022

The MCU is STM32G474RB

This is the STM32 code:

/* CRC init function */

void MX_CRC_Init(void)

{

 /* USER CODE BEGIN CRC_Init 0 */

 /* USER CODE END CRC_Init 0 */

 /* USER CODE BEGIN CRC_Init 1 */

 /* USER CODE END CRC_Init 1 */

 hcrc.Instance = CRC;

 hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE;

 hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE;

 hcrc.Init.GeneratingPolynomial = 7;

 hcrc.Init.CRCLength = CRC_POLYLENGTH_8B;

 hcrc.Init.InitValue = 0;

 hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;

 hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;

 hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;

 if (HAL_CRC_Init(&hcrc) != HAL_OK)

 {

  Error_Handler();

 }

 /* USER CODE BEGIN CRC_Init 2 */

 /* USER CODE END CRC_Init 2 */

}

  MX_CRC_Init();

 /* USER CODE BEGIN 2 */

  uint32_t data[5] = { 0x28, 0x4f, 0x4c, 0x43, 0x29 };

  uint8_t crc = HAL_CRC_Calculate(&hcrc, data, 5);

  if (config_ethernet_enable) {

HAL_UART_MspDeInit(&huart1);

}

This is the Python code:

import crc8

...

data = bytes(message, 'UTF-8')

checksum = calculateCRC8(data)

...

def calculateCRC8(data):

  hash = crc8.crc8()

  hash.update(data)

  digest = hash.digest()

  digestInt = int.from_bytes(digest, "big", signed=False)

  if DEBUG:

    print('CRC8: ' + str(digestInt))

    print('CRC8: ' + str(hash.hexdigest()))

  return digestInt

The results from Python and STM32 codes are different. From Python 0xF3 (243) and from STM32 code 0x97 (151).

Thanks for the help.

RPG
RPGAuthor
Associate III
June 14, 2022

Using another library called crcmod in Python I get the same result as with crc8:

import crcmod

....

data = bytes(message, 'UTF-8')

checksum = calculateCRC8(data)

....

def calculateCRC8(data):

  crc8 = crcmod.Crc(0x107,initCrc=0,rev=False,xorOut=0)

  crc8.update(data)

  if DEBUG:

    print('CRC8: ' + str(crc8.crcValue))

    print('CRC8: ' + str(crc8.hexdigest()))

   

  return crc8.crcValue

#  

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
June 14, 2022

uint32_t data[5] = { 0x28, 0x4f, 0x4c, 0x43, 0x29 };

I'd expect the STM32 to return 0x97

Being fed bytes, this is then a byte count

uint8_t data[5] = { 0x28, 0x4f, 0x4c, 0x43, 0x29 };

uint8_t crc = HAL_CRC_Calculate(&hcrc, (void *)data, 5);

I'd expect the STM32 to return 0xF3 (0xCA if the initialization is 0xFF)

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
RPG
RPGAuthor
Associate III
June 14, 2022

OK! Now it works! Thank you very much for pointing out :)

But I read that the API expects a uint32_t pointer as input buffer parameter here:

/**

 * @brief Compute the 7, 8, 16 or 32-bit CRC value of an 8, 16 or 32-bit data buffer

 *     starting with hcrc->Instance->INIT as initialization value.

 * @param hcrc CRC handle

 * @param pBuffer pointer to the input data buffer, exact input data format is

 *     provided by hcrc->InputDataFormat.

 * @param BufferLength input data buffer length (number of bytes if pBuffer

 *     type is * uint8_t, number of half-words if pBuffer type is * uint16_t,

 *     number of words if pBuffer type is * uint32_t).

 * @note By default, the API expects a uint32_t pointer as input buffer parameter. <----------------------

 *    Input buffer pointers with other types simply need to be cast in uint32_t. <----------------------

 *    and the API will internally adjust its input data processing based on the <----------------------

 *    handle field hcrc->InputDataFormat. <----------------------

 * @retval uint32_t CRC (returned value LSBs for CRC shorter than 32 bits)

 */

uint32_t HAL_CRC_Calculate(CRC_HandleTypeDef *hcrc, uint32_t pBuffer[], uint32_t BufferLength)

Tesla DeLorean
Guru
June 14, 2022

Sure, they want a suitably aligned pointer for efficiency, and so the CM0 implementations don't hard fault, but in other situations, where you're InputDataFormat says you're consuming and counting bytes, you're likely to want the data in those forms, and cast the pointer to keep the compiler from complaining.

ST could have perhaps executed this better, but the didn't

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
RPG
RPGAuthor
Associate III
June 15, 2022

I am trying to setup this configuration with HAL, CRC-8 CCITT but the polynomial X8 + X2 + X + 1 cannot be inserted into the Generating Polynomial textfield because a, b and c (Xa+Xb+Xc) cannot be greater than 7. Is there a way to do it?

Thanks in advance.

0693W00000NrvRHQAZ.png

waclawek.jan
Super User
June 14, 2022

Nice catch, Tesla! :)

JW

waclawek.jan
Super User
June 15, 2022

> I am trying to setup this configuration with HAL, CRC-8 CCITT but the polynomial X8 + X2 + X + 1

> cannot be inserted into the Generating Polynomial textfield because a, b and c (Xa+Xb+Xc) cannot be greater than 7. Is there a way to do it?

Confusingly, there are several "standards" how CRC poly is written. The most commonly used of them omits the x^N term, as that's implicit, so your poly should be set as 0x07 (x^2+x^1+x^0).

Or just ditch Cube/CubeMX and write your own code.

JW

RPG
RPGAuthor
Associate III
June 15, 2022

Ok thank you for the reply. Now it makes more sense :)