Electrical – SENT CRC calculation

communicationcrc

I am using SENT protocol in my project.

In my SENT implementation, the data nibbles are 3. So 12 bit data, including a status nibble and CRC nibble.

I need to calculate the CRC for 3 data nibbles.

The seed value for CRC calculation is 5 and the polynomial is

\$ x^{4} + x^{3} + x^2 + 1 \$

I have done the following for CRC calculation:

char CheckSum, i;
char CrcLookup[16] = {0, 13, 7, 10, 14, 3, 9, 4, 1, 12, 6, 11, 15, 2, 8, 5};
CheckSum= 5; // initialize checksum with seed "0101"
for (i=0; i<3; i++) {
CheckSum = CheckSum ^ Data[i];
CheckSum = CrcLookup[CheckSum];
}

In SENT analyser, I could see CRC error. The log is as follows

SENT_LOG

Can anyone tell me how to calculate the CRC for SENT protocol.

Note: I have 0XABC as data nibble and 3 is status nibble.

Best Answer

After a lot of searching, comprising going on the SAE J2716 norm to see exactly what was the implementation like, I found out that the code was wrong. The order of the operations was inverted, and of course you should be sure that you are not accessing items out of bounds, like you would with your code.

The correct implementation should be:

uint8_t calculatedCRC, i;
const uint8_t CrcLookup[16] = {0, 13, 7, 10, 14, 3, 9, 4, 1, 12, 6, 11, 15, 2, 8, 5};
calculatedCRC = 5; // initialize checksum with seed "0101"

for (i = 0; i < 6; i++)
{
    calculatedCRC = CrcLookup[calculatedCRC];
    calculatedCRC = (calculatedCRC ^ Data[i]) & 0x0F;
}
// One more round with 0 as input
calculatedCRC = CrcLookup[calculatedCRC];

If you have, like in my case, the complete payload in a 32-bit variable in the format SDDDDDDC (S is the status nibble, C the CRC you have to verify), then the code can be modified in this way:

uint32_t crcData = YourOriginal32BitSentFrame;

uint8_t calculatedCRC, i;
const uint8_t CrcLookup[16] = {0, 13, 7, 10, 14, 3, 9, 4, 1, 12, 6, 11, 15, 2, 8, 5};
calculatedCRC = 5; // initialize checksum with seed "0101"

for (i = 0; i < 6; i++)
{
    uint8_t crcDatum = (crcData >> 24) & 0x0F;

    calculatedCRC = CrcLookup[calculatedCRC];
    calculatedCRC = calculatedCRC ^ crcDatum;
    crcData <<= 4;
}
// One more round with 0 as input
calculatedCRC = CrcLookup[calculatedCRC];

Best regards