0

I'm building something which uses the DS18B20 temperature sensor. First I am trying to understand the example CRC in the Maxim application note 27, "Understanding and Using Cyclic Redundancy Checks with Maxim iButton Products" (https://www.analog.com/en/technical-articles/understanding-and-using-cyclic-redundancy-checks-with-maxim-1wire-and-ibutton-products.html). It doesn't look too hard to code the conversion but my problem is that I cannot find any calculator that gives me the correct answer of 0xA2.

On page 5, example 2 the complete ROM code is given in hex as A2=(CRC), 00 00 00 01 B8 1C 02=(Family code). The generator polynomial is 100110001 (X8+X5+X4+1). On the site https://crccalc.com/ it has a CRC-8/MAXIM algorithm which has the correct generator but the RefIn and RefOut are both true whereas I cannot see anything in the application note about reversing parts (although I have tried this). On the site https://tomeko.net/online_tools/crc8.php?lang=en it claims to implement the CRC from the application note but it gives the same answers as crccalc.com. Also note that crccalc has the same lookup table for the Maxim algorithm as the application note so no surprise the two web sites are giving the same answers. Finally I found a site, https://www.rndtool.info/CRC-step-by-step-calculator/, that allows me to add the polynomial and bit stream in binary and it shows the 'hand' calculation of the CRC. This says nothing about input and output refs so I assume they are false. This gives different answers to the other two sites probably because of the ref values but still does not give 0xA2.

Has anyone correctly calculated the given value in the application note?

I don't want to start programming until I understand what is going on and I cannot read data from a device if I cannot decipher the CRC correctly. This is driving me mad at the moment. I've tried the number reflected and forwards with the generator reflected and forwards plus reversing the answer but I never get 0xA2.

Archie
  • 15
  • 3

2 Answers2

1

You didn't give a language in your tags. Here is an example in C:

#include <stdio.h>

unsigned crc8maximdow(unsigned char *data, size_t len) {
    unsigned crc = 0;
    for (size_t i = 0; i < len; i++) {
        crc ^= data[i];
        for (unsigned k = 0; k < 8; k++)
            crc = crc & 1 ? (crc >> 1) ^ 0x8c : crc >> 1;
    }
    return crc;
}

int main(void) {
    unsigned char data[] = {2, 0x1c, 0xb8, 1, 0, 0, 0};
    printf("0x%02x\n", crc8maximdow(data, sizeof(data)));
    return 0;
}

That prints 0xa2.

Mark Adler
  • 101,978
  • 13
  • 118
  • 158
  • Thank you. i notice that you reversed the polynomial, 0x8c instead of 0x31 and you are processing each byte completely before going onto the next one. From the tutorials I have seen it is processed as a continuous stream of bits so I was expecting to look for a 1 bit then process and as the bits are shifted feed bits from the next byte into the process. Is that wrong? Or just a quirk of this particular system? I'm also unclear on the first XOR when i=0. I thought you only XOR when a 1 bit lines up with the n+1 bit of the generator polynomial as per the k loop? – Archie Dec 13 '22 at 16:30
  • Exclusive-oring the eight bits all at once has exactly the same effect as feeding them in one at a time. You can try one at a time and see. – Mark Adler Dec 13 '22 at 19:50
  • The polynomial is reflected because this CRC definition is reflected. If you're shifting down instead of up, the polynomial needs to be reflected. The alternative would be to reflect the bytes coming in, shift up instead of down, use the polynomial as is, and then reflect the output. Obviously silly, since you can instead just reflect the polynomial and shift down to do the exact same operations. – Mark Adler Dec 13 '22 at 19:52
  • I don't know what you mean by lining up bits. Perhaps you need to ask a new question. These comment fields aren't really meant for more questions. – Mark Adler Dec 13 '22 at 19:53
0

Using Mark's answer above I worked out what I was doing wrong with the Maxim example. Tutorials were talking about 'reflecting' the input data so I literally took the 56-bit bit pattern and reversed it which gave the wrong answer in the site https://crccalc.com/. Instead I reversed the hex numbers so that 00 00 00 01 B8 1C 02 becomes 02 1C B8 01 00 00 00 which gives the correct CRC of 0xA2 on the website. Hope this may help anyone else having the same problem.

Archie
  • 15
  • 3