T4 FlexIO - Looking back at my T4 beta testing library FlexIO_t4

KurtE

Senior Member+
During the T4 beta I did some playing around with the Flex IO sub-system that is part of the T4...
With it I have versions of a SPI handler and a Serial port handler.

The code is up on github: https://github.com/KurtE/FlexIO_t4

At some point it might be nice to maybe merge in and probably enhance some of the support code into the T4 core files or some standard library, and potentially maybe use this support to build into some standard library like SoftwareSerial.

But after having a discussion this morning up on another thread about having an array of HardwareSerial objects and pros and cons versus array of Streams, I thought I would hack up a simple sketch, which tries to output a buffer of N bytes out to a lot of IO pins, like all of the SerialX objects on T4 as well as several ones built up from Flex IO...

I ran into some bugs in my library code. Some of which I have fixed, some I am still debugging.

Right now having an issue with something to do with using either pin 18 or 22 in the list and even when I remove them from being output to, just creating/init of the FlexSerial object gives me some strange stuff on that pin... Again debugging.

But if anyone is curious about this. Here is a quick and dirty sketch that tries to output a buffer currently defined as 128 bytes long as quick as possible to something logically like 13 or 14 serial ports on T4...

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

FlexSerial SerialF1(-1, 2); // currently setup for pin 2 TX
FlexSerial SerialF2(-1, 3); // currently setup for pin 3 TX
FlexSerial SerialF3(-1, 4); // currently setup for pin 4 TX
FlexSerial SerialF4(-1, 5); // currently setup for pin 5 TX
FlexSerial SerialF5(-1, 6); // currently setup for pin 6 TX
FlexSerial SerialF6(-1, 18); // currently setup for pin 18 TX
FlexSerial SerialF7(-1, 22); // currently setup for pin 19 TX

Stream *streams[] = {&Serial1, &Serial2, &Serial3, &Serial4, &Serial5, &Serial6, &Serial7,
                     &SerialF1, &SerialF2, &SerialF3, &SerialF4, &SerialF5, &SerialF6/*, &SerialF7 */
                    };
const uint8_t count_streams = sizeof(streams) / sizeof(streams[0]);

#define BUFFER_SIZE 128
#define BAUD 115200
uint8_t buffer[BUFFER_SIZE];
uint8_t loop_count = 0;


void setup() {
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  while (!Serial && millis() < 4000);
  Serial.begin(115200);
  delay(250);

  // Lets initialize all of the Hardware Serial ports.
  Serial1.begin(BAUD); // 0, 1
  Serial2.begin(BAUD); // 7, 8
  Serial3.begin(BAUD); // 15, 14
  Serial4.begin(BAUD); // 16, 17
  Serial5.begin(BAUD); // 21, 20
  Serial6.begin(BAUD); // 25, 24
  Serial7.begin(BAUD); // 28, 29
  Serial.println("\nSerialF1 begin");if (!SerialF1.begin(BAUD)) Serial.println("SerialF1 begin failed\n");
  Serial.println("\nSerialF2 begin");if (!SerialF2.begin(BAUD)) Serial.println("SerialF2 begin failed\n");
  Serial.println("\nSerialF3 begin");if (!SerialF3.begin(BAUD)) Serial.println("SerialF3 begin failed\n");
  Serial.println("\nSerialF4 begin");if (!SerialF4.begin(BAUD)) Serial.println("SerialF4 begin failed\n");
  Serial.println("\nSerialF5 begin");if (!SerialF5.begin(BAUD)) Serial.println("SerialF5 begin failed\n");
  Serial.println("\nSerialF6 begin");if (!SerialF6.begin(BAUD)) Serial.println("SerialF6 begin failed\n");
  Serial.println("\nSerialF7 begin");if (!SerialF7.begin(BAUD)) Serial.println("SerialF7 begin failed\n");
  delay(500);

  Serial.println("End Setup");
}

uint8_t loop_char = 'a';
void loop() {
  loop_count++;
  // maybe first 10 bytes will bee loop count;
  memset(buffer, loop_count, 10);
  for (uint16_t bi = 10; bi < sizeof(buffer); bi++) buffer[bi] = bi & 0xff;
  digitalWriteFast(13, HIGH);
  uint16_t buffer_indexes[count_streams] = {0};
  uint32_t start_time = millis();
  bool not_done_yet = true;
  while (not_done_yet) {
    digitalWriteFast(12, HIGH);
    not_done_yet = false; // assume we are done.
    for (uint8_t serial_index = 0; serial_index < count_streams; serial_index++) {
      if (buffer_indexes[serial_index] < sizeof(buffer)) {
        uint16_t cbOutput = sizeof(buffer) - buffer_indexes[serial_index];
        uint16_t cbAvailForWrite = streams[serial_index]->availableForWrite();
        if (cbAvailForWrite < cbOutput) {
          cbOutput = cbAvailForWrite;
          not_done_yet = true;
        }
        streams[serial_index]->write(&buffer[buffer_indexes[serial_index]], cbOutput);
        buffer_indexes[serial_index] += cbOutput;
      }
    }
    delayMicroseconds(10);
    digitalWriteFast(12, LOW);
  }
  // Now lets wait until all of them finish their output
  for (uint8_t serial_index = 0; serial_index < count_streams; serial_index++) {
    streams[serial_index]->flush();
  }
  digitalWriteFast(13, LOW);
  Serial.printf("loop %u time: %u\n", loop_count, millis() - start_time);
  delay(250);
}
For this, I brought out my older Saleae Logic 16 analyzer to show the channels. Channel 10, is the one that is screwing up, where I am not outputting to it, but it still appears to output a start/stop... Investigating. The last channel shown is pin 13, which shows me the full time it took to output on all of the channels. The one above it is pin 12, which shows the different iterations through the loop looking at how much data it can output to each channel.. Note I put in the delay of 10 microseconds to see if I was hanging before or after the output of the last channel...
screenshot.jpg

Anyway I thought I would throw this out here as a way to prod myself to look at it again ;)
 
Interesting work KurtE!

Good luck debugging - especially the dead data free channel that has the timing right for Start/Stop
 
Thanks, still debugging, and still trying to remember/figure out all of those registers and their interaction...
 
When you do, I hope you'll tell me & everyone else how it all works. NXP's documentation leaves much to be desired in almost every chapter, but FlexIO seems particularly sparse on description of how the registers & hardware really work.
 
Thanks @Paul,

I will try... Right now I am trying to figure out why, when I have 4 different Tx Serial only objects on FlexIO1, and I don't actually do anything on lets say the third one, it still continues to fire outputting sometimes just NULL other times whatever it last output, but only when the one above it fires...

