# SENT CRC calculation

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 = {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 Can anyone tell me how to calculate the CRC for SENT protocol.

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

• Are you applying the data[i] in the correct order using 0 -> 1 -> 2 -> 3 ? It could be that it needs to be: 3 -> 2 -> 1 -> 0 Feb 3, 2017 at 13:24
• yeah, I am sending the data in correct order, MSB is first Feb 3, 2017 at 13:37
• CheckSum = CheckSum^0x0A; I copied your code, but comparing CRC Calc with dsPIC32 built in CRC I had to add CheckSum = CheckSum^0x0A; then my calc of CRC was same as the built in CRC calc. Nov 7, 2018 at 18:38
• Sorry to write you more than one and a half years after, but... What if Data[i] is greater than 16? Isn't this case going to generate an index out of bounds error? Nov 21, 2018 at 15:32

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 = {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 = {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

According to the document here: http://www.nxp.com/assets/documents/data/en/application-notes/AN4219.pdf So if you have the status nibble in data you should try just computing CRC over data , data  and data .

• That's right !! as I already said that CRC calculation is for only 3 data nibbles. And I am computing only for data nibbles i.e data, data and data. Feb 3, 2017 at 14:13
• @AbdulGafoor - Unless you have changed your code showing in the above question I happen to see a FOR loop that iterates over data, data and data instead of what you intended. Feb 3, 2017 at 23:49
• for status I am using another byte. It is not included in the data[], please ignore my above comment. Feb 6, 2017 at 6:45