2018-03-20 02:15 AM
Hello,
I am trying to calculate crc32 on stm32f769NI MCU and found that the generated crc doesn't match the standard crc32 algorithm with 0x4C11DB7 as the polynomial and 0xFFFFFFFF as the initial value.
I am using this link(
http://www.sunshine2k.de/coding/javascript/crc/crc_js.html
) to compare the crc obtained from stm.I have configured the board as below.
CRC_HandleTypeDef hcrc;
__HAL_RCC_CRC_CLK_ENABLE(); hcrc.Instance = CRC; hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_ENABLE; hcrc.Init.CRCLength= CRC_POLYLENGTH_32B; hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE; hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE; hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE; hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES; HAL_CRC_Init(&hcrc);I am calculating crc on a test buffer as below
uint32_t test[] ={49,50,51,52};
CRCValue = HAL_CRC_Calculate(&hcrc,(uint32_t *)test, 4);Please let me know if something is wrong or should I add something.
Any help is appreciated.
Thanks
2018-03-20 06:50 AM
>>I am trying to calculate crc32 on stm32f769NI MCU and found that the generated crc doesn't match the standard crc32 algorithm with 0x4C11DB7 as the polynomial and 0xFFFFFFFF as the initial value.
Thing is CRC's are dependent on the polynomial and shift direction of the register itself and how the data is presented both in bit, byte or word form. Get any of these different, and different numbers will drop out of your 'standard'. The STM32 CRC unit uses an endian ordering that is backward compared the way the ARM core manages the words.
The problem with on-line solutions is that you have no insight to how any of this works.
You are passing the HAL_CRC_Calculate() 16 bytes, is that what you're doing to the website?
What parameters are you providing the website?
What is your test pattern?
What is the value is supposed to come out?
Have you worked this from first-principles, or just stuffed numbers in an online calculator?
What value comes out?
2018-04-23 12:18 PM
The standard (read most common) CRC32 implementation includes reflecting both input and output (the two check boxes on Sunshine's page). For the STM32 that is implemented by :
hcrc
.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_BYTES;hcrc
.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE;You must also manually invert the output (Final XOR value of 0xFFFFFFFF) by looking at (~
CRCValue
) because the hardware and HAL do not implement a final XOR.
As Clive One mentioned, you are passing words rather than bytes which may be an issue. The CRC will calculate over 4 bytes rather than all 16 if that is what you intended. Keep in mind that if you switch from bytes to words in InputDataFormat then the size parameter of 4 is now 4 words rather than 4 bytes.
I suspect that what you may have wanted is:
uint8_t test[] ={49,50,51,52};
That should get you there, but note that if you use CRC_INPUTDATA_FORMAT_WORDS you will also need to change the input mode to CRC_INPUTDATA_INVERSION_WORD.