How to deal with CRC?

Hi Folks! I am programming a sketch to communicate with SPI acceleration censor. There is a requirement that in all messages to and from the sensor a 4-bit CRC shall be added. PFA page 17. Here are couple of things I don't exactly undestand:

  1. CRC shall be added in messages to the sensor. But what about from sensor? Can we ignore it?
  2. What does it mean, CRC shall be checked for all I/P messages? Is it meant that if we send a wrong CRC for particular message, it will respond with an error?
  3. If the sended messages are known and if I calculate CRC bits previously and store in list to send if it is necessary, will it work?

Datasheet of the sensor

The CRC is just a (reasonably) unique fingerprint for a specific block of data.
If you send the sensor a message with the wrong CRC then the data will be treated as 'corrupt' and will be ignored.

When you receive a message from the chip you can either ignore the CRC completely, or use it to verify that the message hasn't been corrupted in some way.

As to whether CRCs be cached and reused for the same payload - I would guess yes, but that's just a guess based on a superficial reading of the datasheet, so I might be wrong.

A cyclic redundancy check (CRC) is an error-detecting code commonly used in digital networks and storage devices to detect accidental changes to raw data. It is calculated for each packet sent by the sensor. When you receive the packet you can chose to ignore it but if there is an error you will not know. From what I saw on the data sheet it will automatically insert an error report in the next message. You need to calculate the CRC and append it to your message in the format they want. Always calculate, it saves a lot of memory and does not take much time. Start at this link: Cyclic redundancy check - Wikipedia.
Good Luck & Have Fun!
Gil

Thank you everyone. I am a bit familiar with CRC, but never used it before. I need only to send 5 commands to the sensor, thats why I am thinking to pre-calculate it.
In general, I want to be able to test the sensor to see if it works. Sensor is a rejected item from my work. I've been told that it works, but maybe it has some failure.

it's common that the CRC/checksum/... value appended to a msg is such that the resulting value for the entire msg is zero. any other result for the msg implies an error.

you may need to check both how it is computed and how it is appended

Try this link: https://ww1.microchip.com/downloads/en/AppNotes/00730a.pdf. Note:hen you add the bytes of a message together then append a 2's complement to the string. The receive side sums that string and the result is zero, it is a good checksum, not a [CRC (Cyclic Redundancy Check), this won't work in your application].
Good Luck & Have Fun!
Gil

I used this crcany code to compile the included crcgen program.
The crcgen program will generate C code for any specified type of CRC from 1 to 32 bits. The generated code contains three different types of CRC-generating function for the specified CRC. Two of them use lookup tables to speed up the computation of the CRC but the tables take up a lot of room. Since you don't need blinding speed and the device only uses messages that are 32 bits long, I've only included the code which calculates the CRC one bit at a time.
I've tested this code and compared its output with this online CRC calculator and they agree.

uint32_t CRC4(uint32_t init, uint32_t mem, size_t bitlen)
{
  mem = mem ^ (init << 28);
  for(int i = 0; i < bitlen; i++) {
    mem = mem & 0x80000000 ? (mem << 1) ^ 0x10000000 : mem << 1;
  }
  mem >>= 28;
  mem &= 0xf;
  return mem;
}

To test a received 32-bit message you would use:

  crc = CRC4(0xA,message,32);
  if(crc != 0) {
    // CRC failed - handle the error
  } else {
    // CRC passed - handle success
  }

To generate the CRC for a message to be sent, use code similar to this:

  crc = CRC4(0xA,send_message & 0xFFFFFFF0,28);
  send_message = (send_message & 0xFFFFFFF0) | crc;
  // now you can transmit send_message to the device

The two occurrences of & 0xFFFFFFF0 make sure that the bottom four bits are zero for the calculation. If your code already ensures this when it constructs send_message, you can remove them.

  1. CRC shall be added in messages to the sensor. But what about from sensor? Can we ignore it?

No, that is not a good idea. You should ignore garbled messages and retry your command.

  1. What does it mean, CRC shall be checked for all I/P messages? Is it meant that if we send a wrong CRC for particular message, it will respond with an error?

Yes. If it detects an invalid CRC, it will respond with an SPI error message (see Table 7.7).

  1. If the sended messages are known and if I calculate CRC bits previously and store in list to send if it is necessary, will it work?

Sure. You can use the CRC4 function to precalculate the CRC for each command and then store each complete command as a constant.

Pete

1 Like