Код:
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;
}
}