Skip to main content
FRieb.1
Associate II
Feb 15, 2022 12:02 PM UTC
Solved

STM32G0 CRC16 mismatch.

Hi,

I am trying to run the CRC calculation with the STM32G031 but the results do not match. The result of the CRC16_CCITT_FALSE should be 0x29B1 according to http://www.sunshine2k.de/coding/javascript/crc/crc_js.html but I get 0x277F.

You can find my implementation below.

unsigned short CRC_16Bit_Polynom(unsigned char *Data, unsigned char Size);
void CRC_Init(void);
 
int main(void)
{
 unsigned char Buffer[] = {'1', '2', '3', '4', '5', '6', '7', '8', '9'};
 CRC_16Bit_Polynom(Buffer, 9);
}
 
void CRC_Init(void)
{
 RCC->AHBENR |= RCC_AHBENR_CRCEN;
 CRC->CR = 0x00000000;
 CRC->CR |= CRC_CR_POLYSIZE_0;
 CRC->INIT = 0xFFFF;
 CRC->POL = 0x1021;
}
 
unsigned short CRC_16Bit_Polynom(unsigned char *Data, unsigned char Size)
{
 unsigned short Ergebnis = 0;
 CRC->CR |= CRC_CR_RESET;
 for(unsigned char i = 1; i <= Size; i++)
 {
	CRC->DR = (unsigned short) *Data;
	Data++;
 }
 Ergebnis = (unsigned short)CRC->DR;
 return Ergebnis;
}

Please kindly help to find the mistake.

This topic has been closed for replies.
Tesla DeLorean
Tesla DeLoreanBest answer
Guru
Feb 15, 2022 11:41 PM UTC
#include <windows.h>
 
#include <stdio.h>
#include <stdlib.h>
 
#define POLY 0x1021
#define INIT 0xFFFF
 
int main(int argc, char **argv)
{
 int i, j, k;
 unsigned short crc;
 unsigned char test[] = { '1', '2', '3', '4', '5', '6', '7', '8', '9' };
 
 crc = INIT;
 
 for(j=0; j<sizeof(test); j++)
 {
 crc = crc ^ (test[j] << 8);
 
 for(i=0; i<8; i++)
 {
 if (crc & 0x8000)
 crc = (crc << 1) ^ POLY;
 else
 crc = (crc << 1);
 }
 }
 
 printf("crc=%04X\n", crc);
 
 return(1);
}

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

7 replies

Tesla DeLorean
Guru
Feb 15, 2022 12:21 PM UTC

Sure you have the length loop right?

Shift direction and ending ordering?​

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
FRieb.1
FRieb.1Author
Associate II
Feb 15, 2022 12:30 PM UTC

Yes, the loop length is correct.

Do you mean the order in which the bytes are written to CRC->DR? Then I am not sure.

The "Reverse Input Data" and the "Reverse Output Data" should be right.

waclawek.jan
Super User
Feb 15, 2022 1:44 PM UTC

unsigned short for your compiler means uint16_t?

CRC->DR is usually defined as *(uint32_t*) i.e. essentially uint32_t.

> CRC->DR = (unsigned short) *Data;

Data you have declared as unsigned char * so *Data picks a byte, extends it to unsigned short (whatever that is), and then stores it into uint32_t register, i.e. it adds up 3x 0x00 to the the read data.

Read CRC operation subchapter of CRC chapter in RM.

JW

FRieb.1
FRieb.1Author
Associate II
Feb 15, 2022 1:50 PM UTC

That's right unsigned short means uint16_t. CRC->DR is the 32 bit CRC data register configured for 16 bit polynomial.

waclawek.jan
Super User
Feb 15, 2022 2:17 PM UTC

> That's right unsigned short means uint16_t.

You still read bytes from the array, and advance pointer, byte-by-byte. The cast to uint16_t extends the byte by 0x00.

> CRC->DR is the 32 bit CRC data register configured for 16 bit polynomial.

But that does not mean CRC->DR acts as a 16-bit register. Writing a 16-bit value to CRC->DR as it's defined in the device header, i.e. 32-bit, means that the 16 bits (which was a byte extended by 0x00) is extended by further 0x0000.

Read CRC operation subchapter of CRC chapter in RM.

If you want to write CRC->DR as 16-bit, in C you need to cast:

*(volatile uint16_t *)&CRC->DR = 16-bit-value;

but you still need to assemble the bytes into 16-bit values.

Or, write byte by byte

*(volatile uint8_t *)&CRC->DR = *Data;

Less efficient, but should work OK, without the problems with outstanding data in odd-length buffers.

JW

Tesla DeLorean
Guru
Feb 15, 2022 11:37 PM UTC

while(Size--) *(volatile uint8_t *)&CRC->DR = *Data++;

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