| 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? |