iLLD_TC27xC  1.0
How to use the FCE CRC Interface driver?
Collaboration diagram for How to use the FCE CRC Interface driver?:

FCE gives CRC-x(x= 8,16,32) message signatures. Kernel 3 is used for CRC-8,Kernel 2 is used for CRC-16,Kernel 0 1nd Kernel 1 is used for CRC-32.

In the following sections it will be described, how to integrate the driver into the application framework.

Preparation

Include Files

Include following header file into your C code:

#include <IfxFce_Crc.h>

Variables

Declare the FCE and CRC handles as global variable in your C code:

// used globally
static IfxFce_Crc fce;
static IfxFce_Crc_Crc fceCrc32_0;
static IfxFce_Crc_Crc fceCrc32_1;
static IfxFce_Crc_Crc fceCrc16;
static IfxFce_Crc_Crc fceCrc8;

Interrupt Handler Installation

See also How to define Interrupts?

Define priorities for the Interrrupt handler. This is normally done in the Ifx_IntPrioDef.h file:

// priorities are normally defined in Ifx_IntPrioDef.h
#define IFX_INTPRIO_FCE 1

Add the interrupt service routine to your C code which should do the error flag handling:

IFX_INTERRUPT(fceISR, 0, IFX_INTPRIO_FCE)
{
{
Ifx_FCE_STS interruptStatus = IfxFce_Crc_getInterruptStatus(&fceCrc32_0);
if (interruptStatus.U )
{
if ( interruptStatus.B.CMF == 1)
{
// CRC Mismatch Error...!
}
if( interruptStatus.B.CEF == 1)
{
// Configuration Error...!
}
if ( interruptStatus.B.LEF == 1)
{
// Length Error...!
}
if ( interruptStatus.B.BEF == 1)
{
// Bus Error...!
}
}
}
{
Ifx_FCE_STS interruptStatus = IfxFce_Crc_getInterruptStatus(&fceCrc32_1);
if (interruptStatus.U )
{
if ( interruptStatus.B.CMF == 1)
{
// CRC Mismatch Error...!
}
if( interruptStatus.B.CEF == 1)
{
// Configuration Error...!
}
if ( interruptStatus.B.LEF == 1)
{
// Length Error...!
}
if ( interruptStatus.B.BEF == 1)
{
// Bus Error...!
}
}
}
{
Ifx_FCE_STS interruptStatus = IfxFce_Crc_getInterruptStatus(&fceCrc16);
if (interruptStatus.U )
{
if ( interruptStatus.B.CMF == 1)
{
// CRC Mismatch Error...!
}
if( interruptStatus.B.CEF == 1)
{
// Configuration Error...!
}
if ( interruptStatus.B.LEF == 1)
{
// Length Error...!
}
if ( interruptStatus.B.BEF == 1)
{
// Bus Error...!
}
}
}
{
Ifx_FCE_STS interruptStatus = IfxFce_Crc_getInterruptStatus(&fceCrc8);
if (interruptStatus.U )
{
if ( interruptStatus.B.CMF == 1)
{
// CRC Mismatch Error...!
}
if( interruptStatus.B.CEF == 1)
{
// Configuration Error...!
}
if ( interruptStatus.B.LEF == 1)
{
// Length Error...!
}
if ( interruptStatus.B.BEF == 1)
{
// Bus Error...!
}
}
}
}

Finally install the interrupt handler in your initialisation function:

// install interrupt handler
IfxCpu_Irq_installInterruptHandler(&amp;fceISR, IFX_INTPRIO_FCE);

Module Initialisation

The module initialisation can be done in the same function. Here an example for all CRC kernels:

