Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 8 of 8

Thread: AVR/teensy 2 and crc16.h

  1. #1
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,828

    AVR/teensy 2 and crc16.h

    This function is wiithin file
    C:\Arduino\libraries\util\crc16.h
    on windows.
    Code:
        static uint16_t _crc_ccitt_update (uint16_t crc, uint8_t data)
        {
            data ^= lo8 (crc);
            data ^= data << 4;
    
            return ((((uint16_t)data << 8) | hi8 (crc)) ^ (uint8_t)(data >> 4)
                    ^ ((uint16_t)data << 3));
        }
    There are other files in Arduino-land that have the same function names but use a traditional bit-shift for loop and probably a different polynomial.
    The author of the code above did not state the initial CRC value (0 or FFFF are common), nor the polynomial. CCITT in common use has several variants.

    Perhaps that function is in the library "core.a"? The CRC16 code is not recompiled each build by my review of the build verbose logs.

    My issue is that an AVR or Teensy 3 must exchange messages with a PC/MAC/Linux that tries to have the same CRC algorithm and initial value but the PC/MAC/Linux must use Python code for portability - - including Python 2.7 and its serial module for all operating systems.

    My Python coded app attempts to duplicate that CRC code. Two instances of my code on two serial ports talks to another copy of itself just fine, of course.
    But the packet from an AVR has exactly the same content but a different CRC.

    I don't know why the function name has a leading underscore in C.

    I've spent a lot of time trying to duplicate the gawd afwul code above in Python (dealing with lack of uint8_t in Python), but I'm also not sure that code is even what the Arduino environment's linker is pulling!

    help appreciated. Maybe some way to get the GCC library manager to list core.a and see what file the crc function is in?
    And does Teensy 3 use the same?

    steve
    Last edited by stevech; 06-21-2014 at 11:52 PM.

  2. #2
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,999
    Maybe this documentation will help?

    http://www.nongnu.org/avr-libc/user-...000e24d981ad20

    At least there you can see the polynomial is x^16 + x^12 + x^5 + 1 (0x8408).

    That page says the initial value is 0xFFFF, but really, it'll be whatever number the calling code passes into the "crc" input on the first time this function is called (and assuming the output value is used as the input to the next call). In other words, this CRC code doesn't have *any* initial value inside its code. You supply the initial value an one of the inputs when you call this function.

    I can't help with Python.

  3. #3
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,828
    thanks very much.
    Do you know if that object code is within Arduino's core.a? And why the C code has the leading underscore in the function name?
    There are several in the .h trees of Arduino and related.
    Last edited by stevech; 06-22-2014 at 02:52 AM.

  4. #4
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,828
    Here's the solution. It works, within the RadioHead RH_Serial protocol implemented on an AVR and a Python equivalent to the same code as on the AVR. Just had to get the Python code to do what type-casting does in C, and get the parens and operator precedence right.

    Forgive my non-Pythonic code but it works. This CRC is a small part of the protocol.
    Code:
     #----------------------------------------------------------------------------
        # Calculate and return an incremental CRC value based on the current value
        # and the data bytes passed in as a string.
        # code below to match crc16.h that RH uses, CCITT or not
        #non-table driven CRC16
        # Polynomial: x^16 + x^12 + x^5 + 1 (0x8408)
        # Initial value: 0xffff
        #static uint16_t _crc_ccitt_update (uint16_t crc, uint8_t data)
        #{
        #    data ^= lo8 (crc);
        #    data ^= data << 4;
        #
        #    return ( ( ( (uint16_t)data << 8) | hi8 (crc)) ^ (uint8_t)(data >> 4) 
        #            ^ ((uint16_t)data << 3));
        #}
    
        def lo8(self,n):
            return n & 0xFF
        
        def hi8(self,n):
            return (n >> 8) & 0xFF
        
        def _crc_ccitt_update(self, crc, c): 
            d = c & 0xFF # ensure uint8_t
            d = d ^ self.lo8(crc)
            d = d ^ ((d << 4) & 0xFF)
            
            ret = ( ( (0xFFFF & (d << 8) | self.hi8(crc)) ^ (d >> 4) ^ (0xFFFF & (d << 3) ) ) )
            return ret
    Last edited by stevech; 06-22-2014 at 06:40 AM.

  5. #5
    Senior Member+ Frank B's Avatar
    Join Date
    Apr 2014
    Location
    Germany
    Posts
    8,230
    On Teensy 3, you can use FastCRC, which really is much faster.

    https://github.com/FrankBoesing/FastCRC

  6. #6
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,828
    Quote Originally Posted by Frank B View Post
    On Teensy 3, you can use FastCRC, which really is much faster.

    https://github.com/FrankBoesing/FastCRC
    Thanks, but the overall system here uses 3rd party software that #includes the Arduino CRC code shown above. I've suggested using an internal CRC to avoid impact if Arduino changes.
    That FastCRC collection is handy to stash for future use! Thanks.

  7. #7
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    23,999
    Quote Originally Posted by stevech View Post
    .... software that #includes the Arduino CRC code shown above.
    This might be nit picking, but crc16.h comes from the avr-libc project, which is part of the toolchain Arduino bundles with the IDE. But it's not code written or maintained by Arduino, merely part of the C library which the toolchain uses. Odds are very low Arduino will ever change it.

  8. #8
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,828
    Thanks for that.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •