cancel
Showing results for 
Search instead for 
Did you mean: 

CRC calculation unit initialize

christophe239955_stm1
Associate II
Posted on January 21, 2010 at 00:51

CRC calculation unit initialize

8 REPLIES 8
christophe239955_stm1
Associate II
Posted on May 17, 2011 at 13:38

As described in the reference manual, the initial-value (reset) cannot be set to something else than 0xFFFFFFFF. This leads into a problem if you want to build the CRC over the whole flash memory and cannot do this without making some breakes in between. If you use the CRC unit in such a break for other things (interface, RAM-check, etc.), there is no possibility to restore the old CRC value and resume the flash-check.

Theoretically it should be possible to calculate (reverse CRC?) a value upon the old CRC. This value can then be written into the CRC_DR unit and as a result there will be the old CRC value in CRC_DR.

In other words: A initializing function for the CRC based upon a given value and the init-value 0xFFFFFFFF.

The function could look like this:

Code:

CRC_Init(Init_Value)

{

uint32_t RevCRC;

CRC_ResetDR(); //Reset the CRC data register (reset-value 0xFFFFFFFF)

RevCRC = ... //Do reverse CRC based on Init_Value and reset-value

CRC_CalcCRC(RevCRC); //after this step: CRC->DR == Init_Value

}

Has someone done this already? Any tips would be great.

good2dog
Associate II
Posted on May 17, 2011 at 13:38

hi,

it may be useful a function that clear CRC to 0x00000000 , starting from the reset value 0xFFFFFFFF :

CRC_ResetDR(); //Reset the CRC data register (reset-value 0xFFFFFFFF)

CRC_CalcCRC(RevCRCclear); //after this step: CRC->DR == 0X00000000

then it's easy to initialise CRC at any value you want, calling

CRC_CalcCRC(any_init_value_you_want)

that's all.

now I'm going to calculate magic number RevCRCclear.

regards

clive2
Associate II
Posted on May 17, 2011 at 13:38

>>now I'm going to calculate magic number RevCRCclear

Wouldn't you just use 0xFFFFFFFF ? Seeing as it XOR's a bit and feeds it back to the remaining taps?

-Clive

CRC FFFFFFFF - Before

CRC_CalcCRC(0xFFFFFFFF);

CRC 00000000 - After

QED

clive2
Associate II
Posted on May 17, 2011 at 13:38

To zero in any condition the following should work

CRC_CalcCRC(CRC_GetCRC());

To get to some other arbitary value

CRC_CalcCRC(Crc32Rev(CRC_GetCRC(),0x12345678));

Where the forward and reverse functions are implemented as follow. These are simple serial implementations for illustration. Source for Win32 testing is attached.

typedef unsigned long DWORD;

DWORD Crc32(DWORD Crc, DWORD Data)

{

int i;

Crc = Crc ^ Data;

for(i=0; i

if (Crc & 0x80000000)

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

else

Crc = (Crc << 1);

return(Crc);

}

DWORD Crc32Rev(DWORD CurrentCrc, DWORD DesiredCrc)

{

DWORD Data;

int i;

for(i=0; i

if (DesiredCrc & 0x00000001)

#if 1

DesiredCrc = ((DesiredCrc ^ 0x04C11DB7) >> 1) | 0x80000000; // Long form

#else // or

DesiredCrc = (DesiredCrc >> 1) ^ 0x82608EDB; // Back feeding polynomial

#endif

else

DesiredCrc = (DesiredCrc >> 1);

Data = DesiredCrc ^ CurrentCrc;

return(Data); // Data Pattern to get Desired CRC from Current CRC

}

-Clive

Posted on May 17, 2011 at 13:38

Well the conversion to the new forum dumped the attachment, and messed with the formatting.

See paper clip icon in upper right for attachment

DWORD Crc32(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);

}

DWORD Crc32Rev(DWORD CurrentCrc, DWORD DesiredCrc)

{

  DWORD Data;

  int i;

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

    if (DesiredCrc & 0x00000001)

#if 1

      DesiredCrc = ((DesiredCrc ^ 0x04C11DB7) >> 1) | 0x80000000; // Long form

#else   // or

      DesiredCrc = (DesiredCrc >> 1) ^ 0x82608EDB; // Back feeding polynomial

#endif

    else

      DesiredCrc = (DesiredCrc >> 1);

  Data = DesiredCrc ^ CurrentCrc;

  return(Data); // Data Pattern to get Desired CRC from Current CRC

}

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

Here is a parallel implementation of the STM32 CRC function in software. By doing 4-bits at a time we only need 16 table entries, this could be done 8-bits at a time, but that would require 256 table entries (1KB). A Thumb2 version would be faster and more compact.

DWORD Crc32Fast(DWORD Crc, DWORD Data)

{

  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 ^ Data; // Apply all 32-bits

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

}

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

it may be useful a function that clear CRC to 0x00000000 , starting from the reset value 0xFFFFFFFF :

CRC_ResetDR(); //Reset the CRC data register (reset-value 0xFFFFFFFF)

CRC_CalcCRC(RevCRCclear); //after this step: CRC->DR == 0X00000000

then it's easy to initialise CRC at any value you want, calling

CRC_CalcCRC(any_init_value_you_want)

now I'm going to calculate magic number RevCRCclear.

Posted on May 17, 2011 at 13:38

''it should be 0xC704DD7B, regards''

What, care to elaborate? The function of this code has been verified on an STM32.

crc

Initializing CRC Unit

CRC FFFFFFFF (0xFFFFFFFF)

CRC_CalcCRC(0xFFFFFFFF)

CRC 00000000 (0x00000000)

crcreset 12345678

CRC 00000000

CRC_CalcCRC(0x85C34F1E)

CRC 12345678

-Clive

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..