2020-10-07 11:40 PM
I am experimenting with CRC Calculation on a STM32F4-Discovery.
As I have seen in the reference manual this MCU is using CRC-32 used in Ethernet. I am also using https://crccalc.com/ (CRC-32/MPEG-2) to validate the results.
I just activate the CRC in CubeMX and this is my source code for 32-bit values:
uint32_t raw_data_32_bit[BUFFER_SIZE] = { 0x00, 0x01, 0x10, 0x1A, 0xAC, 0xC0 };
uint32_t crc_value_32_bit = 0;
uint8_t is_error_32_bit = 1;
crc_value_32_bit = HAL_CRC_Calculate(&hcrc, raw_data_32_bit, BUFFER_SIZE);
if (crc_value_32_bit == expected_crc_value_32_bit) {
is_error_32_bit = 0;
}
which is working like a charm.
Then I would like to do the same for 8-bit values with this code:
uint32_t expected_crc_value_8_bit = 0xA4541FC6;
uint8_t raw_data_8_bit[BUFFER_SIZE] = { 0x00, 0x01, 0x10, 0x1A, 0xAC, 0xC0 };
uint32_t crc_value_8_bit = 0;
uint8_t is_error_8_bit = 1;
crc_value_8_bit = HAL_CRC_Calculate(&hcrc, (uint32_t *) raw_data_8_bit, BUFFER_SIZE); // returns 0xe7206456
if (crc_value_8_bit == expected_crc_value_8_bit) {
is_error_8_bit = 0;
}
but it returns a different result from the result returns from https://crccalc.com/. The only way to make it work is to create a new 32-bit array using this code:
uint32_t data [BUFFER_SIZE];
for (uint8_t i = 0; i < BUFFER_SIZE; i++)
data[i] = raw_data_8_bit[i];
crc_value_8_bit = HAL_CRC_Calculate(&hcrc, data, BUFFER_SIZE);
if (crc_value_8_bit == expected_crc_value_8_bit) {
is_error_8_bit = 0;
}
Could someone explain why the 8-bit returns something different from the expected? What am I doing wrong?
2020-10-08 12:28 AM
In the first case, you calculate CRC from an array of {0x1A100100, 0xqqqqC0AC, 0xqqqqqqqq, 0xqqqqqqqq, 0xqqqqqqqq, 0xqqqqqqqq}, where qq are whatever bytes happen to be in the memory just after raw_data_8_bit[].
In the second case, you calculate CRC from {0x00000000, 0x000000001, 0x00000010, 0x0000001A, 0x000000AC, 0x000000C0}
2020-10-08 02:31 AM
+1
sizeof() the arrays is different, the function is taking a word count, not a byte count.
2020-10-08 03:08 AM
@Community member
I thought that the conversion
(uint32_t *) raw_data_8_bit
converts the pointer of an 8-bit value into a 32-bit value pointer.
Maybe I have not understand something in pointer functionality. If you could, I would like a more detailed explanation or even some keywords for a google search in order to read an article.
@Community member
Wow! So, is there any way (apart from the third code snippet) to calculate CRC on an 8-bit array?
In this video here, it seems it is working as expected!
@everyone
Thank you for your time.
2020-10-08 04:18 AM
Yes that casts the pointer but 8 words is still 32 bytes, not 8
Check the units used by HAL_CRC_Calculate() and use the right ones..
2020-10-08 11:21 PM
In C, information on variable's *type* is *not* passed to the called function. Rather, the value passed is used according to whatever type is declared for that parameter in the function's declaration.
JW
2022-02-03 05:17 PM
I think you should initialize the CRC using the right parameters for a 8 bit CRC.
Here is an example:
HAL_StatusTypeDef CRC_configure_CDMA2000(){
hcrc.Instance = CRC;
hcrc.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE;
hcrc.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_DISABLE;
hcrc.Init.GeneratingPolynomial = 0x9b;
hcrc.Init.CRCLength = CRC_POLYLENGTH_8B;
hcrc.Init.InitValue = 0xff;
hcrc.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;
hcrc.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;
hcrc.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;
return HAL_CRC_Init(&hcrc);
}
And then use the CRC as follows:
uint8_t crc_data[4] = {0x1A, 0x2B, 0x3C,0x4D};
uint32_t crc_result;
crc_result = HAL_CRC_Calculate(&hcrc, (uint32_t*)crc_data, 4);
Hope this helps,
Gumer
2022-02-03 09:17 PM
The thread is over a year old, and discusses a STM32F4 part that doesn't support a programmable CRC peripheral, so only ST's 32-bit one.