cancel
Showing results for 
Search instead for 
Did you mean: 

CRC32 calculation mismatch

ibarnes2
Associate
Posted on April 09, 2010 at 05:29

CRC32 calculation mismatch

6 REPLIES 6
daviddavid94
Associate II
Posted on May 17, 2011 at 13:46

STM32's hardware CRC is NOT the same as the pkzip/ethernet CRC.

Search for a topic in this forum titled ''

CRC calculation in software''. I attached a file in that thread which has C code for a table-driven CRC which matches STM32's hardware.

cheers,

Brian

mdeneen2
Associate II
Posted on May 17, 2011 at 13:46

Ian,

I have used the STM32's CRC module, and it produces the same CRC32 result as the crc32 in python's zlib module, and other crc32 calculators.

bit-reverse 0xC704DD7B = 0xDEBB20E3

0xDEBB20E3 ^ 0xFFFFFFFF = 0x2144DF1C (ta-da!)

It took me a while to figure this out.  Hopefully it helps you! 

I had to bit-reverse all words going to the CRC32 module, and then bit-reverse the result and xor it with 0xFFFFFFFF.  You will see this when you start calculating the CRC32 of something besides 0x00.

I'm not using the standard peripheral library, but you should be able to follow this:

This is for GCC...

u32 rbit(u32 d)

{

    __asm__

    (

            '' rbit %0, %0''

            : ''=r'' (d)

            : ''0'' (d)

            : ''cc''

    );

    return d;

}

u32 crc32(u32 *data, u32 wordCount)

{

    u32 i;

    u32 crc;

    CK_CRCEN = 1;

    CRCReset();

    for(i = 0; i < wordCount; i ++)

    {

        CRCCalc(rbit(data[i]));

    }

    crc = rbit(CRCGet()) ^ 0xFFFFFFFFL;

    CK_CRCEN = 0;

    return crc;

}

ibarnes2
Associate
Posted on May 17, 2011 at 13:46

Hi Brian, thanks for the fast reply. I will definitely check out your post. It seems strange that they use a different CRC, but seem to hint in the RM0008 that it is the one used for ethernet:

3.2 CRC main features

 

�? Uses CRC-32 (Ethernet) polynomial: 0x4C11DB7

 

– X32 + X26 + X23 + X22 + X16 + X12 + X11 + X10 +X8 + X7 + X5 + X4 + X2+ X +1

Posted on May 17, 2011 at 13:46

//****************************************************************************

DWORD CRC32WideFast(DWORD Crc, DWORD Size, BYTE *Buffer)

{

    Size = Size >> 2; // /4

  while(Size--)

  {

      static const DWORD CrcTable[16] = { // Nibble lookup table for 0x04C11DB7 polynomial

        0x00000000,0x04C11DB7,0x09823B6E,0x0D4326D9,0x130476DC,0x17C56B6B,0x1A864DB2,0x1E475005,

        0x2608EDB8,0x22C9F00F,0x2F8AD6D6,0x2B4BCB61,0x350C9B64,0x31CD86D3,0x3C8EA00A,0x384FBDBD };

    Crc = Crc ^ *((DWORD *)Buffer); // Apply all 32-bits

        Buffer += 4;

      // Process 32-bits, 4 at a time, or 8 rounds

      Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; // Assumes 32-bit reg, masking index to 4-bits

      Crc = (Crc << 4) ^ CrcTable[Crc >> 28]; //  0x04C11DB7 Polynomial used in STM32

      Crc = (Crc << 4) ^ CrcTable[Crc >> 28];

      Crc = (Crc << 4) ^ CrcTable[Crc >> 28];

      Crc = (Crc << 4) ^ CrcTable[Crc >> 28];

      Crc = (Crc << 4) ^ CrcTable[Crc >> 28];

      Crc = (Crc << 4) ^ CrcTable[Crc >> 28];

      Crc = (Crc << 4) ^ CrcTable[Crc >> 28];

    }

  return(Crc);

}

//****************************************************************************

DWORD CrcSTM32(DWORD Crc, DWORD Data)

{

  int i;

  Crc = Crc ^ Data;

  for(i=0; i<32; i++)

    if (Crc & 0x80000000)

      Crc = (Crc << 1) ^ 0x04C11DB7; // Polynomial used in STM32

    else

      Crc = (Crc << 1);

  return(Crc);

}

//****************************************************************************

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
juozas
Associate III
Posted on May 17, 2011 at 13:46

Hi,

Thanks to clive1 I have made function for Visual Basic .NET 2008.

The function returns 0xC704DD7B if bufer contains four ''0'' bytes:

   Public Function CRC32WideFast(ByVal Buffer() As Byte, ByVal Size As Integer) As UInteger

        Dim Crc As UInteger = 0

        Const uintInitialValue As UInteger = &HFFFFFFF

        Crc = (uintInitialValue << 4) Or &HF ' to avoid error message ''Constant expression not representable''

        Dim i As Integer = 0

        Dim k As Integer = 0

        Dim uintTmp As UInteger = 0

        '// Nibble lookup table for 0x04C11DB7 polynomial:

        Dim CrcTable() As UInteger = { _

          &H0, &H4C11DB7, &H9823B6E, &HD4326D9, &H130476DC, &H17C56B6B, &H1A864DB2, &H1E475005, _

          &H2608EDB8, &H22C9F00F, &H2F8AD6D6, &H2B4BCB61, &H350C9B64, &H31CD86D3, &H3C8EA00A, &H384FBDBD}

        Size = Size >> 2 ' /4

        For i = 0 To Size - 1

            uintTmp = Buffer(i * 4)

            uintTmp = uintTmp Or (Buffer(i * 4 + 1) << 😎

            uintTmp = uintTmp Or (Buffer(i * 4 + 2) << 16)

            uintTmp = uintTmp Or (Buffer(i * 4 + 3) << 24)

            Crc = Crc Xor uintTmp '; // Apply all 32-bits

            '// Process 32-bits, 4 at a time, or 8 rounds:

            Crc = (Crc << 4) Xor CrcTable(Crc >> 28) '; // Assumes 32-bit reg, masking index to 4-bits

            Crc = (Crc << 4) Xor CrcTable(Crc >> 28) '; //  0x04C11DB7 Polynomial used in STM32

            Crc = (Crc << 4) Xor CrcTable(Crc >> 28)

            Crc = (Crc << 4) Xor CrcTable(Crc >> 28)

            Crc = (Crc << 4) Xor CrcTable(Crc >> 28)

            Crc = (Crc << 4) Xor CrcTable(Crc >> 28)

            Crc = (Crc << 4) Xor CrcTable(Crc >> 28)

            Crc = (Crc << 4) Xor CrcTable(Crc >> 28)

        Next

        Return (Crc)

    End Function

cheers,

Juozas

Andrew Neil
Evangelist
Posted on May 17, 2011 at 13:46

''It seems strange that they use a different CRC''

No, it's not really strange at all: ''CRC32'' simply means a CRC with 32 bits; it tells you nothing about the algorithm used to generate the CRC - there are literally dozens of different 32-bit CRC algorithms!

This article tells you all you need to know (and more!) about CRCs: 

http://www.repairfaq.org/filipg/LINK/F_crc_v3.html