How Do You Check CRC16 From Application?

General discussions about V-USB, our firmware-only implementation of a low speed USB device on Atmel's AVR microcontrollers
Post Reply
rjburke377
Posts: 7
Joined: Tue Oct 06, 2009 7:01 am

How Do You Check CRC16 From Application?

Post by rjburke377 » Thu Oct 29, 2009 7:27 am

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

christian
Objective Development
Objective Development
Posts: 1443
Joined: Thu Nov 09, 2006 11:46 am

Re: How Do You Check CRC16 From Application?

Post by christian » Sun Nov 01, 2009 10:54 am

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

blargg
Rank 3
Rank 3
Posts: 102
Joined: Thu Nov 14, 2013 10:01 pm

Re: How Do You Check CRC16 From Application?

Post by blargg » Mon Nov 25, 2013 11:20 pm

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.

Post Reply