USBhost_t36 device compatibility problem

Zenbob

Well-known member
We have a USB MIDI device called OXI One that is failing on the USB host. We used a Teensy 3.6 with a powered USB hub, as the device needs 500mA and is USB powered. To eliminate our code, we used the InputFucntions example to test it and captured some debug output. We also tested with a different MIDI controller which works. We hacked midi.cpp and got it working, but its probably a dangerous hack, see below.

Code:
USB Host InputFunctions example
sizeof Device = 36
sizeof Pipe = 96
sizeof Transfer = 64
power up USBHS PHY
 reset waited 4
USBHS_ASYNCLISTADDR = 0
USBHS_PERIODICLISTBASE = 1FFF3000
periodictable = 1FFF3000
port change: 10001803
    connect
  begin reset
port change: 18001205
  port enabled
  end recovery
new_Device: 480 Mbit/sec
new_Pipe
enumeration:
enumeration:
enumeration:
Device Descriptor:
  12 01 00 02 09 00 02 40 E2 04 14 04 00 01 00 01 00 01 
    VendorID = 04E2, ProductID = 0414, Version = 0100
    Class/Subclass/Protocol = 9(Hub) / 0 / 2(Multi-TT)
    Number of Configurations = 1
enumeration:
enumeration:
Product: USB 2.0 Hub [MTT]
enumeration:
Config data length = 41
enumeration:
Configuration Descriptor:
  09 02 29 00 01 01 00 E0 32 
    NumInterfaces = 1
    ConfigurationValue = 1
  09 04 00 00 01 09 00 01 00 
    Interface = 0
    Number of endpoints = 1
    Class/Subclass/Protocol = 9(Hub) / 0 / 1(Single-TT)
  07 05 81 03 01 00 0C 
    Endpoint = 1 IN
    Type = Interrupt
    Max Size = 1
    Polling Interval = 12
  09 04 00 01 01 09 00 02 00 
    Interface = 0
    Number of endpoints = 1
    Class/Subclass/Protocol = 9(Hub) / 0 / 2(Multi-TT)
  07 05 81 03 01 00 0C 
    Endpoint = 1 IN
    Type = Interrupt
    Max Size = 1
    Polling Interval = 12
enumeration:
USBHub memory usage = 960
USBHub claim_device this=1FFF2700
found possible interface, altsetting=0
found possible interface, altsetting=1
number of interfaces found = 2
best interface is 0 using altsetting 1
USBHub control callback
09 29 04 89 00 32 64 00 FF 00 00 00 00 00 00 00 
Hub ports = 4
USBHub control callback
unhandled setup, message = 10B01
USBHub control callback
USBHub control callback
USBHub control callback
USBHub control callback
power turned on to all ports
device addr = 1
new_Pipe
allocate_interrupt_pipe_bandwidth
  ep interval = 12
  interval = 256
 best_bandwidth = 2, at offset = 0
pipe cap1 = F0012101




OXI...
HUB Callback (member)
status = 10
getstatus, port = 4
USBHub control callback
01 01 01 00 
New Port Status
  status=10101  port=4
  state=0
  Device is present: 
  Has Power
USBHub control callback
Port Status Cleared, port=4
timer event (20000 us): Debounce Timer, this = 1FFF2700, timer = 1FFF2A18
ports in use bitmask = 10
getstatus, port = 4
USBHub control callback
01 01 00 00 
New Port Status
  status=101  port=4
  state=2
  Device is present: 
  Has Power
timer event (19999 us): Debounce Timer, this = 1FFF2700, timer = 1FFF2A18
ports in use bitmask = 10
getstatus, port = 4
USBHub control callback
01 01 00 00 
New Port Status
  status=101  port=4
  state=3
  Device is present: 
  Has Power
timer event (19999 us): Debounce Timer, this = 1FFF2700, timer = 1FFF2A18
ports in use bitmask = 10
getstatus, port = 4
USBHub control callback
01 01 00 00 
New Port Status
  status=101  port=4
  state=4
  Device is present: 
  Has Power
timer event (19999 us): Debounce Timer, this = 1FFF2700, timer = 1FFF2A18
ports in use bitmask = 10
getstatus, port = 4
USBHub control callback
01 01 00 00 
New Port Status
  status=101  port=4
  state=5
  Device is present: 
  Has Power
timer event (19999 us): Debounce Timer, this = 1FFF2700, timer = 1FFF2A18
ports in use bitmask = 10
getstatus, port = 4
USBHub control callback
01 01 00 00 
New Port Status
  status=101  port=4
  state=6
  Device is present: 
  Has Power
sending reset
send_setreset
USBHub control callback
unhandled setup, message = 40323
timer event (19999 us): Debounce Timer, this = 1FFF2700, timer = 1FFF2A18
ports in use bitmask = 0
HUB Callback (member)
status = 10
getstatus, port = 4
USBHub control callback
03 01 10 00 
New Port Status
  status=100103  port=4
  state=7
  Device is present: 
  Enabled, speed = 12 Mbit/sec
  Has Power
