0x06, // bInterfaceClass (0x06 = still image) | 0x06, // bInterfaceClass (0x06 = still image) | ||||
0x01, // bInterfaceSubClass | 0x01, // bInterfaceSubClass | ||||
0x01, // bInterfaceProtocol | 0x01, // bInterfaceProtocol | ||||
0, // iInterface | |||||
4, // iInterface | |||||
// endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 | // endpoint descriptor, USB spec 9.6.6, page 269-271, Table 9-13 | ||||
7, // bLength | 7, // bLength | ||||
5, // bDescriptorType | 5, // bDescriptorType | ||||
3, | 3, | ||||
{0,0,0,0,0,0,0,0,0,0} | {0,0,0,0,0,0,0,0,0,0} | ||||
}; | }; | ||||
#ifdef MTP_INTERFACE | |||||
struct usb_string_descriptor_struct usb_string_mtp = { | |||||
2 + 3 * 2, | |||||
3, | |||||
{'M','T','P'} | |||||
}; | |||||
#endif | |||||
void usb_init_serialnumber(void) | void usb_init_serialnumber(void) | ||||
{ | { | ||||
#ifdef MULTITOUCH_INTERFACE | #ifdef MULTITOUCH_INTERFACE | ||||
{0x2200, MULTITOUCH_INTERFACE, multitouch_report_desc, sizeof(multitouch_report_desc)}, | {0x2200, MULTITOUCH_INTERFACE, multitouch_report_desc, sizeof(multitouch_report_desc)}, | ||||
{0x2100, MULTITOUCH_INTERFACE, config_descriptor+MULTITOUCH_HID_DESC_OFFSET, 9}, | {0x2100, MULTITOUCH_INTERFACE, config_descriptor+MULTITOUCH_HID_DESC_OFFSET, 9}, | ||||
#endif | |||||
#ifdef MTP_INTERFACE | |||||
{0x0304, 0x0409, (const uint8_t *)&usb_string_mtp, 0}, | |||||
#endif | #endif | ||||
{0x0300, 0x0000, (const uint8_t *)&string0, 0}, | {0x0300, 0x0000, (const uint8_t *)&string0, 0}, | ||||
{0x0301, 0x0409, (const uint8_t *)&usb_string_manufacturer_name, 0}, | {0x0301, 0x0409, (const uint8_t *)&usb_string_manufacturer_name, 0}, |
data = reply_buffer; | data = reply_buffer; | ||||
break; | break; | ||||
case 0x0082: // GET_STATUS (endpoint) | case 0x0082: // GET_STATUS (endpoint) | ||||
if (setup.wIndex > NUM_ENDPOINTS) { | |||||
i = setup.wIndex & 0x7F; | |||||
if (i > NUM_ENDPOINTS) { | |||||
// TODO: do we need to handle IN vs OUT here? | // TODO: do we need to handle IN vs OUT here? | ||||
endpoint0_stall(); | endpoint0_stall(); | ||||
return; | return; | ||||
} | } | ||||
reply_buffer[0] = 0; | reply_buffer[0] = 0; | ||||
reply_buffer[1] = 0; | reply_buffer[1] = 0; | ||||
if (*(uint8_t *)(&USB0_ENDPT0 + setup.wIndex * 4) & 0x02) reply_buffer[0] = 1; | |||||
if (*(uint8_t *)(&USB0_ENDPT0 + i * 4) & 0x02) reply_buffer[0] = 1; | |||||
data = reply_buffer; | data = reply_buffer; | ||||
datalen = 2; | datalen = 2; | ||||
break; | break; | ||||
#endif | #endif | ||||
#if defined(MTP_INTERFACE) | #if defined(MTP_INTERFACE) | ||||
case 0x2164: // Cancel Request (PTP spec, 5.2.1, page 8) | |||||
// TODO: required by PTP spec | |||||
endpoint0_stall(); | |||||
return; | |||||
case 0x2166: // Device Reset (PTP spec, 5.2.3, page 10) | |||||
case 0x64A1: // Cancel Request (PTP spec, 5.2.1, page 8) | |||||
// TODO: required by PTP spec | // TODO: required by PTP spec | ||||
endpoint0_stall(); | endpoint0_stall(); | ||||
return; | return; | ||||
case 0x2167: // Get Device Statis (PTP spec, 5.2.4, page 10) | |||||
case 0x66A1: // Device Reset (PTP spec, 5.2.3, page 10) | |||||
// TODO: required by PTP spec | // TODO: required by PTP spec | ||||
endpoint0_stall(); | endpoint0_stall(); | ||||
return; | return; | ||||
case 0x67A1: // Get Device Statis (PTP spec, 5.2.4, page 10) | |||||
// For now, always respond with status ok. | |||||
reply_buffer[0] = 0x4; | |||||
reply_buffer[1] = 0; | |||||
reply_buffer[2] = 0x01; | |||||
reply_buffer[3] = 0x20; | |||||
data = reply_buffer; | |||||
datalen = 4; | |||||
break; | |||||
#endif | #endif | ||||
// TODO: this does not work... why? | // TODO: this does not work... why? |