2025-06-20 4:30 AM
Hi,
I am trying to use the STM32H5 CRC unit via HAL to calculate a CRC32 (ISO-HDLC) over multiple chunks.
This works correctly via:
hcrc.Instance = CRC;
hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE;
hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE;
hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTE;
hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE;
hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
if (HAL_CRC_Init(&hcrc) != HAL_OK)
{
Error_Handler();
}
// calculate CRC32 over two identical chunks, HCRC keeps state!
temp = HAL_CRC_Calculate(&hcrc, (uint32_t *)data, strlen(data)); // 0x444a273c
crc = ~temp; // 0xbbb5d8c3 OK
temp = HAL_CRC_Accumulate(&hcrc, (uint32_t *)data, strlen(data)); // 0x405e36b1
crc = ~temp; // 0xbfa1c94e OK
Now I need to do something similiar as in https://community.st.com/t5/stm32-mcus-products/hal-function-crc-accumulate-re-init-and-calculate/td-p/672395: the CRC unit is shared for different things and I need to reinitialize it between the chunks. Where is the missed trick in that solution?
hcrc.Instance->INIT = 0xffffffff;
temp = HAL_CRC_Calculate(&hcrc, (uint32_t *)data, strlen(data)); // 0x444a273c
crc = ~temp; // 0xbbb5d8c3 OK
// ...
// restart with former DR register content
hcrc.Instance->INIT = temp;
temp = HAL_CRC_Calculate(&hcrc, (uint32_t *)data, strlen(data)); // 0x3ce52cc3 unexpected!
crc = ~temp; // 0xc31ad33c
For the 2nd chunk I do not invert the prior result. What am I missing? I want both code snippets to give the same results.
This is my reference:
import crcmod
# Create CRC function with HDLC parameters
crc32_hdlc = crcmod.mkCrcFun(0x104C11DB7, initCrc=0, rev=True, xorOut=0xFFFFFFFF)
crc = crc32_hdlc(chunk)
print(f"CRC32/HDLC: {crc:08X}")
crc = crc32_hdlc(chunk,crc)
print(f"CRC32/HDLC: {crc:08X}")
#Prints:
#CRC32/HDLC: BBB5D8C3
#CRC32/HDLC: BFA1C94E
Thanks!
Matthias
2025-06-20 5:01 AM
How's "data" defined? Provide complete test patterns
Initialized as 0x00000000 or 0xFFFFFFFF
Might need to bit reverse, not invert, to push in intermediate context.
2025-06-20 10:01 AM
And if you avoid Cube/HAL? Using the CRC unit at register level is easy, just mind the endianness and written data width. For a few-words experiment, doing it entirely in debugger with no code is sufficient and fun.
JW