Making the FlexIO_t4 library more Teensy 4.x board independent.


Senior Member+
With the currently released version of this library. Each time PJRC releases support for another Teensy 4.x
board, the tables within this library (like many others) needed to be updated.

This also has issue if someone wishes to make a custom Teensy board.
With the Devboard4 setup, I built my own variant, which added the new pins to the pin table, which works
for some of the functionality but not all.

I have a version of the library that allowed a variant to overwrite the tables by making the tables have weak attributes.
Which worked, but it is still a pain.

So I decided to make a version of the library that instead of has tables built with teensy pin numbers mapping to which
flex io pin. It instead maps from a IMXRT pin mux register address to FlexIO pin.

That is for FlexIO1, I have the table:
// FlexIO1
static  const FLEXIO_t4_Pins_t flexio_t4_pins_flexio1[] PROGMEM = {
    {nullptr, 0}

And so instead of simply walking the old list looking for Teensy pin numbers, I simply retrieve the
pin_mux pointer from the Teensy pin table and then match for it...

uint8_t FlexIOHandler::mapIOPinToFlexPin(uint8_t pin)
    // Map the pin to its port config register which we will use to
    // look it up in the table of pins
    if (pin >= CORE_NUM_DIGITAL) return 0xff; // pin is out of range.

    volatile uint32_t *pin_mux = portConfigRegister(pin);

      // Now lets walk through all of the pins associated with this object.
    const FLEXIO_t4_Pins_t *pin_list = pins();

    for (uint8_t i = 0; i < 32; i++ ) {
        if (pin_list[i].mux == nullptr) break; // short liset (flexio1)
          if (pin_list[i].mux == pin_mux) {
#ifdef DEBUG_FlexIO
            Serial.println("Enable flexio clock");
            hardware().clock_gate_register |= hardware().clock_gate_mask;

            return pin_list[i].flex_pin;
    return 0xff;

Which in my first test of it appears to still be working. That is I can still read an HM0360 camera using flexio on a Micromod teensy

This code is currently pushed up in a new branch:

I need to do some more testing, before I hopefully migrate this back into my main branch.

If anyone else wishes to test it out, that would be great.

@KurtE this is great!I guess this won't affect current implementations of mapIOPinToFlexPin(uint8_t pin)?
I'll be happy to have a go at it when I get a new ILI9488 display in (current 9486 is dead)
The only thing it changes is how it does the map...
Also I started from version where I removed the pin information from the hardware structure to a pin info structure...
I could have done either way and made the pin info setup for 32 entries...

Where for example the Teensy 4.1 pin table for FlexIO 1
extern const FLEXIO_t4_Pins_t flexio_t4_pins_flexio2[]  __attribute__((weak))= {
    {6, 10, 0x14}, {7, 17, 0x14}, {8, 16, 0x14}, {9, 11, 0x14}, {10, 0, 0x14}, {11, 2, 0x14}, {12, 1, 0x14}, {13, 3, 0x14}, {32, 12, 0x14},
    {34, 29, 0x14}, {35, 28, 0x14}, {36, 18, 0x14}, {37, 19, 0x14}

Where before it looped on this table looking for the pin number, which is the first entry in each tuple.
As I mentioned I simply mapped the pin to the IOMUXC mux register for each of the pins... and do similar

Note: I removed the last item from each of the tuples (which is the value to set the mux register to, and moved it to the hardware
table for it, as it is constant for all of the pins of each FlexIO.

Wish list: I wish that we could simply pass in the pin names, like instead of: IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_0
you could pass in: GPIO_EMC_0. Obviously I could create a macro for building the tables,
But will probably also add in something like: mapIOPinToFlexPin(IOMUXC_SW_MUX_CTL_PAD_GPIO_EMC_0) which would work
as well. I will probably add these as well. Note: the current method would simply map the pin and call the other...

Which for example some Arduino boards like the GIGA allow you to do. For example, you can do:
pinMode(2, OUTPUT);
likewise you could do the same thing: pinMode(PA3, OUTPUT);
Which is the Pin name (Port A pin 3)
These are the same pin names I believe you can use if you decide to use MicroPython.

Now back to playing