Hi All
I am trying to use the CRC module for a CRC32 calculation but haven't been able to get it to produce the expected values just yet. Since there is no standard example that I can find and the user's manual doesn't give any details about the form of the polynomial it is presently a case of trial and error and not yet finding the right combination.
The polynomial is
x(32) + x(26) + x(23) + x(22) + x(16) + x(12) + x(11) + x(10) + x(8) + x(7) + x(5) + x(4) + x(2) + x + 1
The seed is 0xffffffff
The polynomial has been tried as 0xedb88320 and 0x04c11db7 (different directions) and all permutation of bit and byte reversals. The result changes according to settings but never matches the expected result using a single 32 bit reference with known result.
Does anyone have any more details??
Regards
Mark
I think Kinetis uses the same module as on the ColdFire V1 (e.g. MM and JE family).
Maybe the manual/examples for these families help (but did not check the details)
There is as well a utility to calculate the CRC:
http://mcuoneclipse.wordpress.com/2012/05/06/crc-calculation-with-mcu10/
(although I did not use it with Kinetis, only for ColdFire).
Hope this helps,
BK
Hi
I checked the JF user's manual and the chapter on the CRC module is identical to that in the Kinetis manual. It doesn't give any more information - it would be much clearer if there was a single example of setting up a typical, well known CRC with the values to be written.
Since CRC-32 has a lot of combination I think that I may write a brute force tester for CRC-16 (smaller and so less permutations) that feeds in every possible polynomial and other settings and tests a known sequence until it finds a match.
Regards
Mark
Hi
It seems as though the difficulties could be solved. The CRC16 test case gave the expected polynomial value (0x1021) which is in fact the default value in the polynomial register after reset :smileyalert:.
CRC-32 IEEE was achieved by using the setting:
CRC_GPOLY = 0x04c11db7;
CRC_CRC = 0xffffffff;
CRC_CTRL = (CRC_CTRL_TCRC_32 | CRC_CTRL_TOTR_BITS_BYTES | CRC_CTRL_TOT_BITS_BYTES | CRC_CTRL_FXOR);
Processing received Ethernet frames and checking with the CRC-32 at the end of them with the result proved that it was accurate.
The source of confusion actually came from a reference that was not in fact using the expected polynomial (although it was stated as to be...); this could obviously not be matched no matter what settings were experimented with...
Regards
Mark
Can you please share the hex values of
#define CRC_CTRL *(volatile unsigned long *)(CRC_BLOCK + 0x8) // CRC Control Register
#define CRC_CTRL_TCRC_16 0x00000000
#define CRC_CTRL_TCRC_32 0x01000000
#define CRC_CTRL_WAS 0x02000000 // writes to CRC data register are seed values
#define CRC_CTRL_FXOR 0x04000000 // invert of complement the read value of the CRC data register
#define CRC_CTRL_TOTR_BITS 0x10000000 // value read from CRC data register is transposed - bits transposed but not bytes
#define CRC_CTRL_TOTR_BITS_BYTES 0x20000000 // value read from CRC data register is transposed - bits and bytes transposed
#define CRC_CTRL_TOTR_BYTES 0x30000000 // value read from CRC data register is transposed - bytes transposed but not bits
#define CRC_CTRL_TOT_BITS 0x40000000 // value written to CRC data register is transposed - bits transposed but not bytes
#define CRC_CTRL_TOT_BITS_BYTES 0x80000000 // value written to CRC data register is transposed - bits and bytes transposed
#define CRC_CTRL_TOT_BYTES 0xc0000000 // value written to CRC data register is transposed - bytes transposed but not bits
Reference from uTasker project code (available on Github).
Regards
Mark
I've certainly had no trouble using the CRC module for code-image checks, as linked-in using the IAR linker checksum options 4-byte, seed 0, reverse bytes MSB first and default CRC32 polynomial, placed at the end of the image:
uint32_t * memptr=(u32_t *)boot_CRC_start; //Calculate a CRC in K60 hdwr using same algorithm as IAR
if( (SIM_SDID & SIM_SDID_REVID_MASK) == 0) //For Rev 1.0 silicon, must disable all Flash caching & Speculation
{
FMC_PFB0CR &= ~0x1FUL; //Clear these bits for errata e2647 & e2644
FMC_PFB1CR &= ~0x1FUL;
}
SIM_SCGC6 |= SIM_SCGC6_CRC_MASK;
CRC_CTRL = CRC_CTRL_WAS_MASK | CRC_CTRL_TCRC_MASK; //32bit CRC
CRC_CRC = 0; //Starting from zero
CRC_CTRL = CRC_CTRL_TCRC_MASK;
CRC_GPOLY = 0x04C11DB7; //Poly to match IAR 32-bit default
do{ //16 byte paragraphs at a time
CRC_CRC = *memptr++;
CRC_CRC = *memptr++;
CRC_CRC = *memptr++;
CRC_CRC = *memptr++;
}while (memptr <= (uint32_t *)&__checksum);
if( CRC_CRC == 0 )
.......continue
BTW, I also 'fill unused flash' with 0xDF on that linker page so that I get a 'SVC 223' if the PC gets 'lost'.