Hello everyone !
I am currently trying to compute CRC32 checksum with a LPC1788.
Here is the functions I am using :
#define u32 unsigned long
void Reg_InitCRC()
{
/* Standard CRC32 */
CRC_MODE = 0x00000036;
/* CRC32 MPEG-2 */
// CRC_MODE = 0x00000002;
CRC_SEED = 0xFFFFFFFF;
}
u32 REG_Calculate_CRC(u32 u32_Data)
{
u32 u32_CRC;
CRC_WR_DATA = u32_Data;
u32_CRC = CRC_SUM;
return u32_CRC;
}
Then, I am testing those function with this code :
u32 u32_data[4];
u32_data[0] = 0xAAAAAAAA;
u32_data[1] = 0x69686968;
u32_data[2] = 0x69686869;
u32_data[3] = 0x12345678;
u32 u32_res = 0;
Reg_InitCRC();
u32_res = REG_Calculate_CRC(u32_data[0]);
CRC_SEED = 0xFFFFFFFF; // Not really needed, just for safety
u32_res = REG_Calculate_CRC(u32_data[1]);
CRC_SEED = 0xFFFFFFFF;
u32_res = REG_Calculate_CRC(u32_data[2]);
CRC_SEED = 0xFFFFFFFF;
u32_res = REG_Calculate_CRC(u32_data[3]);
So when doing this, I am observing a really strange behavior. When the input data is an u32 composed of identicals u8 (example : 0xAAAAAAAA) or "symetrical" u8 (0x12343412 and 0x69686869) the CRC output is correct (for both CRC32 and CRC32-MPEG2).
But when the data input is made of differents u8 (example : 0x12345678), the output is not what I am expecting at all.
Here's a table summing up my situation :
Input | My CRC32 output | Real CRC32 output | My MPEG2 output | Real MPEG2 output |
0xAAAAAAAA | 0xb596e05e | 0xB596E05E | 0x42fc4b29 | 0x42FC4B29 |
0x12343412 | 0xb0a58ffb | 0xB0A58FFB | 0x9db25e0f | 0x9DB25E0F |
0x69686869 | 0xb8e4c55e | 0xB8E4C55E | 0xff43f3da | 0xFF43F3DA |
0x12345678 | 0xaf6d87d2 | 0x4A090E98 | 0xad37d056 | 0xDF8A8A2B |
When looking at this table, I finnally understood : if I want to have the "expected" CRC32, I have to reverse bytes (and not bits) in my input. So for the last line :
0x78563412 in my code (but actually computing CRC32 for 0x12345678) | 0x4a090e98 | 0x4A090E98 | 0xdf8a8a2b | 0xDF8A8A2B |
So my question is : why do I have to switch the endianess of my u32 to find the expected result ?
Note : I am using this website to check CRC32.
已解决! 转到解答。
Hi,
I suppose that the CRC module of LPC1788 uses big endian format.
With PC CRC tools, if you input 0x78563412, the CRC32 output will be 0xaf6d87d2
With LOPC1788, if you input 0x12345678, the CRC32 output will be 0xaf6d87d2.
In conclusion, the CRC module of LPC1788 use big endian.
Hope it can help you
BR
XiangJun Rong
Hi,
I suppose that the CRC module of LPC1788 uses big endian format.
With PC CRC tools, if you input 0x78563412, the CRC32 output will be 0xaf6d87d2
With LOPC1788, if you input 0x12345678, the CRC32 output will be 0xaf6d87d2.
In conclusion, the CRC module of LPC1788 use big endian.
Hope it can help you
BR
XiangJun Rong
Hi
How about using the init function:
void Reg_InitCRC()
{
/* Standard CRC32 */
CRC_MODE = 0x00000032; //instead of 0x36
/* CRC32 MPEG-2 */
// CRC_MODE = 0x00000002;
CRC_SEED = 0xFFFFFFFF;
}
I think that the BIT_RVS_WR should be cleared rather than being set.
Hope it can help you
BR
XiangJun Rong
Hi,
First of all, thank you for your answer.
I think I already tried that, I will double check this afternoon.
But if I understand the documentation clearly, what BIT_RVS_WR is doing is reversing the bits order (and not the bytes).
So, 0x1234 5678 will be treated as 0x1E6A 2C48, am I right ?
(in binary)
00010010 00110100 01010110 01111000 --> 00011110 01101010 00101100 01001000