// create module config
IfxFce_Crc_initModuleConfig(&fceConfig, &MODULE_FCE0);
// ISR priorities and interrupt target
fceConfig.isrPriority = IFX_INTPRIO_FCE;
// initialize module
//IfxFce_Crc fce; // defined globally
IfxFce_Crc_initModule(&fce, &fceConfig);
// initialize CRC kernels
IfxFce_Crc_initCrcConfig(&crcConfig, &fce);
//IfxFce_Crc_Crc fceCrc32_0; // defined globally
IfxFce_Crc_initCrc(&fceCrc32_0, &crcConfig);
//IfxFce_Crc_Crc fceCrc32_1; // defined globally
IfxFce_Crc_initCrc(&fceCrc32_1, &crcConfig);
//IfxFce_Crc_Crc fceCrc16; // defined globally
IfxFce_Crc_initCrc(&fceCrc16, &crcConfig);
//IfxFce_Crc_Crc fceCrc8; // defined globally
IfxFce_Crc_initCrc(&fceCrc8, &crcConfig);

CRC Calculation

Now, all 4 FCE kernels are configured and can be used to calculate CRC values.

In following examples, CRC is calculated over following array:

#define CHECK_DATA_SIZE 25
uint32 checkData[CHECK_DATA_SIZE] = {
0xbe9957bb,
0x1c706c1e,
0x14c3db3f,
0x7fb17a93,
0xb0d9d5a7,
0x768093e0,
0x88b206a0,
0xc51299e4,
0xe8a97d48,
0x89367f27,
0x70095984,
0xec030f75,
0xdc22f8d4,
0xd951407b,
0x34ae18c6,
0x4d47ba7d,
0x0e2e4622,
0x4a2e90d3,
0xdaec3752,
0xcd3ed11c,
0x36b416b7,
0x8ea28658,
0xdd37eee3,
0x23928b62,
0x84eb4b22,
};

Function calls:

// Common usage:
{
uint32 fceCrc = IfxFce_Crc_calculateCrc32(&fceCrc32_0, checkData, CHECK_DATA_SIZE, 0x00000000);
// -> CRC32 will be 0xd95def75
}
// Piecewise CRC calculation over two (more more) memory blocks.
// Please note that the initial value requires a bytewise reflection, and an inversion whenever it's passed for the next calculation:
{
uint32 fceCrc;
fceCrc = IfxFce_Crc_calculateCrc32(&fceCrc32_1, (uint32 *)&checkData[0], CHECK_DATA_SIZE-10, 0x00000000);
fceCrc = IfxFce_Crc_calculateCrc32(&fceCrc32_1, (uint32 *)&checkData[CHECK_DATA_SIZE-10], 10, ~IfxFce_reflectCrc32(fceCrc, 32));
// -> CRC32 will be 0xd95def75 (as well)
}
// using the CRC16 kernel
{
uint32 fceCrc;
fceCrc = IfxFce_Crc_calculateCrc16(&fceCrc16, (uint16 *)checkData, CHECK_DATA_SIZE*2, 0x00000000);
// -> CRC16 will be 0xda6f
}
// using the CRC8 kernel
{
uint32 fceCrc;
fceCrc = IfxFce_Crc_calculateCrc8(&fceCrc8, (uint16 *)checkData, CHECK_DATA_SIZE*4, 0x00000000);
// -> CRC8 will be 0x61
}

Error Interrupt on CRC mismatch

By default, all error interrupts aside from the CRC mismatch interrupt (CMF) are enabled.

In order to use the CMF interrupt as well, the appr. error flag has to be enabled during configuration:

// initialize CRC kernel with CRC check enabled
IfxFce_Crc_initCrcConfig(&crcConfig, &fce);
IfxFce_Crc_initCrc(&fceCrc32_0, &crcConfig);

And the expected CRC value has to be written into the expectedCrc field of the handle before the CRC calculation is started.

{
// Expected CRC:
fceCrc32_0.expectedCrc = 0xd95def75;
// do calculation
uint32 fceCrc = IfxFce_Crc_calculateCrc32(&fceCrc32_0, checkData, CHECK_DATA_SIZE, 0x00000000);
// we can expect, that an error interrupt has been triggered if the CRC over checkData didn't match.
}