I know I am probably doing something stupid, like off by one in some mask, or potentially setting up a register like timer to say to cascade into the timer+1 or ???

Also were some cases I was mucking with setting/clearing bit in register which the ISR also mucks with. Or ???
 
Thanks @manitou and others, Yes I started off with some of their examples. However sometimes the issue I was running into, is it might work great for their one example, but it has been unclear at times on how to slightly modify the sketch to handle using a different timer or pin or shifter, and some of the other interactions, where you must use two shifters or timers which most be consecutive. And you have DMA on FlexIO1 and FlexIO2 but not on FlexIO3, and on 1 and 2 there are only 2 DMA sources, that are shared by two channels...

What I am sort of tearing my few strands of hair out, is things, like the sketch above... I was seeing some strange results so I disabled one of my logical uarts on FlexIO1, that is I initialized it, and in two different cases I either output nothing or only something at the beginning...

I thought I would describe some of my head scratching. Not sure if anyone has any ideas, or thoughts on it, but sometimes writing it down helps to come up with ideas/solutions...

And I am getting cases of things still outputting that I don't think should and others that don't output... So for example I turned on more debug code (and added some more)...

So for example I am creating 7 of these Flex Serial objects:
My debug info at startup shows data like: For now ignore the FI1: lines, more about this in the next part...
Code:
SerialF1 begin
pin 2 maps to: 20000be8, port: 401ac000(FLEXIO1) pin 4
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:30402 0 0 0
SHIFTCFG:32 0 0 0
TIMCTL:1c00401 0 0 0
TIMCFG:2222 0 0 0
TIMCMP:f81 0 0 0
FI1: 1 1 4* 0 0

SerialF2 begin
pin 3 maps to: 20000be8, port: 401ac000(FLEXIO1) pin 5
timer index: 1 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:1 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:30402 1030502 0 0
SHIFTCFG:32 32 0 0
TIMCTL:1c00401 1c00501 0 0
TIMCFG:2222 2222 0 0
TIMCMP:f81 f81 0 0
FI1: 2 3 5* 0 1

SerialF3 begin
pin 4 maps to: 20000be8, port: 401ac000(FLEXIO1) pin 6
timer index: 2 shifter index: 2 mask: 4
Before configure flexio
CCM_CDCDR: 33f71f92
FI1: 1 3 4 0 3
VERID:1010001 PARAM:2100808 CTRL:1 PIN: 0
SHIFTSTAT:4 SHIFTERR=0 TIMSTAT=1
SHIFTSIEN:3 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:30402 1030502 2030602 0
SHIFTCFG:32 32 32 0
TIMCTL:1c00401 1c00501 1c00601 0
TIMCFG:2222 2222 2222 0
TIMCMP:f81 f81 f81 0
FI1: 4 7 6* 0 3

SerialF4 begin
pin 5 maps to: 20000be8, port: 401ac000(FLEXIO1) pin 8
FI1: 2 7 5 0 7
timer index: 3 shifter index: 3 mask: 8
Before configure flexio
CCM_CDCDR: 33f71f92
VERID:1010001 PARAM:2100808 CTRL:1 PIN: 30
SHIFTSTAT:0 SHIFTERR=0 TIMSTAT=3
SHIFTSIEN:7 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:30402 1030502 2030602 3030802
SHIFTCFG:32 32 32 32
TIMCTL:1c00401 1c00501 1c00601 1c00801
TIMCFG:2222 2222 2222 2222
TIMCMP:f81 f81 f81 f81
FI1: 8 f 8* 0 7
FI1: 1 f 4 0 f
FI1: 4 f 6 0 f

SerialF5 begin
pin 6 maps to: 20000bf8, port: 401b0000(FLEXIO2) pin a
timer index: 0 shifter index: 0 mask: 1
Before configure flexio
CCM_CDCDR: 33f71f92
VERID:1010001 PARAM:2200808 CTRL:1 PIN: 0
SHIFTSTAT:0 SHIFTERR=0 TIMSTAT=0
SHIFTSIEN:0 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:30a02 0 0 0
SHIFTCFG:32 0 0 0
TIMCTL:1c00a01 0 0 0
TIMCFG:2222 0 0 0
FI1: 8 f 8 0 f
TIMCMP:f81 0 0 0

SerialF6 begin
pin 18 maps to: 20000c08, port: 42020000(FLEXIO3) pin 1
timer index: 0 shifter index: 0 mask: 1
Before configure flexio
CCM_CDCDR: 33f71f92
VERID:1010001 PARAM:2200808 CTRL:1 PIN: 0
SHIFTSTAT:0 SHIFTERR=0 TIMSTAT=0
FI1: 1 f 4 0 f
FI1: 4 f 6 0 f
SHIFTSIEN:0 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:30102 0 0 0
SHIFTCFG:32 0 0 0
TIMCTL:1c00101 0 0 0
TIMCFG:2222 0 0 0
TIMCMP:f81 0 0 0

SerialF7 begin
pin 19 maps to: 20000c08, port: 42020000(FLEXIO3) pin 0
timer index: 1 shifter index: 1 mask: 2
Before configure flexio
CCM_CDCDR: 33f71f92
FI1: 2 f 5 0 f
VERID:1010001 PARAM:2200808 CTRL:1 PIN: 0
SHIFTSTAT:2 SHIFTERR=0 TIMSTAT=0
SHIFTSIEN:1 SHIFTEIEN=0 TIMIEN=0
FI1: 8 f 8 0SHIFTSTATE=0
SHIFTCTL:30102 1030002 0 0
SHIFTCFG:32 32 0 0
TIMCTL:1c00101 1c00001 0 0
TIMCFG:2222 2222 0 0
TIMCMP:f81 f81 0 0

So if you look at the section SerialF4, it shows that the first 4 objects were created on FlexIO1, and I used up all of the Shifters and Timers. Now back to the FI1: messages.

I hacked up my Interrupt for FlexIO1, like:
Code:
void IRQHandler_FlexIO1() {
	FlexIOHandlerCallback **ppfhc = flex1_Handler_callbacks;
	Serial.printf("FI1: %x %x ", FLEXIO1_SHIFTSTAT, FLEXIO1_SHIFTSIEN);
	for (uint8_t i = 0; i < 4; i++) {
		if (*ppfhc) {
			if ((*ppfhc)->call_back(&flexIO1)) return;
		}
		ppfhc++;
	}
	flexIO1.IRQHandler();
	Serial.printf(" %x %x\n", FLEXIO1_SHIFTSTAT, FLEXIO1_SHIFTSIEN);
	 asm("dsb");
}
So I print data out and start of interrupt, I check for logical callback, which I have 4 on this one, which get called, and then at the end I have another output:
I also hacked the Serial callback that if it is on FlexIO1 it prints out, it's logical FlexIO pin number where for example Teensy pin 2 maps to FlexIO1 pin 4, ... And if if the output to the shift register is the last one, it outputs a * (and disables it's ISR bit in the SHIFTSIEN

