Skip to main content
lowpowermcu
Associate III
January 12, 2011
Question

CRC computation

  • January 12, 2011
  • 45 replies
  • 12131 views
Posted on January 12, 2011 at 13:46

CRC computation

#stm-crc32 #stm32f2-crc
This topic has been closed for replies.

45 replies

Tesla DeLorean
Guru
June 17, 2012
Posted on June 17, 2012 at 15:38

Faster algorithm using nibble table lookup, trade off between speed and size.

WORD Crc16ModbusFast(WORD Crc, BYTE Data) // sourcer32@gmail.com
{
static const WORD CrcTable[16] = { // Nibble lookup for 0xA001 polynomial
0x0000,0xCC01,0xD801,0x1400,0xF001,0x3C00,0x2800,0xE401,
0xA001,0x6C00,0x7800,0xB401,0x5000,0x9C01,0x8801,0x4400 };
Crc = Crc ^ Data;
// Process 8-bits, 4 at a time, or 2 rounds
Crc = (Crc >> 4) ^ CrcTable[Crc & 0xF];
Crc = (Crc >> 4) ^ CrcTable[Crc & 0xF];
return(Crc);
}

Could use a 256 entry table, but would eat 512 bytes of ROM/FLASH
Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
esiqueira
Associate III
June 18, 2012
Posted on June 18, 2012 at 18:19

this works perfectly

MANY THANKS!

Fristedt.Jan
Associate III
May 28, 2013
Posted on May 28, 2013 at 09:19

Thank you clive1!

A very good post. Maybe ST can make an appnote about this subject. After all, CRC is not a trivial subject. So many ways to do it and only one correct.

scaldov
Visitor II
November 2, 2013
Posted on November 02, 2013 at 21:20

Fully hardware method:

<code>

uint32_t reverse_32(uint32_t data)
{
 asm(''rbit r0,r0'');
 return data;
};
uint32_t crc32_ether(char *buf, int len, int clear)
{
 uint32_t *p = (uint32_t*) buf;
 uint32_t crc, crc_reg;
 if(clear) CRC_ResetDR();
 while(len >= 4) {
 crc_reg = CRC_CalcCRC(reverse_32(*p++));
 len -= 4;
 }
 crc = reverse_32(crc_reg);
 if(len) {
 CRC_CalcCRC(crc_reg);
 switch(len) {
 case 1:
 crc_reg = CRC_CalcCRC(reverse_32((*p & 0xFF) ^ crc) >> 24);
 crc = ( crc >> 8 ) ^ reverse_32(crc_reg);
 break;
 case 2:
 crc_reg = CRC_CalcCRC(reverse_32((*p & 0xFFFF) ^ crc) >> 16);
 crc = ( crc >> 16 ) ^ reverse_32(crc_reg);
 break;
 case 3:
 crc_reg = CRC_CalcCRC(reverse_32((*p & 0xFFFFFF) ^ crc) >> 8);
 crc = ( crc >> 24 ) ^ reverse_32(crc_reg);
 break;
 }
 }
 return ~crc;
}

</code>
Amel NASRI
Technical Moderator
November 13, 2013
Posted on November 13, 2013 at 15:01

Maybe ST can make an appnote about this subject. After all, CRC is not a trivial subject.

 

There is a new application note''

http://www.st.com/web/en/catalog/tools/FM147/CL1794/SC961/SS1743/PF259064

'', hoping it will bring some help for CRC users.

-Mayla-

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.
amtb1968
Visitor II
July 16, 2014
Posted on July 16, 2014 at 16:22

Dear Sir:

 We want to calculate the CRC check sum for program code which write to the FLASH memory address 0x08010000, we use the CRC peripheral in the STM32 family (Suggested by Mayla) but we get an error message (HardFault Stack_dump registers ) during processing to 27xxxx Bytes. No matter we add more stack size, it always the same result. We do not what the reason? Can anyone help us, thanks! The example is as below~

BR

Alan

=============================

#define FLASH_ADDRESS 0x08010000

#define PROGRAM_SIZE 358068

.....

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);

CRCValue = CRC_CalcBlockCRC((uint32_t *), PROGRAM_SIZE ); //It will cause error inside this subroutine

.......

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, DISABLE);

printf(''\r\n CRC Value = 0x%0x\r\n'', CRCValue);

amtb1968
Visitor II
July 16, 2014
Posted on July 16, 2014 at 16:25

Dear Sir:

 We want to calculate the CRC check sum for program code which write to the FLASH memory address 0x08010000, we use the CRC peripheral in the STM32 family (Suggested by Mayla) but we get an error message (HardFault Stack_dump registers ) during processing to 27xxxx Bytes. No matter we add more stack size, it always the same result. We do not what the reason? Can anyone help us, thanks! The example is as below~

BR

Alan

=============================

#define FLASH_ADDRESS 0x08010000

#define PROGRAM_SIZE 358068

.....

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, ENABLE);

CRCValue = CRC_CalcBlockCRC((uint32_t *)

FLASH_ADDRESS

 , PROGRAM_SIZE ); //It will cause error inside this subroutine

.......

RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_CRC, DISABLE);

printf(''\r\n CRC Value = 0x%0x\r\n'', CRCValue);

Tesla DeLorean
Guru
July 16, 2014
Posted on July 16, 2014 at 18:18

The ST Library function has a count of 32-bit words, not bytes. Scale your length parameter accordingly.

/**
* @brief Computes the 32-bit CRC of a given buffer of data word(32-bit).
* @param pBuffer: pointer to the buffer containing the data to be computed
* @param BufferLength: length of the buffer to be computed
* @retval 32-bit CRC
*/
uint32_t CRC_CalcBlockCRC(uint32_t pBuffer[], uint32_t BufferLength)
{
uint32_t index = 0;
for(index = 0; index < 
BufferLength
; index++)
{
CRC->DR = pBuffer[index];
}
return (CRC->DR);
}

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
amtb1968
Visitor II
July 18, 2014
Posted on July 18, 2014 at 09:54

Dear Clive1

:

Thanks for your reminder!

BR

Alan

amtb1968
Visitor II
July 18, 2014
Posted on July 18, 2014 at 13:38

Dear Clive1:

  Why the CRC value calculated from ST's CRC_CalcBlockCRC() is different from this one you provided here? We use to read a file and compare the result from each other.  The example is as below~

DWORD CRCValue;

FILE *file;

file = fopen(''file.bin'', ''rb'');

fseek(file, 0L, SEEK_END);

sz = ftell(file);

fseek(file, 0L, SEEK_SET);

Buffer = (char*)malloc(sz);

fread(Buffer, 1, sz, file);

CRCValue = 0xFFFFFFFF;

for(int i=0; i < sz/4; i+=4){

CRCValue = Crc32Fast(CRCValue, *(Buffer+i));

}

////////////////////////

BR

Alan