From edaae3957a90903b5bd92fa3575aafc79a4c0d12 Mon Sep 17 00:00:00 2001 From: Gareth McMullin Date: Thu, 29 Dec 2011 12:49:47 +1300 Subject: Use USB Interface Association Descriptors. This allows windows to see it as a composite device and load different driver for each interface. --- src/stm32/cdcacm.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 8 deletions(-) (limited to 'src/stm32/cdcacm.c') diff --git a/src/stm32/cdcacm.c b/src/stm32/cdcacm.c index 690081e..0be7cbf 100644 --- a/src/stm32/cdcacm.c +++ b/src/stm32/cdcacm.c @@ -53,9 +53,9 @@ static const struct usb_device_descriptor dev = { .bLength = USB_DT_DEVICE_SIZE, .bDescriptorType = USB_DT_DEVICE, .bcdUSB = 0x0200, - .bDeviceClass = USB_CLASS_CDC, - .bDeviceSubClass = 0, - .bDeviceProtocol = 0, + .bDeviceClass = 0xEF, /* Miscellaneous Device */ + .bDeviceSubClass = 2, /* Common Class */ + .bDeviceProtocol = 1, /* Interface Association */ .bMaxPacketSize0 = 64, .idVendor = 0x0483, .idProduct = 0x5740, @@ -138,7 +138,7 @@ static const struct usb_interface_descriptor gdb_comm_iface[] = {{ .bInterfaceClass = USB_CLASS_CDC, .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, .bInterfaceProtocol = USB_CDC_PROTOCOL_AT, - .iInterface = 0, + .iInterface = 4, .endpoint = gdb_comm_endp, @@ -160,6 +160,17 @@ static const struct usb_interface_descriptor gdb_data_iface[] = {{ .endpoint = gdb_data_endp, }}; +static const struct usb_iface_assoc_descriptor gdb_assoc = { + .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE, + .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, + .bFirstInterface = 0, + .bInterfaceCount = 2, + .bFunctionClass = USB_CLASS_CDC, + .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, + .bFunctionProtocol = USB_CDC_PROTOCOL_AT, + .iFunction = 0, +}; + #ifdef INCLUDE_UART_INTERFACE /* Serial ACM interface */ static const struct usb_endpoint_descriptor uart_comm_endp[] = {{ @@ -231,7 +242,7 @@ static const struct usb_interface_descriptor uart_comm_iface[] = {{ .bInterfaceClass = USB_CLASS_CDC, .bInterfaceSubClass = USB_CDC_SUBCLASS_ACM, .bInterfaceProtocol = USB_CDC_PROTOCOL_AT, - .iInterface = 0, + .iInterface = 5, .endpoint = uart_comm_endp, @@ -252,6 +263,17 @@ static const struct usb_interface_descriptor uart_data_iface[] = {{ .endpoint = uart_data_endp, }}; + +static const struct usb_iface_assoc_descriptor uart_assoc = { + .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE, + .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, + .bFirstInterface = 2, + .bInterfaceCount = 2, + .bFunctionClass = USB_CLASS_CDC, + .bFunctionSubClass = USB_CDC_SUBCLASS_ACM, + .bFunctionProtocol = USB_CDC_PROTOCOL_AT, + .iFunction = 0, +}; #endif const struct usb_dfu_descriptor dfu_function = { @@ -272,14 +294,26 @@ const struct usb_interface_descriptor dfu_iface = { .bInterfaceClass = 0xFE, .bInterfaceSubClass = 1, .bInterfaceProtocol = 1, - .iInterface = 0, + .iInterface = 6, .extra = &dfu_function, .extralen = sizeof(dfu_function), }; +static const struct usb_iface_assoc_descriptor dfu_assoc = { + .bLength = USB_DT_INTERFACE_ASSOCIATION_SIZE, + .bDescriptorType = USB_DT_INTERFACE_ASSOCIATION, + .bFirstInterface = 4, + .bInterfaceCount = 1, + .bFunctionClass = 0xFE, + .bFunctionSubClass = 1, + .bFunctionProtocol = 1, + .iFunction = 6, +}; + static const struct usb_interface ifaces[] = {{ .num_altsetting = 1, + .iface_assoc = &gdb_assoc, .altsetting = gdb_comm_iface, }, { .num_altsetting = 1, @@ -287,6 +321,7 @@ static const struct usb_interface ifaces[] = {{ }, { #ifdef INCLUDE_UART_INTERFACE .num_altsetting = 1, + .iface_assoc = &uart_assoc, .altsetting = uart_comm_iface, }, { .num_altsetting = 1, @@ -294,6 +329,7 @@ static const struct usb_interface ifaces[] = {{ }, { #endif .num_altsetting = 1, + .iface_assoc = &dfu_assoc, .altsetting = &dfu_iface, }}; @@ -321,6 +357,9 @@ static const char *usb_strings[] = { "Black Sphere Technologies", "Black Magic Probe", serial_no, + "Black Magic GDB Server", + "Black Magic UART Port", + "Black Magic Firmware Upgrade", }; static void dfu_detach_complete(struct usb_setup_data *req) @@ -364,8 +403,7 @@ static int cdcacm_control_request(struct usb_setup_data *req, uint8_t **buf, return 0; struct usb_cdc_line_coding *coding = (void*)*buf; - usart_set_baudrate(USART1, coding->dwDTERate, - rcc_ppre2_frequency); + usart_set_baudrate(USART1, coding->dwDTERate); usart_set_databits(USART1, coding->bDataBits); switch(coding->bCharFormat) { case 0: -- cgit v1.2.3