felis / USB_Host_Shield_2.0

Revision 2.0 of USB Host Library for Arduino.
https://chome.nerpa.tech
1.8k stars 779 forks source link

Clarification requested (how to select one of multiple devices on a hub) #535

Closed billmoser closed 4 years ago

billmoser commented 4 years ago

I've been working from the USBH_MIDI/bidirectional_converter to build an interface for my USB device, a Source Audio guitar effects pedal. Thanks to this library, I've been able to successfully communicate with the device! In the future, I'd like to work with multiple Source Audio Pedals, all of which are slightly different. In the desktop world, I've done this with pyusb by filtering first on the device, then on the interface type, but I can't see an analog of the device filtering operation here. Looking at usbh_midi.cpp, lines 135-185 (in USBH_MIDI::Init) it appears that what is happening is that whatever device is next in the pool is selected. Then, in parseConfigDescr, MIdi-specific filtering is done to select the correct interface, but that assumes that the device selected is a midi device, does it not? So, what happens when multiple devices, some MIDI, and some not, are attached to the hub? is there a filtering mechanism I'm missing?

xxxajk commented 4 years ago

You would need one instance per midi device, and combine the data yourself. I personally wold use something better than AVR for the task too, because I don't think AVR will be able to keep up with the traffic on USB beyond a certain number of devices. USB is pretty heavy with RAM and CPU usage beyond one device, and AVR will struggle, unfortunately.

That said, consider moving to MIPS or ARM MCU with lots of RAM, helps even if you stay with UHS2. Furthermore, if you want an easier to use MIDI, also move to UHS3, which fits better with ARM and MIPS based MCU. UHS30 takes advantage of how ARM and MIPS can prioritize interrupts so that you don't miss any messages. UHS3 also saves the information about the device, so in your case, you would be able to do extra filtering based upon capabilities. If you have to extend MIDI to store anything that is not stored already, UHS3 allows you to use any driver class as a base class. It also provides a few handy callbacks if you don't have to go that far.

billmoser commented 4 years ago

Sorry, I was not very clear on what I'm asking. The question isn't about MIDI (my devices use USB for configuration, they aren't MIDI controllers). My question is this: suppose I had two different devices attached to my usb hub, say an xbox and a Midi controller, and I have these lines of code near the top of my .ino file: USB Usb; USBH_MIDI Midi(&Usb); XBOXONE Xbox(&Usb); How does the code sort out which device on the hub gets associated with the USBH_MIDI/XBOXONE objects? Looking at the code, I just don't see how it this can work, other than randomly, depending on how the devices are enumerated on the bus.

xxxajk commented 4 years ago

UHS2 treats the device as a whole, meaning composite multi-function devices can't fully be used, but single function devices will. UHS2 resets the device and then scans the device and interface descriptor for each driver, and the first matching interface or device descriptor wins, taking over the entire device. It resets the device over and over again, until a match, or fail.

For example, a mouse and joystick on a single device will fail to enumerate both functions on UHS2. This is part of the reason why I wrote UHS3 in the first place, not even including the other bad behaviours that sometimes cause devices to lock up.

UHS3 does a single reset and checks each interface instead, and assigns a driver to a matching interface. This allows composite devices work, either fully, or selectively by supporting interface drivers. it also makes it easier to understand what is going on.

billmoser commented 4 years ago

My devices are separate physical boxes, not a composite. I'm getting a usb hub tomorrow, I guess I'll put both devices on the hub and see what happens :)