diff --git a/board/drivers/usb.h b/board/drivers/usb.h index a6d367f634cf2e..c43a8ce4008c68 100644 --- a/board/drivers/usb.h +++ b/board/drivers/usb.h @@ -72,7 +72,7 @@ uint8_t resp[MAX_RESP_LEN]; #define ENDPOINT_TYPE_INT 3 // This is an arbitrary value used in bRequest -#define MS_VENDOR_CODE 0xFF +#define MS_VENDOR_CODE 0x20 //Convert machine byte order to USB byte order #define TOUSBORDER(num)\ @@ -190,30 +190,25 @@ uint8_t winusb_ext_compatid_os_desc[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // Reserved }; uint8_t winusb_ext_prop_os_desc[] = { - 0xCC, 0x00, 0x00, 0x00, // dwLength + 0x8e, 0x00, 0x00, 0x00, // dwLength 0x00, 0x01, // bcdVersion 0x05, 0x00, // wIndex - 0x02, 0x00, // wCount + 0x01, 0x00, // wCount // first property 0x84, 0x00, 0x00, 0x00, // dwSize 0x01, 0x00, 0x00, 0x00, // dwPropertyDataType 0x28, 0x00, // wPropertyNameLength 'D',0, 'e',0, 'v',0, 'i',0, 'c',0, 'e',0, 'I',0, 'n',0, 't',0, 'e',0, 'r',0, 'f',0, 'a',0, 'c',0, 'e',0, 'G',0, 'U',0, 'I',0, 'D',0, 0, 0, // bPropertyName (DeviceInterfaceGUID) - 0x4E, 0x00, 0x00, 0x00, // dwPropertyDataLength - '{',0, 'C',0, 'C',0, 'E',0, '5',0, '2',0, '9',0, '1',0, 'C',0, '-',0, 'A',0, '6',0, '9',0, 'F',0, '-',0, '4',0, '9',0, '9',0, '5',0, '-',0, 'A',0, '4',0, 'C',0, '2',0, '-',0, '2',0, 'A',0, 'E',0, '5',0, '7',0, 'A',0, '5',0, '1',0, 'A',0, 'D',0, 'E',0, '9',0, '}',0, 0, 0, // bPropertyData ({CCE5291C-A69F-4995-A4C2-2AE57A51ADE9}) - // second property - 0x3E, 0x00, 0x00, 0x00, // dwSize - 0x01, 0x00, 0x00, 0x00, // dwPropertyDataType - 0x0C, 0x00, // wPropertyNameLength - 'L',0, 'a',0, 'b',0, 'e',0, 'l',0, 0, 0, // bPropertyName (Label) - 0x24, 0x00, 0x00, 0x00, // dwPropertyDataLength - 'p',0, 'a',0, 'n',0, 'd',0, 'a',0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 // bPropertyData (panda) + 0x4e, 0x00, 0x00, 0x00, // dwPropertyDataLength + '{',0, 'c',0, 'c',0, 'e',0, '5',0, '2',0, '9',0, '1',0, 'c',0, '-',0, 'a',0, '6',0, '9',0, 'f',0, '-',0, '4',0 ,'9',0 ,'9',0 ,'5',0 ,'-',0, 'a',0, '4',0, 'c',0, '2',0, '-',0, '2',0, 'a',0, 'e',0, '5',0, '7',0, 'a',0, '5',0, '1',0, 'a',0, 'd',0, 'e',0, '9',0, '}',0, 0, 0, // bPropertyData ({CCE5291C-A69F-4995-A4C2-2AE57A51ADE9}) }; #endif // current packet USB_Setup_TypeDef setup; uint8_t usbdata[0x100]; +uint8_t* ep0_txdata = NULL; +uint16_t ep0_txlen = 0; // Store the current interface alt setting. int current_int0_alt_setting = 0; @@ -252,6 +247,26 @@ void USB_WritePacket(const uint8_t *src, uint16_t len, uint32_t ep) { } } +// IN EP 0 TX FIFO has a max size of 127 bytes (much smaller than the rest) +// so use TX FIFO empty interrupt to send larger amounts of data +void USB_WritePacket_EP0(uint8_t *src, uint16_t len) { + #ifdef DEBUG_USB + puts("writing "); + hexdump(src, len); + #endif + + uint16_t wplen = min(len, 0x40); + USB_WritePacket(src, wplen, 0); + + if (wplen < len) { + ep0_txdata = src + wplen; + ep0_txlen = len - wplen; + USBx_DEVICE->DIEPEMPMSK |= 1; + } else { + USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; + } +} + void usb_reset() { // unmask endpoint interrupts, so many sets USBx_DEVICE->DAINT = 0xFFFFFFFF; @@ -428,16 +443,15 @@ void usb_setup() { switch (setup.b.wIndex.w) { // Extended Compat ID OS Descriptor case 4: - USB_WritePacket((uint8_t*)winusb_ext_compatid_os_desc, min(sizeof(winusb_ext_compatid_os_desc), setup.b.wLength.w), 0); + USB_WritePacket_EP0((uint8_t*)winusb_ext_compatid_os_desc, min(sizeof(winusb_ext_compatid_os_desc), setup.b.wLength.w)); break; // Extended Properties OS Descriptor case 5: - USB_WritePacket((uint8_t*)winusb_ext_prop_os_desc, min(sizeof(winusb_ext_prop_os_desc), setup.b.wLength.w), 0); + USB_WritePacket_EP0((uint8_t*)winusb_ext_prop_os_desc, min(sizeof(winusb_ext_prop_os_desc), setup.b.wLength.w)); break; default: - USB_WritePacket(0, 0, 0); + USB_WritePacket_EP0(0, 0); } - USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; break; #endif default: @@ -750,6 +764,24 @@ void usb_irqhandler(void) { break; } + if (USBx_INEP(0)->DIEPINT & USB_OTG_DIEPMSK_ITTXFEMSK) { + #ifdef DEBUG_USB + puts(" IN PACKET QUEUE\n"); + #endif + + if (ep0_txlen != 0 && (USBx_INEP(0)->DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV) >= 0x40) { + uint16_t len = min(ep0_txlen, 0x40); + USB_WritePacket(ep0_txdata, len, 0); + ep0_txdata += len; + ep0_txlen -= len; + if (ep0_txlen == 0) { + ep0_txdata = NULL; + USBx_DEVICE->DIEPEMPMSK &= ~1; + USBx_OUTEP(0)->DOEPCTL |= USB_OTG_DOEPCTL_CNAK; + } + } + } + // clear interrupts USBx_INEP(0)->DIEPINT = USBx_INEP(0)->DIEPINT; // Why ep0? USBx_INEP(1)->DIEPINT = USBx_INEP(1)->DIEPINT; diff --git a/tests/read_winusb_descriptors.py b/tests/read_winusb_descriptors.py new file mode 100644 index 00000000000000..e38df8d1caa9c3 --- /dev/null +++ b/tests/read_winusb_descriptors.py @@ -0,0 +1,29 @@ +#!/usr/bin/env python +from panda import Panda +from hexdump import hexdump + +DEBUG = False + +if __name__ == "__main__": + p = Panda() + + len = p._handle.controlRead(Panda.REQUEST_IN, 0x06, 3 << 8 | 238, 0, 1) + print 'Microsoft OS String Descriptor' + dat = p._handle.controlRead(Panda.REQUEST_IN, 0x06, 3 << 8 | 238, 0, len[0]) + if DEBUG: print 'LEN: {}'.format(hex(len[0])) + hexdump("".join(map(chr, dat))) + + ms_vendor_code = dat[16] + if DEBUG: print 'MS_VENDOR_CODE: {}'.format(hex(len[0])) + + print '\nMicrosoft Compatible ID Feature Descriptor' + len = p._handle.controlRead(Panda.REQUEST_IN, ms_vendor_code, 0, 4, 1) + if DEBUG: print 'LEN: {}'.format(hex(len[0])) + dat = p._handle.controlRead(Panda.REQUEST_IN, ms_vendor_code, 0, 4, len[0]) + hexdump("".join(map(chr, dat))) + + print '\nMicrosoft Extended Properties Feature Descriptor' + len = p._handle.controlRead(Panda.REQUEST_IN, ms_vendor_code, 0, 5, 1) + if DEBUG: print 'LEN: {}'.format(hex(len[0])) + dat = p._handle.controlRead(Panda.REQUEST_IN, ms_vendor_code, 0, 5, len[0]) + hexdump("".join(map(chr, dat)))