2025-03-25 7:55 AM
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?
2025-03-25 8:27 AM
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.
2025-05-21 5:00 PM
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;
}