cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 Hardware CRC32 algorithm

ADejo.1
Associate II

We have two microcontroller, one is the STM32H7 and another one without hardware CRC (need to be software CRC through an algorithm).

I use SPI communication with this hardware CRC32 and I would like to know the software algorithm able to have the same value as for the hardware CRC calculation.

I can see proposal of algorithm up to STM32F4, but for newer version of microcontroller such STM32H7, I just see anything.

Of course, I tried the CRC algorithm of the previous version but doesn't work.

7 REPLIES 7

The underlying CRC for the H7 is the same as the F4, you can however changes widths, and reverse bits and bytes which obviously will have some pretty significant impact on the numbers that drop out the end.

I'd have to run the math on this, but I believe it should be the same polynomial and application as the F4

STM32Cube_FW_H7_V1.7.0\Projects\STM32H743I-EVAL\Examples\CRC\CRC_Example\Src\main.c

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

C:\>crch7

379E9F06 (379E9F06)

QED

//****************************************************************************
// CRCH7.C -  sourcer32@gmail.com
//****************************************************************************
 
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
 
typedef unsigned long uint32_t;
 
#define BUFFER_SIZE    114
 
/* Used for storing CRC Value */
uint32_t uwCRCValue = 0;
 
static const uint32_t aDataBuffer[BUFFER_SIZE] =
{
  0x00001021, 0x20423063, 0x408450a5, 0x60c670e7, 0x9129a14a, 0xb16bc18c,
  0xd1ade1ce, 0xf1ef1231, 0x32732252, 0x52b54294, 0x72f762d6, 0x93398318,
  0xa35ad3bd, 0xc39cf3ff, 0xe3de2462, 0x34430420, 0x64e674c7, 0x44a45485,
  0xa56ab54b, 0x85289509, 0xf5cfc5ac, 0xd58d3653, 0x26721611, 0x063076d7,
  0x569546b4, 0xb75ba77a, 0x97198738, 0xf7dfe7fe, 0xc7bc48c4, 0x58e56886,
  0x78a70840, 0x18612802, 0xc9ccd9ed, 0xe98ef9af, 0x89489969, 0xa90ab92b,
  0x4ad47ab7, 0x6a961a71, 0x0a503a33, 0x2a12dbfd, 0xfbbfeb9e, 0x9b798b58,
  0xbb3bab1a, 0x6ca67c87, 0x5cc52c22, 0x3c030c60, 0x1c41edae, 0xfd8fcdec,
  0xad2abd0b, 0x8d689d49, 0x7e976eb6, 0x5ed54ef4, 0x2e321e51, 0x0e70ff9f,
  0xefbedfdd, 0xcffcbf1b, 0x9f598f78, 0x918881a9, 0xb1caa1eb, 0xd10cc12d,
  0xe16f1080, 0x00a130c2, 0x20e35004, 0x40257046, 0x83b99398, 0xa3fbb3da,
  0xc33dd31c, 0xe37ff35e, 0x129022f3, 0x32d24235, 0x52146277, 0x7256b5ea,
  0x95a88589, 0xf56ee54f, 0xd52cc50d, 0x34e224c3, 0x04817466, 0x64475424,
  0x4405a7db, 0xb7fa8799, 0xe75ff77e, 0xc71dd73c, 0x26d336f2, 0x069116b0,
  0x76764615, 0x5634d94c, 0xc96df90e, 0xe92f99c8, 0xb98aa9ab, 0x58444865,
  0x78066827, 0x18c008e1, 0x28a3cb7d, 0xdb5ceb3f, 0xfb1e8bf9, 0x9bd8abbb,
  0x4a755a54, 0x6a377a16, 0x0af11ad0, 0x2ab33a92, 0xed0fdd6c, 0xcd4dbdaa,
  0xad8b9de8, 0x8dc97c26, 0x5c644c45, 0x3ca22c83, 0x1ce00cc1, 0xef1fff3e,
  0xdf7caf9b, 0xbfba8fd9, 0x9ff86e17, 0x7e364e55, 0x2e933eb2, 0x0ed11ef0
};
 
/* Expected CRC Value */
uint32_t uwExpectedCRCValue = 0x379E9F06;
 
//****************************************************************************
 
uint32_t Crc32(uint32_t Crc, const uint32_t Data)
{
  int i;
 
  Crc = Crc ^ Data;
 
  for(i=0; i<32; i++)
    if (Crc & 0x80000000)
      Crc = (Crc << 1) ^ 0x04C11DB7; // Polynomial used in STM32
    else
      Crc = (Crc << 1);
 
  return(Crc);
}
 
//****************************************************************************
 
uint32_t Crc32Block(uint32_t Crc, uint32_t WordCount, const uint32_t *Data)
{
  while(WordCount--)
    Crc = Crc32(Crc, *Data++);
 
  return(Crc);
}
 
//****************************************************************************
 
int main(int argc, char **argv)
{
  printf("%08X (%08X)\n", Crc32Block(0xFFFFFFFF, BUFFER_SIZE, aDataBuffer), uwExpectedCRCValue);
 
  return(0);
}
 
//****************************************************************************

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

Thanks for this feedback.

I make a simple test:

CRC32 with polynomial = 0x1EDC6F41, init value = 0x55555555. (no input/output reverse)

I send 4 bytes (0x12, 0x34,0x56,0x78) through SPI communication and on scope I measure what is phisically sent:

0693W000000WL0VQAW.png

Frame: 0001001000110100011110000101011000000101001001001010101101110011

datas = 0x12347856 (00010010001101000111100001010110) --> the second half-word= 0x7856 is sent through little endian convention

CRC32 = 0x0524AB73 (00000101001001001010101101110011)

I can't get the same value (CRC32 = 0x0524AB73) with the algorithm

I use the same algorithm as you: CRCToCheck = Crc32(0x55555555, 0x12347856)

CRCToCheck = 0x27F11ABF ( != 0x0524AB73)

I also tried to fill with empty value 0x00000000 after these 4 Bytes, after 31999 iteration I stop it. CRC is still not equal.

Could you help me to know why the CRC is not good equal to hardware CRC?

>>I use the same algorithm as you: CRCToCheck = Crc32(0x55555555, 0x12347856)

>> CRCToCheck = 0x27F11ABF ( != 0x0524AB73)

Not least because you're using the wrong polynomial, my example isn't using Castagnoli !!

I get 0x524AB730 when the initialization word is ZERO, and the polynomial is correct. Can't really explain the rotation here, but not got much to work with.

Why does it endian switch the last byte pair?

Show the H7 SPI initialization and data transfer code..

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

Hello, could you clarify the polynomial use to reach CRC = 0x524AB730 ?

And conditions for...

Thanks

Castagnoli​, initialized to zero

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

Thanks for your reply.

I don’t reach the good CRC;

I will share you my source code:

SPI_InitStructure.TransferDirection = LL_SPI_SIMPLEX_TX;
        SPI_InitStructure.Mode = LL_SPI_MODE_MASTER;
        SPI_InitStructure.BaudRate = LL_SPI_BAUDRATEPRESCALER_DIV4; /* 64 MHZ input clk / 4 */
        SPI_InitStructure.BitOrder = LL_SPI_MSB_FIRST;
        SPI_InitStructure.ClockPhase = LL_SPI_PHASE_1EDGE;
        SPI_InitStructure.ClockPolarity = LL_SPI_POLARITY_LOW;
        SPI_InitStructure.CRCCalculation = LL_SPI_CRCCALCULATION_ENABLE;
        SPI_InitStructure.CRCPoly =  0x1edc6f41u;
        SPI_InitStructure.DataWidth = LL_SPI_DATAWIDTH_8BIT;
        LL_SPI_SetCRCWidth(SPI_CH1, LL_SPI_CRC_32BIT);
        LL_SPI_SetTxCRCInitPattern(SPI_CH1, LL_SPI_TXCRCINIT_ALL_ZERO_PATTERN); /* enable tx pattern with 0 */ 

Any idea where the issue could come from?