Author Topic: Same CRC routine returns different results... :o  (Read 1945 times)

0 Members and 1 Guest are viewing this topic.

Offline ricko_ukTopic starter

  • Super Contributor
  • ***
  • Posts: 1015
  • Country: gb
Same CRC routine returns different results... :o
« on: July 23, 2021, 08:43:47 pm »
Hi,
this is a weird one...

I have the same CRC routine (literally cut and paste) on a PIC32MZ and an Arduino Uno (which I am using just to check general functionality.

On the arduino the CRC routine returns a number (which I can see on the bus with the logic analyser is correct) and when I parse the received data that value and the entire stream is also correct (the receive buffer on the PIC32 is an exact copy of the sent buffer from the Arduino).

But when I calculate the CRC on the PIC32 using the same cut-and-paste routine using the same data input it returns a different value...

For example:
- this is the one calculated on the arduino...  0xCE9C3870
- this is the one calculate don the PIC32....   0x24637E70

The only thing that is strange is that the least significant byte of the CRC is always calculated correctly on the PIC32 but only that byte, not the other 3.

Any idea what could cause that?

The Arduino sketch, including the CRC routine is this:

Code: [Select]
#include <SPI.h>

const int SSpin = 10;
const int SBusy = 9;

#define SPI_CMD__LOAD_START           0x01

SPISettings settingsA(100000, MSBFIRST, SPI_MODE2);
uint8_t buffer[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

void setup() {
  // put your setup code here, to run once:
  pinMode (SSpin, OUTPUT);
  pinMode (SBusy, INPUT);
  SPI.begin();
}


uint32_t rc_crc32(uint32_t crc, const char *buf, size_t len)
{
  static uint32_t table[256];
  static int have_table = 0;
  uint32_t rem;
  uint8_t octet;
  int i, j;
  const char *p, *q;
 
  /* This check is not thread safe; there is no mutex. */
  if (have_table == 0) {
    /* Calculate CRC table. */
    for (i = 0; i < 256; i++) {
      rem = i;  /* remainder from polynomial division */
      for (j = 0; j < 8; j++) {
        if (rem & 1) {
          rem >>= 1;
          rem ^= 0xedb88320;
        } else
          rem >>= 1;
      }
      table[i] = rem;
    }
    have_table = 1;
  }
 
  crc = ~crc;
  q = buf + len;
  for (p = buf; p < q; p++) {
    octet = *p;  /* Cast to unsigned octet. */
    crc = (crc >> 8) ^ table[(crc & 0xff) ^ octet];
  }
  return ~crc;
}

void loop() {

  uint32_t tmpCRC = 0;
 
    SPI.beginTransaction(settingsA);
 
  while (1)
  {
    buffer[0] = SPI_CMD__LOAD_START;    //cmd
    buffer[1] = 0xAA;   //cmd option
    buffer[2] = 0x55;   //cmd option
    buffer[3] = 1;      //data length
    buffer[4] = 'A';   //data

    tmpCRC = rc_crc32(0, (char*) buffer, 5);

    buffer[5] = tmpCRC >> 3;  //CRC1
    buffer[6] = tmpCRC >> 2; //CRC2
    buffer[7] = tmpCRC >> 1;  //CRC3
    buffer[8] = tmpCRC;  //CRC4
   
    digitalWrite (SSpin, LOW);
    //SPI.transfer('A');
    SPI.transfer(buffer, 9);
    digitalWrite (SSpin, HIGH);
    delay(1000);
  }
}



The Pic32 code is below. The structParsedMessage.ui32_CRC corresponds to the sent CRC AND to the CRC I see on the SPI bus with the logic analyser:

Code: [Select]
        case MESSAGE_RECEIVED:
        {
            structParsedMessage.ui32_CRC = aui8_RxBuffer[ui8_RxBufferBytesCount - 4];
            structParsedMessage.ui32_CRC = structParsedMessage.ui32_CRC << 8;                   
            structParsedMessage.ui32_CRC = structParsedMessage.ui32_CRC | aui8_RxBuffer[ui8_RxBufferBytesCount - 3];
            structParsedMessage.ui32_CRC = structParsedMessage.ui32_CRC << 8;                   
            structParsedMessage.ui32_CRC = structParsedMessage.ui32_CRC | aui8_RxBuffer[ui8_RxBufferBytesCount - 2];
            structParsedMessage.ui32_CRC = structParsedMessage.ui32_CRC << 8;                   
            structParsedMessage.ui32_CRC = structParsedMessage.ui32_CRC | aui8_RxBuffer[ui8_RxBufferBytesCount - 1];
           
            //check CRC
            uint32_t tmpCRC = rc_crc32(0, (char*) aui8_RxBuffer, 5); //(ui8_RxBufferBytesCount - 4));
            if (tmpCRC == structParsedMessage.ui32_CRC)
            {
                //CRC match so message received correctly
                _nop();
            }
            else
            {
                //CRC did not match
                _nop();
            }
            break;
        }


Thank you :)
« Last Edit: July 23, 2021, 08:46:37 pm by ricko_uk »
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14466
  • Country: fr
Re: Same CRC routine returns different results... :o
« Reply #1 on: July 23, 2021, 09:33:14 pm »
Do you mean that the rc_crc32() on the PIC32 is the exact same code as the one used on Arduino?
 

Online oPossum

  • Super Contributor
  • ***
  • Posts: 1416
  • Country: us
  • Very dangerous - may attack at any time
Re: Same CRC routine returns different results... :o
« Reply #2 on: July 23, 2021, 09:35:43 pm »
Try this change on the Arduino...

Code: [Select]
         rem ^= 0xedb88320ULL;
 

Offline ricko_ukTopic starter

  • Super Contributor
  • ***
  • Posts: 1015
  • Country: gb
Re: Same CRC routine returns different results... :o
« Reply #3 on: July 23, 2021, 09:36:22 pm »
Thank you SiliconWizzard,
It is included in the Arduino code (the first code snippet in the OP).

It is this part:

Code: [Select]

uint32_t rc_crc32(uint32_t crc, const char *buf, size_t len)
{
  static uint32_t table[256];
  static int have_table = 0;
  uint32_t rem;
  uint8_t octet;
  int i, j;
  const char *p, *q;
 
  /* This check is not thread safe; there is no mutex. */
  if (have_table == 0) {
    /* Calculate CRC table. */
    for (i = 0; i < 256; i++) {
      rem = i;  /* remainder from polynomial division */
      for (j = 0; j < 8; j++) {
        if (rem & 1) {
          rem >>= 1;
          rem ^= 0xedb88320;
        } else
          rem >>= 1;
      }
      table[i] = rem;
    }
    have_table = 1;
  }
 
  crc = ~crc;
  q = buf + len;
  for (p = buf; p < q; p++) {
    octet = *p;  /* Cast to unsigned octet. */
    crc = (crc >> 8) ^ table[(crc & 0xff) ^ octet];
  }
  return ~crc;
}

 

Online Kjelt

  • Super Contributor
  • ***
  • Posts: 6460
  • Country: nl
Re: Same CRC routine returns different results... :o
« Reply #4 on: July 23, 2021, 09:40:25 pm »
Not sure, no time to check but is the endianess of both uc's the same ?
This has bitten me quite often with security algorithms in the past.
 

Offline ricko_ukTopic starter

  • Super Contributor
  • ***
  • Posts: 1015
  • Country: gb
Re: Same CRC routine returns different results... :o
« Reply #5 on: July 23, 2021, 09:41:27 pm »
thank you oPossum, :)
I tried that just now but the result is the same. Any other suggestions?
 

