CRC-8, I2C Cyclic redundancy check

Hello all,

I'm using a I2C device that also works with CRC error detection. I wish to implement it but I don't know how.

The manufacturer says: "The every I2C byte are calculated using CRC8 algorithms. The CRC polynomial is following: x8 + x5 + x3 + x2 + x + 1." I know that this is equal to 100101111.

Also the manufacturer says an example when we send data to the device with the CRC enabled: Data:0xC0 0xC0 0x00 0xCF 0xFF, followed by the CRC: 0x2E.

So, the thing is: how could I calculate this 0x2E in my code?

Reading in the internet I found this function:

//CRC-8 - based on the CRC8 formulas by Dallas/Maxim
//code released under the therms of the GNU GPL 3.0 license
byte CRC8(const byte *data, size_t dataLength)
{
  byte crc = 0x00;
  while (dataLength--) 
  {
    byte extract = *data++;
    for (byte tempI = 8; tempI; tempI--)
   {
      byte sum = (crc ^ extract) & 0x01;
      crc >>= 1;
      if (sum)
     {
        crc ^= 0x8C;
      }
      extract >>= 1;
    }
  }
  return crc;
}

But this code don't ask the the CRC polynomial. help please :frowning:

Thanks in advance!

Does the identity of this device have to remain a secret?

It is the NCV7685, I know that because of his similar question here: https://forum.arduino.cc/index.php?topic=669132.0.

@ammc Please be clear if you asked the question before or even on another forum.

I think the documentation may be off. This code produces the desired answer

const byte data[] = { 0xC0, 0xC0, 0x00, 0xFF, 0xCF };
void setup() {

  Serial.begin(9600);
  Serial.println("Ready");
  byte crc = Compute_CRC8(data, sizeof(data));
  Serial.print("CRC =");
  Serial.println(crc, HEX);

}

void loop() {
}

byte Compute_CRC8(byte *bytes, int len) {
  const byte generator = B00101111;   // polynomial = x^8 + x^5 + x^3 + x^2 + x + 1 (ignore MSB which is always 1)
  byte crc = 0;

  while (len--)
  {
    crc ^= *bytes++; /* XOR-in the next input byte */

    for (int i = 0; i < 8; i++)
    {
      if ((crc & 0x80) != 0)
      {
        crc = (byte)((crc << 1) ^ generator);
      }
      else
      {
        crc <<= 1;
      }
    }
  }
  return crc;
}

but you will notice that the value (0xCFFF) is computed with LSB first, not MSB first

You can also use a lookup table for faster runtime execution. I'm getting the same results as blh64 using this code that uses a lookup table.