Now per loop of outputting data to all of them, I get:

Code:
FI1: f b 458 4 b
FI1: f b 458 4 b
FI1: f b 458 4 b
FI1: f b 458 4 b
...
FI1: f b 458 4 b
FI1: f b 4*58 4 a
FI1: f a 5*8 5 8
loop 1 time: 6
end F1:5 8 F2:1 0 F3: 1 0

So the line: FI1: f b 458 4 b
Says I entered the ISR with the SHIFTSTAT=f (all 4 shift registers can accept data), SHIFTSIEN=b (so channels 1, 2, 4) should generate interrupts on shifter,
The 458 says that our FlexIO pins 4, 5, 8 output, which corresponds to Our IO pins 2, 3, 5. FlexIO pin 6(our pin 4) should not. And at the end the SHIFTSTAT=4 says we did not update that channel and we are still ready to interrupt on those 3 channels.

When we get to: FI1: f b 4*58 4 a - like above except the first channel fifo is empty so it removes its Interrupt from the SHIFTSIEN so at end it is now a.
Likewise FI1: f a 5*8 5 - says the second channel completed, and disabled it's bit... So it won't interrupt any more...

And now the big issue: I don't get any more Interrupts. So what happened to the last byte I output on SHIFTER 4? It never comes back and say it is done...

I put in a wait at the end of the code of 250ms and then print out the state of the 3 shifter states and interrupt enables, and it still has that same state...

Maybe I should look for an errata sheet to see if maybe there is some issue with the 4th channel or ...
 
We've been bitten before by improper address or offset in Include files. I assume you've reviewed the flexio addresses, names, offsets in the include files ... 269 FLEXIO 's in imxrt.h! Hoping the reference manual info is correct.
 
Thanks @manitou - Will double check. I originally created that structure in the header file back in the beta time frame off of the IMXRT1052 documents.

The interesting thing is all of the things like SHIFTCTL are arrays of 4 items each so if one works, you would think they all do... And likewise the SHIFTSTAT and SHIFTSIEN are simple 32 bit registers where the bottom 4 bits control which of the channels are set or enabled... Some of them are set a bit to clear (W1C) and others are whole values, so need to also double check that I am properly doing that and that I am protecting the set/clear operations from having it interrupted by ISR...

