Skip to main content
johnsotack9
Associate III
March 1, 2013
Question

Background CRC32 in segments on STM32F4

  • March 1, 2013
  • 5 replies
  • 1253 views
Posted on March 01, 2013 at 22:32

I would like to do a background CRC32 on FLASH such that I do 256 bytes at a time and get a final result.  The system must continue to run and meet RT deadlines while the CRC is calculated.  Additionally, communication functions use the CRC unit.

From reading the reference manual, it appears I can only reset the CRC to 0xffffffff.  I would like to continue the CRC incrementally with 256 Byte blocks, starting with the previous CRC that is no longer present.  Is there a way to set the CRC to a stored previous CRC continuation value.  For example if the result of the CRC for the previous 256 block as 0x0230dfef, I would want to start with that value in the DR.

I could reset the CRC for each block and prepend the previous CRC but this is a custom algorithm and I would like to stick with the standard Ethernet CRC.

John
    This topic has been closed for replies.

    5 replies

    Tesla DeLorean
    Guru
    March 1, 2013
    Posted on March 01, 2013 at 23:17

    Well the reset does pose some issues, but there is a reverse polynomial math trick to advance the current value to any other value. I probably wouldn't even bother to reset it.

    Will go dig up the thread/code.
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    Tesla DeLorean
    Guru
    March 1, 2013
    Posted on March 01, 2013 at 23:50

    DWORD Crc32RevFast(DWORD CurrentCrc, DWORD DesiredCrc) // sourcer32@gmail.com
    {
    static const DWORD CrcTable[16] = {
    0x00000000,0xB2B4BCB6,0x61A864DB,0xD31CD86D,0xC350C9B6,0x71E47500,0xA2F8AD6D,0x104C11DB,
    0x82608EDB,0x30D4326D,0xE3C8EA00,0x517C56B6,0x4130476D,0xF384FBDB,0x209823B6,0x922C9F00 };
    DWORD Data;
    DesiredCrc = (DesiredCrc >> 4) ^ CrcTable[DesiredCrc & 0x0F];
    DesiredCrc = (DesiredCrc >> 4) ^ CrcTable[DesiredCrc & 0x0F];
    DesiredCrc = (DesiredCrc >> 4) ^ CrcTable[DesiredCrc & 0x0F];
    DesiredCrc = (DesiredCrc >> 4) ^ CrcTable[DesiredCrc & 0x0F];
    DesiredCrc = (DesiredCrc >> 4) ^ CrcTable[DesiredCrc & 0x0F];
    DesiredCrc = (DesiredCrc >> 4) ^ CrcTable[DesiredCrc & 0x0F];
    DesiredCrc = (DesiredCrc >> 4) ^ CrcTable[DesiredCrc & 0x0F];
    DesiredCrc = (DesiredCrc >> 4) ^ CrcTable[DesiredCrc & 0x0F];
    Data = DesiredCrc ^ CurrentCrc;
    return(Data);
    }
    Usage
    uint32_t CRCContext;
    CRCContext = CRC->DR; // Save current
    // ... some other usage
    CRC->DR = Crc32RevFast(CRC->DR, CRCContext); // Restore prior
    // continue

    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
    johnsotack9
    Associate III
    March 4, 2013
    Posted on March 04, 2013 at 16:50

    This is the next best thing to being able to seed the CRC result register.  I will probably do blocks of 256 words, so the added overhead of the Reverse CRC should not be too significant.

    I greatly prefer having a single Ethernet CRC32 rather than coming up with a variation.

    Your help with various technical queries has been greatly appreciated.

    John

    johnsotack9
    Associate III
    March 4, 2013
    Posted on March 04, 2013 at 22:33

    The reversal is working.  The CRC->DR is at the desired (old CRC) when finished.

    John

    Tesla DeLorean
    Guru
    March 4, 2013
    Posted on March 04, 2013 at 22:59

    <G>

    One potential optimization is to check if the value is already the one you want.
    Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..