cancel
Showing results for 
Search instead for 
Did you mean: 

problem w/ setting polynomial for CRC

BradWalker
Associate

I'm trying to set the polynomial for the CRC block and having some difficulty. I want to set the CRC block to compute a CRC-32K (Reversed Koopman) over my data.

Here are the details

CRC-32K (reversed Koopman polynomial) - 0xEB31D82E

Input data - 0x31, 0x32, . . ., 0x39

I expect the resulting CRC to be 0x2D3DD0AE

How I setup my STMh755 CRC block

 

 

#define CRC_POLYNOMIAL_32B 0xeb31d82e
static const uint8_t aDataBuffer[] = {
0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39
};

/*##-1- Configure the CRC peripheral #######################################*/
CrcHandle.Instance = CRC;

/* The default polynomial is not used. It is required to defined it in CrcHandle.Init.GeneratingPolynomial*/
CrcHandle.Init.DefaultPolynomialUse = DEFAULT_POLYNOMIAL_DISABLE;

/* Set the value of the polynomial */
CrcHandle.Init.GeneratingPolynomial = CRC_POLYNOMIAL_32B;

/* The user-defined generating polynomial generates a
8-bit long CRC */
CrcHandle.Init.CRCLength = CRC_POLYLENGTH_32B;

/* The default init value is used */
CrcHandle.Init.DefaultInitValueUse = DEFAULT_INIT_VALUE_ENABLE;

/* The input data are not inverted */
CrcHandle.Init.InputDataInversionMode = CRC_INPUTDATA_INVERSION_NONE;

/* The output data are not inverted */
CrcHandle.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_DISABLE;

/* The input data are 32-bit long */
CrcHandle.InputDataFormat = CRC_INPUTDATA_FORMAT_BYTES;

if (HAL_CRC_Init(&CrcHandle) != HAL_OK)
{
/* Initialization Error */
Error_Handler();
}

/*##-2- Compute the CRC of "aDataBuffer" ###################################*/

uwCRCValue = HAL_CRC_Calculate(&CrcHandle, (uint32_t *)&aDataBuffer, BUFFER_SIZE);

 

 

 

A couple of issues:

1 - I get a return error from HAL_CRC_Init(). Why does HAL layer only allow ODD parity polynomials?

 

 

  /* Ensure that the generating polynomial is odd */
  if ((Pol & (uint32_t)(0x1U)) ==  0U)
  {
    status =  HAL_ERROR;
  }

 

 

2 - Am I missing something in setting up the CRC block?

Thanks.

 

 

 

2 REPLIES 2

Mechanically I'm not sure the hardware has this limitation, it shouldn't need too.

Did some hackery that suggests it's not, where I did a 15-bit CRC/Polynomial

https://github.com/cturvey/RandomNinjaChef/blob/main/STM32_CRC15_CRC_CAN.c

The hardware is LEFT shifting

The initial value would be 0xFFFFFFFF and the result inverted to get the solution, right shifting.

// Related to musings here
// https://community.st.com/t5/stm32-mcus-products/problem-w-setting-polynomial-for-crc/td-p/730403

// CRC-32K (reversed Koopman polynomial) - 0xEB31D82E
// Input data - 0x31, 0x32, . . ., 0x39
// I expect the resulting CRC to be 0x2D3DD0AE

// Copyright (C) 2024 Clive Turvey (aka Tesla DeLorean, sourcer32@gmail.com)
//  All Rights Reserved

//******************************************************************************

#include <windows.h>
#include <stdio.h>

typedef unsigned char uint8_t;
typedef unsigned int uint32_t;

//******************************************************************************

uint8_t data[] = {
  0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39 };

//******************************************************************************

uint32_t crc32k(uint32_t crc, size_t size, uint8_t *buffer)
{
  int i;
  while(size--)
  {
    crc ^= (uint32_t)*buffer++;
    for(i=0; i<8; i++)
      if (crc & 0x00000001)
        crc = (crc >> 1) ^ 0xEB31D82E;
      else
        crc >>= 1;
  }

  return(crc);
}

//******************************************************************************

int main(int argc, char **argv)
{
  uint32_t crc;

  crc = crc32k(0xFFFFFFFF, sizeof(data), data);
  printf("%08X %08X\n", crc, ~crc);

  return(1);
}

//******************************************************************************

Is suspect I can make the hardware work, but will take the polynomial being reversed, byte input reversed, answer reversed and inverted.

 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..

I made the magic happen on a STM32G031 to hand..

In ST-Speak inversion means bit-reversal

CRC-32-K 2D3DD0AE TEST 2D3DD0AE ?

 

//****************************************************************************

void TestCRC(void) // sourcer32@gmail.com PayPal accepted.. gauge by man-hours saved
{
  uint8_t test[] = { 0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39 }; // 0x2D3DD0AE

  /* CRC handler declaration */
  CRC_HandleTypeDef CrcHandle = {0};

  /* CRC Peripheral clock enable */
  __HAL_RCC_CRC_CLK_ENABLE();

  /*##-1- Configure the CRC peripheral #######################################*/
  CrcHandle.Instance = CRC;

  /* The default polynomial is not used. It is required to defined it in CrcHandle.Init.GeneratingPolynomial*/
  CrcHandle.Init.DefaultPolynomialUse    = DEFAULT_POLYNOMIAL_DISABLE; // ST double-negative, use user supplied

  /* Set the value of the polynomial */
  CrcHandle.Init.GeneratingPolynomial    = 0x741B8CD7; // 32-bit CRC-32-K, bit reversed 0xEB31D82E, hw left shifts, always

  /* The user-defined generating polynomial generates a 32-bit long CRC */
  CrcHandle.Init.CRCLength               = CRC_POLYLENGTH_32B;
	
  /* The default init value is not used */
  CrcHandle.Init.DefaultInitValueUse     = DEFAULT_INIT_VALUE_DISABLE; // ST double-negative

  /* The used-defined initialization value */
  CrcHandle.Init.InitValue               = 0xFFFFFFFF; // 32-bit all set

  /* The input data is inverted (bit-reversed) */
  CrcHandle.Init.InputDataInversionMode  = CRC_INPUTDATA_INVERSION_BYTE; // Bit swap byte end-to-end

  /* The output data is inverted (bit-reversed)*/
  CrcHandle.Init.OutputDataInversionMode = CRC_OUTPUTDATA_INVERSION_ENABLE;// Bit swap word end-to-end

  /* The input data are 8-bit long */
  CrcHandle.InputDataFormat              = CRC_INPUTDATA_FORMAT_BYTES;

  if (HAL_CRC_Init(&CrcHandle) != HAL_OK)
  {
    /* Initialization Error */
    Error_Handler(__FILE__, __LINE__);
  }

  /* Note that I negate the response the hardware spins end-to-end */
  printf("CRC-32-K %08X TEST 2D3DD0AE ?\n", ~HAL_CRC_Calculate(&CrcHandle, (uint32_t *)test, sizeof(test)));
}

//****************************************************************************

 

 

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..