Skip to main content
Visitor II
January 9, 2025
Solved

CRC problem

  • January 9, 2025
  • 2 replies
  • 840 views

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???

    This topic has been closed for replies.
    Best answer by Tesla DeLorean

    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);
    }

     

    2 replies

    Graduate
    January 9, 2025

    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.

    https://github.com/STMicroelectronics/stm32g4xx-hal-driver/blob/6cdb4c3f4d485eb2bd0717fa240f3ff9687f96dc/Src/stm32g4xx_hal_crc.c#L432 

     

    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.

    Graduate II
    January 9, 2025

    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);
    }

     

    machinistAuthor
    Visitor II
    January 10, 2025

    Thanks a lot! I understand what I did wrong.