AnsweredAssumed Answered

Teensy 4 (IMXRT1062) FlexIO Serial transmit issues shifter != 0

Question asked by Kurt Eckhardt on Nov 6, 2019
Latest reply on Nov 12, 2019 by Kurt Eckhardt

Hi,

 

Sorry in advance, I am not sure how detailed to start off here. 

 

I have been reasonably active on the Teensy T4 beta and now release, which is using an IMXRT1062 and started playing around with the FlexIO subsystem, including maybe a library to allow myself and other to create logical Serial ports and the like using the FlexIO subsystem.

 

For those unaware of the Teensy 3.x and now T.4, they are typically setup to run under an Arduino setup, where you insteall the Teensy boards, by installing Teensyduino.  My current set of code is up on github in the project. FlexIO_t4

This is a WIP and for simple things I thought I had it working.

 

But then I created a more complicated test case, where I create something like seven Serial objects using FlexIO to go with the 7 Hardware Serial objects, and the idea was to have all of these write out a block of data at the same time.  And when I hooked it up to a logic analyzer, some were working and some were not, and I started to pull my hair out...

 

In the above example, I had 4 Objects setup to use FlexIO1 object, 1 using FlexIO2 and 2 using FlexIO3. 

The first thing I noticed is  when some of the logical Serial ports completed their output and their queue was empty and as such I disabled their Interrupt as part of their interrupt not all of the data came through and in other cases a logical serial port completed their output, their ISR enable bit was cleared and they were not called again, BUT the system continued to output the last byte the was output on that pin over and over again... .

 

There are lots of more details up on the PJRC Forum thread: PJRC (Teensy) Forum 

 

Their are two newer test case examples part of my github project.  The FlexSerial_transmit_many_streams.ino, I setup to be able to disable some of the pins I was trying and in addition I could hard code Which flexIO object to use, likewise which timer and which shifter on it... 

 

But maybe first up here it might be better to start off with simpler test case:

In this case I am creating just one of my Serial objects.

//============================================================================
// Simple output only test for Flex Serial pin defined on Pin 2
// Idea is to connect pin 0 (Serail1 RX pin) to Pin2 (Flex IO output)
//
// And the program will hopefully echo the stuff to The serial output
//============================================================================

#include <FlexIO_t4.h>
#include <FlexSerial.h>

#define TX_PIN 3
#define TX_FLEX_IO_INDEX 0
#define TX_FLEX_IO_TIMER 0
#define TX_FLEX_IO_SHIFTER 0
FlexSerial SerialFlex(-1, TX_PIN, -1, -1, -1, TX_FLEX_IO_INDEX, TX_FLEX_IO_TIMER, TX_FLEX_IO_SHIFTER);

int count_bytes_still_expected = 0;

void setup() {
pinMode(13, OUTPUT);
while (!Serial && millis() < 4000);
Serial.begin(115200);
Serial1.begin(115200); // lets start up Serial1, to see if we can receive anything from our FlexSerial
delay(500);
SerialFlex.begin(115200);

Serial.printf("Connect jumper from pin %d to 0)\n", TX_PIN);
Serial.println("End Setup");
count_bytes_still_expected = 32; // close enough...
SerialFlex.println("Enter something to have it echo");
}


void loop() {
int ch;
if (Serial.available()) {
count_bytes_still_expected = 0;
digitalWrite(13, !digitalRead(13));
while ((ch = Serial.read()) != -1){
SerialFlex.write(ch);
count_bytes_still_expected++;
}
}
delay(500);

}

void serialEvent1() {
int ch;
while ((ch = Serial1.read()) != -1) {
if (count_bytes_still_expected > -10) {
Serial.write(ch);
count_bytes_still_expected--;
} else if (count_bytes_still_expected == -10) {
Serial.println("*** Error receiving too many bytes ***");
count_bytes_still_expected--;
}
}
}

With it configured like above it is setup to output using Timer0 and Shifter0 and works as expected.  I have lots of debug outputs turned on in my library so I get debug output like:

pin 3 maps to: 20000b70, port: 401ac000(FLEXIO1) pin 5
timer index: 0 shifter index: 0 mask: 1
Before configure flexio
CCM_CDCDR: 33f71f92
VERID:1010001 PARAM:2100808 CTRL:1 PIN: 0
SHIFTSTAT:0 SHIFTERR=0 TIMSTAT=0
SHIFTSIEN:0 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:30502 0 0 0
SHIFTCFG:32 0 0 0
TIMCTL:1c00501 0 0 0
TIMCFG:2222 0 0 0
TIMCMP:f81 0 0 0
Connect jumper from pin 3 to 0)
End Setup
FI1: 1 1 0 3(E)* 0 0 0
FI1: 1 1 0 3(n) 0 1 0
FI1: 1 1 0 3(t) 0 1 0
FI1: 1 1 0 3(e) 0 1 0
FI1: 1 1 0 3(r) 0 1 0
FI1: 1 1 0 3( ) 0 1 0
FI1: 1 1 0 3(s) 0 1 0
FI1: 1 1 0 3(o) 0 1 0
FI1: 1 1 0 3(m) 0 1 0
FI1: 1 1 0 3(e) 0 1 0
FI1: 1 1 0 3(t) 0 1 0
FI1: 1 1 0 3(h) 0 1 0
FI1: 1 1 0 3(i) 0 1 0
FI1: 1 1 0 3(n) 0 1 0
FI1: 1 1 0 3(g) 0 1 0
FI1: 1 1 0 3( ) 0 1 0
FI1: 1 1 0 3(t) 0 1 0
FI1: 1 1 0 3(o) 0 1 0
FI1: 1 1 0 3( ) 0 1 0
FI1: 1 1 0 3(h) 0 1 0
FI1: 1 1 0 3(a) 0 1 0
FI1: 1 1 0 3(v) 0 1 0
FI1: 1 1 0 3(e) 0 1 0
FI1: 1 1 0 3( ) 0 1 0
FI1: 1 1 0 3(i) 0 1 0
FI1: 1 1 0 3(t) 0 1 0
FI1: 1 1 0 3( ) 0 1 0
FI1: 1 1 0 3(e) 0 1 0
FI1: 1 1 0 3(c) 0 1 0
FI1: 1 1 0 3(h) 0 1 0
FI1: 1 1 0 3(o) 0 1 0
FI1: 1 1 0 3(0d) 0 1 0
FI1: 1 1 0 3(0a)* 0 0 0

