cancel
Showing results for 
Search instead for 
Did you mean: 

Python and CRC8 verification

Pilous Droip
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:
 check = AddToCRC(i, check)
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
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

def AddToCRC(b, crc):

     crc ^= b

     for i in xrange(8):

          odd = (crc & 1) == 1

          crc >>= 1

          if (odd):

               crc ^= 0x8C

     return crc

def AddToCRC(b, 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..
Pilous Droip
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 */
 *returnCRC = LL_CRC_ReadData8(CRC);
 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]
def AddToCRC(b, crc):
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 :
 check = AddToCRC(i, check)
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] << 8) | 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 */

  return(LL_CRC_ReadData8(CRC));

}

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..