Python and CRC8 verification
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2018-07-03 1:11 AM
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- Labels:
-
CRC
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2018-07-03 2:34 AM
The 0xF8 value looks reasonable, show how you are computing on the STM32
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2018-07-03 4:39 AM
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 crcdef AddToCRC(b, crc): crc ^= b for i in xrange(8): if ((crc & 1) == 1): crc = (crc >> 1) ^ 0x8C else crc >>= 1 return crcUp vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2018-07-03 4:41 AM
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?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2018-07-03 4:47 AM
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);�?�?�?�?�?�?�?�?�?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2018-07-03 7:29 AM
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.
Up vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2018-07-03 7:42 AM
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);�?�?�?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2018-07-03 7:59 AM
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2018-07-03 10:44 AM
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 backasswarduint8_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
000000000000008F000000F8000000DD000000F4Crc8CSlow : F4CRC:F4
CRC-BLOCK: Pass 0 00000000 00 00000000 1 00000000 AB 0000008F 2 0000008F FF 000000F8 3 000000F8 FE 000000DD 4 000000DD 01 000000F4000000F4CRC-BYTEWISE: PassUp vote any posts that you find helpful, it shows what's working..
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
2018-07-03 10:54 AM
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 Zerouint8_t Crc8CQuick(uint8_t Crc, int Size, uint8_t *Buffer)
{ static const uint8_t CrcTable[] = { // Nibble table for polynomial 0x8C0x00,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);
}Up vote any posts that you find helpful, it shows what's working..
