Skip to main content
Graduate
May 9, 2024
Solved

HAL Function CRC Accumulate != Re-Init and Calculate

  • May 9, 2024
  • 3 replies
  • 2899 views

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?

    This topic has been closed for replies.
    Best answer by EXUE.2

    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.

    3 replies

    Graduate II
    May 10, 2024

    Show the configuration and test patterns. Outputs and Expectations

    Any reversal settings will likely break your second method

    EXUE.2Answer
    ST Employee
    May 10, 2024

    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.

    astral256Author
    Graduate
    May 10, 2024

    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;