After I posted it, I also added looking at the SHIFTERR field which did show the bit 4 value as an error (which since output is an under run I tried then clearing (W1C) to its field and got some more strange stuff... Will play some more.. Then maybe give it a break and look again... In the end it may turn out to be something stupid. And probably the last place that I look.

Thanks again
 
@KurtE - this was the post I was referencing about FlexIO3: https://community.nxp.com/thread/514359

EDIT: I just downloaded your latest repository and gave you sketch a try along with the change to the IRQhandler but can not seem to duplicate your results? Must be missing something - here is what I get:
Code:
SerialF1 begin
pin 2 maps to: 20000b08, port: 401ac000 pin 4
timer index: 0 shifter index: 0 mask: 1
Before configure flexio
CCM_CDCDR: 33f71f92
VERID:2100808 PARAM:1 CTRL:1 PIN: 10
SHIFTSTAT:1 SHIFTERR=0 TIMSTAT=0
SHIFTSIEN:0 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:30402 0 0 0
SHIFTCFG:32 0 0 0
TIMCTL:1c00401 0 0 0
TIMCFG:2222 0 0 0
TIMCMP:f81 0 0 0

SerialF2 begin
pin 3 maps to: 20000b08, port: 401ac000 pin 5
timer index: 1 shifter index: 1 mask: 2
Before configure flexio
CCM_CDCDR: 33f71f92
VERID:2100808 PARAM:1 CTRL:1 PIN: 30
SHIFTSTAT:3 SHIFTERR=0 TIMSTAT=0
SHIFTSIEN:0 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:30402 1030502 0 0
SHIFTCFG:32 32 0 0
TIMCTL:1c00401 1c00501 0 0
TIMCFG:2222 2222 0 0
TIMCMP:f81 f81 0 0

SerialF3 begin
pin 4 maps to: 20000b08, port: 401ac000 pin 6
timer index: 2 shifter index: 2 mask: 4
Before configure flexio
CCM_CDCDR: 33f71f92
VERID:2100808 PARAM:1 CTRL:1 PIN: 70
SHIFTSTAT:7 SHIFTERR=0 TIMSTAT=0
SHIFTSIEN:0 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:30402 1030502 2030602 0
SHIFTCFG:32 32 32 0
TIMCTL:1c00401 1c00501 1c00601 0
TIMCFG:2222 2222 2222 0
TIMCMP:f81 f81 f81 0

SerialF4 begin
pin 5 maps to: 20000b08, port: 401ac000 pin 8
timer index: 3 shifter index: 3 mask: 8
Before configure flexio
CCM_CDCDR: 33f71f92
VERID:2100808 PARAM:1 CTRL:1 PIN: 170
SHIFTSTAT:f SHIFTERR=0 TIMSTAT=0
SHIFTSIEN:0 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:30402 1030502 2030602 3030802
SHIFTCFG:32 32 32 32
TIMCTL:1c00401 1c00501 1c00601 1c00801
TIMCFG:2222 2222 2222 2222
TIMCMP:f81 f81 f81 f81

SerialF5 begin
pin 6 maps to: 20000b18, port: 401b0000 pin a
timer index: 0 shifter index: 0 mask: 1
Before configure flexio
CCM_CDCDR: 33f71f92
VERID:2200808 PARAM:1 CTRL:1 PIN: 400
SHIFTSTAT:1 SHIFTERR=0 TIMSTAT=0
SHIFTSIEN:0 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:30a02 0 0 0
SHIFTCFG:32 0 0 0
TIMCTL:1c00a01 0 0 0
TIMCFG:2222 0 0 0
TIMCMP:f81 0 0 0

SerialF6 begin
pin 18 maps to: 20000b28, port: 42020000 pin 1
timer index: 0 shifter index: 0 mask: 1
Before configure flexio
CCM_CDCDR: 33f71f92
VERID:2200808 PARAM:1 CTRL:1 PIN: 2
SHIFTSTAT:1 SHIFTERR=0 TIMSTAT=0
SHIFTSIEN:0 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:30102 0 0 0
SHIFTCFG:32 0 0 0
TIMCTL:1c00101 0 0 0
TIMCFG:2222 0 0 0
TIMCMP:f81 0 0 0

SerialF7 begin
pin 22 maps to: 20000b28, port: 42020000 pin 8
timer index: 1 shifter index: 1 mask: 2
Before configure flexio
CCM_CDCDR: 33f71f92
VERID:2200808 PARAM:1 CTRL:1 PIN: 102
SHIFTSTAT:3 SHIFTERR=0 TIMSTAT=0
SHIFTSIEN:0 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:30102 1030802 0 0
SHIFTCFG:32 32 0 0
TIMCTL:1c00101 1c00801 0 0
TIMCFG:2222 2222 0 0
TIMCMP:f81 f81 0 0
End Setup
FI1: f 1  e 1
FI1: f 1  e 1
FI1: e 3  c 1
FI1: c 7  8 3
FI1: 8 f  0 7
FI1: f f  0 f
FI1: f f  0 f
FI1: f f  0 f
FI1: f f  0 f
FI1: f f  0 f
 
Last edited:
@mjs513 - Good real early morning, COFFEE needed.

Yep - I noted that FlexIO3 has no DMA access earlier, these objects are marked in my table as Dma source 0xff which I check for and don't try...

Also what may not be obvious in my table, is for example for FLEXIO1: DMAMUX_SOURCE_FLEXIO1_REQUEST0, DMAMUX_SOURCE_FLEXIO1_REQUEST1, DMAMUX_SOURCE_FLEXIO1_REQUEST2, DMAMUX_SOURCE_FLEXIO1_REQUEST3,

Looks like 4 DMAMUX_SOURCE... But from imxrt.h
Code:
#define DMAMUX_SOURCE_FLEXIO1_REQUEST0		0
#define DMAMUX_SOURCE_FLEXIO1_REQUEST1		0
#define DMAMUX_SOURCE_FLEXIO1_REQUEST2		64
#define DMAMUX_SOURCE_FLEXIO1_REQUEST3		64
There are only 2 unique ones, similar for FLEXIO2...

I just uploaded the latest stuff, which allows me to have the serial objects define what FlexIO object to use, plus which timer and shifter... And I did not get far enough yesterday,
I want to clean up the sketch to make it easier to configure which ones to enable or not.... Right now sort of a mess, where I need to edit 3 places or so to change which object.

Code:
//============================================================================
// Simple output only test for Flex Serial pin defined on Pin 2
// Idea is to connect pin 0 (Serial1 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>

#if 0
FlexSerial SerialF1(-1, 2, -1, 0, 0, 0, 0, 0); // currently setup for pin 2 TX
#endif
FlexSerial SerialF2(-1, 3, -1, 0, 0, 0, 1, 1); // currently setup for pin 3 TX
FlexSerial SerialF3(-1, 4, -1, 0, 0, 0, 2, 2); // currently setup for pin 4 TX
#if 0
FlexSerial SerialF4(-1, 5, -1, 0, 0, 0, 3, 3); // currently setup for pin 5 TX
#endif
FlexSerial SerialF5(-1, 6); // currently setup for pin 6 TX
FlexSerial SerialF6(-1, 18); // currently setup for pin 18 TX
FlexSerial SerialF7(-1, 19); // currently setup for pin 19 TX

Stream *streams[] = {&Serial1, &Serial2, &Serial3, &Serial4, &Serial5, &Serial6, &Serial7,
                     /*&SerialF1, */ &SerialF2, &SerialF3, /*&SerialF4 ,*/ &SerialF5, &SerialF6, &SerialF7
                    };
const uint8_t count_streams = sizeof(streams) / sizeof(streams[0]);

#define BUFFER_SIZE 75
#define BAUD 115200
uint8_t buffer[BUFFER_SIZE];
uint8_t loop_count = 0;

void outputStr(Stream *pstream, const char *str_buf) {

  digitalWriteFast(13, HIGH);
  pstream->write(str_buf);
  //  pstream->flush();
  digitalWriteFast(13, LOW);

}

void setup() {
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  while (!Serial && millis() < 4000);
  Serial.begin(115200);
  delay(250);

  // Lets initialize all of the Hardware Serial ports.
  Serial1.begin(BAUD); outputStr(&Serial1, "Serial1");// 0, 1
  Serial2.begin(BAUD); outputStr(&Serial2, "Serial2");// 7, 8
  Serial3.begin(BAUD); outputStr(&Serial3, "Serial3");// 15, 14
  Serial4.begin(BAUD); outputStr(&Serial4, "Serial4");// 16, 17
  Serial5.begin(BAUD); outputStr(&Serial5, "Serial5");// 21, 20
  Serial6.begin(BAUD); outputStr(&Serial6, "Serial6");// 25, 24
  Serial7.begin(BAUD); outputStr(&Serial7, "Serial7");// 28, 29
//  Serial.println("\nSerialF1 begin"); if (!SerialF1.begin(BAUD)) Serial.println("SerialF1 begin failed\n");
//  outputStr(&SerialF1, "SerialF1(2)");
  Serial.println("\nSerialF2 begin"); if (!SerialF2.begin(BAUD)) Serial.println("SerialF2 begin failed\n");
  outputStr(&SerialF2, "SerialF2(3)");
  Serial.println("\nSerialF3 begin"); if (!SerialF3.begin(BAUD)) Serial.println("SerialF3 begin failed\n");
  outputStr(&SerialF3, "SerialF3(4)");
//  Serial.println("\nSerialF4 begin"); if (!SerialF4.begin(BAUD)) Serial.println("SerialF4 begin failed\n");
//  outputStr(&SerialF4, "SerialF4(5)");
  Serial.println("\nSerialF5 begin"); if (!SerialF5.begin(BAUD)) Serial.println("SerialF5 begin failed\n");
  outputStr(&SerialF5, "SerialF5(6)");
  Serial.println("\nSerialF6 begin"); if (!SerialF6.begin(BAUD)) Serial.println("SerialF6 begin failed\n");
  outputStr(&SerialF6, "SerialF6(18)");
  Serial.println("\nSerialF7 begin"); if (!SerialF7.begin(BAUD)) Serial.println("SerialF7 begin failed\n");
  outputStr(&SerialF7, "SerialF7(19)");
  delay(500);

  Serial.println("End Setup");
}

uint8_t loop_char = 'a';
void loop() {
  loop_count++;
  // maybe first 10 bytes will bee loop count;
  memset(buffer, loop_count, 10);
  for (uint16_t bi = 10; bi < sizeof(buffer); bi++) buffer[bi] = bi & 0xff;
  digitalWriteFast(13, HIGH);
  uint16_t buffer_indexes[count_streams] = {0};
  uint32_t start_time = millis();
  bool not_done_yet = true;
  while (not_done_yet) {
    digitalWriteFast(12, HIGH);
    not_done_yet = false; // assume we are done.
    for (uint8_t serial_index = 0; serial_index < count_streams; serial_index++) {
      if (buffer_indexes[serial_index] < sizeof(buffer)) {
        uint16_t cbOutput = sizeof(buffer) - buffer_indexes[serial_index];
        uint16_t cbAvailForWrite = streams[serial_index]->availableForWrite();
        if (cbAvailForWrite < cbOutput) {
          cbOutput = cbAvailForWrite;
          not_done_yet = true;
        }
        streams[serial_index]->write(&buffer[buffer_indexes[serial_index]], cbOutput);
        buffer_indexes[serial_index] += cbOutput;
      }
    }
    //delayMicroseconds(10);
    digitalWriteFast(12, LOW);
  }
  // Now lets wait until all of them finish their output
  for (uint8_t serial_index = 0; serial_index < count_streams; serial_index++) {
    streams[serial_index]->flush();
  }
  digitalWriteFast(13, LOW);
  Serial.printf("loop %u time: %u\n", loop_count, millis() - start_time);
  delay(250);
  Serial.printf("end F1:%x %x F2:%x %x F3: %x %x\n", FLEXIO1_SHIFTSTAT, FLEXIO1_SHIFTSIEN,
                FLEXIO2_SHIFTSTAT, FLEXIO2_SHIFTSIEN, FLEXIO3_SHIFTSTAT, FLEXIO3_SHIFTSIEN );
  Serial.printf("CCM_CDCDR: %x\n", CCM_CDCDR);
  Serial.printf("VERID:%x PARAM:%x CTRL:%x PIN: %x\n", IMXRT_FLEXIO1_S.VERID, IMXRT_FLEXIO1_S.PARAM, IMXRT_FLEXIO1_S.CTRL, IMXRT_FLEXIO1_S.PIN);
  Serial.printf("SHIFTSTAT:%x SHIFTERR=%x TIMSTAT=%x\n", IMXRT_FLEXIO1_S.SHIFTSTAT, IMXRT_FLEXIO1_S.SHIFTERR, IMXRT_FLEXIO1_S.TIMSTAT);
  Serial.printf("SHIFTSIEN:%x SHIFTEIEN=%x TIMIEN=%x\n", IMXRT_FLEXIO1_S.SHIFTSIEN, IMXRT_FLEXIO1_S.SHIFTEIEN, IMXRT_FLEXIO1_S.TIMIEN);
  Serial.printf("SHIFTSDEN:%x SHIFTSTATE=%x\n", IMXRT_FLEXIO1_S.SHIFTSDEN, IMXRT_FLEXIO1_S.SHIFTSTATE);
  Serial.printf("SHIFTCTL:%x %x %x %x\n", IMXRT_FLEXIO1_S.SHIFTCTL[0], IMXRT_FLEXIO1_S.SHIFTCTL[1], IMXRT_FLEXIO1_S.SHIFTCTL[2], IMXRT_FLEXIO1_S.SHIFTCTL[3]);
  Serial.printf("SHIFTCFG:%x %x %x %x\n", IMXRT_FLEXIO1_S.SHIFTCFG[0], IMXRT_FLEXIO1_S.SHIFTCFG[1], IMXRT_FLEXIO1_S.SHIFTCFG[2], IMXRT_FLEXIO1_S.SHIFTCFG[3]);
  Serial.printf("TIMCTL:%x %x %x %x\n", IMXRT_FLEXIO1_S.TIMCTL[0], IMXRT_FLEXIO1_S.TIMCTL[1], IMXRT_FLEXIO1_S.TIMCTL[2], IMXRT_FLEXIO1_S.TIMCTL[3]);
  Serial.printf("TIMCFG:%x %x %x %x\n", IMXRT_FLEXIO1_S.TIMCFG[0], IMXRT_FLEXIO1_S.TIMCFG[1], IMXRT_FLEXIO1_S.TIMCFG[2], IMXRT_FLEXIO1_S.TIMCFG[3]);
  Serial.printf("TIMCMP:%x %x %x %x\n", IMXRT_FLEXIO1_S.TIMCMP[0], IMXRT_FLEXIO1_S.TIMCMP[1], IMXRT_FLEXIO1_S.TIMCMP[2], IMXRT_FLEXIO1_S.TIMCMP[3]);


  while (Serial.read() == -1) ;
  while (Serial.read() != -1) ;
  delay(1000);
}

With this configuration, I have 2 Flex Serial objects on FLEXIO1 on timers/shifters 1 and 2 (0 and 3 where commented out).
Output was:
Code:
SerialF2 begin
pin 3 maps to: 20000c98, port: 401ac000(FLEXIO1) pin 5
timer index: 1 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 1030502 0 0
SHIFTCFG:0 32 0 0
TIMCTL:0 1c00501 0 0
TIMCFG:0 2222 0 0
TIMCMP:0 f81 0 0
[COLOR="#FF0000"]FI1: 2 2 0 5* 0 0 0[/COLOR]

SerialF3 begin
pin 4 maps to: 20000c98, port: 401ac000(FLEXIO1) pin 6
timer index: 2 shifter index: 2 mask: 4
Before configure flexio[COLOR="#FF0000"][/COLOR]
CCM_CDCDR: 33f71f92
VERID:1010001 PARAM:2100808 CTRL:1 PIN: 0
SHIFTSTAT:0 SHIFTERR=0 TIMSTAT=0
SHIFTSIEN:2 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:0 1030502 2030602 0
SHIFTCFG:0 32 32 0
TIMCTL:0 1c00501 1c00601 0
TIMCFG:0 2222 2222 0
TIMCMP:0 f81 f81 0
[COLOR="#FF0000"]FI1: 4 6 0 6 0 6 0[/COLOR]

SerialF5 begin
pin 6 maps to: 20000ca8, port: 401b0000(FLEXIO2) pin a
timer index: 0 shifter index: 0 mask: 1
Before configure flexio
[COLOR="#FF0000"]FI1: 2 6 0 5 0 6 0[/COLOR]
CCM_CDCDR: 33f71f92
VERID:1010001 PARAM:2200808 CTRL:1 PIN: 0
SHIFTSTAT:1 SHIFTERR=0 TIMSTAT=0
SHIFTSIEN:0 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:30a02 0 0 0
SHIFTCFG:32 0 0 0
TIMCTL:1c00a01 0 0 0
TIMCFG:2222 0 0 0
TIMCMP:f81 0 0 0

SerialF6 begin
pin 18 maps to: 20000cb8, port: 42020000(FLEXIO3) pin 1
timer index: 0 shifter index: 0 mask: 1
Before configure flexio
[COLOR="#FF0000"]FI1: 4 6 0 6 0 6 0[/COLOR]
CCM_CDCDR: 33f71f92
VERID:1010001 PARAM:2200808 CTRL:1 PIN: 0
SHIFTSTAT:1 SHIFTERR=0 TIMSTAT=0
SHIFTSIEN:0 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:30102 0 0 0
SHIFTCFG:32 0 0 0
TIMCTL:1c00101 0 0 0
TIMCFG:2222 0 0 0
TIMCMP:f81 0 0 0

SerialF7 begin
pin 19 maps to: 20000cb8, port: 42020000(FLEXIO3) pin 0
timer index: 1 shifter index: 1 mask: 2
Before configure flexio
CCM_CDCDR: 33f71f92
VERID:1010001 PARAM:2200808 CTRL:1 PIN: 0
SHIFTSTAT:0 SHIFTERR=0 TIMSTAT=0
SHIFTSIEN:1 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:30102 1030002 0 0
SHIFTCFG:32 32 0 0
TIMCTL:1c00101 1c00001 0 0
TIMCFG:2222 2222 0 0
TIMCMP:f81 f81 0 0
[COLOR="#FF0000"]FI1: 4 6 0 6 0 6 0
FI1: 2 6 0 5 0 6 0
FI1: 4 6 0 6 0 6 0
FI1: 2 6 0 5 0 6 0
FI1: 4 6 0 6 0 6 0
FI1: 2 6 0 5 0 6 0
FI1: 4 6 0 6 0 6 0
FI1: 2 6 0 5 0 6 0
FI1: 4 6 0 6 0 6 0
FI1: 2 6 0 5 0 6 0
FI1: 4 6 0 6 0 6 0
FI1: 2 6 0 5 0 6 0
FI1: 4 6 0 6 0 6 0
FI1: 2 6 0 5 0 6 0
FI1: 4 6 0 6 0 6 0
FI1: 2 6 0 5* 0 4 0
FI1: 4 4 0 6* 0 0 0[/COLOR]
[COLOR="#008000"]End Setup[/COLOR]
FI1: 6 2 6 55$6$ 0 2 0
FI1: 4 6 0 6 0 6 0
FI1: 2 6 0 5 0 6 0
FI1: 4 6 0 6 0 6 0
FI1: 2 6 0 5 0 6 0
FI1: 4 6 0 6 0 6 0
FI1: 2 6 0 5 0 6 0
FI1: 4 6 0 6 0 6 0
FI1: 2 6 0 5 0 6 0
FI1: 4 6 0 6 0 6 0
FI1: 2 6 0 5 0 6 0
...
FI1: 2 6 0 5 0 6 0
FI1: 4 6 0 6 0 6 0
FI1: 2 6 0 5 0 6 0
FI1: 4 6 0 6 0 6 0
FI1: 2 6 0 5 0 6 0
FI1: 4 6 0 6 0 6 0
FI1: 2 6 0 5 0 6 0
FI1: 4 6 0 6 0 6 0
FI1: 2 6 0 5* 0 4 0
FI1: 4 4 0 6* 0 0 0
loop 1 time: 6
end F1:6 0 F2:1 0 F3: 1 0
CCM_CDCDR: 33f71f92
VERID:1010001 PARAM:2100808 CTRL:1 PIN: 60
SHIFTSTAT:6 SHIFTERR=6 TIMSTAT=6
SHIFTSIEN:0 SHIFTEIEN=0 TIMIEN=0
SHIFTSDEN:0 SHIFTSTATE=0
SHIFTCTL:0 1030502 2030602 0
SHIFTCFG:0 32 32 0
TIMCTL:0 1c00501 1c00601 0
TIMCFG:0 2222 2222 0
TIMCMP:0 f81 f81 0
Note, the FI1: output shows Error state before and after now as well...
But you really see issues when you look at Logic Analyzer output...
screenshot.jpg
The top line is Serial1, which is fine, next blank one was the one I disabled. But now look at the 3 and 4th line, these are my FlexIO objects on FlexIO1. First issue, why garbage character on 4th line that started up when the 3rd line was starting?

Then if you look at all of the FI1: messages before endSetup, it looks like there are about the right number for the strings I output when I init each object: SerialF2(5)
But then you notice the system keeps outputing an ) character after this on Both of these...

Another issue shows up for the Two objects defined for FlexIO3 (Channels 9 and 10). Notice on 10 the trailing ) is not output. It does output the ) when I startup the next sequence, but agin it won't finish the last character at the end of that sequence either...
 
Quick update: I hacked the above test case to make it a little easier to handle different configurations:
Code:
//============================================================================
// Test to create multiple Flex Serial output objects and see how they
// all interact...
//============================================================================

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

FlexSerial FlexSerials[] = {
//  { -1, 2, -1, 0, 0, 0, 0, 0},
  { -1, 3, -1, 0, 0, 0, 1, 1},
//  { -1, 4, -1, 0, 0, 0, 2, 2},
//  { -1, 5, -1, 0, 0, 0, 3, 3},
  { -1, 6},
  { -1, 18},
  { -1, 19}
};

const uint8_t count_flexSerials = sizeof(FlexSerials) / sizeof(FlexSerials[0]);

Stream *streams[7 + count_flexSerials] = {&Serial1, &Serial2, &Serial3, &Serial4, &Serial5, &Serial6, &Serial7};
const uint8_t count_streams = sizeof(streams) / sizeof(streams[0]);

#define BUFFER_SIZE 75
#define BAUD 115200
uint8_t buffer[BUFFER_SIZE];
uint8_t loop_count = 0;

void outputStr(Stream *pstream, const char *str_buf, uint8_t index) {

  digitalWriteFast(13, HIGH);
  pstream->write(str_buf);
  pstream->print(index,DEC);
  //  pstream->flush();
  digitalWriteFast(13, LOW);

}

void setup() {
  pinMode(13, OUTPUT);
  pinMode(12, OUTPUT);
  while (!Serial && millis() < 4000);
  Serial.begin(115200);
  delay(250);

  // Lets initialize all of the Hardware Serial ports.
  Serial1.begin(BAUD); outputStr(&Serial1, "Serial",1);// 0, 1
  Serial2.begin(BAUD); outputStr(&Serial2, "Serial", 2);// 7, 8
  Serial3.begin(BAUD); outputStr(&Serial3, "Serial", 3);// 15, 14
  Serial4.begin(BAUD); outputStr(&Serial4, "Serial", 4);// 16, 17
  Serial5.begin(BAUD); outputStr(&Serial5, "Serial", 5);// 21, 20
  Serial6.begin(BAUD); outputStr(&Serial6, "Serial", 6);// 25, 24
  Serial7.begin(BAUD); outputStr(&Serial7, "Serial", 7);// 28, 29
  for (uint8_t i = 0; i < count_flexSerials; i++) {
    Serial.println("\nFlexSerial object begin");
    if (!FlexSerials[i].begin(BAUD)) Serial.println("   *** Failed ***\n"); 
    streams[7+i] = &FlexSerials[i];
    outputStr(&FlexSerials[i],"FlexSerial", i);
  }
  delay(500);

  Serial.println("End Setup");
}

uint8_t loop_char = 'a';
void loop() {
  loop_count++;
  // maybe first 10 bytes will bee loop count;
  memset(buffer, loop_count, 10);
  for (uint16_t bi = 10; bi < sizeof(buffer); bi++) buffer[bi] = bi & 0xff;
  digitalWriteFast(13, HIGH);
  uint16_t buffer_indexes[count_streams] = {0};
  uint32_t start_time = millis();
  bool not_done_yet = true;
  while (not_done_yet) {
    digitalWriteFast(12, HIGH);
    not_done_yet = false; // assume we are done.
    for (uint8_t serial_index = 0; serial_index < count_streams; serial_index++) {
      if (buffer_indexes[serial_index] < sizeof(buffer)) {
        uint16_t cbOutput = sizeof(buffer) - buffer_indexes[serial_index];
        uint16_t cbAvailForWrite = streams[serial_index]->availableForWrite();
        if (cbAvailForWrite < cbOutput) {
          cbOutput = cbAvailForWrite;
          not_done_yet = true;
        }
        streams[serial_index]->write(&buffer[buffer_indexes[serial_index]], cbOutput);
        buffer_indexes[serial_index] += cbOutput;
      }
    }
    //delayMicroseconds(10);
    digitalWriteFast(12, LOW);
  }
  // Now lets wait until all of them finish their output
  for (uint8_t serial_index = 0; serial_index < count_streams; serial_index++) {
    streams[serial_index]->flush();
  }
  digitalWriteFast(13, LOW);
  Serial.printf("loop %u time: %u\n", loop_count, millis() - start_time);
  delay(250);
  Serial.printf("end F1:%x %x F2:%x %x F3: %x %x\n", FLEXIO1_SHIFTSTAT, FLEXIO1_SHIFTSIEN,
                FLEXIO2_SHIFTSTAT, FLEXIO2_SHIFTSIEN, FLEXIO3_SHIFTSTAT, FLEXIO3_SHIFTSIEN );
  Serial.printf("CCM_CDCDR: %x\n", CCM_CDCDR);
  Serial.printf("VERID:%x PARAM:%x CTRL:%x PIN: %x\n", IMXRT_FLEXIO1_S.VERID, IMXRT_FLEXIO1_S.PARAM, IMXRT_FLEXIO1_S.CTRL, IMXRT_FLEXIO1_S.PIN);
  Serial.printf("SHIFTSTAT:%x SHIFTERR=%x TIMSTAT=%x\n", IMXRT_FLEXIO1_S.SHIFTSTAT, IMXRT_FLEXIO1_S.SHIFTERR, IMXRT_FLEXIO1_S.TIMSTAT);
  Serial.printf("SHIFTSIEN:%x SHIFTEIEN=%x TIMIEN=%x\n", IMXRT_FLEXIO1_S.SHIFTSIEN, IMXRT_FLEXIO1_S.SHIFTEIEN, IMXRT_FLEXIO1_S.TIMIEN);
  Serial.printf("SHIFTSDEN:%x SHIFTSTATE=%x\n", IMXRT_FLEXIO1_S.SHIFTSDEN, IMXRT_FLEXIO1_S.SHIFTSTATE);
  Serial.printf("SHIFTCTL:%x %x %x %x\n", IMXRT_FLEXIO1_S.SHIFTCTL[0], IMXRT_FLEXIO1_S.SHIFTCTL[1], IMXRT_FLEXIO1_S.SHIFTCTL[2], IMXRT_FLEXIO1_S.SHIFTCTL[3]);
  Serial.printf("SHIFTCFG:%x %x %x %x\n", IMXRT_FLEXIO1_S.SHIFTCFG[0], IMXRT_FLEXIO1_S.SHIFTCFG[1], IMXRT_FLEXIO1_S.SHIFTCFG[2], IMXRT_FLEXIO1_S.SHIFTCFG[3]);
  Serial.printf("TIMCTL:%x %x %x %x\n", IMXRT_FLEXIO1_S.TIMCTL[0], IMXRT_FLEXIO1_S.TIMCTL[1], IMXRT_FLEXIO1_S.TIMCTL[2], IMXRT_FLEXIO1_S.TIMCTL[3]);
  Serial.printf("TIMCFG:%x %x %x %x\n", IMXRT_FLEXIO1_S.TIMCFG[0], IMXRT_FLEXIO1_S.TIMCFG[1], IMXRT_FLEXIO1_S.TIMCFG[2], IMXRT_FLEXIO1_S.TIMCFG[3]);
  Serial.printf("TIMCMP:%x %x %x %x\n", IMXRT_FLEXIO1_S.TIMCMP[0], IMXRT_FLEXIO1_S.TIMCMP[1], IMXRT_FLEXIO1_S.TIMCMP[2], IMXRT_FLEXIO1_S.TIMCMP[3]);


  while (Serial.read() == -1) ;
  while (Serial.read() != -1) ;
  delay(1000);
}
So just an array of FlexSerial objects with constructor parameters... so just comment out the ones not wanted and it loops through these adds them onto list of streams (could be cleaner)...
The version I put up here only left one object on FlexIO1 and it is still screwing up continuously output the last character... In this case a 0... (index number)...

Wonder if this is a case to ask up on NXP?
 
Just starting to play with this now - have to go through it somewhat. The last character is getting me. This is just me walking through and then for debugging - it Tx's the right characters until the it hits the last one then when the buffer is finished supposedly it keeps transmitting. Not getting a stop tx'ing or the buffer count is off so it keeps going,,,,,,

Maybe it is a question for NXP - I have asked and got some interesting responses.

EDIT:
Just tried making a change and now its hanging the T4, i.e, shows serial port off line

EDIT2: something weird with the IDE - had to close out the ide and restart it and then got the t4 back on line....
 
Last edited:
@KurtE
Now that I am up and running again and looking at the output I am getting confused on the pin mapping. If I am reading this right you are using pins 6, 18 and 19?
On the output I am seeing:
Code:
pin 3 maps to: 20000b8c, port: 401ac000(FLEXIO1) pin 5
timer index: 1 shifter index: 1 mask: 2
…..
pin 6 maps to: 20000b9c, port: 401b0000(FLEXIO2) pin a [COLOR="#FF0000"] <--- is this mean pin 10?[/COLOR]
timer index: 0 shifter index: 0 mask: 1
,,,,
pin 18 maps to: 20000bac, port: 42020000(FLEXIO3) pin 1 
timer index: 0 shifter index: 0 mask: 1
.....
pin 19 maps to: 20000bac, port: 42020000(FLEXIO3) pin 0
timer index: 1 shifter index: 1 mask: 2
to me pins 18 and 19 kind of makes sense.
 
Ooops - looks like I did hit the post while I was hacking away...
Yep pin a (was output in hex) so yep 10... And looking at Excel document it shows pin 6 as flexIO 2:10
Code:
		Serial.printf("pin %d maps to: %x, port: %x", _txPin, (uint32_t)_tx_pflex, (uint32_t)p);
		if (p == &IMXRT_FLEXIO1_S) Serial.print("(FLEXIO1)");
		else if (p == &IMXRT_FLEXIO2_S) Serial.print("(FLEXIO2)");
		else if (p == &IMXRT_FLEXIO3_S) Serial.print("(FLEXIO3)");
		Serial.printf(" pin %x\n", _tx_flex_pin);  Serial.flush();

Sorry about that, maybe should change %x to %u

I am thinking that this code may be too intertwined to ask up on NXP?
Thinking making a simple test case with just one object where I define pin, FlexIO object, timer, and shifter and maybe one Hardware Serial port.

Here is a simple test case:
Code:
//============================================================================
// 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 1
#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);


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");
  SerialFlex.println("Enter something to have it echo");
}


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

}

void serialEvent1() {
  int ch;
  while ((ch = Serial1.read()) != -1) {
    Serial.write(ch);
  }
}
Slightly modified version of example sketch, where I echo anything typed in... And I allow you to specify more explicit configuration data.
The normal is to set TIMER above to 0 as well.

Which works fine. This works fine as well with Timer=1 and shifter = 0
If I try the other way Timer 0 shifter 1 it hangs totally.
If I try T=1, S=1
Then it gets into that strange state where it continuously outputs the last data...

Wonder if that is simple enough to post on NXP?
 
@KurtE
Have a question for you on how FlexIO works. Using T=0 and S=1. I will see what I guess you would expect jumping pin 3 to pin 0:
Code:
pin 3 maps to: 20000b30, 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
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
and if I type "hi" I get
Code:
FI1: 1 1 0 5* 0 0 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5* 0 0 0
hi
but at the same time if I hook up pin 5 to pin 0:
Code:
pin 3 maps to: 20000b30, 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
FI1: 1 1 0 5* 0 0 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5* 0 0 0
and if type "hi"
Code:
FI1: 1 1 0 5* 0 0 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5 0 1 0
FI1: 1 1 0 5* 0 0 0
I see the packet but no echo from pin 5 to pin 0 -> probably transmitting from pin 3. So does this mean I am transminting on pins 3 and 5? Guess I need to read the manual again.
 
Here is part 2. If I try T=1 and S=0 on pin 5 and sending HI
Code:
pin 3 maps to: 20000b30, 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 5* 0 0 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5* 0 0 0
FI1: 2 2 2 5*5$ 0 0 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5 0 2 0
FI1: 2 2 0 5* 0 0 0
and yes it hangs with that infinite loop on the last character and I see the same output as above on pin 5 but I can't use SM to type "hi". But it do see the LED come on when I type hi from pin 5. Probably should be doing this with a second Teensy to read pins 3 and 5

Hope this makes sense.
 
Hi @mjs513 - I hacked up my sketch to not endlessly output the last character screwing up the Terminal Monitor:
Code:
//============================================================================
// 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 1
#define TX_FLEX_IO_SHIFTER 1
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--;
    }
  }
}

Sorry about some of my less than clear debug messages.
Messages like: FI1: 2 2 0 5* 0 0 0
The 5 is the FlexIO pin (Not the Teensy pin)...
So Arduino pin 3 is FlexIO pin 1:5 in my excel document.

Maybe should change the debug output line(340): if (p == &IMXRT_FLEXIO1_S) Serial.print(_tx_flex_pin, DEC);
TO instead maybe output _txPin which would be the Arduino pin instead.

Also thinking about maybe adding to the debug data the value being stored out so maybe like 2 2 0 5(H) 0 0 0
Where in () if printable than char else Hex? But not sure if that is too much data?
 
KurtE said:
Also thinking about maybe adding to the debug data the value being stored out so maybe like 2 2 0 5(H) 0 0 0
Where in () if printable than char else Hex? But not sure if that is too much data?
Not for me - usually helps more with the debugging.

Sorry about some of my less than clear debug messages.
Messages like: FI1: 2 2 0 5* 0 0 0
The 5 is the FlexIO pin (Not the Teensy pin)...
So Arduino pin 3 is FlexIO pin 1:5 in my excel document.
Yeah - DELEETED my error -------------- Like I said - have to read or at least skim FlexIO chapter of the manual.

I hacked up my sketch to not endlessly output the last character screwing up the Terminal Monitor:
Thanks much appreciated :)
 
Last edited:
Hi @mjs513 - Updated Github with the debug output changes.
Decimal FlexIO pin number in early summary info.

Also outputs now the Teensy Pin number instead of FlexIO pin number in callback and I output the char in () in call back. Single char if in range ' '-'~' else two character hex....

I also added the two test programs we have been playing with as examples...

Tomorrow, if I don't figure out anything else will post this info over to NXP community and see if anyone has ideas.
 
Evening @KurtE
Thanks - just updated the lib. Started looking though the manual and the flex-uart example from the SDK for starts - then tomorrow will play more.

I did put a scope on pin 3 of the T4 for the case of T=1, S=1. I do see a continuous stream of a group of 3 pulses. But is I send as bunch of characters I see superimposed over the base signal of that continuous character you are getting. So its working but for that continuous character.....
 
Good Morning @mjs513 -

I have now posted a semi verbose question up on the NXP forum... Assuming it gets approved by the Moderator...
Will be interesting to see if I get any suggestions...

Will trying again soon. May do other diversions first

Edit: I am not sure if visible, but:
https://community.nxp.com/message/1228929
 
Morning @KurtE
Been playing the lib most of the morning. Reading = checking - trying and just can't see why it continues to send. Unless when you test for head = tail in the write you have to zero out the buffer so it thinks the buffer size is 0? But when I put some more debug prints in doesn't look like that's where it coming the problem is.
 
@mjs513 - I also assumed it was a bug like you mentioned, except the only place I stuff something into the shift buffer is in that function which does Serial prints, which are not happening...

As I mentioned it will be interesting to see if someone looks at the settings I have for the registers and goes... Oh you can't set bit X in this register, or hopefully something like that....

And not something like, there is bug in the system and it only works properly with shifter 0...
 
Back
Top