Offline ricko_ukTopic starter

  • Super Contributor
  • ***
  • Posts: 1015
  • Country: gb
Re: Same CRC routine returns different results... :o
« Reply #6 on: July 23, 2021, 09:44:38 pm »
Thank you Kjelt, :)
I checked and both Arduino Uno (ATMega 328P) and PIC32MZ are both little endian.
 

Offline ricko_ukTopic starter

  • Super Contributor
  • ***
  • Posts: 1015
  • Country: gb
Re: Same CRC routine returns different results... :o
« Reply #7 on: July 23, 2021, 09:45:51 pm »
@SiliconWizzard,
yes they are both the same code, literally cut and paste. That's why it doesn't make much sense that they return different results.
 

Online oPossum

  • Super Contributor
  • ***
  • Posts: 1416
  • Country: us
  • Very dangerous - may attack at any time
Re: Same CRC routine returns different results... :o
« Reply #8 on: July 23, 2021, 09:46:45 pm »
Is the generated CRC table the same on both?
 

Offline ricko_ukTopic starter

  • Super Contributor
  • ***
  • Posts: 1015
  • Country: gb
Re: Same CRC routine returns different results... :o
« Reply #9 on: July 23, 2021, 09:50:06 pm »
@oPossum,
Unfortunately on the Arduino there is no way to debug or see/output the table apart from the serial port but at the moment all the serial to USB I have are connected to running experiments I cannot stop.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14466
  • Country: fr
