CRC calculation weird result

I need to calculate CRC on stm32f4 series MCU, luckily this family has HW for it. It is very simple, only 1 data register and then only one bite in next register for reset. Check it if you want at CRC section in datasheet, it is starting at page 66 and it is very short text. datasheet

So I firstly enabled clock for CRC unit and reset it:

CRC->CR |= 1;

Then I filled data register and read it back, because CRC value is stored there after conversion:

CRC->DR = 0xC1;
Serial.println(CRC->DR, HEX); //printed 9E4F5055

and the result was correct, you can verify it on if you use hex value 000000C1 and look at the result under CRC-32/MPEG-2 protocol. But if I fill DR register like this:

*((uint8_t *)&CRC->DR) = 0xC1;
Serial.println(CRC->DR, HEX); //printed BFA1DC65

It has printed CRC result for value C1C1C1C1, why?

As I expected when I use uint16_t instead:

*((uint16_t *)&CRC->DR) = 0xC1;
Serial.println(CRC->DR, HEX); //printed 5EA9E92

It prints CRC value for 00C100C1, know someone why it is doing this?

The CRC registers are 32 bits long so when you only fill it with an 8/16 bit value the results are not going to be what you expect.
See if it works correctly with...

*((uint32_t *)&CRC->DR) = 0xC1;
Serial.println(CRC->DR, HEX);

This simple detection mechanism works if an odd number of bits in a byte changes, but The CRC calculation or cyclic redundancy check was the result of this.The theory of a CRC calculation is straightforward. The data is treated by the CRC algorithm as a binary number. This number is divided by another binary number called the polynomial. The rest of the division is the CRC checksum, which is appended to the transmitted message.

The CRC registers are 32 bits long so when you only fill it with an 8/16 bit value the results are not going to be what you expect.

Thanks for answer but I am asking why it is happening, I know the results are not what I expected. Why it is matching result for C1C1C1C1 message?

It seems like the register will expand any given value to fit the entire register by repeating it. Accessing the register as 8-bit will cause the register to filled with four times 8-bit (eg. 0xC1 becomes 0xC1C1C1C1) and when accessing it as 16-bit it will be filled with two 16-bit values (eg. 0xC1 becomes 0x00C100C1).

First of all, that register is not meant be used that way. It is a 32-bit register. Since the stm32f4 is 32-bit microcontroller I suspect when you try to do an 8-bit write the byte is reflected on each 8 bits of the internal data bus of the processor. Similarly when you try to do a 16-bit write. I'm sure the chip designers didn't worry about it since it shouldn't be used that way.

Yeah, you are right. I will be using it only with 32bit values. Thank you for answers!

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.