Skip to main content
EThom.3
Senior II
September 16, 2026
Question

CRC – trouble understanding bit reversal

  • September 16, 2026
  • 7 replies
  • 16 views

I’ve trawled through several CRC-related threads without finding an explanation of this: How to properly set up bit reversal.

Normally, I use CRC-16 XMODEM, which uses the 0x1021 polynomial and no bit reversal. This works perfectly fine when I use this code:

void xmodemCalcCRC (uint8_t Data, uint16_t *CRCVal)
{
CRC->POL = 0x1021; // CRC polynomial
CRC->INIT = *CRCVal; // Previous CRC result
CRC->CR = CRC_CR_POLYSIZE_0; // 16-bit polynomial
*(__IO uint8_t*)(&CRC->DR) = Data; // Feed an 8-bit value into the algorithm
*CRCVal = CRC->DR; // Read the result
}

The reason I set the polynomial, the initial value and configuration every time is to accommodate different CRC methods in the same application.

Now, in a current project (using an STM32L433 microcontroller) I need to use CRC-16 Kermit as well. According to crccalc.com, Kermit CRC uses bit reversal on input and output. This is where my trouble begins: When bit reversing, I don’t get the correct result.

The only thing I change in my code is the bit reversal configuration bits:

void kermitCalcCRC (uint8_t Data, uint16_t *CRCVal)
{
CRC->POL = 0x1021;
CRC->INIT = *CRCVal;
CRC->CR = CRC_CR_REV_OUT | CRC_CR_REV_IN_0 | CRC_CR_POLYSIZE_0;
*(__IO uint8_t*)(&CRC->DR) = Data;
*CRCVal = CRC->DR;
}

As I feed the CRC unit one byte at a time, I have set the REV_IN[0] bit, as this should do the input bit reversal by byte. But the result I get is incorrect. As an example, the text string “00 6 0 0 0 3 0 “ gives me the CRC result 0xF3BF, where I expected 0xAFEA.

I have tried adding the CRC RESET bit, and also shuffled the order of operations. This has made no difference whatsoever.

I must be missing something, but what?

As a fallback, I have code for doing CRC-16 Kermit calculations without using the CRC unit. But I would really like to get this to work, as I believe it is faster as well as flash space saving.

7 replies

TDK
September 16, 2026

Can you try REV_IN = 0b11? The user manual is light on details for how REV_IN interacts when the incoming data is not a full word.

As an example, the text string “00 6 0 0 0 3 0 “ gives me the CRC result 0xF3BF, where I expected 0xAFEA.

I concur 0xAFEA is the correct result. Can’t determine how it’s getting 0xF3BF.

CRC Detective

 

The included code only calculates the CRC for a single byte. Perhaps you can show the full code where it calculates the string.

"If you feel a post has answered your question, please click ""Accept as Solution""."
EThom.3
EThom.3Author
Senior II
September 16, 2026

I tried REV_IN = 0b11 just now, with this modified line:

  CRC->CR = CRC_CR_REV_OUT | CRC_CR_REV_IN_1 | CRC_CR_REV_IN_0 | CRC_CR_POLYSIZE_0 | CRC_CR_RESET;

I got the exact same CRC result: 0xF3BF.

To show you a complete code that actually makes sense, I will have to make some bigger modifications. Currently, my application receives a message (including transmitted CRC value) from an external device, and calculates CRC – incorrectly.

But the CRC function call is presently in a simple for loop:

    uiCRCVal = 0;
for (j = 0; j < (i - 4); j++) kermitCalcCRC(pMsg[j], &uiCRCVal); // Calculate CRC value

However, to get the current function to calculate CRC-16 XMODEM value correctly, all I need to do is to turn bit reversal off. So the only difference between correct CRC-16 XMODEM and wrong CRC-16 Kermit is the bit reversal settings. This is what confuses me the most.

“Ah - perfect, I just need to switch on bit reversal!”

3 minutes later

“Errr… apparently not…?”

By the way – thank you for the CRC Detective tip. I was not familiar with that one.

TDK
September 16, 2026

Oh, I see now that your code sets INIT on every byte before calculating the next and that’s how you’re converting the entire string. Not very efficient, but it should work. My guess is the problem is related to that. Maybe it is reversing bits in INIT, or expecting them to be reversed.

Can you provide the CRC it calculates for “0” and for “00”?

"If you feel a post has answered your question, please click ""Accept as Solution""."