Skip to main content
newbie_stm32
Associate III
May 23, 2023
Solved

CRC-16-IBM using HAL APIs

  • May 23, 2023
  • 5 replies
  • 5438 views

Hi community, I am working on CRC generation with polynomial 0x8005 and initial value 0x0000, so I configured it as below


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

This topic has been closed for replies.
Best answer by Tesla DeLorean

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);
}

5 replies

waclawek.jan
Super User
May 23, 2023

> uint32_t bufer[]

Are you sure you didn't mean uint8_t buffer[]?

JW

Tesla DeLorean
Guru
May 23, 2023

Not the MODBUS one, but the reverse 0xA001 vs 0x8005

https://community.st.com/s/question/0D50X00009XkhPASAZ/stm32foxx-crc-usage-of-hal-drivers

But needs to BYTE feed for sure.

You sure on the 0x43B8, I get that in the reversed / inverse sense. The STM32 is a left-shifting beast.

Do you have other exemplars ?

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Tesla DeLorean
Guru
May 23, 2023
Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
newbie_stm32
Associate III
May 24, 2023

Hi @Community member​, yes you are right it's a typo. The CRC is 0x43BD. But I got 0xe2cb after changing it to uint8_t.

waclawek.jan
Super User
May 24, 2023

Have you changed the array type?

Your link2 gives me 0x43BD too, btw.

JW

newbie_stm32
Associate III
May 24, 2023

Hi @Community member​, It's a typo it must be 0x43BD. I changed the array size to uint8_t and got a CRC of 0xe2cb which is CRC-16/BUYPASS.

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
May 25, 2023

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);
}

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
waclawek.jan
Super User
May 24, 2023

As Clive (Tesla) said above, you have to swap the bits order. You did not tell us the STM32 model you are using, but you may be able to experiment with bit ordering in CRC_CR.

JW

newbie_stm32
Associate III
May 25, 2023

Hi @Community member​, I am using NUCLEO-G491RE development board.

newbie_stm32
Associate III
May 25, 2023

Hi thanks for your inputs