Dear Support,
I have MPC5643L micro and using CRC32 bit with CRC32_ETHERNET. I am generating 32 bit CRC using following configuration.
{/* swap_bitwise swap_bytewise swap inv poly seed_val */
{ CbFALSE, CbFALSE, CbFALSE, CbFALSE, CeGENR_e_CRC32_ETHERNET, 0xFFFFFFFF
Above works fine and successfully running.
This calculated CRC we store in one external EERPOM and I need to use that stored data using some other device and calculate same 32 bit CRC. I tried few 32 bit CRC algorithm from net but not matching with what MPC5643L calculates.
Please let me know if you need more info on how I implemented/ configure CRC on MPC5643L.
Please could help me in locating ready C source code which calculates same 32 bit CRC as MPC5643L.
Thanks
Amar
Hi,
I do not have such code but from my experience, you should enable inversion (INV bit in CRC_CFG). My tests show that then I'm getting the same result as some online CRC32 calculators available on web. I believe that some of the algorithms you already tested will work.
Regards,
Lukas
Hi Lukas,
Thank you for response. I will try to enable INV bit and check. However I want to know why I need to enable INV bit to match with some of the online calculator.
Based on my couple of week research I found on algo from net which matches with nxp 32 bit calculation. But that only matches with data input of all zeros. (0x00, 0x00....). When I change zeros to some values and zeros as well then it does not match. I tried various options (like byte swap, reverse bytes) in my algo but did not work. So I expect nxp must be having some source code which will generate 32 bit check sum matching with nxp. Also no where i found which polynimial nxp used in there way of calculating 32 bit checksum.
I am providing source code which I used to calculate 32 bit check sum. Please recommend if you have anything.
#include <stdio.h> 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 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 ); } void test( void ) { BYTE vector[ 12 ] = { 0x02, 0x07, 0x02, 0x00, 0x18, 0x8A, 0xD0, 0x23, 0x25, 0x2B, 0x09, 0x00 }; DWORD Crc; int i; for ( i = 0; i < 12; i++ ) printf( "%02X ", vector[ i ] ); putchar( '\n' ); Crc = 0xFFFFFFFF; // Initial state for ( i = 0; i < 12; i += 4 ) { Crc = Crc32Fast( Crc, *( (DWORD *) &vector[ i ] ) ); // 4-bytes at a time } printf( "%08X test\n", Crc ); } int main( int argc, char **argv ) { printf( "%08X\n\n", Crc32( 0xFFFFFFFF, 0x12345678 ) ); // 0xDF8A8A2B printf( "%08X\n\n", Crc32Fast( 0xFFFFFFFF, 0x12345678 ) ); // 0xDF8A8A2B test( ); return ( 1 ); } I will soon let you know INV bit enable result. Thanks Amar
Hi,
it's general IP module which can be integrated to any kind of architecture. So, these options are there to support different architectures.
And I forgot to mention one more thing - it also depends how you write the data to input register. If you write byte stream (8bit data), you will get different result if you write the data as 32bit or 8bit. Here is a description I wrote in SW example for MPC5748G (https://community.nxp.com/docs/DOC-332223 ):
If we want to write "byte stream" into input register, we have to ensure
that a bytes are really written as a bytes. When this command is used:
CRC.INP.R = '0';
... the compiler will use stw instruction (store word) instead of stb
(store byte) because input register is defined as vuint32_t in header
file. The workaround is to re-type te pointer like this:
*(uint8_t*)&CRC.INP.R = '0';
Regards,
Lukas
Hi Likas,
Your example and work around is good but not suitable to me. I cannot make changes to my micro code which generates 32 bit CRC.
Also the code you provided is same as what we have in our micro.
My question is I need any C / C++ source code which generates the same CRC generated by MPC5643L micro. I gave you the way we configure CRC registers as well.
Please support if you have any way/solution.
Thanks
Amar
Hi,
If you don't change the configuration as mentioned, it does not return 'standard' CRC32. If you can't change the configuration, you need to update the code to follow this difference:
I do not have such code.
Regards,
Lukas