Shop OBEX P1 Docs P2 Docs Learn Events
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

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)

Comments

  • 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.

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

  • Cluso99Cluso99 Posts: 18,069
    edited 2021-08-25 02:24

    There are some good CRC writeups - google is your friend

    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.

  • 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
                    add       p_src, #1
                    rev       b
                    setq      b
                    crcnib    crc, #$8C
                    crcnib    crc, #$8C
                    djnz      n, #.loop
      end
    
  • 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)

  • ChrisGadd
    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)

  • @"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(" ")
    
  • ChrisGadd
    Thanks for reply. Just want to include this for clarity. Putting into general usage notes I am making.
    Your spin program will be very useful for this purpose.
    Regards
    Bob (WRD)

Sign In or Register to comment.