2018-07-03 01: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 #crc2018-07-03 02:34 AM
The 0xF8 value looks reasonable, show how you are computing on the STM32
2018-07-03 04: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 crc2018-07-03 04: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?
2018-07-03 04: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);�?�?�?�?�?�?�?�?�?
2018-07-03 07: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.
2018-07-03 07: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);�?�?�?
2018-07-03 07: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
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: Pass2018-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);
}