Use USB Interface Association Descriptors.
This allows windows to see it as a composite device and load different driver for each interface.
This commit is contained in:
parent
4f0ed8361a
commit
edaae3957a
|
@ -53,9 +53,9 @@ static const struct usb_device_descriptor dev = {
|
||||||
.bLength = USB_DT_DEVICE_SIZE,
|
.bLength = USB_DT_DEVICE_SIZE,
|
||||||
.bDescriptorType = USB_DT_DEVICE,
|
.bDescriptorType = USB_DT_DEVICE,
|
||||||
.bcdUSB = 0x0200,
|
.bcdUSB = 0x0200,
|
||||||
.bDeviceClass = USB_CLASS_CDC,
|
.bDeviceClass = 0xEF, /* Miscellaneous Device */
|
||||||
.bDeviceSubClass = 0,
|
.bDeviceSubClass = 2, /* Common Class */
|
||||||
.bDeviceProtocol = 0,
|
.bDeviceProtocol = 1, /* Interface Association */
|
||||||
.bMaxPacketSize0 = 64,
|
.bMaxPacketSize0 = 64,
|
||||||
.idVendor = 0x0483,
|
.idVendor = 0x0483,
|
||||||
.idProduct = 0x5740,
|
.idProduct = 0x5740,
|
||||||
|
@ -138,7 +138,7 @@ static const struct usb_interface_descriptor gdb_comm_iface[] = {{
|
||||||
.bInterfaceClass = USB_CLASS_CDC,
|
.bInterfaceClass = USB_CLASS_CDC,
|
||||||
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
|
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
|
||||||
.bInterfaceProtocol = USB_CDC_PROTOCOL_AT,
|
.bInterfaceProtocol = USB_CDC_PROTOCOL_AT,
|
||||||
.iInterface = 0,
|
.iInterface = 4,
|
||||||
|
|
||||||
.endpoint = gdb_comm_endp,
|
.endpoint = gdb_comm_endp,
|
||||||
|
|
||||||
|
@ -160,6 +160,17 @@ static const struct usb_interface_descriptor gdb_data_iface[] = {{
|
||||||
.endpoint = gdb_data_endp,
|
.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
|
#ifdef INCLUDE_UART_INTERFACE
|
||||||
/* Serial ACM interface */
|
/* Serial ACM interface */
|
||||||
static const struct usb_endpoint_descriptor uart_comm_endp[] = {{
|
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,
|
.bInterfaceClass = USB_CLASS_CDC,
|
||||||
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
|
.bInterfaceSubClass = USB_CDC_SUBCLASS_ACM,
|
||||||
.bInterfaceProtocol = USB_CDC_PROTOCOL_AT,
|
.bInterfaceProtocol = USB_CDC_PROTOCOL_AT,
|
||||||
.iInterface = 0,
|
.iInterface = 5,
|
||||||
|
|
||||||
.endpoint = uart_comm_endp,
|
.endpoint = uart_comm_endp,
|
||||||
|
|
||||||
|
@ -252,6 +263,17 @@ static const struct usb_interface_descriptor uart_data_iface[] = {{
|
||||||
|
|
||||||
.endpoint = uart_data_endp,
|
.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
|
#endif
|
||||||
|
|
||||||
const struct usb_dfu_descriptor dfu_function = {
|
const struct usb_dfu_descriptor dfu_function = {
|
||||||
|
@ -272,14 +294,26 @@ const struct usb_interface_descriptor dfu_iface = {
|
||||||
.bInterfaceClass = 0xFE,
|
.bInterfaceClass = 0xFE,
|
||||||
.bInterfaceSubClass = 1,
|
.bInterfaceSubClass = 1,
|
||||||
.bInterfaceProtocol = 1,
|
.bInterfaceProtocol = 1,
|
||||||
.iInterface = 0,
|
.iInterface = 6,
|
||||||
|
|
||||||
.extra = &dfu_function,
|
.extra = &dfu_function,
|
||||||
.extralen = sizeof(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[] = {{
|
static const struct usb_interface ifaces[] = {{
|
||||||
.num_altsetting = 1,
|
.num_altsetting = 1,
|
||||||
|
.iface_assoc = &gdb_assoc,
|
||||||
.altsetting = gdb_comm_iface,
|
.altsetting = gdb_comm_iface,
|
||||||
}, {
|
}, {
|
||||||
.num_altsetting = 1,
|
.num_altsetting = 1,
|
||||||
|
@ -287,6 +321,7 @@ static const struct usb_interface ifaces[] = {{
|
||||||
}, {
|
}, {
|
||||||
#ifdef INCLUDE_UART_INTERFACE
|
#ifdef INCLUDE_UART_INTERFACE
|
||||||
.num_altsetting = 1,
|
.num_altsetting = 1,
|
||||||
|
.iface_assoc = &uart_assoc,
|
||||||
.altsetting = uart_comm_iface,
|
.altsetting = uart_comm_iface,
|
||||||
}, {
|
}, {
|
||||||
.num_altsetting = 1,
|
.num_altsetting = 1,
|
||||||
|
@ -294,6 +329,7 @@ static const struct usb_interface ifaces[] = {{
|
||||||
}, {
|
}, {
|
||||||
#endif
|
#endif
|
||||||
.num_altsetting = 1,
|
.num_altsetting = 1,
|
||||||
|
.iface_assoc = &dfu_assoc,
|
||||||
.altsetting = &dfu_iface,
|
.altsetting = &dfu_iface,
|
||||||
}};
|
}};
|
||||||
|
|
||||||
|
@ -321,6 +357,9 @@ static const char *usb_strings[] = {
|
||||||
"Black Sphere Technologies",
|
"Black Sphere Technologies",
|
||||||
"Black Magic Probe",
|
"Black Magic Probe",
|
||||||
serial_no,
|
serial_no,
|
||||||
|
"Black Magic GDB Server",
|
||||||
|
"Black Magic UART Port",
|
||||||
|
"Black Magic Firmware Upgrade",
|
||||||
};
|
};
|
||||||
|
|
||||||
static void dfu_detach_complete(struct usb_setup_data *req)
|
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;
|
return 0;
|
||||||
|
|
||||||
struct usb_cdc_line_coding *coding = (void*)*buf;
|
struct usb_cdc_line_coding *coding = (void*)*buf;
|
||||||
usart_set_baudrate(USART1, coding->dwDTERate,
|
usart_set_baudrate(USART1, coding->dwDTERate);
|
||||||
rcc_ppre2_frequency);
|
|
||||||
usart_set_databits(USART1, coding->bDataBits);
|
usart_set_databits(USART1, coding->bDataBits);
|
||||||
switch(coding->bCharFormat) {
|
switch(coding->bCharFormat) {
|
||||||
case 0:
|
case 0:
|
||||||
|
|
|
@ -193,7 +193,7 @@ void uart_init(void)
|
||||||
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO9);
|
GPIO_CNF_OUTPUT_ALTFN_PUSHPULL, GPIO9);
|
||||||
|
|
||||||
/* Setup UART parameters. */
|
/* Setup UART parameters. */
|
||||||
usart_set_baudrate(USART1, 38400, rcc_ppre2_frequency);
|
usart_set_baudrate(USART1, 38400);
|
||||||
usart_set_databits(USART1, 8);
|
usart_set_databits(USART1, 8);
|
||||||
usart_set_stopbits(USART1, USART_STOPBITS_1);
|
usart_set_stopbits(USART1, USART_STOPBITS_1);
|
||||||
usart_set_mode(USART1, USART_MODE_TX_RX);
|
usart_set_mode(USART1, USART_MODE_TX_RX);
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
|
|
||||||
#include "gdb_packet.h"
|
#include "gdb_packet.h"
|
||||||
|
|
||||||
//#define INCLUDE_UART_INTERFACE
|
#define INCLUDE_UART_INTERFACE
|
||||||
|
|
||||||
/* Important pin mappings for STM32 implementation:
|
/* Important pin mappings for STM32 implementation:
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue