2023-05-23 07:31 AM - edited 2023-11-20 04:49 AM
Hi community, I am working on CRC generation with polynomial 0x8005 and initial value 0x0000, so I configured it as below
I am using the data as shown below and the CRC should be 0x43B8 but the value got from the API is different. So I am missing something.
uint32_t bufer[] = { 0x23, 0x41, 0x54, 0x4F, 0x4E, 0xFF, 0x53, 0x4C, 0x30, 0x43, 0x55, 0x52, 0xFF, 0x0A, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39 };
uint32_t crc = HAL_CRC_Calculate(&hcrc, bufer, sizeof(bufer));
I appreciate your input.
Solved! Go to Solution.
2023-05-25 12:17 AM
Hi thanks for your inputs
2023-05-25 01:26 PM
link1 with hex 23 41 54 4F 4E FF 53 4C 30 43 55 52 FF 0A 30 31 32 33 34 35 36 37 38 39
also 0x43BD
Ok, so are we still looking for a STM32 HW example?
If the HW reports different values one or more of the settings is wrong. The implementation is difficult, and sensitive to bit and byte ordering. It's also not a reentrant resource.
2023-05-25 01:37 PM
0xE2CB is a left shifting answer
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
int main(int argc, char **argv)
{
int i, j, k;
uint16_t crc;
uint8_t test[] = { 0x23,0x41,0x54,0x4F,0x4E,0xFF,0x53,0x4C,0x30,0x43,0x55,0x52,0xFF,0x0A,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39 };
#define POLY 0x8005
crc = 0x0000;
for(j=0; j<sizeof(test); j++)
{
crc = crc ^ (test[j] << 8);
for(i=0; i<8; i++)
{
if (crc & 0x8000)
crc = (crc << 1) ^ POLY;
else
crc = (crc << 1);
}
}
printf("crc=%04X\n", crc);
return(1);
}
0x43BD is the right shifting answer with the 0xA001 poly (ie 0x8005 reversed)
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
int main(int argc, char **argv)
{
int i, j, k;
uint16_t crc;
uint8_t test[] = { 0x23,0x41,0x54,0x4F,0x4E,0xFF,0x53,0x4C,0x30,0x43,0x55,0x52,0xFF,0x0A,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39 };
#define POLY 0xA001
crc = 0x0000;
for(j=0; j<sizeof(test); j++)
{
crc = crc ^ test[j];
for(i=0; i<8; i++)
{
if (crc & 0x0001)
crc = (crc >> 1) ^ POLY;
else
crc = (crc >> 1);
}
}
printf("crc=%04X\n", crc); // 0x43BD
return(1);
}
2023-05-25 01:48 PM
I've posted MODBUS examples for STM32 HW before, here's illustration we're talking about same algo
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
uint16_t Crc16ModbusFast(uint16_t Crc, size_t Size, uint8_t *Buffer) // sourcer32@gmail.com
{
static const uint16_t CrcTable[16] = { // Nibble lookup for 0xA001 polynomial
0x0000,0xCC01,0xD801,0x1400,0xF001,0x3C00,0x2800,0xE401,
0xA001,0x6C00,0x7800,0xB401,0x5000,0x9C01,0x8801,0x4400 };
while(Size--)
{
Crc = Crc ^ *Buffer++;
// Process 8-bits, 4 at a time, or 2 rounds
Crc = (Crc >> 4) ^ CrcTable[Crc & 0xF];
Crc = (Crc >> 4) ^ CrcTable[Crc & 0xF];
}
return(Crc);
}
int main(int argc, char **argv)
{
int i, j, k;
uint16_t crc;
uint8_t test[] = { 0x23,0x41,0x54,0x4F,0x4E,0xFF,0x53,0x4C,0x30,0x43,0x55,0x52,0xFF,0x0A,0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39 };
#define POLY 0xA001
crc = 0x0000;
for(j=0; j<sizeof(test); j++)
{
crc = crc ^ test[j];
for(i=0; i<8; i++)
{
if (crc & 0x0001)
crc = (crc >> 1) ^ POLY;
else
crc = (crc >> 1);
}
}
printf("crc=%04X\n", crc); // 0x43BD
printf("crc=%04X\n", Crc16ModbusFast(0, sizeof(test), test)); // 0x43BD
return(1);
}
2023-05-25 01:52 PM
Here's the SPL variant, you'll need to set the initialization value to zero, but this should give you all the boxes you need to check.
https://github.com/cturvey/RandomNinjaChef/blob/main/STM32F3_DISCO_Programmable_CRC_SPL_Example.c
2023-05-25 09:55 PM
@Community member thanks for the e.g
2023-05-25 10:01 PM
> Ok, so are we still looking for a STM32 HW example?
No, it's done I got it.