cancel
Showing results for 
Search instead for 
Did you mean: 

CRC-32 on F4/F7

kevin2399
Associate III
Posted on June 27, 2016 at 16:07

Just thought I'd save people some time if they are trying to get the CRC engine on the F4/F7 to produce the same results as most online calculators.

If you are using CubeMX to configure your CRC, you need to specify the Input Inversion Mode as BYTE and the Output Inversion Mode as ENABLE.  Note that when ST uses the term inversion, what they really mean is bit reversal, or reflection.  Not sure why they think inverting is the same as bit reversal.

It would be nice if ST would make these the defaults, since the other defaults are for the 32-bit CRC.  If you use their defaults, you won't get a CRC that matches anything I could find with any online calculator.

Once you have the crc from HAL_CRC_Calculate(), you need to invert it (yes, I do mean invert, e.g. change ones to zeros and vice versa).  Since it is a uint32_t, you can just use crc=~crc.  This will give you the result as calculated by the following online calculators:

http://www.lammertbies.nl/comm/info/crc-calculation.html

http://www.zorc.breitbandkatze.de/crc.html

When you use the 2nd link, there are options you can specify, but if you just click the CRC-32 button, the default options are the ones that give you the same result as the first link.  Make sure you read how to enter hexadecimal values if that is what you want to do.

Hope this saves others some time. 
5 REPLIES 5
Posted on June 27, 2016 at 18:57

Generally speaking I find there is a chronic over reliance on online calculators, and a lack of real understanding of the underlying mathematics and gate level design of CRC and LFSR circuits.

They deal very poorly with shift direction, and endian issues. The CRC polynomial, shift-direction, shift count and endianess of the STM32 (F1/F2/F4) are very awkwardly juxtaposed. It suggests the person dropping the cell into the design lacked the kind of clarity I mentioned earlier. That's the real reason the online calculators don't work well with it.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Lynn Linse
Associate III
Posted on December 09, 2016 at 21:51

Thanks for offering tips! Always appreciated.

I have a similar question, but sadly on the L152, there doesn't seem to be any way to change the CRC behavior. I'd hoped to use a PC-based tool to create the CRC for the FW to check ... but so far, I've not found such a tool. There are a LOT of things (like the public crc32.exe and even python's zlib module) claiming to create the Ethernet CRC32 (aka: polynomial 0x04C11DB7) and while they all agree on the result, sadly the L152 doesn't agree!

I even tried:

1) reversing the bits in bytes on PC

2) reversing the bits in uint32 on PC

3) various byte swapping on groups of 2 or 4

None of those gave the same answer as the L152.  Worst case, I'll just need to run my code on the L152 before release - eyeball what the L152 says & record that for manual insertion back into the FW to allow checking FW integrity.

Maybe STMicro should invest in creating a C/C++ example code which can match the fixed L1 (or default F) CRC?

Posted on December 09, 2016 at 22:10

 ,

 ,

I believe I have demonstrated this several times in the last decade

 ,

 ,
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on December 09, 2016 at 22:35

Yes ... I see now that you have - LOTS of stuff to dig through in this forum! I found using your code to make this Python routine to match the STM32 result. Course Python3 now has infinite number size, so the masking each loop is critical (or one ends up with a thousand digit crc). As my PC has lots of time (relatively to my doing it manually) to create the CRC, I'm not worried about how fast this is:

def stm32_crc32(crc, data):

    ♯ Clive's suggestion from STMicro forum

    crc = crc ^ data

    for i in range(0, 32):

        if crc & 0x80000000:

            crc = ((crc << 1) ^ 0x04C11DB7) & 0xFFFFFFFF  ♯ Polynomial used in STM32

        else:

            crc = (crc << 1) & 0xFFFFFFFF

    return crc

Matthew Vernon
Associate
Posted on April 24, 2018 at 18:13

Some additional notes that may help:

1. The reflection settings used above also reflect the initial value for some unknown reason. This means that if you want to compute a CRC in chunks you have to:

   A. Take the CRC result of the first chunk before inverting

   B. Reflect this value, meaning the first bit becomes the last and so on

   C. Use this reflected value as the initial value (.InitValue in Cube) for the next chunk

2. When reflection is turned off there is a byte ordering ... irregularity. Computing the CRC by word and by byte will give you different results. To make an online calculator match you must reverse each word (i/e the bytes ABCD become DCBA). Use the following settings for the online calculator (or CRC/MPEG-2 option if it exists):

   A. Input reflection off

   B. Output reflection off

   C. XOR value of 0

   D. Initial value of 0xFFFFFFFF

   E. Polynomial is 

0x04C11DB7 just as for more common CRC32 calculations