USBHub control callback
unhandled setup, message = 140123
timer event (25000 us): Hello, I'm resettimer, this = 1FFF2700, timer = 1FFF2A34
port_doing_reset = 4
PORT_RECOVERY
new_Device: 12 Mbit/sec
new_Pipe
enumeration:
enumeration:
enumeration:
Device Descriptor:
  12 01 00 02 00 00 00 40 E9 28 11 11 00 02 01 02 03 01 
    VendorID = 28E9, ProductID = 1111, Version = 0200
    Class/Subclass/Protocol = 0 / 0 / 0
    Number of Configurations = 1
enumeration:
enumeration:
Manufacturer: OXI Instruments
enumeration:
Product: OXI ONE
enumeration:
Serial Number: 00000738000036350000384600006144
enumeration:
Config data length = 115
enumeration:
Configuration Descriptor:
  09 02 73 00 01 01 00 80 FA 
    NumInterfaces = 1
    ConfigurationValue = 1
  09 04 00 00 02 01 03 00 05 
    Interface = 0
    Number of endpoints = 2
    Class/Subclass/Protocol = 1 / 3 / 0
  07 24 00 00 01 61 00 
  06 24 02 01 01 06 
  06 24 02 02 02 07 
  09 24 03 01 03 01 02 01 08 
  09 24 03 02 04 01 01 01 09 
  06 24 02 01 05 00 
  06 24 02 02 06 00 
  09 24 03 01 07 01 06 01 00 
  09 24 03 02 08 01 05 01 00 
  09 05 01 02 40 00 00 00 00 
    Endpoint = 1 OUT
    Type = Bulk
    Max Size = 64
    Polling Interval = 0
  06 25 01 02 01 05 
  09 05 81 02 40 00 00 00 00 
    Endpoint = 1 IN
    Type = Bulk
    Max Size = 64
    Polling Interval = 0
  06 25 01 02 03 07 
enumeration:
USBHub memory usage = 960
USBHub claim_device this=1FFF2AC0
Descriptor 4 = INTERFACE
MIDIDevice claim this=1FFF2020
len = 106
  Interface is MIDI
type: 36, len: 7
    Unknown MIDI CS_INTERFACE descriptor!
Descriptor 36 =  ???
Descriptor 36 =  ???
Descriptor 36 =  ???
Descriptor 36 =  ???
Descriptor 36 =  ???
Descriptor 36 =  ???
Descriptor 36 =  ???
Descriptor 36 =  ???
Descriptor 36 =  ???
Descriptor 5 = ENDPOINT
Descriptor 37 =  ???
Descriptor 5 = ENDPOINT
Descriptor 37 =  ???

Notice the iJack descriptors are conspicuously missing, which we see with the working controller. The working controller has iJack: 0x00.

Looking at USBTreeView output under Windows, I can see a couple of potential issues that Windows is ok with, but the Teensy host code might not tolerate. Perhaps being more forgiving of this misbehavior would enhance the host code? We suspect it is the iJack string descriptor error.

USBTreeView
OXI MIDI In Device Descriptor example.png

We were able to hack midi.cpp, forcing "ismidi" to true and got OXI MIDI to work, but this would probably has some undesirable consequences.
Code:
println("    Unknown MIDI CS_INTERFACE descriptor!");
//return false; // unknown
ismidi = true;

Hopefully someone can help us create a workable solution, with the goal of having the host enumeration code being a little more tolerant to bad actors such as this.

Thanks!
 
There's also an "unknow descriptor" on the USB Device View screen shot above, 0x24. Apparently its typically used on cell phones for mic and speaker select.
 
There's also an "unknow descriptor" on the USB Device View screen shot above, 0x24. Apparently its typically used on cell phones for mic and speaker select.
The root cause of the failure was found to be the "unknown descriptor" above. The descriptor is recognized as 0x24 = Audio CS_INTERFACE but the subtype is 0x00. Valid types are 1, 2, 3 or 4, and a couple of special cases for Yamaha and Roland. We added a case to the subtype parser in midi.cpp to verify it was bailing on the missing subtype. Hopefully the vendor of the device can fix it, but we're also going to change the parser to ignore bad data since it works fine we do (fingers crossed).

Here’s the code we changed in midi.cpp for the bad case.

Code:
if (type == 0x24) {  // 0x24 = Audio CS_INTERFACE, audio 1.0, page 99
			uint32_t subtype = p[2];
			//println("subtype: ", subtype);
			if (subtype == 0) {
				// Interface Header, midi 1.0, page 21
				println("    MIDI Header (ignored)");
				ismidi = true;
				println("    !!!!!!   MIDI CS_INTERFACE Subtype = 0    !!!!!!!");
 
Back
Top