2025-01-09 07:13 AM
Hello,
I am trying to use the CRC module on a STM32G491 (bare metal). But I simply can not get the same CRC as when I calculate it with some online tools.
With
https://www.lddgo.net/en/encrypt/crc
and
https://www.sunshine2k.de/coding/javascript/crc/crc_js.html
I get 0xA6322B20 as custom CRC for simply the value 0x05 and pol 0x04C11DB7 and init value 0xFFFFFFFF in 32bit (no revs).
RCC->AHB1ENR |= bit12; // enable CRC clock
CRC->CR |= bit0; // reset CRC
while((CRC->CR&bit0)==bit0); // probably not necassary
CRC->DR = 5;
uint32_t crc = CRC->DR;
This gives me the value 0xD0C1B610. The Polynomial formula on lddgo is stated as x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1 which is the same as stated in the RM0440 section 16 page 454.
So where am I going wrong???
2025-01-09 08:07 AM - edited 2025-01-09 08:08 AM
If you are writing bare-metal code, you should know what are you doing - or at least check the hal library, it is not against the law.
You are assigning 8 bits data into 32 bits register, so it gets implicitly typed to uint32_t, which given the endianness and the padding bytes ends up producing wrong data, unsurprisingly.
2025-01-09 09:44 AM
The default CRC is 32-bit is left shifting, you are feeding it a word, equivalent to the bytes 0x00,0x00,0x00,0x05
The problem with on-line calculators and CRC is that's there are many valid ways of applying data, and the interface is less than ideal in setting / expressing that correctly.
// STM32 CRC functional equivalent sourcer32@gmail.com
#include <windows.h>
#include <stdio.h>
typedef unsigned char uint8_t;
typedef unsigned int uint32_t;
uint32_t crc32stm(uint32_t crc, uint32_t data)
{
int i;
crc ^= data;
for(i=0; i<32; i++)
if (crc & 0x80000000)
crc = (crc << 1) ^ 0x04C11DB7;
else
crc <<= 1;
return(crc);
}
int main(int argc, char **argv)
{
uint32_t crc;
printf("%08X\n", crc32stm(0xFFFFFFFF,0x00000005)); // 0xD0C1B610
return(1);
}