cancel
Showing results for 
Search instead for 
Did you mean: 

HAL Function CRC Accumulate != Re-Init and Calculate

astral256
Associate II

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?

1 ACCEPTED SOLUTION

Accepted Solutions
EXUE.2
ST Employee

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.

View solution in original post

3 REPLIES 3

Show the configuration and test patterns. Outputs and Expectations

Any reversal settings will likely break your second method

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
EXUE.2
ST Employee

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.

astral256
Associate II

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;