T3.6 crash when using Serial Port #6 for MIDI - after Teensy Damaged

SteveBar

Well-known member
Hi ALL,
I searched for this potential issue and did not have any luck finding it... if there is info on this please LMK. :)

We isolated this issue using example 'Basic I/O' as a starting point (code below). There are four 5-pin MIDI connectors attached to the T3.6. UART1 Pins 0&1 and UART6 Pins 47&48 (with all the resistors, optos, etc..).

Theory of Operation:
Receive MIDI msgs into midiA port RX and send MIDI msgs to midiF port TX.

Tests:
1) Run code as is and as soon as a MIDI msg is sent the T3.6 hangs. You can hear the USB drop tune from Windows.
2) Comment out the midiF.send, un-comment midiA.send, and it works.
3) Change 'Serial6' to 'Serial(2-5)' and move HW RX and TX port wires, all the other ports work.

MIDI msgs attempted: NoteOn, NoteOff, CC

Thanks,
Steve
Conductive Labs

Code:
#include <MIDI.h>

 // Serial hardware UART 1&6
    MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, midiA); 
    MIDI_CREATE_INSTANCE(HardwareSerial, Serial6, midiF);  //  Change 'Serial6' to 'Serial(2-5)' and move HW RX and TX port wires


void setup()
{

    Serial.begin(115200);
    Serial.println("Starting up MIDI Serial in1/out6 test");
    
    midiA.begin(MIDI_CHANNEL_OMNI); 
    midiF.begin(MIDI_CHANNEL_OMNI);

    midiA.turnThruOff();    
    midiF.turnThruOff();
}

void loop()
{
    if (midiA.read())  // If we have received a message
    {

        midi::MidiType msgType = midiA.getType();
        byte channel = midiA.getChannel();
        byte data1 = midiA.getData1();
        byte data2 = midiA.getData2();
        
        //midiA.send(msgType, data1, data2, channel);     // <-- works
        midiF.send(msgType, data1, data2, channel);   // <-- does not work, locks up Teensy
        
    }
}
 
Can someone try this code on their T3.6 to see if it locks up? No soldering required, because the no MIDI data ever comes out the port.
Thanks
Steve
 
I'm traveling without access to my workbench until Monday.

When I do return, is there any chance you could give me a test program which only transmits on the problematic port, without waiting for input from another port? That way, I can just run it on a Teensy 3.6 and connect my oscilloscope to the transmitting pin, without needing to find MIDI gear that will send data to a different port than the one supposedly have the issue.

I ask this only because my workbench has an oscilloscope that's always ready to use. But if I have to make serial MIDI, that's not normally on my workbench. I would need to set up another Teensy or go get a MIDI keyboard and wire stuff up. If you can give me a test program which simply transmits without needing input, I can test that much easier and quicker.
 
Actually this may not surprise me.

On Teensy 3.6 the hardware for Serial6 has a complete different sub-system associated with it.

That is Serial6 used LPUART0 (Chapter 62 of the PDF manual), whereas Serial1-5 use UARTS (chapter 59).

But wonder what is crashing on it.... I don't know anything about MIDI, but maybe as Paul mentioned if you have a simple enough example that crashes without external inputs, would be possible to debug...
 
Note: I tried some simple test of it, like:
Code:
#include <MIDI.h>

// Serial hardware UART 1&6
MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, midiA);
MIDI_CREATE_INSTANCE(HardwareSerial, Serial6, midiF);  //  Change 'Serial6' to 'Serial(2-5)' and move HW RX and TX port wires


void setup()
{
  while (!Serial && millis() < 5000) ;
  Serial.begin(115200);
  Serial.println("Starting up MIDI Serial in1/out6 test");

  midiA.begin(MIDI_CHANNEL_OMNI);
  midiF.begin(MIDI_CHANNEL_OMNI);
  Serial.println("After Midi begins");
  midiA.turnThruOff();
  midiF.turnThruOff();
  Serial.println("After turn through off");
}

