USB isolator solution for Teensy 4.0 (vs T3.6)

Status
Not open for further replies.

rvh

Well-known member
I am migrating an audio project from T3.6 to T4, and have run into a problem in relation to USB isolators. I don't need high rates as I'm only transferring midi data, and have been using an inexpensive ADUM4136 based isolator very successfully with the T3.6. However the T4 must be sending the USB midi data out much quicker because the mid data received from the T4 is severely corrupted when I insert the isolator in the USB path.

Assuming that's the problem, is there a way to slow down the Teensy USB transfer rate (without affecting anything else)? This would be my preferred solution because that way I can keep using the same isolators. Alternatively, is there a specific but inexpensive USB isolator that works well with the T4? Moving to a high cost isolator is not an option, nor is limiting the USB speed on the computer side because the solution needs to work for non-technical users.

I saw some older threads related to this but am hoping that now the T4 has been around for longer there would be an effective solution.

p.s. another reason I think it's likely that it's the fast T4 USB rate that's the problem is that when the computer sends midi data to the Teensy, the isolator works fine.
 
I ran into a similar issue with USB to RJ45 extenders, here's what I found:
T3.x are USB Full Speed devices (12Mbps), whereas T4.x are High Speed by default (480Mbps) - those rates are bitstream rates, i.e. even if the usage data rate is low, the line encoding will always result in the specified bit rate on the physical interface

There's probably a way to force the T4.x USB PHY to fall back to Full Speed. I no longer needed the long cable so I kind of gave up on the solution, unfortunately

Marc
 
You could try uncommenting this line in usb.c

Code:
        //USB1_PORTSC1 |= USB_PORTSC1_PFSC; // force 12 Mbit/sec

But loading new code will still be done at 480 Mbit/sec speed, so you'll probably need to change to a direct connection when you upload your program.
 
This is odd in the sense that I've verified that with USB + Serial, Teensy 4.0 and 4.1 work fine over an eBay el-cheapo ADuM3160-based full speed USB isolator. In fact, that is my typical workflow when I don't need high speed, just to be sure my USB ports won't fry due to my ineptitude. However, I haven't done any MIDI stuff with 4.0 or 4.1 at all. To me, this sounds like very MIDI-specific; is that possible?

I'm waiting for the chipageddon to pass, so that TI ISOUSB211 becomes available. Mouser has the devkits available (for about 65€). The chip provides low/full/high-speed isolation, with a board complexity similar to ADuM3160, except with more bypass capacitors, added 1.8V LDO, and TVS diodes. With these, a low/full/high-speed USB 2 isolator can be implemented for about $20.

If anyone has any specific tests with Teensy 4.0 or 4.1 and an ADuM3160-based USB isolator (full speed, 12 Mbit/s) in mind, feel free to drop me a private message or email (both are in my profile here); I'd be happy to re-check.
 
You could try uncommenting this line in usb.c

Code:
        //USB1_PORTSC1 |= USB_PORTSC1_PFSC; // force 12 Mbit/sec

But loading new code will still be done at 480 Mbit/sec speed, so you'll probably need to change to a direct connection when you upload your program.

Thanks Paul, unfortunately when I uncommented that line in the (core) usb.c file, the MIDI data sent from the Teensy to the computer were corrupted both with and without the isolator. Note also that the problem is only with receiving data FROM the T4. It loads programs and responds to midi commands from the computer T4 just fine with the isolator inline.

Below is a very simple sketch that illustrates the problem for anyone who has a cheap isolator and wants to try this. I'm using MIDI OX to receive the midi note on events from this sketch, and am sending a count value to the Serial port at the same time. The Serial print never shows any missing counts, with or without the isolator. But the midi data are corrupted when using the isolator. On one or two tries I saw a few note-on events at first before the data were corrupted, but more typically I get just corrupted data with no note on events.

Code:
void setup()
{
}
int n=0;
void loop()
{
  usbMIDI.sendNoteOn(64, 127, 10);  
  Serial.println(n++);
  delay(30);
  usbMIDI.sendNoteOff(64, 0, 10);  
  delay(300);  
}

p.s. The isolator I'm using is ADUM4160 based (not 4136 as I first described)
 
This is odd in the sense that I've verified that with USB + Serial, Teensy 4.0 and 4.1 work fine over an eBay el-cheapo ADuM3160-based full speed USB isolator. In fact, that is my typical workflow when I don't need high speed, just to be sure my USB ports won't fry due to my ineptitude. However, I haven't done any MIDI stuff with 4.0 or 4.1 at all. To me, this sounds like very MIDI-specific; is that possible?

