2010-04-08 08:29 PM
CRC32 calculation mismatch
2011-05-17 04:46 AM
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, Brian2011-05-17 04:46 AM
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; }2011-05-17 04:46 AM
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
2011-05-17 04:46 AM
//****************************************************************************
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); } //****************************************************************************2011-05-17 04:46 AM
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) << 8) 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 Functioncheers,
Juozas2011-05-17 04:46 AM
''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: