cancel
Showing results for
Did you mean:

# Python and CRC8 verification

Senior
Posted on July 03, 2018 at 10:11

Helo friends,

I try calculate CRC8 in python and compare with CRC in STM And I have a problem.

My python CRC is return wrong value.

Python script:

``````def AddToCRC(b, crc):
b2 = b
for i in xrange(8):
odd = ((b2^crc) & 1) == 1
crc >>= 1
b2 >>= 1
if (odd):
crc ^= 0x8C
return crc�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?``````

And I call this function here:

``````TestValue = [0, 0xAB, 0xFF]
check = 0
for i in TestValue:
print(hex(check))�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?``````

And I get CRC8 in STM32F: 0x8B

And CRC from python script: 0xF8

Any idea, how to calculate CRC8 in python for STM32?

#crc8 #crc
11 REPLIES 11
Guru
Posted on July 03, 2018 at 11:34

The 0xF8 value looks reasonable, show how you are computing on the STM32

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 03, 2018 at 11:39

These might be computationally more efficient

crc ^= b

for i in xrange(8):

odd = (crc & 1) == 1

crc >>= 1

if (odd):

crc ^= 0x8C

return crc

crc ^= b

for i in xrange(8):

if ((crc & 1) == 1):

crc = (crc >> 1) ^ 0x8C

else

crc >>= 1

return crc
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Senior
Posted on July 03, 2018 at 13:41

Okay. I used your python modification, and the result is the same. But I think that problem is with polynomial:

STM use: 0x04C11DB7

Is It Posible?

Posted on July 03, 2018 at 11:47

Here is my function to calculate CRC. And before call this function I enable CRC.

``````uint32_t CRC__Calculate8(uint8_t* arr, uint32_t count, const uint8_t reset, uint8_t *returnCRC)
{
/* Variable control - here miss */
/* Reset CRC data register if necessary */
if (reset) {
/* Reset generator */
LL_CRC_ResetCRCCalculationUnit(CRC);
}
/* Calculate CRC */
while (count--) {
/* Set new value */
LL_CRC_FeedData8(CRC, *arr++);
}
/* Return data */
return ERR_CRC_OK;
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?``````

And work with function

``````uint8_t TestDATA[] = {0, 0xAB, 0xFF};
uint8_t returnCRC = 0;
CRC__Calculate8(TestDATA, 3, 1, &returnCRC);�?�?�?�?�?�?�?�?�?``````

Posted on July 03, 2018 at 14:29

You don't state which STM32 you're using.

You don't show how you initialize the CRC peripheral and the polynomial selected.

Initialization value will also be important.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 03, 2018 at 14:42

Now I try only enable pheripherals:

``LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_CRC);�?``

And polynomial is used default. I try changed it, but it was without changes.

So I enable clock for CRC and call my test function:

``````uint8_t TestDATA[] = {0, 0xAB, 0xFF};
uint8_t returnCRC = 0;
CRC__Calculate8(TestDATA, 3, 1, &returnCRC);�?�?�?``````

Posted on July 03, 2018 at 14:59

Ok. Complete with set polynomial is here:

``````LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_CRC);
LL_CRC_SetPolynomialCoef(CRC, 0x07);
LL_CRC_SetPolynomialSize(CRC, LL_CRC_POLYLENGTH_8B);�?�?�?�?�?�?``````

After this I call:

``````uint8_t Test[] = {0x00, 0xAB, 0xFF, 0xFE, 0x01};
CRC__Calculate8(Test, 5, 1, &returnCRC);�?�?�?�?``````

And it was return value: 0xa2

But python sript:

``````Test = [0, 0xAB, 0xFF, 0xFE, 0x01]
crc ^= b
for i in xrange(8):
if ((crc & 1) == 1):
crc = (crc >> 1) ^ 0x8C
else:
crc >>= 1
return crc
check = 0x00
for i in Test :
print(hex(check))�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?``````

return:0xF4

And 0xA2 is dofferent from 0xF4

Posted on July 03, 2018 at 17:44

Ok, throwing random numbers into the configuration/polynomial isn't going to drop valid numbers out the end.

/* (1) Enable peripheral clock for CRC                 *********************/

LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_CRC);

/* (2) Configure CRC functional parameters  ********************************/

/* Configure CRC calculation unit with user defined polynomial value, 8-bit long */

LL_CRC_SetPolynomialCoef(CRC, 0x31); // 0x8C reversed - STM32 backassward

LL_CRC_SetPolynomialSize(CRC, LL_CRC_POLYLENGTH_8B);

LL_CRC_SetInitialData(CRC, 0);

LL_CRC_SetInputDataReverseMode(CRC, LL_CRC_INDATA_REVERSE_BYTE); // BYTE

LL_CRC_SetOutputDataReverseMode(CRC, LL_CRC_OUTDATA_REVERSE_BIT); // STM32 backassward

uint8_t Calculate_CRC_Block(uint32_t BufferSize, const uint8_t *Buffer)

{

uint32_t index;

/* Compute the CRC of Data Buffer array*/

for (index = 0; index < (BufferSize / 4); index++)

{

uint32_t d32 = (uint32_t)((Buffer[4 * index] << 24) | (Buffer[4 * index + 1] << 16) | (Buffer[4 * index + 2] << 😎 | Buffer[4 * index + 3]);

LL_CRC_FeedData32(CRC, d32);

}

/* Last bytes specific handling */

if ((BUFFER_SIZE % 4) != 0)

{

if  (BUFFER_SIZE % 4 == 1)

{

uint8_t d8 = Buffer[4 * index];

LL_CRC_FeedData8(CRC, d8);

}

if  (BUFFER_SIZE % 4 == 2)

{

uint16_t d16 = (uint16_t)((Buffer[4 * index ]<<8) | Buffer[4 * index + 1]);

LL_CRC_FeedData16(CRC, d16);

}

if  (BUFFER_SIZE % 4 == 3)

{

uint16_t d16 = (uint16_t)((Buffer[4 * index]<<8) | Buffer[4 * index + 1]);

uint8_t d8 = Buffer[4 * index + 2];

LL_CRC_FeedData16(CRC, d16);

LL_CRC_FeedData8(CRC, d8);

}

}

/* Return computed CRC value */

}

CRC Test

00000000

0000008F

000000F8

000000DD

000000F4

Crc8CSlow : F4

CRC:F4

CRC-BLOCK: Pass

0 00000000 00 00000000

1 00000000 AB 0000008F

2 0000008F FF 000000F8

3 000000F8 FE 000000DD

4 000000DD 01 000000F4

000000F4

CRC-BYTEWISE: Pass
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on July 03, 2018 at 17:54

I'll observe that the STM32 design for the CRC is chronically unhelpful. It is left-shifting, big-endian and not thread-safe.

// Dallas 1-Wire CRC Test App -

mailto:sourcer32@gmail.com

//  x^8 + x^5 + x^4 + 1 0x8C (0x18C)

//  Right Shift

//  Initialized to Zero

uint8_t Crc8CQuick(uint8_t Crc, int Size, uint8_t *Buffer)

{

static const uint8_t CrcTable[] = { // Nibble table for polynomial 0x8C

0x00,0x9D,0x23,0xBE,0x46,0xDB,0x65,0xF8, //

mailto:sourcer32@gmail.com

0x8C,0x11,0xAF,0x32,0xCA,0x57,0xE9,0x74 };

while(Size--)

{

Crc ^= *Buffer++; // Apply Data

Crc = (Crc >> 4) ^ CrcTable[Crc & 0x0F]; // Two rounds of 4-bits

Crc = (Crc >> 4) ^ CrcTable[Crc & 0x0F];

}

return(Crc);

}

uint8_t Crc8CSlow(uint8_t Crc, int Size, uint8_t *Buffer)

{

int i;

while(Size--)

{

Crc ^= *Buffer++; // Apply Data

for (i=0; i<8; i++) // 1-bit at a time

if (Crc & 0x01)

Crc = (Crc >> 1) ^ 0x8C; // Polynomial used in Dallas 1-Wire

else

Crc = (Crc >> 1);

printf('%08X\n', Crc);

}

return(Crc);

}
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..