AVR/teensy 2 and crc16.h

Status
Not open for further replies.

stevech

Well-known member
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:
Maybe this documentation will help?

http://www.nongnu.org/avr-libc/user-manual/group__util__crc.html#ga1c1d3ad875310cbc58000e24d981ad20

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.
 
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:
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:
.... 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.
 
Status
Not open for further replies.
Back
Top