AnsweredAssumed Answered

USB device STATUS_DEVICE_DATA_ERROR

Question asked by Martin Dusek on Aug 30, 2018
Latest reply on Sep 9, 2018 by Daniel Chen

Hi,

I create composite USB device. So far I have custom class with 2 interrupt and 1 bulk endpoint and generic HID working. Now I wanted to add virtual COM to this configuration. This is how my descriptor looks like:

 

struct {
TUsbConfigurationDescriptor ConfigurationDescriptor;
uint8_t IAD[8];
TUsbInterfaceDescriptor ScannerInterfaceDescriptor;
TUsbEndpointDescriptor ScannerInterruptInEndpointDescriptor;
TUsbEndpointDescriptor ScannerInterruptOutEndpointDescriptor;
TUsbEndpointDescriptor ScannerBulkInEndpointDescriptor;
TUsbInterfaceDescriptor HidGenericInterfaceDescriptor;
TUsbHidDescriptor HidGenericDescriptor;
TUsbEndpointDescriptor HidGenericInterruptInEndpointDescriptor;
TUsbEndpointDescriptor HidGenericInterruptOutEndpointDescriptor;
TUsbInterfaceDescriptor VcomCicInterfaceDescriptor;
uint8_t VcomCicDescriptors[19];
TUsbEndpointDescriptor VcomCicNotificatonEndpointDescriptor;
TUsbInterfaceDescriptor VcomDataInterfaceDescriptor;
TUsbEndpointDescriptor VcomDataInEndpointDescriptor;
TUsbEndpointDescriptor VcomDataOutEndpointDescriptor;

} ConfigurationDescriptor = {
{
.bLength = sizeof(TUsbConfigurationDescriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_CONFIGURE,
.wTotalLength = sizeof(ConfigurationDescriptor),
.bNumInterfaces = USB_DEVICE_INTERFACE_COUNT,
.bConfigurationValue = USB_CONFIGURE_INDEX,
.iConfiguration = 0,
.bmAttributes = (USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_D7_MASK) |
(USB_DEVICE_CONFIG_SELF_POWER << USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_SELF_POWERED_SHIFT) |
(USB_DEVICE_CONFIG_REMOTE_WAKEUP << USB_DESCRIPTOR_CONFIGURE_ATTRIBUTE_REMOTE_WAKEUP_SHIFT),
.MaxPower = USB_DEVICE_MAX_POWER / 2
},
// Interface association descriptor for virtual COM
{
8,
USB_DESCRIPTOR_TYPE_INTERFACE_ASSOCIATION,
0x02,
0x02,
USB_CDC_VCOM_CIC_CLASS, 0x03,
0x00,
0x00,
},
// Scanner - custom class
{
.bLength = sizeof(TUsbInterfaceDescriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
.bInterfaceNumber = USB_SCANNER_INTERFACE_INDEX,
.bAlternateSetting = 0,
.bNumEndpoints = USB_SCANNER_ENDPOINT_COUNT,
.bInterfaceClass = USB_DEVICE_SCANNER_CLASS,
.bInterfaceSubClass = 0,
.bInterfaceProtocol = 0,
.iInterface = 0
},
{
.bLength = sizeof(TUsbEndpointDescriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = USB_SCANNER_INTERRUPT_IN_ENDPOINT | (USB_IN << 7U),
.bmAttributes = USB_ENDPOINT_INTERRUPT,
.wMaxPacketSize = USB_SCANNER_INTERRUPT_PACKET_SIZE,
.bInterval = USB_SCANNER_INTERRUPT_INTERVAL
},
{
.bLength = sizeof(TUsbEndpointDescriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = USB_SCANNER_INTERRUPT_OUT_ENDPOINT | (USB_OUT << 7U),
.bmAttributes = USB_ENDPOINT_INTERRUPT,
.wMaxPacketSize = USB_SCANNER_INTERRUPT_PACKET_SIZE,
.bInterval = USB_SCANNER_INTERRUPT_INTERVAL
},
{
.bLength = sizeof(TUsbEndpointDescriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = USB_SCANNER_BULK_IN_ENDPOINT | (USB_IN << 7U),
.bmAttributes = USB_ENDPOINT_BULK,
.wMaxPacketSize = USB_SCANNER_BULK_PACKET_SIZE,
.bInterval = 0x00
},
// Generic HID
{
.bLength = sizeof(TUsbInterfaceDescriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
.bInterfaceNumber = USB_HID_GENERIC_INTERFACE_INDEX,
.bAlternateSetting = 0,
.bNumEndpoints = USB_HID_GENERIC_ENDPOINT_COUNT,
.bInterfaceClass = USB_HID_GENERIC_CLASS,
.bInterfaceSubClass = USB_HID_GENERIC_SUBCLASS,
.bInterfaceProtocol = USB_HID_GENERIC_PROTOCOL,
.iInterface = 0
},
{
.bLength = sizeof(TUsbHidDescriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_HID,
.wHIDClassSpecComp = 0x0111,
.bCountry = 0,
.bNumDescriptors = 1,
.b1stDescType = USB_DESCRIPTOR_TYPE_HID_REPORT,
.w1stDescLength = sizeof(g_UsbDeviceHidGenericReportDescriptor)
},
{
.bLength = sizeof(TUsbEndpointDescriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = USB_HID_GENERIC_INTERRUPT_IN_ENDPOINT | (USB_IN << 7),
.bmAttributes = USB_ENDPOINT_INTERRUPT,
.wMaxPacketSize = HID_REPORT_SIZE,
.bInterval = 0x01
},
{
.bLength = sizeof(TUsbEndpointDescriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = USB_HID_GENERIC_INTERRUPT_OUT_ENDPOINT | (USB_OUT << 7),
.bmAttributes = USB_ENDPOINT_INTERRUPT,
.wMaxPacketSize = HID_REPORT_SIZE,
.bInterval = 0x01
},
// Virtual COM
{
.bLength = sizeof(TUsbInterfaceDescriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
.bInterfaceNumber = USB_CDC_VCOM_COMM_INTERFACE_INDEX,
.bAlternateSetting = 0,
.bNumEndpoints = USB_CDC_VCOM_ENDPOINT_CIC_COUNT,
.bInterfaceClass = USB_CDC_VCOM_CIC_CLASS,
.bInterfaceSubClass = USB_CDC_VCOM_CIC_SUBCLASS,
.bInterfaceProtocol = USB_CDC_VCOM_CIC_PROTOCOL,
.iInterface = 0
},
{
USB_DESCRIPTOR_LENGTH_CDC_HEADER_FUNC,
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE,
USB_CDC_HEADER_FUNC_DESC, 0x10,
0x01,

USB_DESCRIPTOR_LENGTH_CDC_CALL_MANAG,
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE,
USB_CDC_CALL_MANAGEMENT_FUNC_DESC,
0x01,
0x01,

USB_DESCRIPTOR_LENGTH_CDC_ABSTRACT,
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE,
USB_CDC_ABSTRACT_CONTROL_FUNC_DESC,
0x06,

USB_DESCRIPTOR_LENGTH_CDC_UNION_FUNC,
USB_DESCRIPTOR_TYPE_CDC_CS_INTERFACE,
USB_CDC_UNION_FUNC_DESC, 0x00,
0x01,
},
{
.bLength = sizeof(TUsbEndpointDescriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = USB_CDC_VCOM_INTERRUPT_IN_ENDPOINT | (USB_IN << 7U),
.bmAttributes = USB_ENDPOINT_INTERRUPT,
.wMaxPacketSize = FS_CDC_VCOM_INTERRUPT_IN_PACKET_SIZE,
.bInterval = FS_CDC_VCOM_INTERRUPT_IN_INTERVAL
},
{
.bLength = sizeof(TUsbInterfaceDescriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_INTERFACE,
.bInterfaceNumber = USB_CDC_VCOM_DATA_INTERFACE_INDEX,
.bAlternateSetting = 0,
.bNumEndpoints = USB_CDC_VCOM_ENDPOINT_DIC_COUNT,
.bInterfaceClass = USB_CDC_VCOM_DIC_CLASS,
.bInterfaceSubClass = USB_CDC_VCOM_DIC_SUBCLASS,
.bInterfaceProtocol = USB_CDC_VCOM_DIC_PROTOCOL,
.iInterface = 0
},
{
.bLength = sizeof(TUsbEndpointDescriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = USB_CDC_VCOM_BULK_IN_ENDPOINT | (USB_IN << 7U),
.bmAttributes = USB_ENDPOINT_BULK,
.wMaxPacketSize = FS_CDC_VCOM_BULK_IN_PACKET_SIZE,
.bInterval = 0
},
{
.bLength = sizeof(TUsbEndpointDescriptor),
.bDescriptorType = USB_DESCRIPTOR_TYPE_ENDPOINT,
.bEndpointAddress = USB_CDC_VCOM_BULK_OUT_ENDPOINT | (USB_OUT << 7U),
.bmAttributes = USB_ENDPOINT_BULK,
.wMaxPacketSize = FS_CDC_VCOM_BULK_OUT_PACKET_SIZE,
.bInterval = 0
}
};

 

This is its value:

0x09 0x02 0x89 0x00 0x04 0x01 0x00 0xc0 0xfa 0x08 0x0b 0x02 0x02 0x02 0x03 0x00 0x00 0x09 0x04 0x00 0x00 0x03 0xff 0x00 0x00 0x00 0x07 0x05 0x81 0x03 0x40 0x00 0x00 0x07 0x05 0x02 0x03 0x40 0x00 0x00 0x07 0x05 0x83 0x02 0x40 0x00 0x00 0x09 0x04 0x01 0x00 0x02 0x03 0x00 0x00 0x00 0x09 0x21 0x11 0x01 0x00 0x01 0x22 0x35 0x00 0x07 0x05 0x84 0x03 0x40 0x00 0x01 0x07 0x05 0x05 0x03 0x40 0x00 0x01 0x09 0x04 0x02 0x00 0x01 0x02 0x02 0x00 0x00 0x05 0x24 0x01 0x10 0x01 0x05 0x24 0x01 0x01 0x01 0x04 0x24 0x02 0x06 0x05 0x24 0x06 0x00 0x01 0x07 0x05 0x86 0x03 0x10 0x00 0x08 0x09 0x04 0x03 0x00 0x02 0x0a 0x00 0x00 0x00 0x07 0x05 0x87 0x02 0x40 0x00 0x00 0x07 0x05 0x08 0x02 0x40 0x00 0x00

 

On my PC this device won't enumerate. I can see code 10 and STATUS_DEVICE_DATA_ERROR error for it in Device Manager. Without virtual COM section in descriptor it runs and enumerate.

 

To create virtual COM I inspired in usb_device_composite_cdc_msc example from SDK - I usee usb_device_cdc_acm.c and the descriptor part is mostly copied from usb_device_descriptor .c .h files.

 

Can you please help what the issue is here?

Outcomes