2020-04-15 11:26 PM
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.
2020-04-16 10:20 AM
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
2020-04-16 10:41 AM
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);
}
//****************************************************************************
2020-04-23 05:45 AM
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:
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?
2020-04-23 07:12 AM
>>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..
2020-04-27 01:38 AM
Hello, could you clarify the polynomial use to reach CRC = 0x524AB730 ?
And conditions for...
Thanks
2020-04-27 01:50 AM
Castagnoli, initialized to zero
2020-04-28 01:26 AM
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?