uint16_t loop_count = 0;
void loop()
{
  delay(500);
  Serial.printf("Loop: Before first Send %d", ++loop_count);  Serial.flush();
  midiF.send(midi::NoteOn, 47, 42, 12);
  midiF.send(midi::NoteOn, 42, 47, 12);
  Serial.println("Loop: after second Send"); Serial.flush();

  if (midiA.read())  // If we have received a message
  {

    midi::MidiType msgType = midiA.getType();
    byte channel = midiA.getChannel();
    byte data1 = midiA.getData1();
    byte data2 = midiA.getData2();

    //midiA.send(msgType, data1, data2, channel);     // <-- works
    midiF.send(msgType, data1, data2, channel);   // <-- does not work, locks up Teensy

  }
}
But so far it is running fine, no hangs

Those two messages come out of one of the examples... Don't know what they do...

Maybe try something like, your first program, but add in maybe something like:
Code:
  if (midiA.read())  // If we have received a message
  {

    midi::MidiType msgType = midiA.getType();
    byte channel = midiA.getChannel();
    byte data1 = midiA.getData1();
    byte data2 = midiA.getData2();

    Serial.printf("t:%d c:%x data1: %x data2:%x\n", millis(), channel, data1, data2); Serial.flush();
 
   //midiA.send(msgType, data1, data2, channel);     // <-- works
    midiF.send(msgType, data1, data2, channel);   // <-- does not work, locks up Teensy

  }
}

And see if you get any set of messages printed out... Then maybe we can try simple program that just outputs those commands, with timing near what you recorded.
 
Thanks guys for looking into this. Really super appreciate it. When I get back to work Monday morning I will try the samples above.

KurtE, Maybe some timing delays would help??? What exactly do you think your coach is doing differently that made it work?

Paul, I will also try to write the smallest program I can to test this and come up with a fail result. I wonder if it’s the midi code or the serial port code. Maybe just doing serial writes would cause the same problem.

Thanks again,
Steve
 
Hi Paul,
Here's an example. Middle C on/off...

Code:
#include <MIDI.h>

    // Serial hardware UART 6
    // MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, midiF);  <--- this works SERIAL #1
    MIDI_CREATE_INSTANCE(HardwareSerial, Serial6, midiF);  


void setup()
{
  midiF.begin(MIDI_CHANNEL_OMNI);
  midiF.turnThruOff();
}

void loop()
{
  midiF.sendNoteOn(60, 127, 1);
  delay(1000);  
  midiF.sendNoteOff(60, 127, 1);
  delay(1000);
}
 
Maybe I have an issue with my T3.6... even this hangs. BTW changing 6 to 1-5 works (using the appropriate pins).
I tried with no MIDI driver to remove complexity, just sending a serial byte 0xF8 = MIDI clock, so you can see it in MIDI-OX.

Code:
void setup()
{  
  Serial6.begin(31250);
}

void loop()
{
  Serial6.write(0xF8);
  delay(1000);  
}
 
Maybe I have an issue with my T3.6... even this hangs. BTW changing 6 to 1-5 works (using the appropriate pins).
I tried with no MIDI driver to remove complexity, just sending a serial byte 0xF8 = MIDI clock, so you can see it in MIDI-OX.

Code:
void setup()
{  
  Serial6.begin(31250);
}

void loop()
{
  Serial6.write(0xF8);
  delay(1000);  
}

Maybe you try with the classic
Code:
void setup()
{  
  while(millis()<1000);
  Serial6.begin(31250);
}
to slow down (hold) setup() for some time before calling Serial6.begin
All others have this line, so I would try this
 
Hi Paul,
We ordered and just received another couple T36's and did a test. Our original T36 has a bad Serial6, the new ones work fine. :)

I don't know how to change the name of this thread or delete it, which I think we should. That is a terrible name for a thread when it is not factual. :-(
As admin please feel free to do what is needed.
Thanks,
Steve
 
Glad you got that resolved - even if finding you broke a Teensy :(

I found I can change thread Title : Thread: T3.6 crash when using Serial Port #6 for MIDI - after Teensy Damaged
 
Thanks.

I wonder how Serial6 got damaged??? I was soldering on the belly-pads to get TX6 cabled up... it may have arrived that way too???
Steve
 
PJRC subjects every Teensy to a bed of nails test against every pin for some significant degree of testing so it wasn't open or dead at that point.

Do pins 47 & 48 both have digital read and write function at this point? If connected together can one output to the other for input High and Low?
 
Back
Top