cancel
Showing results for 
Search instead for 
Did you mean: 

STM32G4 CRC8 with user polynomial doesn't match other method

YWang.31
Associate II

Hello, there,

I need CRC8 in my design. Thinking with the Polynomial programmability in Stm32G4 . It should be straight forward.

When I tried to test with the example "CRC_UserDefinedPolynomial" coming with stm32cube_fw_g4_v130 in "Examples_LL" folder, the result (0xA6) matches the "expected value" set in the code.

However, when the same group of the data is tested with other CRC calculator for Poly 0x9B, eg. https://crccalc.com/, the result is 0x88 instead of 0xA6.

Then I tried another example (different data set 0x1, 0x2, 0x3, 0x4) with HAL, the result doesn't match either.

0693W000003QyciQAC.jpg0693W000003QycTQAS.jpg

The CRC hardware is a blackbox so I couldn't figure it out why. Is there anyone having running into similar issue and knowing the cause of the mismatch?

I would like to appreciate any inputs.

Thanks.

1 ACCEPTED SOLUTION

Accepted Solutions
YWang.31
Associate II

Thanks to the OPs who viewed this thread, especially @waclawek.jan and @TDK. Just to update in case it can be helpful to anyone may run into it.

I dug a little more in the Calculate_CRC() of the example, seems the original code trying to use the 32B capacity as much as possible even for CRC8, should be more efficiently if possible, but it's over my head and didn't work for me.

With a minor mods to just use 8B data feed, now the result matches the other calculator.

View solution in original post

11 REPLIES 11

Post input, polynomial, initial value, expected output, real output.

JW

TDK
Guru

Also keep in mind the polynomial is just one part of the CRC. The Initial value, RefIn, RefOut and XorOut will also affect the result.

If you feel a post has answered your question, please click "Accept as Solution".

0693W000003QygVQAS.png

Hi, JW,

Thank you for your attention.

Here is the settings( all copied from the example since I just want to test ):

the files are in \STM32Cube\Respository\STM32Cube_FW_G4_V1.3.0\Projects\NUCLEO-G474RE\Examples_LL\CRC\CRC_UserDefinedPolynomial

void MX_CRC_Init(void)
{
 
  /* Peripheral clock enable */
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_CRC);
 
  LL_CRC_SetInputDataReverseMode(CRC, LL_CRC_INDATA_REVERSE_NONE);
  LL_CRC_SetOutputDataReverseMode(CRC, LL_CRC_OUTDATA_REVERSE_NONE);
  LL_CRC_SetPolynomialCoef(CRC, LL_CRC_DEFAULT_CRC32_POLY);
  LL_CRC_SetPolynomialSize(CRC, LL_CRC_POLYLENGTH_32B);
  LL_CRC_SetInitialData(CRC, LL_CRC_DEFAULT_CRC_INITVALUE);
  /* USER CODE BEGIN CRC_Init 2 */
 
  /* Configure CRC calculation unit with user defined polynomial value, 8-bit long */
  LL_CRC_SetPolynomialCoef(CRC, CRC8_POLYNOMIAL_VALUE);
  LL_CRC_SetPolynomialSize(CRC, LL_CRC_POLYLENGTH_8B);
 
  /* USER CODE END CRC_Init 2 */
}
#define BUFFER_SIZE    39
#define  CRC8_POLYNOMIAL_VALUE    0x9B
 
/* USER CODE BEGIN PV */
__IO uint8_t ubCRCValue = 0;
 
 
static const uint8_t aDataBuffer[BUFFER_SIZE] =
{
  0x21, 0x10, 0x00, 0x00, 0x63, 0x30, 0x42, 0x20, 0xa5, 0x50, 0x84, 0x40,
  0xe7, 0x70, 0xc6, 0x60, 0x4a, 0xa1, 0x29, 0x91, 0x8c, 0xc1, 0x6b, 0xb1,
  0xce, 0xe1, 0xad, 0xd1, 0x31, 0x12, 0xef, 0xf1, 0x52, 0x22, 0x73, 0x32,
  0xa1, 0xb2, 0xc3
};
 
/* Expected CRC Value */
uint8_t ubExpectedCRCValue = 0xA6;
........
 
main()
{
  LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_SYSCFG);
  LL_APB1_GRP1_EnableClock(LL_APB1_GRP1_PERIPH_PWR);
 
  NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
 
  /* System interrupt init*/
 
  /** Disable the internal Pull-Up in Dead Battery pins of UCPD peripheral
  */
  LL_PWR_DisableUCPDDeadBattery();
 
/* USER CODE END PV */
 SystemClock_Config();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_CRC_Init();
  /* USER CODE BEGIN 2 */
	
	/* Perform CRC calculation on data contained in aDataBuffer */
  ubCRCValue = Calculate_CRC(BUFFER_SIZE);
	  /* Check if CRC computed result value is equal to expected one */
  CheckCRCResultValue();
	
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
  }
  /* USER CODE END 3 */
}
 
uint8_t Calculate_CRC(uint32_t BufferSize)
{
  register uint32_t data = 0;
  register uint32_t index = 0;
 
  /* Compute the CRC of Data Buffer array*/
  for (index = 0; index < (BufferSize / 4); index++)
  {
    data = (uint32_t)((aDataBuffer[4 * index + 3] << 24) | (aDataBuffer[4 * index + 2] << 16) | (aDataBuffer[4 * index + 1] << 8) | aDataBuffer[4 * index]);
    LL_CRC_FeedData32(CRC, data);
  }
 
  /* Last bytes specific handling */
  if ((BUFFER_SIZE % 4) != 0)
  {
    if (BUFFER_SIZE % 4 == 1)
    {
      LL_CRC_FeedData8(CRC, aDataBuffer[4 * index]);
    }
    if (BUFFER_SIZE % 4 == 2)
    {
      LL_CRC_FeedData16(CRC, (uint16_t)((aDataBuffer[4 * index + 1] << 8) | aDataBuffer[4 * index]));
    }
    if (BUFFER_SIZE % 4 == 3)
    {
      LL_CRC_FeedData16(CRC, (uint16_t)((aDataBuffer[4 * index + 1] << 8) | aDataBuffer[4 * index]));
      LL_CRC_FeedData8(CRC, aDataBuffer[4 * index + 2]);
    }
  }
 
  /* Return computed CRC value */
  return (LL_CRC_ReadData8(CRC));
}

Hi, TDK,

I understand possible impact of the parameters you mentioned. But to my understanding, even those match, the result still doesn't match.

Thanks.

YW

Observe content of CRC registers during calculation. Try with simple examples first.

JW

YWang.31
Associate II

I tried both http://www.sunshine2k.de/coding/javascript/crc/crc_js.html and https://crccalc.com/. These two match well.

Then I tried various Input/Output Reflect (Reverse or Non-reverse), Initial value(0x0 or 0xFF). So far, none match the result from above sites.

Maybe only ST guys with internal info can solve the puzzle. It's from their example, wonder how they verified the result.

The screenshot I gave above matches the value you said in initial post comes from STM32.

Did you observe the CRC registers during calculation? Show us, what you've seen, for a simple example.

JW

YWang.31
Associate II

Thanks to the OPs who viewed this thread, especially @waclawek.jan and @TDK. Just to update in case it can be helpful to anyone may run into it.

I dug a little more in the Calculate_CRC() of the example, seems the original code trying to use the 32B capacity as much as possible even for CRC8, should be more efficiently if possible, but it's over my head and didn't work for me.

With a minor mods to just use 8B data feed, now the result matches the other calculator.