Re: Same CRC routine returns different results... :o
« Reply #10 on: July 23, 2021, 09:52:59 pm »
I don't understand this part:
Code: [Select]
    buffer[5] = tmpCRC >> 3;  //CRC1
    buffer[6] = tmpCRC >> 2; //CRC2
    buffer[7] = tmpCRC >> 1;  //CRC3
    buffer[8] = tmpCRC;  //CRC4

It doesn't look right to me.
 

Offline ricko_ukTopic starter

  • Super Contributor
  • ***
  • Posts: 1015
  • Country: gb
Re: Same CRC routine returns different results... :o
« Reply #11 on: July 23, 2021, 10:03:09 pm »

In front of the PC for almost 16 hours so maybe I am doing something really stupid... But the idea is to split 32-bit CRC into 4 bytes and load it into the buffer to be sent.
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 14466
  • Country: fr
Re: Same CRC routine returns different results... :o
« Reply #12 on: July 23, 2021, 10:08:19 pm »

In front of the PC for almost 16 hours so maybe I am doing something really stupid... But the idea is to split 32-bit CRC into 4 bytes and load it into the buffer to be sent.

I thought that was the intent. But it won't work. You're right shifting the CRC by 3, then 2, then 1 bit, then 0 bit. Only the last (LSByte) will be right. I think this is your problem here. ;)
 

Offline ricko_ukTopic starter

  • Super Contributor
  • ***
  • Posts: 1015
  • Country: gb
Re: Same CRC routine returns different results... :o
« Reply #13 on: July 23, 2021, 10:10:26 pm »
 :-DD  :-DD  |O  |O
I noticed that after posting it. I was about to reply how stupid that error was but u replied first.

Thank you as always! :)
 

Offline DavidAlfa

  • Super Contributor
  • ***
  • Posts: 5903
  • Country: es
Re: Same CRC routine returns different results... :o
« Reply #14 on: July 23, 2021, 11:33:11 pm »
You're overloading yourself! You need to close everything and go for a walk!
My advice is to go to a nearby quarry and ask for 1-day job breaking stone with hand tools.
After that, take a shower and a long nap. 2-3 days later you will wake up like new!  :-+  :-DD
Hantek DSO2x1x            Drive        FAQ          DON'T BUY HANTEK! (Aka HALF-MADE)
Stm32 Soldering FW      Forum      Github      Donate
 

Offline ricko_ukTopic starter

  • Super Contributor
  • ***
  • Posts: 1015
  • Country: gb
Re: Same CRC routine returns different results... :o
« Reply #15 on: July 24, 2021, 12:44:30 pm »
David,
that sounds about right... it sounds like a holiday!   :-DD
 

Offline harerod

  • Frequent Contributor
  • **
  • Posts: 449
  • Country: de
  • ee - digital & analog
    • My services:
Re: Same CRC routine returns different results... :o
« Reply #16 on: July 25, 2021, 04:35:35 pm »
So were you able to resolve the problem?

My five cents would have been:
Exactly the same source will yield different results, when compiler implementations vary.
With C, a classic would be sizeof(int).

Edit: grammar...
« Last Edit: July 25, 2021, 09:06:59 pm by harerod »
 

Offline Siwastaja

  • Super Contributor
  • ***
  • Posts: 8172
  • Country: fi
Re: Same CRC routine returns different results... :o
« Reply #17 on: July 25, 2021, 05:57:54 pm »
Sounds like the result was identical but readout of the result from the micro was buggy, no?
 

Offline ricko_ukTopic starter

  • Super Contributor
  • ***
  • Posts: 1015
  • Country: gb
Re: Same CRC routine returns different results... :o
« Reply #18 on: July 29, 2021, 08:50:17 pm »
Siwastaja,
yes :)  :-DD
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf