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; }
View more