Page 1 of 1

How Do You Check CRC16 From Application?

Posted: Thu Oct 29, 2009 7:27 am
by rjburke377
Is there an example that shows how to verify CRC16 from uchar usbFunctionWrite( uchar *data, uchar len ) ?

What parms do you pass to usbCrc16() and what do you compare? usbdrv.s seems to suggest unsigned crc = usbCrc16(buffer + 1, usbRxLen - 3) but I don't know how this relates to usbFunctionWrite().

/RJ

Re: How Do You Check CRC16 From Application?

Posted: Sun Nov 01, 2009 10:54 am
by christian
The function call in the comment is somewhat outdated now...

You would call usbCrc16(data, len) and compare the result to data[len] and data[len + 1].

Re: How Do You Check CRC16 From Application?

Posted: Mon Nov 25, 2013 11:20 pm
by blargg
Or, if wasting a few cycles isn't a problem (and you know that len < 256-2),

Code: Select all

uchar usbFunctionWrite( uchar* data, uchar len )
{
    if ( usbCrc16( data, len + 2 ) != 0x4FFE )
    {
        // CRC error
    }
    ...
}

This relies on the property that the checksum of some data with its usb CRC appended is 0x4FFE, which is just the CRC of two zero bytes alone. This occurs because the appended CRC XORs itself and the previous data out of the CRC, leaving the equivalent of two zero bytes and no data.

OK, and to check the CRC of normal incoming requests:

Code: Select all

uchar usbFunctionSetup( uchar data [8] )
{
    if ( usbCrc16( data, 8 + 2 ) != 0x4FFE )
    {
        // report error to host somehow, perhaps returning a zero-length reply (return 0;)
    }
    ...
}

Though this still doesn't check ones handled internally by V-USB, like descriptor reading.

Added to V-USB Wiki

EDIT: And if you just want to ignore any packets with an invalid CRC (including those handled by V-USB internally), just add this to usbconfig.h:

Code: Select all

/* Check CRC of all received data */
#define USB_RX_USER_HOOK( data, len ) { \
    if ( usbCrc16( data, len + 2 ) != 0x4FFE )\
        return;\
}

This gets inserted into usbProcessRx() at the beginning, which is called from usbPoll(). The downside is that you don't get to take any application-specific action. I'm not sure how well this works, ignoring packets. The host might not notice, thus leaving the CRC error still harmful to reliable functioning.