2024-05-09 04:22 PM
I have gotten the following code to correctly validate CRC's, so I know I have configured the CRC correctly:
uint32_t calcCRC = 0;
hcrc.Instance->INIT = 0xFFFFFFFF;
calcCRC = HAL_CRC_Calculate(&hcrc, (uint32_t*) pointer, length);
calcCRC = HAL_CRC_Accumulate(&hcrc, (uint32_t*) pointer2, length2);
calcCRC = calcCRC ^ 0xFFFFFFFF;
However, if I were to run the same exact computation except replacing the accumulate with two separate calculates and resetting the INIT to the previous CRC result, I am unable to validate CRC's:
uint32_t calcCRC = 0;
hcrc.Instance->INIT = 0xFFFFFFFF;
calcCRC = HAL_CRC_Calculate(&hcrc, (uint32_t*) pointer, length);
hcrc.Instance->INIT = calcCRC;
calcCRC = HAL_CRC_Calculate(&hcrc, (uint32_t*) pointer2, length2);
calcCRC = calcCRC ^ 0xFFFFFFFF;
I would like to re-initialize the STM32CRC with the output of the previous CRC calculation and pick up where I left off. Unfortunately, I am unable to validate CRC's using this method of re-initialize and calculate. How can I get it to work like this? Am I fundamentally misunderstanding how the Calculate/Accumulate functions work in the HAL?
Solved! Go to Solution.
2024-05-10 01:30 AM
1. I also think it is caused by the inverted configuration as below 2 parameters:
/* The input data are not inverted */
CrcHandle.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
/* The output data are not inverted */
CrcHandle.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
2. the difference of HAL_CRC_Accumulate() and HAL_CRC_Calculate() is that there add one more function in HAL_CRC_Calculate() as below:
/* Reset CRC Calculation Unit (hcrc->Instance->INIT is
* written in hcrc->Instance->DR) */
__HAL_CRC_DR_RESET(hcrc);
so if your inverted configurations are disabled, it should work.
2024-05-09 05:13 PM
Show the configuration and test patterns. Outputs and Expectations
Any reversal settings will likely break your second method
2024-05-10 01:30 AM
1. I also think it is caused by the inverted configuration as below 2 parameters:
/* The input data are not inverted */
CrcHandle.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
/* The output data are not inverted */
CrcHandle.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
2. the difference of HAL_CRC_Accumulate() and HAL_CRC_Calculate() is that there add one more function in HAL_CRC_Calculate() as below:
/* Reset CRC Calculation Unit (hcrc->Instance->INIT is
* written in hcrc->Instance->DR) */
__HAL_CRC_DR_RESET(hcrc);
so if your inverted configurations are disabled, it should work.
2024-05-10 11:59 AM
You were both correct, it has to do with output inversion. Eliminating the inversion prevented me from validating the CRC without also changing the CRC algorithm on the host device, so instead I can invert the output of the first calculate before feeding it back into the INIT register. Thank you so much for the speedy reply and the accurate help!
uint32_t calcCRC = 0;
hcrc.Instance->INIT = 0xFFFFFFFF;
calcCRC = HAL_CRC_Calculate(&hcrc, (uint32_t*) pointer, length);
PLACEHOLDER_INVERTING_FUNCTION(&calcCRC)
hcrc.Instance->INIT = calcCRC;
calcCRC = HAL_CRC_Calculate(&hcrc, (uint32_t*) pointer2, length2);
calcCRC = calcCRC ^ 0xFFFFFFFF;