2013-03-01 01:32 PM
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. John2013-03-01 02:17 PM
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.2013-03-01 02:50 PM
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
2013-03-04 07:50 AM
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. John2013-03-04 01:33 PM
The reversal is working. The CRC->DR is at the desired (old CRC) when finished.
John2013-03-04 01:59 PM
<G>
One potential optimization is to check if the value is already the one you want.