Changing interface order in USB descriptor

BlakeB

Member
Hello,
I'm working with some folks on getting Windows MIDI APIs to correctly recognize/distinguish when two of our same devices are connected. Included in the initial feedback was this:
I’m not sure that order matters here (it often does with USB, though), but every MIDI device I have checked lists either audio streaming or MIDI streaming as its first interface (after any IAD)

We are using USB_MIDI16_SERIAL, with one tweak (we only support 12 virtual cables, so MIDI_NUM_CABLES is set to 12). My naive reading of the code in usb_desc.c suggested that I could change the order of the interfaces by simply moving the block of code that defines the MIDI interface, i.e. that begins like this:
#ifdef MIDI_INTERFACE
// Standard MS Interface Descriptor,
9, // bLength
4, // bDescriptorType
MIDI_INTERFACE, // bInterfaceNumber
0, // bAlternateSetting
2, // bNumEndpoints
0x01, // bInterfaceClass (0x01 = Audio)
0x03, // bInterfaceSubClass (0x03 = MIDI)
0x00, // bInterfaceProtocol (unused for MIDI)
0, // iInterface
// MIDI MS Interface Header, USB MIDI 6.1.2.1, page 21, Table 6-2


Above the two defined CDC interfaces, but clearly there are a couple more things to tweak. I found this in usb_desc.h:
#define NUM_INTERFACE 3
#define CDC_IAD_DESCRIPTOR 1
#define CDC_STATUS_INTERFACE 0
#define CDC_DATA_INTERFACE 1 // Serial

...
#define MIDI_INTERFACE 2 // MIDI
Which, again naively, appears to indicate the order, so I modified it thusly:
#define NUM_INTERFACE 3
#define CDC_IAD_DESCRIPTOR 1
#define CDC_STATUS_INTERFACE 1
#define CDC_DATA_INTERFACE 2 // Serial

...
#define MIDI_INTERFACE 0 // MIDI
I'm still not quite done, though, sadly. With just these changes, everyone gets very confused, and the device can't be enumerated on the bus at all - doesn't show up in Device Manager, etc.


Next on my list is to tweak this bit or arithmetic to reflect the new interface order (from usb_desc.c):
#define CDC_IAD_DESCRIPTOR_POS CONFIG_HEADER_DESCRIPTOR_SIZE
#ifdef CDC_IAD_DESCRIPTOR
#define CDC_IAD_DESCRIPTOR_SIZE 8
#else
#define CDC_IAD_DESCRIPTOR_SIZE 0
#endif
#define CDC_DATA_INTERFACE_DESC_POS CDC_IAD_DESCRIPTOR_POS+CDC_IAD_DESCRIPTOR_SIZE
#ifdef CDC_DATA_INTERFACE
#define CDC_DATA_INTERFACE_DESC_SIZE 9+5+5+4+5+7+9+7+7
#else
#define CDC_DATA_INTERFACE_DESC_SIZE 0
#endif
#define CDC2_DATA_INTERFACE_DESC_POS CDC_DATA_INTERFACE_DESC_POS+CDC_DATA_INTERFACE_DESC_SIZE
#ifdef CDC2_DATA_INTERFACE
#define CDC2_DATA_INTERFACE_DESC_SIZE 8 + 9+5+5+4+5+7+9+7+7
#else
#define CDC2_DATA_INTERFACE_DESC_SIZE 0
#endif
#define CDC3_DATA_INTERFACE_DESC_POS CDC2_DATA_INTERFACE_DESC_POS+CDC2_DATA_INTERFACE_DESC_SIZE
#ifdef CDC3_DATA_INTERFACE
#define CDC3_DATA_INTERFACE_DESC_SIZE 8 + 9+5+5+4+5+7+9+7+7
#else
#define CDC3_DATA_INTERFACE_DESC_SIZE 0
#endif
#define MIDI_INTERFACE_DESC_POS CDC3_DATA_INTERFACE_DESC_POS+CDC3_DATA_INTERFACE_DESC_SIZE
#ifdef MIDI_INTERFACE
#if !defined(MIDI_NUM_CABLES) || MIDI_NUM_CABLES < 1 || MIDI_NUM_CABLES > 16
#error "MIDI_NUM_CABLES must be defined between 1 to 16"
#endif
#define MIDI_INTERFACE_DESC_SIZE 9+7+((6+6+9+9)*MIDI_NUM_CABLES)+(9+4+MIDI_NUM_CABLES)*2
#else
#define MIDI_INTERFACE_DESC_SIZE 0
#endif

Has anyone else attempted this? Anything else you can think of that needs modified? Am I barking up the wrong tree, i.e. the order doesn't end up mattering here?

Thanks,
Blake
 
After double-checking, I found that either a) I've introduced a copy/paste error, or some other error, when moving the MIDI_INTERFACE block above CDC_DATA_INTERFACE in the config_descriptor declaration in usb_desc.c, or b) there's still something that needs to be modified that I'm missing, or c) ???. I'm still at the spot I described above when I try to modify the config_descriptor struct, i.e. the device no longer shows up on the bus. Any suggestions would be welcome.
 
All right, I believe I've found the right order for things now. The MIDI interface, if I want it to be first, needs to be before the IAD, because the purpose of the IAD (??) is to simply group the two following interfaces of function class CDC. The device enumerates with things in the order MIDI, IAD, CDC, CDC2, and shows up in that order in both USBView and TDD. Fun stuff!
 
Back
Top