And the Output to Logic Analyzer is reasonable, there is an initial NULL character I need to look at.

In the above Debug information lines like:

FI1: 1 1 0 3(0a)* 0 0 0

I only output for FlexIO1 interrupts the first three numbers 1 1 0 corresponds to: FLEXIO1_SHIFTSTAT, FLEXIO1_SHIFTSIEN, FLEXIO1_SHIFTERR

So I have SHIFT State bit set for Shifter 0, likewise an interrupt enable on Shifter 0 and No error bits.

The 3(0a) Says, I called back to my code to process the interrupt for Pin 3 (Flex IO1 Pin 5) and I output  0a (line feed).

The * says My output queue is now empty so I will disable my Interrupt.

The Last three numbers: is again the Sift state, interrupt enable, and Error state at the end of my Interrupt handler, so In this case I cleared both the Shift state and the Interrupt...

 

If I then change to use Timer1 instead of 0, still works fine.

pin 3 maps to: 20000b70, port: 401ac000(FLEXIO1) pin 5
timer index: 1 shifter index: 0 mask: 1
Before configure flexio
CCM_CDCDR: 33f71f92
VERID:1010001 PARAM:2100808 CTRL:1 PIN: 0
SHIFTSTAT:0 SHIFTERR=0 TIMSTAT=0
SHIFTSIEN:0 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:1030502 0 0 0
SHIFTCFG:32 0 0 0
TIMCTL:0 1c00501 0 0
TIMCFG:0 2222 0 0
TIMCMP:0 f81 0 0
Connect jumper from pin 3 to 0)
End Setup

If I instead configure back to TImer0 but use Shifter 1 (and likewise if timer1 and shifter 1), The debug output looks OK,

pin 3 maps to: 20000b70, port: 401ac000(FLEXIO1) pin 5
timer index: 0 shifter index: 1 mask: 2
Before configure flexio
CCM_CDCDR: 33f71f92
VERID:1010001 PARAM:2100808 CTRL:1 PIN: 0
SHIFTSTAT:0 SHIFTERR=0 TIMSTAT=0
SHIFTSIEN:0 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:0 30502 0 0
SHIFTCFG:0 32 0 0
TIMCTL:1c00501 0 0 0
TIMCFG:2222 0 0 0
TIMCMP:f81 0 0 0
Connect jumper from pin 3 to 0)
End Setup
FI1: 2 2 0 3(E)* 0 0 0
FI1: 2 2 0 3(n) 0 2 0
FI1: 2 2 0 3(t) 0 2 0
FI1: 2 2 0 3(e) 0 2 0
FI1: 2 2 0 3(r) 0 2 0
FI1: 2 2 0 3( ) 0 2 0
FI1: 2 2 0 3(s) 0 2 0
FI1: 2 2 0 3(o) 0 2 0
FI1: 2 2 0 3(m) 0 2 0
FI1: 2 2 0 3(e) 0 2 0
FI1: 2 2 0 3(t) 0 2 0
FI1: 2 2 0 3(h) 0 2 0
FI1: 2 2 0 3(i) 0 2 0
FI1: 2 2 0 3(n) 0 2 0
FI1: 2 2 0 3(g) 0 2 0
FI1: 2 2 0 3( ) 0 2 0
FI1: 2 2 0 3(t) 0 2 0
FI1: 2 2 0 3(o) 0 2 0
FI1: 2 2 0 3( ) 0 2 0
FI1: 2 2 0 3(h) 0 2 0
FI1: 2 2 0 3(a) 0 2 0
FI1: 2 2 0 3(v) 0 2 0
FI1: 2 2 0 3(e) 0 2 0
FI1: 2 2 0 3( ) 0 2 0
FI1: 2 2 0 3(i) 0 2 0
FI1: 2 2 0 3(t) 0 2 0
FI1: 2 2 0 3( ) 0 2 0
FI1: 2 2 0 3(e) 0 2 0
FI1: 2 2 0 3(c) 0 2 0
FI1: 2 2 0 3(h) 0 2 0
FI1: 2 2 0 3(o) 0 2 0
FI1: 2 2 0 3(0d) 0 2 0
FI1: 2 2 0 3(0a)* 0 0 0

However the Logic Analyzer shows that the last character output (the line feed) will continue to output forever.  Or at least until you try to output something else, which will output, but again

Again the only difference is using Shifter 1 instead of Shifter 0. 

 

As I mentioned there are similar issues when multiple shifters are used for additional Serial objects, like some stopping output when I disable the interrupt for a different one... 

 

Hope some of this makes sense?  And hopefully It is something simple that I messed up on.

 

But would very much appreciate any suggestions and/or information like yes there are issues with using the different shifters...

 

Thanks again

Kurt

Outcomes