Код:
const char usb_device_descriptor[] = { ... }; const char usb_configuration_descriptor[] = { ... }; const char usb_language_string[] = { ... }; const char usb_product_string[] = { ... }; const char usb_serial_string[] = { ... }; const char usb_status[] = { ... }; struct { int address; int data_length; const char *data_pointer; } usb_context;
Код:
int usb_request ( char *buf ) { const char *ptr = 0; int req = buf[0] | buf[1] << 8; if( req == 0x680 /* get descriptor */ ) { switch( buf[2] | buf[3] << 8 ) { case 0x100 : { ptr = usb_device_descriptor; break; } case 0x200 : { ptr = usb_configuration_descriptor; break; } case 0x300 : { ptr = usb_language_string; break; } case 0x302 : { ptr = usb_product_string; break; } case 0x303 : { ptr = usb_serial_string; break; } default : return 0; } } else if( req == 0x80 || req == 0x81 || req == 0x82 /* get status */ ) { ptr = usb_status; } else if( req == 0x500 /* set address */ ) { usb_context.address = buf[2]; } else if( req == 0x100 || req == 0x101 || req == 0x102 /* clear future */ || req == 0x300 || req == 0x301 || req == 0x302 /* set future */ || req == 0x900 /* set configuration */ || req == 0xB01 /* set interface */ ) { } else { return 0; } if( ptr ) { int len = buf[6] | buf[7] << 8; usb_context.data_length = len < *ptr ? len : *ptr; usb_context.data_pointer = ptr + 1; } else { usb_context.data_length = 0; } return req; }
Код:
int usb_reply ( char *buf, int max ) { int len = usb_context.data_length; if( len > 0 ) { int n = len < max ? len : max; for( int i = 0; i < n; i++ ) buf[i] = *usb_context.data_pointer++; usb_context.data_length -= max; return n; } else if( len == 0 ) { usb_context.data_length = -1; return 0; } else { return -1; } }