2022-06-13 09:15 PM
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?
Solved! Go to Solution.
2022-06-14 06:30 AM
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)
2022-06-13 11:18 PM
Which STM32? What are the details of CRC? Show the Python code and example data+result.
JW
2022-06-14 12:52 AM
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.
2022-06-14 05:54 AM
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
#
2022-06-14 06:30 AM
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)
2022-06-14 06:37 AM
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)
2022-06-14 09:15 AM
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
2022-06-14 01:48 PM
Nice catch, Tesla! :)
JW
2022-06-15 03:28 AM
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.
2022-06-15 06:08 AM
> 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