FCE Kernel 2 Hardware CRC 16 CCITT - reproduce results with c-Code

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Not applicable
I want to calculate a checksum over a flash area containing the application code. The checksum is calculated within build process on the PC, and is checked by the bootloader running on the XMC4500 before the jump to the application is done.
My problem is, that I am not able to find the correct algorithm on the PC to get the same checksum as calculated by the FCE Kernel 2.

I used the "SIMPLE" algorithm (chapter 8. of "A PAINLESS GUIDE TO CRC ERROR DETECTION ALGORITHM" by Ross N. Williams) on the PC (as suggested by the XMC4500 user manual).

The parameter for the CCITT CRC16 (Kernel 2) are (according to Ross N. Williams):
Poly: 0x1021
Start: 0xFFFF
XOR: 0x0000
REFIN: no reflection
REFOUT: no reflection

When I calc the checksum (by PC or by a sheet of paper) of the message data 0x0102 the result (only feeding in the 16bit msg, without "tail" (augmented 16 zero bits) is: 0x1C0D

My XMC Bootloader executes the following code:


FCE->CLC = 0; // Clear the DISR (disable request) bit
while( (FCE->CLC & FCE_CLC_DISS_Msk) != 0 ) {/*Wait until module is active*/ }
FCE_KE2->CFG = 0x0; // Byte Wise reflection disabled, Bit Wise reflection disabled, XOR 0x0000
FCE_KE2->CRC = 0xFFFF;

// -> Debugger now reads:
// IR = 0x00000000
// RES = 0x0000FFFF
// CFG = 0x00000000
// STS = 0x00000000

FCE_KE2->IR = 0x0102;
// -> Debugger now reads:
// IR = 0x00000102
// RES = 0x00000E7C (=CRC)
// CFG = 0x00000000
// STS = 0x00000000


The result is 0x0E7C -> different to the expected 0x1C0D...
I tried to manually reflect bitwise/bytewise the input data for the FCE_KE2->IR but I did not achieve to get the expected result:

Start value FCE_KE2->IR FCE_KE2->RES
0xFFFF 0x0201 0x6B4C
0xFFFF 0x0102 0x0E7C
0xFFFF 0x4080 0x814B
0xFFFF 0x8040 0x4E53
0x00000 0x0201 0x7643
0x00000 0x0102 0x1373

* Is there any pseudo code or logical diagram what the kernel does?

* Is it possible to process a uneven number of input bytes? In the Internet there is often a Test String "123456789" -> 0x313233...39 used as test data for checksum calculation...

Thanks a lot for your help!

Mario
0 Likes
14 Replies
Not applicable
Maybe you have the same problem as I had. I found, that it is problem with different endianity on PC and XMC platform. So you are computing CRC from different data representation, therefore computed CRCs are not equal... Try to swap endianity of input data on the PC.
0 Likes
Not applicable
Hi Panx,

That was my first idea, and I swapped the bytes, reflected them... but nothing lead me to the expected result...
I tried 0x0201, 0x4080, 0x8040... instead of 0x0102 but I had no luck...
Do you use the Kernel2 with 16bit CCITT algorithm too? Could you send me your c-Code or a dummy algorithm which is able to reproduce the FCE calculations?
Thanks!
Best regards
Mario
0 Likes
Not applicable
Hello,
I used IEEE 802.3 32bit, so my problem was little different and corect byte swaping helped...
I thing that your problem is somewhere in your CRC computation on the PC, because when I try to compute your task by this online tool: http://www.zorc.breitbandkatze.de/crc.html (HEX value 0x0102 is inserted as "%01%02"), the result was 0x0E7C (the same as from your XMC).
Here is the complete C code of used algorithm: http://www.zorc.breitbandkatze.de/crctester.c
I hope it helps.
0 Likes
Not applicable
Hello,
I used IEEE 802.3 32bit, so my problem was little different and corect byte swaping helped...
I thing that your problem is somewhere in your CRC computation on the PC, because when I try to compute your task by this online tool: http://www.zorc.breitbandkatze.de/crc.html (HEX value 0x0102 is inserted as "%01%02"), the result was 0x0E7C (the same as from your XMC, isn't it?).
Here is the complete C code of used algorithm: http://www.zorc.breitbandkatze.de/crctester.c
I hope it helps.
0 Likes
Not applicable
Hello,
I used IEEE 802.3 32bit, so my problem was little different and corect byte swaping helped...
I thing that your problem is somewhere in your CRC computation on the PC, because when I try to compute your task by this online tool: http://www.zorc.breitbandkatze.de/crc.html (HEX value 0x0102 is inserted as "%01%02"), the result was 0x0E7C (the same as from your XMC, isn't it?).
Here is the complete C code of used algorithm: http://www.zorc.breitbandkatze.de/crctester.c
I hope it helps.
0 Likes
Not applicable
Hello,
I used IEEE 802.3 32bit, so my problem was little different and corect byte swaping helped...
I thing that your problem is somewhere in your CRC computation on the PC, because when I try to compute your task by this online tool: http://www.zorc.breitbandkatze.de/crc.html (HEX value 0x0102 is inserted as "%01%02"), the result was 0x0E7C (the same as from your XMC, isn't it?).
Here is the complete C code of used algorithm: http://www.zorc.breitbandkatze.de/crctester.c
I hope it helps.
0 Likes
Not applicable
Hello,
I used IEEE 802.3 32bit, so my problem was little different and corect byte swaping helped...
I thing that your problem is somewhere in your CRC computation on the PC, because when I try to compute your task by this online tool: http://www.zorc.breitbandkatze.de/crc.html (HEX value 0x0102 is inserted as "%01%02"), the result was 0x0E7C (the same as from your XMC, isn't it?).
Here is the complete C code of used algorithm: http://www.zorc.breitbandkatze.de/crctester.c
I hope it helps.
0 Likes
Not applicable
Hello,
I used IEEE 802.3 32bit, so my problem was little different and corect byte swaping helped...
I thing that your problem is somewhere in your CRC computation on the PC, because when I try to compute your task by this online tool: http://www.zorc.breitbandkatze.de/crc.html (HEX value 0x0102 is inserted as "%01%02"), the result was 0x0E7C (the same as from your XMC, isn't it?).
Here is the complete C code of used algorithm: http://www.zorc.breitbandkatze.de/crctester.c
I hope it helps.
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Hi guys,

I did not continue reading this thread, but this topic has been discussed before and hope you can find useful info from below mentioned link..

Discussed topic..
http://www.infineonforums.com/archive/index.php/t-2260.html?

You can verify XMC4000 FCE result from the below link.

http://depa.usst.edu.cn/chenjq/www2/software/crc/CRC_Javascript/CRCcalculation.htm
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
See FCE configuration

1313.attach
0 Likes
Not applicable
Hi Travis,

thanks for your response. I know the thread you send to me, but the problem is not solved in my opinion (at least not for the Kernel 2 of the FCE). The Problem gets even worse, because now I have three possible results (The online tool result is different to my algorithm and to the Kernel 2 result...). And as mentioned in the linked thread, the online tool does not describe what the algorithm is doing (Reflection, endianess, augmentation...), because of this it is not a great help...

My algorithm is described within the "Painless Guide" and within this article http://srecord.sourceforge.net/crc16-ccitt.html there are some basic calculations and examples.

I attached a screenshot of the online tool and did calculations for different endianess/bit-/byte-reflections, and some screenshots while debugging the FCE, and the results...
0x0102 -> Testdata result: 0x1373 The FCE Kernel 2 result is: 0x0E7C -> augmented (16 zero bits) = 0x9C14 SIMPLE algorithm (painless guide): 0x1C0D
0x0201 -> Endianess changed 0x7643 0x64BC -> augmented (16 zero bits) = 0x5E98
0x8040 -> complete bit reflection 0x535C 0x4E53 -> augmented (16 zero bits) = 0x4455
0x4080 -> byte wise bit reflection 0x9C44 0x814B -> augmented (16 zero bits) = 0xD106

1321.attach
result of online tool for data 0x0102...

1322.attach
starting point/init of FCE Kernel2: CRC = 0xFFFF -> InitValue = 0xFFFF, CFG = 0x0 -> no reflections, XOR with 0x0000....

1323.attach
result after putting 0x0102 into IR...


I hope you can help me with my two questions (please have a look at my first post...)

Thanks!

Best regards Mario
0 Likes
Not applicable
Hi there,

I found an online CRC-calculator with which I could reproduce the FCE Kernel 2 results (http://www.zorc.breitbandkatze.de/crc.html). There is also the C-Code for download available, so I can use the FCE module for my checksum calculations in future...

1324.attach
This are the options I used to reproduce the FCE Kernel 2 results ( FCE_KE2->CRC= 0xFFFF (start value), FCE_KE2->CFG =0x0 (Kernel configuration), FCE_KE2->IR = 0x0102 )

The Problem was the start value in the SIMPLE Algorithm: I used 0xFFFF but the code in the internet takes this value and computes some XORs with the Polynom to get to a start value of 0x84cf -> If I use this start value within my code I get the same result as the FCE... -> this modified start value seems to include the CRC tail (augmentation of 16 zero bytes) but I haven't understand the algorithm completely up to now...

Then the only open question is, if there is a possibility to process data with a length != %2, e.g. 9Bytes with the Kernel 2 (16Bit poly)...

Thanks a lot for your help...

Best regards

Mario
0 Likes
Travis
Employee
Employee
First solution authored Welcome! 500 replies posted
Hi all,

Please note that there are 3 different CRC polynomial in XMC4000.

– CRC kernel 0 and 1: IEEE 802.3 CRC32 ethernet polynomial: 0x04C11DB71)
x32+x26+x23+x22+x16+x12+x11+x10+x8+x7+x5+x4+x2+x+1

– CRC kernel 2: CCITT CRC16 polynomial: 0x1021 - x16+x12+x5+1

– CRC kernel 3: SAE J1850 CRC8 polynomial: 0x1D - x8+x4+x3+x2+1
0 Likes
Not applicable
Hi there,

I had a timing problem with my function which feeds the CRC algorithm and then reads back the result:

std::int32_t FCE_Feed(std::uint8_t argKernelIdx, std::uint32_t argData, std::uint32_t * p_argCrc)
{
std::int32_t status = FUNC_RETURN_OK;
std::uint32_t tmpKernelAddress = a_constFceKernelBase[argKernelIdx];
FCE_KE_TypeDef * p_tmpKernel = (FCE_KE_TypeDef*)tmpKernelAddress;
// *** Check parameter ***
// Check Kernel
if ( argKernelIdx >= FCE_KERNEL_CNT )
{
status = FUNC_RETURN_ERROR;
}
else
{ // Parameter ok..
p_tmpKernel->IR = argData;
*p_argCrc = p_tmpKernel->RES;
}
return status;
}


The Code to write the IR and to read the RES was assembled to two directly following Assembler instructions. When the µC (XMC4500 running @60MHz) executes the read of the RES there was still the old result in this register. Placing some "nops" between the two instructions solved the problem...

Best regards Mario
0 Likes