CRCBIT sample program using \$8C CCR8 says divisor \$9D any suggestions to learn Propeller CRCBIT — Parallax Forums

# CRCBIT sample program using \$8C CCR8 says divisor \$9D any suggestions to learn Propeller CRCBIT

Posts: 151

Did some preliminary Internet search on CRC8 and there apears to be multiple standards
CRC8-CDMA200,CRC8-DARC,CRC8-ITU . The attached code was found on internet from Parallax forum. It seems to work but I was hoping to get some background information to explain what the CRCBIT instruction does. If someone can point me in the right direction it would be apreciated.
Thanks and Regards
Bob (WRD)

• Posts: 290

crcbit performs the instructions:

```             testb crc,#0  wz
shr   crc,#1
if_c_ne_z  xor   crc,POLY
```

You're required to have the bit you want to apply the instruction to already in C, as in this CANbus example using crc15_reversed polynomial \$4CD1.

```    crc               z   c      bitstream
%000000000000000   0   0   %11000101100000000100001000      shift bitstream left into c, test bit 0 of crc into z, shift crc right 1
%100110011010001   0   1   %1000101100000000100001000       c_ne_z so xor polynomial
%010011001101000   1   1   %000101100000000100001000
%001001100110100   0   0   %00101100000000100001000
%000100110011010   0   0   %0101100000000100001000
%000010011001101   0   0   %101100000000100001000
%000001001100110   1   1   %01100000000100001000
%000000100110011   0   0   %1100000000100001000
%000000010011001   1   1   %100000000100001000
%000000001001100   1   1   %00000000100001000
%000000000100110   0   0   %0000000100001000
%000000000010011   0   0   %000000100001000
%100110011011000   1   0   %00000100001000
%010011001101100   0   0   %0000100001000
%001001100110110   0   0   %000100001000
%000100110011011   0   0   %00100001000
%100100000011100   1   0   %0100001000
%010010000001110   0   0   %100001000
%101111011010110   0   1   %00001000
%010111101101011   0   0   %0001000
%101101101100100   1   0   %001000
%010110110110010   0   0   %01000
%001011011011001   0   0   %1000
%000101101101100   1   1   %000
%000010110110110   0   0   %00
%000001011011011   0   0   %0
%100110110111100   1   0
```

The final result needs to be reversed and shifted to the lsb; %001111011011001.
Also, some polynomials require the starting value to be initialized, which for crcbit also needs to be reversed. CRC17 for CAN-FD iso requires the crc to be initialized to \$1_0000, which for crcbit means I initialize crc to \$00001.
As far as crc8 goes, the only one I've used is for the 1-wire bus, which is \$31 forward or \$8C reversed, with no initialization. The wikipedia article on "cycle redundancy check" is a good resource for finding the various polynomials.

Attached a bit of code I wrote while trying to figure how it all worked, and how to back-port it into something I could do on the P1.

• Posts: 151

Thanks Chris . Will try to go through this. I have limited understanding on CRC.
Regards
Bob (WRD)

• Posts: 17,955
edited 2021-08-25 02:24

If you search the older thread(s) where I suggested adding CRC to the P2 design I gave a spin1 example of the CRC function.

• Posts: 7,708

This is the CRC8 that I have in my Spin1 1-Wire object

```pub crc8x(p_src, n) : crc | b

'' Returns CRC8 of n bytes at p_src
'' -- implementation by Micah Dowty

repeat n
b := byte[p_src++]
repeat 8
if (crc ^ b) & 1
crc := (crc >> 1) ^ \$8C
else
crc >>= 1
b >>= 1
```

After some of experimenting and suggestions by forum members, that method in the P2 version of the object looks like this:

```pub crc8(p_src, n) : crc | b

'' Returns CRC8 of n bytes from data at p_src

org
.loop           rdbyte    b, p_src
rev       b
setq      b
crcnib    crc, #\$8C
crcnib    crc, #\$8C
djnz      n, #.loop
end
```
• Posts: 151

Thanks for responses have looked into code provided and I believe that CRC8-MAXIM Divisor = X8 + X5 + X4 +1 = \$131 is what is being targeted for 1 wire devices and I did learn stuff
The code from Chris Gadd I would like to understand (not sure of object "Serial" version to use) both version of code CRCBIT anc CRCNIB (Jonny Mac) give the sam results and match the CRC8Maxim
Calculator (Online CRC Calculator) I have attached program modifications, so not understanding exactly how instruction works (value \$8C how it relates to CRC8Maxim divisor) the code provided makes it usable for the notes I am generating (CRC is rather complicated )thanks again
Regards
Bob (WRD)

• Posts: 151

Is it possible to have a dscrete set of assembly instruction to emulate "crcbit crc, #\$8C " I have been trying to get a handle on CRC in particular CRC8-Dallas\Maxim
{ testb crc,#0 wz
shr crc,#1
if_c_ne_z xor crc, #\$8C }
I have looked at what you sent and not being comfortable with propeller II assembly took sometime to get some understanding . I have modified your code with debug and have attached a propeller
program I would like to modify to replace CRCBIT instruction.
Regards and Thanks
Bob (WRD)

• Posts: 290

@"Bob Drury" said:
Is it possible to have a discrete set of assembly instruction to emulate "crcbit crc, #\$8C "

It looks like you've already done it in your .4 example, just comment out the crcbit instruction and uncomment the three discrete instructions and you'll see it gives the same result.
As mentioned, it was something I did to learn how it worked; it's pointless to use on the P2 as crcbit does the same thing, faster, in fewer instructions, and without corrupting the Z flag.

If you're not comfortable with assembly, here's a Spin method that also gives the same result:

```PUB CR8_spin(p_src,n) : crc | data
repeat n
data := byte[p_src++]                               ' retrieve a byte of data
repeat 8
if crc & 1 <> data & 1                            ' if lsb of crc and lsb of data are not equal
crc >>= 1                                       '  shift crc right 1
crc ^= \$8C                                      '  xor crc with polynomial \$8C
else                                              ' if lsbs are equal
crc >>= 1                                       '  then shift but don't xor
data >>= 1                                        ' put next bit of data into lsb
debug(ubin_byte(crc),ubin_byte(data))
debug(" ")
```
• Posts: 151