cancel
Showing results for 
Search instead for 
Did you mean: 

CRC computation

lowpowermcu
Associate II
Posted on January 12, 2011 at 13:46

CRC computation

#stm-crc32 #stm32f2-crc
45 REPLIES 45
Posted on June 17, 2012 at 15:13

// 16-Bit CRC of Right Shifting MODBUS Polynomial 0xA001
 #include <
windows.h
>
#include <
stdio.h
>
WORD Crc16Modbus(WORD Crc, BYTE Data)
{
int i;
Crc = Crc ^ Data;
for(i=0; i<
8
; i++)
if (Crc & 0x0001)
Crc = (Crc >> 1) ^ 0xA001; // Polynomial used by MODBUS
else
Crc = (Crc >> 1); // Right shifting algorithm
return(Crc);
}
int main(int argc, char **argv)
{
BYTE TestData[] = { 0x01,0x04,0x75,0x54,0x00,0x02 };
WORD crc;
int i;
crc = 0xFFFF; // Initial state
for(i=0; i<sizeof(TestData); i++)
crc = Crc16Modbus(crc, TestData[i]);
printf(''CRC = %04
X'', crc);
return(1);
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
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 Venmo
Up vote any posts that you find helpful, it shows what's working..
esiqueira
Associate II
Posted on June 18, 2012 at 18:19

this works perfectly

MANY THANKS!

Fristedt.Jan
Associate II
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
Associate
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
ST Employee
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
Associate II
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
Associate II
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);

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 Venmo
Up vote any posts that you find helpful, it shows what's working..
amtb1968
Associate II
Posted on July 18, 2014 at 09:54

Dear Clive1

:

Thanks for your reminder!

BR

Alan