cancel
Showing results for 
Search instead for 
Did you mean: 

Calculate CRC-8-ATM with Hardware CRC Unit of STM32F7

Flo25
Associate II

How can you calculate a CRC-8-ATM using the CRC unit of a STM32F7?

I want to check the CRC of the output of an ADC ADS127L11 which is transmitted via SPI. The user manual says the CRC calculation is based on CRC-8-ATM. The output is an 8-bit CRC, and the polynomial is X^8+X^2+X^1+X^0. I cannot configure this in the CRC unit of my STM32F7.

Does anybody know if and how you can use the embedded CRC unit for CRC-8-ATM calculation?

2 REPLIES 2

So an 0x07 polynomial value.

You want to use the CRC unit built into the SPI, or the stand-alone CRC unit of the STM32?

Do you have some example test vectors?

Have you checked it with a software implementation?

Generally on the SPI, I'd expect you run the pattern through the reception, with the CRC polynomial set up, and if correct the CRC register/check will zero out.

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

Thanks for your answer. Basically, I was an ***.

 

Here is an excerpt of my solution. Yes, I see there some weaknesses in returning how to return the values, it’s an excerpt. Maybe it helps someone.

#include "stm32f756xx.h"

#define CONFIG_COUNT 1u

typedef enum
{
  REV_IN_NOT_AFFECTED = 0uL,             //!< 00: Bit order not affected
  REV_IN_BYTE =         CRC_CR_REV_IN_0, //!< 01: Bit reversal done by byte
  REV_IN_HALF_WORD =    CRC_CR_REV_IN_1, //!< 10: Bit reversal done by half-word
  REV_IN_WORD =         CRC_CR_REV_IN    //!< 11: Bit reversal done by word
} InBitInversionMode_t;

typedef enum {
  POLY_SIZE_32 = 0x0uL,             //!< 32 Bit polynomial
  POLY_SIZE_16 = CRC_CR_POLYSIZE_0, //!< 16 Bit polynomial
  POLY_SIZE_8  = CRC_CR_POLYSIZE_1, //!<  8 Bit polynomial
  POLY_SIZE_7  = CRC_CR_POLYSIZE    //!<  7 Bit polynomial
} PolySize_t;

typedef struct
{
  bool isOutBitInverted;              //!< Reversal of the bit order of the output data
  InBitInversionMode_t inBitInverted; //!< Reversal of the bit order of the input data
  PolySize_t polySize;                //!< Size of the CRC polynomial
  uint32_t crcPoly;                   //!< Programmable CRC polynomial
  uint32_t crcInit;                   //!< Initial CRC value
} CrcConfig_t;

static const CrcConfig_t crcConfig[CONFIG_COUNT] =
{
  { // HAL_CRC_ADC
    false,
    REV_IN_NOT_AFFECTED,
    POLY_SIZE_8,
    0x07uL,              //!< CRC_8_ATM -> X^8 + X^2 + X^1 + X^0
    0xFFFFFFFFuL
  }
}

void HalCrc_Init(void)
{
  RCC->AHB1ENR |= RCC_AHB1ENR_CRCEN; // Enable CRC clock
  CRC->CR = CRC_CR_RESET;
}

void HalCrc_Config(const HalCrc_Config_t config)
{
  CRC->CR = CRC_CR_RESET;
  
  CRC->POL = (uint32_t)(crcConfig[config].crcPoly);
  CRC->INIT = (uint32_t)(crcConfig[config].crcInit);
  
  CRC->CR |= (crcConfig[config].isOutBitInverted) ? CRC_CR_REV_OUT: 0uL;
  CRC->CR |= (uint32_t)(crcConfig[config].inBitInverted);
  CRC->CR |= (uint32_t)(crcConfig[config].polySize);
}

void HalCrc_Calculate8(uint32_t* const crc, const uint8_t* data, const uint8_t length)
{
  CRC->CR |= CRC_CR_RESET;
  for(uint8_t bytePos = 0; bytePos < length; bytePos++)
  {
    *(uint8_t*)(CRC_BASE) = data[bytePos]; // Write data to CRC data register
  }
  *crc = CRC->DR;
}

uint32_t HalCrc_Accumulate8(const uint8_t data)
{
  *(uint8_t*)(CRC_BASE) = data; // Write data to CRC data register
  return CRC->DR;
}