cancel
Showing results for 
Search instead for 
Did you mean: 

Background CRC32 in segments on STM32F4

johnsotack9
Associate II
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
5 REPLIES 5
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 Up vote any posts that you find helpful, it shows what's working..
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 Up vote any posts that you find helpful, it shows what's working..
johnsotack9
Associate II
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 II
Posted on March 04, 2013 at 22:33

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

John

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 Up vote any posts that you find helpful, it shows what's working..