This is my first question on this forum. Hope this question being useful to someone else.
I want my USB device being able to manage two different configs, but I haven't found any example on google with two different config, so that's why I am asking on this forum.
I have used a Chibios example with creates a USB device descriptor with a single config descriptor. After that I was able to add a second config descriptor (USBDescriptor type) in my source code (bConfigurationValue=1 and bConfigurationValue=2).
My issue is related with my usb_get_descriptor_cb callback (defined as second parameter of my USBConfig variable):
static const USBDescriptor *usb_get_descriptor_cb(USBDriver *usbp, uint8_t dtype, uint8_t dindex, uint16_t lang);
Parameter "dtype" is used in a switch case with USB_DESCRIPTOR_CONFIGURATION to return the config descriptor. But, how can I get the config identifier (bConfigurationValue) to know which configuration descriptor should be returned?
Thanks a lot in advance!
Issue developing a USB device with two config descriptors
Re: Issue developing a USB device with two config descriptors
the configuration index should be in dindex - exactly how it works for string descriptors.
Re: Issue developing a USB device with two config descriptors
So depending on dtype, the dindex meaning changes. That make sense. Thanks a lot for your answer!
However, I have tried re-implement my solution in a different, and hopefully easier way. But it's not working as expected. Hope someone with more experience on this can give me some advice. I'm sorry for this very long reply, but I think its necesary to undestand my question.
My USB-device board has three functional blocks available:
* HID sensors
* HID inputs
* CDC serial port
I want to separate all that functionality in two different configs:
config 1: HID sensors + HID inputs
config 2: HID sensors + CDC serial port
In my first solution I used two different config_descriptor arrays, each one defining a single configuration:
That solution requires returning a pointer to the proper configuration in the usb_get_descriptor_cb. config_descriptor_02 is still work in progress, but
hardcoding config_descriptor_01, all works as expected (I can read sensors and buttos from userspace).
In my second proposed solution I have supposed all previos stuff can be merged in a single array:
That solution always returns the same configuration descriptor in the usb_get_descriptor_cb.
Now my question. Taking into account the second proposed solution, this commands is not working as expected:
The tree of descriptors displayed is wrong. Both the first and second Configuration Descriptor displayed shows all the fields exactly the same:
But in config_descriptor array, they are different. Do you think this is a problem related with the second proposed solution? Or that second solution should work as expected and it's simply a bug in my source code?
However, I have tried re-implement my solution in a different, and hopefully easier way. But it's not working as expected. Hope someone with more experience on this can give me some advice. I'm sorry for this very long reply, but I think its necesary to undestand my question.
My USB-device board has three functional blocks available:
* HID sensors
* HID inputs
* CDC serial port
I want to separate all that functionality in two different configs:
config 1: HID sensors + HID inputs
config 2: HID sensors + CDC serial port
In my first solution I used two different config_descriptor arrays, each one defining a single configuration:
Code: Select all
uint8_t config_descriptor_01[] = {
SIZE,
USB_DESC_CONFIGURATION,
USB_DESC_INTERFACE,
USB_DESC_HID,
USB_DESC_ENDPOINT, // IN sensors
iUSB_DESC_ENDPOINT, // OUT sensors
USB_DESC_INTERFACE,
USB_DESC_HID,
USB_DESC_ENDPOINT, // IN buttons
};
uint8_t config_descriptor_02[] = {
SIZE,
USB_DESC_CONFIGURATION,
USB_DESC_INTERFACE,
USB_DESC_HID,
USB_DESC_ENDPOINT, // IN sensors
USB_DESC_ENDPOINT, // OUT sensors
USB_DESC_INTERFACE,
header functional,
call management functional,
ACM functional,
union functional,
USB_DESC_ENDPOINT, // IRQ
USB_DESC_INTERFACE,
USB_DESC_ENDPOINT, // IN data
USB_DESC_ENDPOINT, // OUT data
};
That solution requires returning a pointer to the proper configuration in the usb_get_descriptor_cb. config_descriptor_02 is still work in progress, but
hardcoding config_descriptor_01, all works as expected (I can read sensors and buttos from userspace).
In my second proposed solution I have supposed all previos stuff can be merged in a single array:
Code: Select all
uint8_t config_descriptor[] = {
SIZE,
USB_DESC_CONFIGURATION,
USB_DESC_INTERFACE,
USB_DESC_HID,
USB_DESC_ENDPOINT, // IN sensors
iUSB_DESC_ENDPOINT, // OUT sensors
USB_DESC_INTERFACE,
USB_DESC_HID,
USB_DESC_ENDPOINT, // IN buttons
USB_DESC_CONFIGURATION,
USB_DESC_INTERFACE,
USB_DESC_HID,
USB_DESC_ENDPOINT, // IN sensors
USB_DESC_ENDPOINT, // OUT sensors
USB_DESC_INTERFACE,
header functional,
call management functional,
ACM functional,
union functional,
USB_DESC_ENDPOINT, // IRQ
USB_DESC_INTERFACE,
USB_DESC_ENDPOINT, // IN data
USB_DESC_ENDPOINT, // OUT data
};
That solution always returns the same configuration descriptor in the usb_get_descriptor_cb.
Now my question. Taking into account the second proposed solution, this commands is not working as expected:
Code: Select all
# lsusb -v -d product:vendor
The tree of descriptors displayed is wrong. Both the first and second Configuration Descriptor displayed shows all the fields exactly the same:
Code: Select all
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 66
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
But in config_descriptor array, they are different. Do you think this is a problem related with the second proposed solution? Or that second solution should work as expected and it's simply a bug in my source code?
Re: Issue developing a USB device with two config descriptors
Continuing with this issue, I have another question related. On the usb_event_cb callback (first callback defined on the USBConfig variable), when the USB_EVENT_CONFIGURED event is handled, the endpoints specified in the configuration must be enabled. But I my particular case, I have two configurations, and each one has a different set of endpoints. I don't have "dindex" available in this callback. How can I know what are the endpoints to be enabled in this case?
Re: Issue developing a USB device with two config descriptors
I come back with my initial issue, providing all internal details for a better understanding.
My USB-device is composed of three different functional blocks:
The inputs and ttyACM pins are shared.
The purpose is developing a Chibios driver to separate all the functionality in two different USB configurations:
I have developed this device descriptor:
And these two configuration descriptors:
When I plug my device, this command displays a wrong tree of descriptors:
This is wrong because the second Configuration Descriptor shows the same values as the first Configuration Descriptor, but they are different as you can see in the source code (see bConfigurationValue and wTotalLength as an example).
What is wrong with that?
My USB-device is composed of three different functional blocks:
- * HID sensors
* HID inputs
* CDC ttyACM
The inputs and ttyACM pins are shared.
The purpose is developing a Chibios driver to separate all the functionality in two different USB configurations:
- * usb-config-1: HID sensors + HID inputs
* usb-config-2: HID sensors + CDC serial port
I have developed this device descriptor:
Code: Select all
static const uint8_t usb_device_descriptor_data[] = {
USB_DESC_DEVICE(0x0110, // bcdUSB
0x00, // bDeviceClass
0x00, // bDeviceSubClass
0x00, // bDeviceProtocol
0x40, // bMaxPacketSize
VENDOR_ID,
PRODUCT_ID,
DEVICE_VER,
1, // iManufacturer
2, // iProduct
3, // iSerialNumber
2) // bNumConfigurations
};
And these two configuration descriptors:
Code: Select all
static const uint8_t config_descriptor_data[] = {
// Configuration Descriptor
USB_DESC_CONFIGURATION(9+9+9+7+7+9+9+7, // wTotalLength
0x02, // bNumInterfaces
0x01, // bConfigurationValue
0x00, // iConfiguration
0x80, // bmAttributes
50), // bMaxPower (100mA)
// Interface Descriptor
USB_DESC_INTERFACE (0x00, // bInterfaceNumber
0x00, // bAlternateSetting
0x02, // bNumEndpoints
0x03, // bInterfaceClass
0x00, // bInterfaceSubClass
0x00, // bInterfaceProtocol
0), // iInterface
// HID Descriptor
USB_DESC_HID (0x110, // bcdHID
0x00, // bCountryCode
0x01, // bNumDescriptors
0x22, // bDescriptorType
sizeof(sensors_hid_report_descriptor_data)),
// Endpoint Descriptor
USB_DESC_ENDPOINT (SENSORS_EP|USB_RTYPE_DIR_HOST2DEV,
0x03, // bmAttributes
0x0040, // wMaxPacketSize
0x0A), // bInterval (10ms)
// Endpoint Descriptor (7 bytes)
USB_DESC_ENDPOINT (SENSORS_EP|USB_RTYPE_DIR_DEV2HOST,
0x03, // bmAttributes
0x0040, // wMaxPacketSize
0x0A), // bInterval (10ms)
// Interface Descriptor (9 bytes)
USB_DESC_INTERFACE (0x01, // bInterfaceNumber
0x00, // bAlternateSetting
0x01, // bNumEndpoints (1)
0x03, // bInterfaceClass (HID class)
0x00, // bInterfaceSubClass (None)
0x00, // bInterfaceProtocol (None)
0), // iInterface
// HID Descriptor (9 bytes) (buttons)
USB_DESC_HID (0x0110, // bcdHID (tipical value)
0x00, // bCountryCode
0x01, // bNumDescriptors
0x22, // bDescriptorType
sizeof(buttons_hid_report_descriptor_data)),
// Endpoint Descriptor (7 bytes)
USB_DESC_ENDPOINT (BUTTONS_EP|USB_RTYPE_DIR_DEV2HOST,
0x03, // bmAttributes (interrupt)
0x0008, // wMaxPacketSize
0x0A), // bInterval (10ms)
// Configuration Descriptor
USB_DESC_CONFIGURATION(9+9+9+7+7+9+5+5+4+5+7+9+7+7, // wTotalLength
0x03, // bNumInterfaces
0x02, // bConfigurationValue
0x00, // iConfiguration
0x80, // bmAttributes
50), // bMaxPower (100mA)
// Interface Descriptor
USB_DESC_INTERFACE (0x00, // bInterfaceNumber
0x00, // bAlternateSetting
0x02, // bNumEndpoints
0x03, // bInterfaceClass (HID class)
0x00, // bInterfaceSubClass (None)
0x00, // bInterfaceProtocol (None)
0), // iInterface
// HID Descriptor
USB_DESC_HID (0x110, // bcdHID
0x00, // bCountryCode
0x01, // bNumDescriptors
0x22, // bDescriptorType
sizeof(sensors_hid_report_descriptor_data)),
// Endpoint Descriptor
USB_DESC_ENDPOINT (SENSORS_EP|USB_RTYPE_DIR_HOST2DEV,
0x03, // bmAttributes (interrupt)
0x0040, // wMaxPacketSize
0x0A), // bInterval (10ms)
// Endpoint Descriptor
USB_DESC_ENDPOINT (SENSORS_EP|USB_RTYPE_DIR_DEV2HOST,
0x03, // bmAttributes (interrupt)
0x0040, // wMaxPacketSize
0x0A), // bInterval (10ms)
// Interface Descriptor
USB_DESC_INTERFACE (0x01, // bInterfaceNumber
0x00, // bAlternateSetting
0x01, // bNumEndpoints
CDC_COMMUNICATION_INTERFACE_CLASS,
CDC_ABSTRACT_CONTROL_MODEL,
0x01, // bInterfaceProtocol (AT cmds)
0), // iInterface
// Header Functional Descriptor
USB_DESC_BYTE (5), // bFunctionLength
USB_DESC_BYTE (CDC_CS_INTERFACE), // bDescriptorType
USB_DESC_BYTE (0x00), // bDescriptorSubtype
USB_DESC_BCD (0x0110), // bcdCDC
// ACM Functional Descriptor
USB_DESC_BYTE (4), // bFunctionLength
USB_DESC_BYTE (CDC_CS_INTERFACE), // bDescriptorType
USB_DESC_BYTE (0x02), // bDescriptorSubtype
USB_DESC_BYTE (0x02), // bmCapabilities (D1)
// Union Functional Descriptor
USB_DESC_BYTE (5), // bFunctionLength
USB_DESC_BYTE (CDC_CS_INTERFACE), // bDescriptorType
USB_DESC_BYTE (0x06), // bDescriptorSubtype
USB_DESC_BYTE (0x01), // bMasterInterface
USB_DESC_BYTE (0x02), // bSlaveInterface
// Call Management Functional Descriptor
USB_DESC_BYTE (5), // bFunctionLength
USB_DESC_BYTE (CDC_CS_INTERFACE), // bDescriptorType
USB_DESC_BYTE (0x01), // bDescriptorSubtype
USB_DESC_BYTE (0x03), // bmCapabilities
USB_DESC_BYTE (0x01), // bDataInterface
// Notification Endpoint Descriptor
USB_DESC_ENDPOINT (CDC_NOTIFICATION_EP|USB_RTYPE_DIR_DEV2HOST,
0x03, // bmAttributes
0x0040, // wMaxPacketSize
0xFF), // bInterval (10ms)
// Interface Descriptor
USB_DESC_INTERFACE (0x02, // bInterfaceNumber
0x00, // bAlternateSetting
0x02, // bNumEndpoints
CDC_DATA_INTERFACE_CLASS,
0x00, // bInterfaceSubClass
0x00, // bInterfaceProtocol
0), // iInterface
// Data OUT Endpoint Descriptor
USB_DESC_ENDPOINT (CDC_DATA_EP|USB_RTYPE_DIR_HOST2DEV,
0x02, // bmAttributes (Bulk)
0x0200, // wMaxPacketSize
0x00), // bInterval
// Data IN Endpoint Descriptor
USB_DESC_ENDPOINT (CDC_DATA_EP|USB_RTYPE_DIR_DEV2HOST,
0x02, // bmAttributes (Bulk)
0x0200, // wMaxPacketSize
0x01) // bInterval
};
When I plug my device, this command displays a wrong tree of descriptors:
Code: Select all
# lsusb -v -d product:vendor
Bus 001 Device 047: ID 0179:0002
Couldn't open device, some information will be missing
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.10
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 64
idVendor 0x0179
idProduct 0x0002
bcdDevice 2.00
iManufacturer 1
iProduct 2
iSerial 3
bNumConfigurations 2
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 66
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 568
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 10
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 10
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 23
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 66
bNumInterfaces 2
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
(Bus Powered)
MaxPower 100mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 2
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 568
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x01 EP 1 OUT
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 10
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 10
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.10
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 23
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x82 EP 2 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 10
This is wrong because the second Configuration Descriptor shows the same values as the first Configuration Descriptor, but they are different as you can see in the source code (see bConfigurationValue and wTotalLength as an example).
What is wrong with that?
Who is online
Users browsing this forum: No registered users and 6 guests