cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F103 CRC32 of uint8_t buffer

Fede Rico
Associate III
Posted on January 10, 2018 at 14:51

Hi there,

I wrote a serial protocol to exchange data between MCU and a PC.

This protocol provides a checksum to verify data integrity.

At the moment I use a simple sum of each byte but I think that the use of CRC peripheral could be an improvements.

Unfortunately the CRC peripheral requires a uint32_t buffer but my payload is an uint8_t.

Casting the uint8_t to uint32_t is a problem because the CRC will be wrong because on the PC side.

I computed the CRC as byte (from serial interface)but I computed the CRC on MCU as word (due to cast uint8_t to uint32_t ).

/* This is my packet structure */
 */
typedef struct PROTOCOL_Packet
{
uint8_t header;
uint16_t length;
uint8_t payload[128];
uint32_t checksum;
 
} PROTOCOL_Packet_t; 

/* This is my routine to compute the CRC: */
 if( CRC_Calculate( (uint32_t*)pkt->payload.bytes, (uint32_t)(*pkt).length, &pkt->checksum ) == APP_TRUE )
 {
 SERIAL_Write( (uint8_t*)pkt, pkt->length + 7 );
 }�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

/* Where CRC_Calculate is: */
uint8_t CRC_Calculate( uint32_t* buffer, uint32_t bufferLen, OUT uint32_t* crc32)
{
 *crc32 = HAL_CRC_Calculate( &hcrc, buffer, (bufferLen/4) );
 return TRUE;
}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

I can't change the type of my payload to uint32_t because on the PC side I want to avoid byte manipulation to retrieve the uint32_t back from bytes.

Any suggestion?

Thanks in advance

#crc32 #stm32f103
1 REPLY 1
Posted on January 10, 2018 at 19:01

The STM32F1 CRC generator has a fixed polynomial, shift direction, byte order and width, this is not terribly consistent with endian ordering of the PC or STM32.

The F3 and some F0 have a more flexible solution.

Do the computation in software. Or byte stuff on the PC side, where the operations are of trivial code on a PC running at >3GHz

//******************************************************************************

uint32_t CRC32(uint32_t Crc, uint32_t Size, uint8_t *Buffer)

{

  while(Size--)

  {

    static const uint32_t CrcTable[] = { // 0xEDB88320 polynomial, right shifting  -

mailto:sourcer32@gmail.com

      0x00000000,0x1DB71064,0x3B6E20C8,0x26D930AC,0x76DC4190,0x6B6B51F4,0x4DB26158,0x5005713C,

      0xEDB88320,0xF00F9344,0xD6D6A3E8,0xCB61B38C,0x9B64C2B0,0x86D3D2D4,0xA00AE278,0xBDBDF21C };

    Crc = Crc ^ (uint32_t)*Buffer++; // Consume a byte at a time

    Crc = (Crc >> 4) ^ CrcTable[Crc & 0x0F]; // Two rounds of 4-bits

    Crc = (Crc >> 4) ^ CrcTable[Crc & 0x0F];

  }

  return(Crc);

}

//******************************************************************************

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