I'm waiting for the chipageddon to pass, so that TI ISOUSB211 becomes available. Mouser has the devkits available (for about 65€). The chip provides low/full/high-speed isolation, with a board complexity similar to ADuM3160, except with more bypass capacitors, added 1.8V LDO, and TVS diodes. With these, a low/full/high-speed USB 2 isolator can be implemented for about $20.

If anyone has any specific tests with Teensy 4.0 or 4.1 and an ADuM3160-based USB isolator (full speed, 12 Mbit/s) in mind, feel free to drop me a private message or email (both are in my profile here); I'd be happy to re-check.

Thanks for the reply. Can you try my simple sketch with your isolator and a midi monitoring software (ideally MIDI OX if you're on windows)? Given the T4 appears to be sending at 480Mbps, the ADUM3160 should not be able to handle that as it's only rated at 12Mpbps (as is the 4160). The newer ADUM4166 is rated at 480, but even the 'cheap' isolators I've seen based in that chip are 4-5x more expensive than the older 12Mpbs ones.
 
Last edited:
I'm on Linux, but I used MIDISnoop, which shows the note ons and offs for E4 (note 64) on channel 10 at velocity 127. With Teensy 4.1 connected directly or via a standard hub, everything works fine.

When I insert the ADuM3160-based USB full-speed isolator between the machine and Teensy 4.1, no MIDI messages get through!
Interestingly, both firmware upload and USB Serial (including Serial Monitor in Arduino IDE) work absolutely fine at the exact same time, with no errors or oddities.

(Note that both ADuM3160 and ADuM4160 are low-speed and full-speed only; ADuM4166 indeed also supports high-speed (480 Mbit/s) like TI USBISO211. The cheap ADuM3160/4160 isolators implement Analog's reference implementation, including a dip switch to select between low and full speed –– I always use full speed ––, and the only difference between them tends to be the selection of the isolated DC-DC converter to provide power to Teensy or whatever USB device it is used with. Some are inefficient, and may not provide enough power, so one may then need to use a powered USB hub on the downstream side.)

So, this leads me to believe that there is something specific to the MIDI descriptors in Teensy that makes it unable to correctly downgrade to full speed operation, and only works at high speed.

I did take a look at the USB Device Class Definition for for MIDI Devices 2.0 – USB MIDI v2.0, and the examples section does mention a device being "full-speed only", indicating that USB MIDI devices can be full or high speed, but I'm definitely not on Paul's level at USB implementation details! ... it is only my *best guess* that the Teensy MIDI implementation is somehow "stuck" in high-speed, and cannot switch down to full speed like e.g. its Serial implementation does.

The key point in my findings is that when the full speed isolator is used, in MIDI+Serial configuration, the serial connection works absolutely fine, but none of the Teensy-sent MIDI messages are seen at the computer side of the isolator. Without the isolator, both work absolutely fine.
 
You could try uncommenting this line in usb.c
Code:
        //USB1_PORTSC1 |= USB_PORTSC1_PFSC; // force 12 Mbit/sec
With this change, in the MIDI+Serial configuration, I get no MIDI messages at all on the computer, with or without the full-speed USB isolator. Programming and USB Serial (including Serial Monitor in Arduino IDE) works fine at the same time, though.

While I may easily be wrong, this does indicate to me that Teensy USB MIDI support works only at high speed, and not at full speed, regardless of how that gets negotiated or forced.

Edited: I double-checked, just to be sure. Using (uncommenting) that line in usb.c to force Teensy to 12 Mbit/sec has the exact same effect as using the full-speed isolator: MIDI messages sent by Teensy are not received, while Serial (and reprogramming Teensy) works fine at the same exact time. With it commented out, as shown above, the MIDI messages are received fine only when there is no full-speed isolator in between.
 
Last edited:
With this change, in the MIDI+Serial configuration, I get no MIDI messages at all on the computer, with or without the full-speed USB isolator. Programming and USB Serial (including Serial Monitor in Arduino IDE) works fine at the same time, though.

While I may easily be wrong, this does indicate to me that Teensy USB MIDI support works only at high speed, and not at full speed, regardless of how that gets negotiated or forced.

Edited: I double-checked, just to be sure. Using (uncommenting) that line in usb.c to force Teensy to 12 Mbit/sec has the exact same effect as using the full-speed isolator: MIDI messages sent by Teensy are not received, while Serial (and reprogramming Teensy) works fine at the same exact time. With it commented out, as shown above, the MIDI messages are received fine only when there is no full-speed isolator in between.

Thanks for running the tests. Your findings are exactly the same as mine.

Paul, is there any chance you could look into this?
 
Ah, but perhaps there is a software bug impacting USB MIDI when running at 12 Mbit speed. I've added it to my list of issues to investigate.
 
Hi

noob question about the cheap usb isolators:

As I understand it they also give power from the host to the teensy.

Is this usable when a teensy has a separate power supply or a common ground with another power supply when using "power" mosfet's?

I can for example use a power usb cable to the teensy connected (with voltage step down) with the same 12V of 24V power supply which the mosfet's are switching. --> common ground

Sometimes I would like to connect a computer (laptop). I would like to shut down 12/24V power, disconnect the usb power cord to the teensy, connect the teensy usb via a cheap usb isolator to a laptop and power up the 12/24V circuit. Would this work?
 
... connect the teensy usb via a cheap usb isolator to a laptop and power up the 12/24V circuit. Would this work?

That's really a question about the cheap USB isolator product, which PJRC does not make or sell.

On this Amazon product page the product description says "The product onboard power supply Sunrise Sun B0505S power 1W, when your USB device operating current more than 180mA, you can use USB double-headed line plus power supply".

I don't quite understand what they mean by "use USB double-headed line plus power supply" (actually, I have no idea at all what that is supposed to mean). But the mention of 180mA maximum current seems pretty clear. Since Teensy 4.0 uses about 100-110mA when running at 600 MHz, seems like there may be some chance of it working if the additional circuitry consumes less than 70mA.

The seller did answer 1 question on the Amazon page. Maybe try asking there?
 
That's really a question about the cheap USB isolator product, which PJRC does not make or sell.
...

Thanks, but I clearly misformulated my question, which is generic in nature. (And from a noob in this sort of stuff)

Normal use 1 12V or 24V power supply for the Teensy (with step down) and the loads on the other side of mosfets --> common ground
When I connect a computer with a cheap USB isolater I seem to get 2 power supply's : one from the isolator for the Teensy and another one from the 12 or 24V power supply for the load.

My naïve understanding is that there could be 2 grounds.

To make matters more complicated : Some of those isolaters have the possibility to add a 5V power supply on the device (aka Teensy) side. I could use that, I suppose they either disable the supply from the computer or connect grounds.
 
Yup, it was a bug in the USB MIDI code affecting transmit when running at 12 Mbit/sec speed.

I've committed a fix on github.

https://github.com/PaulStoffregen/cores/commit/70ba01accd728abe75ebfc8dcd8b3d3a8f3e3f25

Hi Paul,

I came back to check this issue today with your new usb_midi.c file copied into the T4 cores folder, and using the simple test code I posted previously:

Code:
void setup()
{
}
int n=0;
void loop()
{
  usbMIDI.sendNoteOn(64, 127, 10);  
  Serial.println(n++);
  delay(30);
  usbMIDI.sendNoteOff(64, 0, 10);  
  delay(300);  
}

But instead of getting steady midi notes (in Midi Ox) I get nothing for long periods (many seconds), and then a short burst of lots of midi data, as if the Teensy is waiting to fill a buffer rather than sending the note on events when issued. I can't get it to work smoothly either with or without isolator, and also with or without uncommenting the force 12Mbit line you suggested previosly. (incidentally is that the preferred way to make T4 use 12Mhz?)

Sysex dumps do work though, which is what I tested previously when I said it seemed to be working. Maybe that's due to added flush commands as discussed in another thread related to T3.6/4 sysex errors?

I've tried this code on two different T4.0, and one T4.1 with no changes in behavior. If the code sends smooth note-on data for you, do you have any idea what could cause what I'm seeing?

Also, running the same code on T3.6 works just fine.

Thanks,
Richard
 
I discovered that my problem was due to the need to comment out the flush command in usb.c to get sysex to behave correctly., as discussed in this thread: https://forum.pjrc.com/threads/70288-usbMIDI-transmission-error?highlight=sysex

However, this then seems to require a manual flush added to your code for any midi event out (not just sysex messages). So the code example I posted needs to be changed to:
Code:
void setup()
{
}
int n=0;
void loop()
{
  usbMIDI.sendNoteOn(64, 127, 10);  
  usb_midi_flush_output();                  
  Serial.println(n++);
  delay(30);
  usbMIDI.sendNoteOff(64, 0, 10);  
  usb_midi_flush_output();                  
  delay(300);  
}
 
Status
Not open for further replies.
Back
Top