/***************************************************************************
 *   Copyright (C) 2025 by Santiago González                               *
 *                                                                         *
 ***( see copyright.txt file at root folder )*******************************/

#include <QDebug>
#include <QPainter>
#include <QFile>
#include <QFileInfo>
#include <QDir>

#include "esp32.h"
#include "itemlibrary.h"
#include "circuit.h"
#include "esp32gpio.h"
#include "esp32iomux.h"
#include "esp32twi.h"
#include "esp32spi.h"
#include "esp32usart.h"
#include "esp32led.h"
#include "esp32pin.h"
#include "utils.h"

#define tr(str) simulideTr("Esp32",str)

#define IOMEM_BASE 0x3FF00000
#define IOMEM_END  0x3FF7FFFF
#define IOMEM_SIZE IOMEM_END-IOMEM_BASE

Esp32::Esp32( QString type, QString id, QString device )
     : QemuDevice( type, id )
{
    m_area = QRect( 0, 0, 15*8, 15*8 );
    m_color = QColor( 50, 50, 70 );

    m_executable = "./data/bin/qemu-system-xtensa";
    m_firmware   = "";

    m_ioMem.resize( IOMEM_SIZE, 0 );
    m_ioMemStart = IOMEM_BASE;

    m_gpio  = new Esp32Gpio(  this, id+"-GPIO" , 0, &m_apbFreq, 0x00044000, 0x00044FFF );
    m_iomux = new Esp32IoMux( this, id+"-IOMUX", 0, &m_apbFreq, 0x00049000, 0x00049FFF );
    m_iomux->setGpio( m_gpio );

    setPackageFile("./data/esp32/esp32.package");
    Chip::setName( m_device );

    Esp32Pin* dummyP = m_gpio->m_dummyPin;
    m_i2cN = 2;
    m_i2cs.resize( m_i2cN );
    m_i2cs[0] = new Esp32Twi( this, id+"-I2C1", 0, &m_apbFreq, 0x00053000, 0x00053FFF );
    m_i2cs[1] = new Esp32Twi( this, id+"-I2C2", 1, &m_apbFreq, 0x00067000, 0x00067FFF );
    for( int i=0; i<m_i2cN; ++i ) m_i2cs[i]->setPins( dummyP, dummyP );

    m_spiN = 2;
    m_spis.resize( m_spiN );
    //m_spis[0] = new Esp32Spi( this, id+"-SPI1", 0, &m_apbFreq, 0x00043000, 0x00043FFF );
    //m_spis[1] = new Esp32Spi( this, id+"-SPI2", 1, &m_apbFreq, 0x00042000, 0x00042FFF );
    m_spis[0] = new Esp32Spi( this, id+"-HSPI", 2, &m_apbFreq, 0x00064000, 0x00064FFF );
    m_spis[1] = new Esp32Spi( this, id+"-VSPI", 3, &m_apbFreq, 0x00065000, 0x00065FFF );
    for( int i=0; i<m_spiN; ++i ) m_spis[i]->setPins( dummyP, dummyP, dummyP, dummyP );

    m_usartN = 3;
    m_usarts.resize( m_usartN );
    m_usarts[0] = new Esp32Usart( this, id+"Usart1", 0, &m_apbFreq, 0x00040000, 0x00040FFF );
    m_usarts[1] = new Esp32Usart( this, id+"Usart2", 1, &m_apbFreq, 0x00050000, 0x00050FFF );
    m_usarts[2] = new Esp32Usart( this, id+"Usart3", 2, &m_apbFreq, 0x0006E000, 0x0006EFFF );
    for( int i=0; i<m_usartN; ++i ) m_usarts[i]->setPins({ dummyP, dummyP});

    m_leds = new Esp32Led( this, id+"Leds", 0, &m_apbFreq, 0x00059000, 0x00059FFF );
    m_leds->setDummy( dummyP );

    m_dummyModule = new QemuModule( this, "UnMapped", 0, nullptr, 0, IOMEM_SIZE );

    createMatrix();
    m_gpio->createIoMux();
}
Esp32::~Esp32(){}

bool Esp32::createArgs()
{
    QFileInfo fi = QFileInfo( m_firmPath );

    if( fi.size() != 4194304 )
    {
        qDebug() << "Error firmware file size:" << fi.size() << "must be 4194304";
        qDebug() << m_firmPath;
        return false;
    }

    int index = m_firmPath.lastIndexOf(".");
    QString firmware = m_firmPath.left( index );
    QString efuses = firmware+".efuse";

    if( !QFileInfo::exists( efuses ) )
        efuses = "./data/bin/esp32/esp32.efuse";

    m_arguments.clear();

    m_arguments << m_shMemKey;          // Shared Memory key

    m_arguments << "qemu-system-xtensa";

    //m_arguments << "-d";
    //m_arguments << "in_asm";

    m_arguments << "-M";
    m_arguments << "esp32-simul";

    m_arguments << "-L";    /// TODO: embed files in Simulide
    m_arguments << "./data/bin/esp32/rom/bin";

    m_arguments << "-drive";
    m_arguments << "file="+firmware+".bin,if=mtd,format=raw";

    m_arguments << "-drive";
    m_arguments << "file="+efuses+",if=none,format=raw,id=efuse";

    m_arguments << "-global";
    m_arguments << "driver=nvram.esp32.efuse,property=drive,value=efuse";

    m_arguments << "-nic";
    m_arguments << "user,model=esp32_wifi,id=u1,net=192.168.4.0/24";

    m_arguments << "-global";
    m_arguments << "driver=timer.esp32.timg,property=wdt_disable,value=true";

    m_arguments << "-icount";
    m_arguments <<"shift=4,align=off,sleep=off";

    //m_arguments << "-kernel";  // Does not work
    //m_arguments <<  firmware+".elf" ;

    /*m_arguments << "-gdb");
    sprintf( m_argv[m_argc++], "tcp::%i", 1234 );*/

    //m_arguments << "-rtc";
    //m_arguments << "clock=vm";

    return true;
}

void Esp32::stamp()
{
    m_cpuFreq = 40000000; // 40 MHz ?????
    m_apbFreq = 40000000;
    QemuDevice::stamp();
}

Pin* Esp32::addPin( QString id, QString type, QString label,
                   int n, int x, int y, int angle, int length, int space )
{
    IoPin* pin = nullptr;

    if( type.contains("rst") )
    {
        pin = new IoPin( angle, QPoint(x, y), m_id+"-"+id, n-1, this, input );
        m_rstPin = pin;
        m_rstPin->setOutHighV( 3.3 );
        m_rstPin->setPullup( 1e5 );
        m_rstPin->setInputHighV( 0.65 );
        m_rstPin->setInputLowV( 0.65 );
    }else{
        n = id.right(2).toInt();
        pin = m_gpio->createPin( n, id, this );
    }
    //qDebug() << n << id << label << type;
    //QColor color = Qt::black;
    //if( !m_isLS ) color = QColor( 250, 250, 200 );

    pin->setPos( x, y );
    pin->setPinAngle( angle );
    pin->setLength( length );
    pin->setSpace( space );
    pin->setLabelText( label );
    //pin->setLabelColor( color );
    pin->setFlag( QGraphicsItem::ItemStacksBehindParent, true );
    return pin;
}

void Esp32::updtFrequency()
{
    if( m_cpuFreq == m_arena->regData
     && m_apbFreq == m_arena->regAddr ) return;

    m_cpuFreq = m_arena->regData;
    m_apbFreq = m_arena->regAddr;

    for( QemuModule* module : m_modules ) module->freqChanged();

    qDebug() << "Esp32::updtFrequency CPU:"<< m_cpuFreq/1000000 <<"MHz,  APB:"<< m_apbFreq/1000000 << "MHz";
}

void Esp32::createMatrix()
{
    // IN
    m_gpio->m_matrixIn[0]   = { nullptr, nullptr, "Ck0" }; // SPICLK
    m_gpio->m_matrixIn[1]   = { nullptr, nullptr, "Mi0" }; // SPIQ
    m_gpio->m_matrixIn[2]   = { nullptr, nullptr, "Mo0" }; // SPID

    m_gpio->m_matrixIn[3]   = { nullptr, nullptr, "HD0" }; // SPIHD
    m_gpio->m_matrixIn[4]   = { nullptr, nullptr, "WP0" }; // SPIWP

    m_gpio->m_matrixIn[5]   = { nullptr, nullptr, "Ss0" }; // SPICS0

    m_gpio->m_matrixIn[6]   = { nullptr, nullptr, "SPICS1" }; // SPICS1
    m_gpio->m_matrixIn[7]   = { nullptr, nullptr, "SPICS2" }; // SPICS2

    m_gpio->m_matrixIn[8]   = { m_spis[0], m_spis[0]->getCkPinPtr(), "CkH" }; // HSPICLK
    m_gpio->m_matrixIn[9]   = { m_spis[0], m_spis[0]->getMiPinPtr(), "MiH" }; // HSPIQ
    m_gpio->m_matrixIn[10]  = { m_spis[0], m_spis[0]->getMoPinPtr(), "MoH" }; // HSPID
    m_gpio->m_matrixIn[11]  = { m_spis[0], m_spis[0]->getSsPinPtr(), "SsH" }; // HSPICS0

    m_gpio->m_matrixIn[12]  = { nullptr, nullptr, "HdH" }; // HSPIHD
    m_gpio->m_matrixIn[13]  = { nullptr, nullptr, "WpH" }; // HSPIWP

    m_gpio->m_matrixIn[14]  = { m_usarts[0], m_usarts[0]->getRxPinPtr(), "Rx0" }; // U0RXD

    m_gpio->m_matrixIn[15]  = { nullptr, nullptr, "U0CTS" }; // U0CTS
    m_gpio->m_matrixIn[16]  = { nullptr, nullptr, "U0DSR" }; // U0DSR

    m_gpio->m_matrixIn[17]  = { m_usarts[1], m_usarts[1]->getRxPinPtr(), "Rx1" }; // U1RXD

    m_gpio->m_matrixIn[18]  = { nullptr, nullptr, "U1CTS" }; // U1CTS
    m_gpio->m_matrixIn[19]  = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[20]  = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[21]  = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[22]  = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[23]  = { nullptr, nullptr, "I2S0O_BCK" }; // I2S0O_BCK
    m_gpio->m_matrixIn[24]  = { nullptr, nullptr, "I2S1O_BCK" }; // I2S1O_BCK
    m_gpio->m_matrixIn[25]  = { nullptr, nullptr, "I2S0O_WS"  }; // I2S0O_WS
    m_gpio->m_matrixIn[26]  = { nullptr, nullptr, "I2S1O_WS"  }; // I2S1O_WS
    m_gpio->m_matrixIn[27]  = { nullptr, nullptr, "I2S0I_BCK" }; // I2S0I_BCK
    m_gpio->m_matrixIn[28]  = { nullptr, nullptr, "I2S0I_WS"  }; // I2S0I_WS

    m_gpio->m_matrixIn[29]  = { m_i2cs[0], m_i2cs[0]->getSclPinPtr(), "Scl0"}; // I2CEXT0_SCL
    m_gpio->m_matrixIn[30]  = { m_i2cs[0], m_i2cs[0]->getSdaPinPtr(), "Sda0"}; // I2CEXT0_SDA

    m_gpio->m_matrixIn[31]  = { nullptr, nullptr, "PWM0_SYNC0" }; // PWM0_SYNC0
    m_gpio->m_matrixIn[32]  = { nullptr, nullptr, "PWM0_SYNC1" }; // PWM0_SYNC1
    m_gpio->m_matrixIn[33]  = { nullptr, nullptr, "PWM0_SYNC2" }; // PWM0_SYNC2
    m_gpio->m_matrixIn[34]  = { nullptr, nullptr, "PWM0_F0" }; // PWM0_F0
    m_gpio->m_matrixIn[35]  = { nullptr, nullptr, "PWM0_F1" }; // PWM0_F1
    m_gpio->m_matrixIn[36]  = { nullptr, nullptr, "PWM0_F2" }; // PWM0_F2
    m_gpio->m_matrixIn[37]  = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[38]  = { nullptr, nullptr, "GPIO_BT_PRIORITY" }; // GPIO_BT_PRIORITY
    m_gpio->m_matrixIn[39]  = { nullptr, nullptr, "PCNT_SIG_CH0_IN0" }; // PCNT_SIG_CH0_IN0
    m_gpio->m_matrixIn[40]  = { nullptr, nullptr, "PCNT_SIG_CH1_IN0" }; // PCNT_SIG_CH1_IN0
    m_gpio->m_matrixIn[41]  = { nullptr, nullptr, "PCNT_CTRL_CH0_IN0"}; // PCNT_CTRL_CH0_IN0
    m_gpio->m_matrixIn[42]  = { nullptr, nullptr, "PCNT_CTRL_CH1_IN0"}; // PCNT_CTRL_CH1_IN0
    m_gpio->m_matrixIn[43]  = { nullptr, nullptr, "PCNT_SIG_CH0_IN1" }; // PCNT_SIG_CH0_IN1
    m_gpio->m_matrixIn[44]  = { nullptr, nullptr, "PCNT_SIG_CH1_IN1" }; // PCNT_SIG_CH1_IN1
    m_gpio->m_matrixIn[45]  = { nullptr, nullptr, "PCNT_CTRL_CH0_IN1"}; // PCNT_CTRL_CH0_IN1
    m_gpio->m_matrixIn[46]  = { nullptr, nullptr, "PCNT_CTRL_CH1_IN1"}; // PCNT_CTRL_CH1_IN1
    m_gpio->m_matrixIn[47]  = { nullptr, nullptr, "PCNT_SIG_CH0_IN2" }; // PCNT_SIG_CH0_IN2
    m_gpio->m_matrixIn[48]  = { nullptr, nullptr, "PCNT_SIG_CH1_IN2" }; // PCNT_SIG_CH1_IN2
    m_gpio->m_matrixIn[49]  = { nullptr, nullptr, "PCNT_CTRL_CH0_IN2"}; // PCNT_CTRL_CH0_IN2
    m_gpio->m_matrixIn[50]  = { nullptr, nullptr, "PCNT_CTRL_CH1_IN2"}; // PCNT_CTRL_CH1_IN2
    m_gpio->m_matrixIn[51]  = { nullptr, nullptr, "PCNT_SIG_CH0_IN3" }; // PCNT_SIG_CH0_IN3
    m_gpio->m_matrixIn[52]  = { nullptr, nullptr, "PCNT_SIG_CH1_IN3" }; // PCNT_SIG_CH1_IN3
    m_gpio->m_matrixIn[53]  = { nullptr, nullptr, "PCNT_CTRL_CH0_IN3"}; // PCNT_CTRL_CH0_IN3
    m_gpio->m_matrixIn[54]  = { nullptr, nullptr, "PCNT_CTRL_CH1_IN3"}; // PCNT_CTRL_CH1_IN3
    m_gpio->m_matrixIn[55]  = { nullptr, nullptr, "PCNT_SIG_CH0_IN4" }; // PCNT_SIG_CH0_IN4
    m_gpio->m_matrixIn[56]  = { nullptr, nullptr, "PCNT_SIG_CH1_IN4" }; // PCNT_SIG_CH1_IN4
    m_gpio->m_matrixIn[57]  = { nullptr, nullptr, "PCNT_CTRL_CH0_IN4"}; // PCNT_CTRL_CH0_IN4
    m_gpio->m_matrixIn[58]  = { nullptr, nullptr, "PCNT_CTRL_CH1_IN4"}; // PCNT_CTRL_CH1_IN4
    m_gpio->m_matrixIn[59]  = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[60]  = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[61]  = { nullptr, nullptr, "Cs1H" }; // HSPICS1
    m_gpio->m_matrixIn[62]  = { nullptr, nullptr, "Cs2H" }; // HSPICS2
    m_gpio->m_matrixIn[63]  = { m_spis[1], m_spis[1]->getCkPinPtr(), "CkV" }; // VSPICLK
    m_gpio->m_matrixIn[64]  = { m_spis[1], m_spis[1]->getMiPinPtr(), "MiV" }; // VSPIQ
    m_gpio->m_matrixIn[65]  = { m_spis[1], m_spis[1]->getMoPinPtr(), "MoV" }; // VSPID
    m_gpio->m_matrixIn[66]  = { nullptr, nullptr, "HdV"  }; // VSPIHD
    m_gpio->m_matrixIn[67]  = { nullptr, nullptr, "WpV"  }; // VSPIWP
    m_gpio->m_matrixIn[68]  = { m_spis[1], m_spis[1]->getSsPinPtr(), "SsV" }; // VSPICS0
    m_gpio->m_matrixIn[69]  = { nullptr, nullptr, "Cs1V" }; // VSPICS1
    m_gpio->m_matrixIn[70]  = { nullptr, nullptr, "Cs2V" }; // VSPICS2
    m_gpio->m_matrixIn[71]  = { nullptr, nullptr, "PCNT_SIG_CH0_5" }; // PCNT_SIG_CH0_IN5
    m_gpio->m_matrixIn[72]  = { nullptr, nullptr, "PCNT_SIG_CH1_5" }; // PCNT_SIG_CH1_IN5
    m_gpio->m_matrixIn[73]  = { nullptr, nullptr, "PCNT_CTRL_CH0_5"}; // PCNT_CTRL_CH0_IN5
    m_gpio->m_matrixIn[74]  = { nullptr, nullptr, "PCNT_CTRL_CH1_5"}; // PCNT_CTRL_CH1_IN5
    m_gpio->m_matrixIn[75]  = { nullptr, nullptr, "PCNT_SIG_CH0_6" }; // PCNT_SIG_CH0_IN6
    m_gpio->m_matrixIn[76]  = { nullptr, nullptr, "PCNT_SIG_CH1_6" }; // PCNT_SIG_CH1_IN6
    m_gpio->m_matrixIn[77]  = { nullptr, nullptr, "PCNT_CTRL_CH0_6"}; // PCNT_CTRL_CH0_IN6
    m_gpio->m_matrixIn[78]  = { nullptr, nullptr, "PCNT_CTRL_CH1_6"}; // PCNT_CTRL_CH1_IN6
    m_gpio->m_matrixIn[79]  = { nullptr, nullptr, "PCNT_SIG_CH0_7" }; // PCNT_SIG_CH0_IN7
    m_gpio->m_matrixIn[80]  = { nullptr, nullptr, "PCNT_SIG_CH1_7" }; // PCNT_SIG_CH1_IN7
    m_gpio->m_matrixIn[81]  = { nullptr, nullptr, "PCNT_CTRL_CH0_7"}; // PCNT_CTRL_CH0_IN7
    m_gpio->m_matrixIn[82]  = { nullptr, nullptr, "PCNT_CTRL_CH1_7"}; // PCNT_CTRL_CH1_IN7
    m_gpio->m_matrixIn[83]  = { nullptr, nullptr, "RMT_0" }; // RMT_SIG_IN0
    m_gpio->m_matrixIn[84]  = { nullptr, nullptr, "RMT_1" }; // RMT_SIG_IN1
    m_gpio->m_matrixIn[85]  = { nullptr, nullptr, "RMT_2" }; // RMT_SIG_IN2
    m_gpio->m_matrixIn[86]  = { nullptr, nullptr, "RMT_3" }; // RMT_SIG_IN3
    m_gpio->m_matrixIn[87]  = { nullptr, nullptr, "RMT_4" }; // RMT_SIG_IN4
    m_gpio->m_matrixIn[88]  = { nullptr, nullptr, "RMT_5" }; // RMT_SIG_IN5
    m_gpio->m_matrixIn[89]  = { nullptr, nullptr, "RMT_6" }; // RMT_SIG_IN6
    m_gpio->m_matrixIn[90]  = { nullptr, nullptr, "RMT_7" }; // RMT_SIG_IN7
    m_gpio->m_matrixIn[91]  = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[92]  = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[93]  = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[94]  = { nullptr, nullptr, "TWAI_RX" }; // TWAI_RX

    m_gpio->m_matrixIn[95]  = { m_i2cs[1], m_i2cs[1]->getSclPinPtr(), "Scl1"}; // I2CEXT1_SCL
    m_gpio->m_matrixIn[96]  = { m_i2cs[1], m_i2cs[1]->getSdaPinPtr(), "Sda1"}; // I2CEXT1_SDA

    m_gpio->m_matrixIn[97]  = { nullptr, nullptr, "HOST_CARD_DETECT_N_1" }; // HOST_CARD_DETECT_N_1
    m_gpio->m_matrixIn[98]  = { nullptr, nullptr, "HOST_CARD_DETECT_N_2" }; // HOST_CARD_DETECT_N_2
    m_gpio->m_matrixIn[99]  = { nullptr, nullptr, "HOST_CARD_WRITE_PRT_1"}; // HOST_CARD_WRITE_PRT_1
    m_gpio->m_matrixIn[100] = { nullptr, nullptr, "HOST_CARD_WRITE_PRT_2"}; // HOST_CARD_WRITE_PRT_2
    m_gpio->m_matrixIn[101] = { nullptr, nullptr, "HOST_CARD_INT_N_1" }; // HOST_CARD_INT_N_1
    m_gpio->m_matrixIn[102] = { nullptr, nullptr, "HOST_CARD_INT_N_2" }; // HOST_CARD_INT_N_2
    m_gpio->m_matrixIn[103] = { nullptr, nullptr, "PWM1_SYNC0" }; // PWM1_SYNC0_IN
    m_gpio->m_matrixIn[104] = { nullptr, nullptr, "PWM1_SYNC1" }; // PWM1_SYNC1_IN
    m_gpio->m_matrixIn[105] = { nullptr, nullptr, "PWM1_SYNC2" }; // PWM1_SYNC2_IN
    m_gpio->m_matrixIn[106] = { nullptr, nullptr, "PWM1_F0" }; // PWM1_F0_IN
    m_gpio->m_matrixIn[107] = { nullptr, nullptr, "PWM1_F1" }; // PWM1_F1_IN
    m_gpio->m_matrixIn[108] = { nullptr, nullptr, "PWM1_F2" }; // PWM1_F2_IN
    m_gpio->m_matrixIn[109] = { nullptr, nullptr, "PWM0_CAP0" }; // PWM0_CAP0_IN
    m_gpio->m_matrixIn[110] = { nullptr, nullptr, "PWM0_CAP1" }; // PWM0_CAP1_IN
    m_gpio->m_matrixIn[111] = { nullptr, nullptr, "PWM0_CAP2" }; // PWM0_CAP2_IN
    m_gpio->m_matrixIn[112] = { nullptr, nullptr, "PWM1_CAP0" }; // PWM1_CAP0_IN
    m_gpio->m_matrixIn[113] = { nullptr, nullptr, "PWM1_CAP1" }; // PWM1_CAP1_IN
    m_gpio->m_matrixIn[114] = { nullptr, nullptr, "PWM1_CAP2" }; // PWM1_CAP2_IN
    m_gpio->m_matrixIn[115] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[116] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[117] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[118] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[119] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[120] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[121] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[122] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[123] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[124] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[125] = { nullptr, nullptr, "---" }; // (not assigned)

    m_gpio->m_matrixIn[126] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[127] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[128] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[129] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[130] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[131] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[132] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[133] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[134] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[135] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[136] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[137] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[138] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[139] = { nullptr, nullptr, "---" }; // (not assigned)

    m_gpio->m_matrixIn[140] = { nullptr, nullptr, "I2S0I_D0" }; // I2S0I_DATA_IN0
    m_gpio->m_matrixIn[141] = { nullptr, nullptr, "I2S0I_D1" }; // I2S0I_DATA_IN1
    m_gpio->m_matrixIn[142] = { nullptr, nullptr, "I2S0I_D2" }; // I2S0I_DATA_IN2
    m_gpio->m_matrixIn[143] = { nullptr, nullptr, "I2S0I_D3" }; // I2S0I_DATA_IN3
    m_gpio->m_matrixIn[144] = { nullptr, nullptr, "I2S0I_D4" }; // I2S0I_DATA_IN4
    m_gpio->m_matrixIn[145] = { nullptr, nullptr, "I2S0I_D5" }; // I2S0I_DATA_IN5
    m_gpio->m_matrixIn[146] = { nullptr, nullptr, "I2S0I_D6" }; // I2S0I_DATA_IN6
    m_gpio->m_matrixIn[147] = { nullptr, nullptr, "I2S0I_D7" }; // I2S0I_DATA_IN7
    m_gpio->m_matrixIn[148] = { nullptr, nullptr, "I2S0I_D8" }; // I2S0I_DATA_IN8
    m_gpio->m_matrixIn[149] = { nullptr, nullptr, "I2S0I_D9" }; // I2S0I_DATA_IN9
    m_gpio->m_matrixIn[150] = { nullptr, nullptr, "I2S0I_D10"}; // I2S0I_DATA_IN10
    m_gpio->m_matrixIn[151] = { nullptr, nullptr, "I2S0I_D11"}; // I2S0I_DATA_IN11
    m_gpio->m_matrixIn[152] = { nullptr, nullptr, "I2S0I_D12"}; // I2S0I_DATA_IN12
    m_gpio->m_matrixIn[153] = { nullptr, nullptr, "I2S0I_D13"}; // I2S0I_DATA_IN13
    m_gpio->m_matrixIn[154] = { nullptr, nullptr, "I2S0I_D14"}; // I2S0I_DATA_IN14
    m_gpio->m_matrixIn[155] = { nullptr, nullptr, "I2S0I_D15"}; // I2S0I_DATA_IN15
    m_gpio->m_matrixIn[156] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[157] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[158] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[159] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[160] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[161] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[162] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[163] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[164] = { nullptr, nullptr, "I2S1I_BCK"}; // I2S1I_BCK_IN
    m_gpio->m_matrixIn[165] = { nullptr, nullptr, "I2S1I_WS" }; // I2S1I_WS_IN
    m_gpio->m_matrixIn[166] = { nullptr, nullptr, "I2S1I_D0" }; // I2S1I_DATA_IN0
    m_gpio->m_matrixIn[167] = { nullptr, nullptr, "I2S1I_D1" }; // I2S1I_DATA_IN1
    m_gpio->m_matrixIn[168] = { nullptr, nullptr, "I2S1I_D2" }; // I2S1I_DATA_IN2
    m_gpio->m_matrixIn[169] = { nullptr, nullptr, "I2S1I_D3" }; // I2S1I_DATA_IN3
    m_gpio->m_matrixIn[170] = { nullptr, nullptr, "I2S1I_D4" }; // I2S1I_DATA_IN4
    m_gpio->m_matrixIn[171] = { nullptr, nullptr, "I2S1I_D5" }; // I2S1I_DATA_IN5
    m_gpio->m_matrixIn[172] = { nullptr, nullptr, "I2S1I_D6" }; // I2S1I_DATA_IN6
    m_gpio->m_matrixIn[173] = { nullptr, nullptr, "I2S1I_D7" }; // I2S1I_DATA_IN7
    m_gpio->m_matrixIn[174] = { nullptr, nullptr, "I2S1I_D8" }; // I2S1I_DATA_IN8
    m_gpio->m_matrixIn[175] = { nullptr, nullptr, "I2S1I_D9" }; // I2S1I_DATA_IN9
    m_gpio->m_matrixIn[176] = { nullptr, nullptr, "I2S1I_D10"}; // I2S1I_DATA_IN10
    m_gpio->m_matrixIn[177] = { nullptr, nullptr, "I2S1I_D11"}; // I2S1I_DATA_IN11
    m_gpio->m_matrixIn[178] = { nullptr, nullptr, "I2S1I_D12"}; // I2S1I_DATA_IN12
    m_gpio->m_matrixIn[179] = { nullptr, nullptr, "I2S1I_D13"}; // I2S1I_DATA_IN13
    m_gpio->m_matrixIn[180] = { nullptr, nullptr, "I2S1I_D14"}; // I2S1I_DATA_IN14
    m_gpio->m_matrixIn[181] = { nullptr, nullptr, "I2S1I_D15"}; // I2S1I_DATA_IN15
    m_gpio->m_matrixIn[182] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[183] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[184] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[185] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[186] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[187] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[188] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[189] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[190] = { nullptr, nullptr, "I2S0I_H_SYNC"  }; // I2S0I_H_SYNC
    m_gpio->m_matrixIn[191] = { nullptr, nullptr, "I2S0I_V_SYNC"  }; // I2S0I_V_SYNC
    m_gpio->m_matrixIn[192] = { nullptr, nullptr, "I2S0I_H_ENABLE"}; // I2S0I_H_ENABLE
    m_gpio->m_matrixIn[193] = { nullptr, nullptr, "I2S1I_H_SYNC"  }; // I2S1I_H_SYNC
    m_gpio->m_matrixIn[194] = { nullptr, nullptr, "I2S1I_V_SYNC"  }; // I2S1I_V_SYNC
    m_gpio->m_matrixIn[195] = { nullptr, nullptr, "I2S1I_H_ENABLE"}; // I2S1I_H_ENABLE
    m_gpio->m_matrixIn[196] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[197] = { nullptr, nullptr, "---" }; // (not assigned)

    m_gpio->m_matrixIn[198] = { m_usarts[2], m_usarts[2]->getRxPinPtr(), "Rx2" }; // U2RXD

    m_gpio->m_matrixIn[199] = { nullptr, nullptr, "U2CTS" }; // U2CTS_IN
    m_gpio->m_matrixIn[200] = { nullptr, nullptr, "EMAC_MDC_I" }; // EMAC_MDC_I
    m_gpio->m_matrixIn[201] = { nullptr, nullptr, "EMAC_MDI_I" }; // EMAC_MDI_I
    m_gpio->m_matrixIn[202] = { nullptr, nullptr, "EMAC_CRS_I" }; // EMAC_CRS_I
    m_gpio->m_matrixIn[203] = { nullptr, nullptr, "EMAC_COL_I" }; // EMAC_COL_I
    m_gpio->m_matrixIn[204] = { nullptr, nullptr, "PCMFSYNC" }; // PCMFSYNC_IN
    m_gpio->m_matrixIn[205] = { nullptr, nullptr, "PCMCLK" }; // PCMCLK_IN
    m_gpio->m_matrixIn[206] = { nullptr, nullptr, "PCMDIN" }; // PCMDIN
    m_gpio->m_matrixIn[207] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[208] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[209] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[210] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[211] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[212] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[213] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[214] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[215] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[216] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[217] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[218] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[219] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[220] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[221] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[222] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[223] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[224] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[225] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[226] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[227] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[228] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[229] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[230] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[231] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[232] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[233] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[234] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[235] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[236] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[237] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[238] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[239] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[240] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[241] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[242] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[243] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[244] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[245] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[246] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[247] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[248] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[249] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[250] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[251] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[252] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[253] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[254] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixIn[255] = { nullptr, nullptr, "---" }; // (not assigned)

    // OUT
    m_gpio->m_matrixOut[0]  = { nullptr, nullptr, "Ck0" }; // SPICLK
    m_gpio->m_matrixOut[1]  = { nullptr, nullptr, "Mi0" }; // SPIQ
    m_gpio->m_matrixOut[2]  = { nullptr, nullptr, "Mo0" }; // SPID

    m_gpio->m_matrixOut[3]  = { nullptr, nullptr, "SPIHD" }; // SPIHD
    m_gpio->m_matrixOut[4]  = { nullptr, nullptr, "SPIWP" }; // SPIWP

    m_gpio->m_matrixOut[5]  = { nullptr, nullptr, "Ss0" }; // SPICS0

    m_gpio->m_matrixOut[6]  = { nullptr, nullptr, "SPICS1" }; // SPICS1
    m_gpio->m_matrixOut[7]  = { nullptr, nullptr, "SPICS2" }; // SPICS2

    m_gpio->m_matrixOut[8]  = { m_spis[0], m_spis[0]->getCkPinPtr(), "CkH" }; // HSPICLK
    m_gpio->m_matrixOut[9]  = { m_spis[0], m_spis[0]->getMiPinPtr(), "MiH" }; // HSPIQ
    m_gpio->m_matrixOut[10] = { m_spis[0], m_spis[0]->getMoPinPtr(), "MoH" }; // HSPID
    m_gpio->m_matrixOut[11] = { m_spis[0], m_spis[0]->getSsPinPtr(), "SsH" }; // HSPICS0

    m_gpio->m_matrixOut[12] = { nullptr, nullptr, "HdH" }; // HSPIHD
    m_gpio->m_matrixOut[13] = { nullptr, nullptr, "WpH" }; // HSPIWP

    m_gpio->m_matrixOut[14] = { m_usarts[0], m_usarts[0]->getTxPinPtr(), "Tx0" }; // U0TXD

    m_gpio->m_matrixOut[15] = { nullptr, nullptr, "U0RTS" }; // U0RTS
    m_gpio->m_matrixOut[16] = { nullptr, nullptr, "U0DTR" }; // U0DTR

    m_gpio->m_matrixOut[17] = { m_usarts[1], m_usarts[1]->getTxPinPtr(), "Tx1" }; // U1TXD

    m_gpio->m_matrixOut[18] = { nullptr, nullptr, "U1RTS" }; // U1RTS
    m_gpio->m_matrixOut[19] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[20] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[21] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[22] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[23] = { nullptr, nullptr, "I2S0O_BCK" }; // I2S0O_BCK
    m_gpio->m_matrixOut[24] = { nullptr, nullptr, "I2S1O_BCK" }; // I2S1O_BCK
    m_gpio->m_matrixOut[25] = { nullptr, nullptr, "I2S0O_WS" }; // I2S0O_WS
    m_gpio->m_matrixOut[26] = { nullptr, nullptr, "I2S1O_WS" }; // I2S1O_WS
    m_gpio->m_matrixOut[27] = { nullptr, nullptr, "I2S0I_BCK" }; // I2S0I_BCK
    m_gpio->m_matrixOut[28] = { nullptr, nullptr, "I2S0I_WS" }; // I2S0I_WS

    m_gpio->m_matrixOut[29] = { m_i2cs[0], m_i2cs[0]->getSclPinPtr() , "Scl0"}; // I2CEXT0_SCL
    m_gpio->m_matrixOut[30] = { m_i2cs[0], m_i2cs[0]->getSdaPinPtr() , "Sda0"}; // I2CEXT0_SDA

    m_gpio->m_matrixOut[31] = { nullptr, nullptr, "SDIO_TOHOST_INT" }; // SDIO_TOHOST_INT
    m_gpio->m_matrixOut[32] = { nullptr, nullptr, "PWM0_OUT0A" }; // PWM0_OUT0A
    m_gpio->m_matrixOut[33] = { nullptr, nullptr, "PWM0_OUT0B" }; // PWM0_OUT0B
    m_gpio->m_matrixOut[34] = { nullptr, nullptr, "PWM0_OUT1A" }; // PWM0_OUT1A
    m_gpio->m_matrixOut[35] = { nullptr, nullptr, "PWM0_OUT1B" }; // PWM0_OUT1B
    m_gpio->m_matrixOut[36] = { nullptr, nullptr, "PWM0_OUT2A" }; // PWM0_OUT2A
    m_gpio->m_matrixOut[37] = { nullptr, nullptr, "PWM0_OUT2B" }; // PWM0_OUT2B
    m_gpio->m_matrixOut[38] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[39] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[40] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[41] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[42] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[43] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[44] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[45] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[46] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[47] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[48] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[49] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[50] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[51] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[52] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[53] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[54] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[55] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[56] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[57] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[58] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[59] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[60] = { nullptr, nullptr, "---" }; // (not assigned)

    m_gpio->m_matrixOut[61] = { nullptr, nullptr, "Cs1H" }; // spis[0]->cs_pin[1] // HSPICS1
    m_gpio->m_matrixOut[62] = { nullptr, nullptr, "Cs2H" }; // spis[0]->cs_pin[2] // HSPICS2

    m_gpio->m_matrixOut[63] = { m_spis[1], m_spis[1]->getCkPinPtr(), "CkV" }; // VSPICLK
    m_gpio->m_matrixOut[64] = { m_spis[1], m_spis[1]->getMiPinPtr(), "MiV" }; // VSPIQ
    m_gpio->m_matrixOut[65] = { m_spis[1], m_spis[1]->getMoPinPtr(), "MoV" }; // VSPID

    m_gpio->m_matrixOut[66]  = { nullptr, nullptr, "HdV" }; // VSPIHD
    m_gpio->m_matrixOut[67]  = { nullptr, nullptr, "WpV" }; // VSPIWP

    m_gpio->m_matrixOut[68] = { m_spis[1], m_spis[1]->getSsPinPtr() , "SsV" }; // VSPICS0

    m_gpio->m_matrixOut[69] = { nullptr, nullptr, "Cs1V" }; // spis[1]->cs_pin[1] // VSPICS1
    m_gpio->m_matrixOut[70] = { nullptr, nullptr, "Cs2V" }; // spis[1]->cs_pin[2] // VSPICS2

    m_gpio->m_matrixOut[71] = { m_leds, m_leds->getPinPtr( 0 )      , "Lh0" }; // ledc_hs_sig_out0
    m_gpio->m_matrixOut[72] = { m_leds, m_leds->getPinPtr( 1 )      , "Lh1" }; // ledc_hs_sig_out1
    m_gpio->m_matrixOut[73] = { m_leds, m_leds->getPinPtr( 2 )      , "Lh2" }; // ledc_hs_sig_out2
    m_gpio->m_matrixOut[74] = { m_leds, m_leds->getPinPtr( 3 )      , "Lh3" }; // ledc_hs_sig_out3
    m_gpio->m_matrixOut[75] = { m_leds, m_leds->getPinPtr( 4 )      , "Lh4" }; // ledc_hs_sig_out4
    m_gpio->m_matrixOut[76] = { m_leds, m_leds->getPinPtr( 5 )      , "Lh5" }; // ledc_hs_sig_out5
    m_gpio->m_matrixOut[77] = { m_leds, m_leds->getPinPtr( 6 )      , "Lh6" }; // ledc_hs_sig_out6
    m_gpio->m_matrixOut[78] = { m_leds, m_leds->getPinPtr( 7 )      , "Lh7" }; // ledc_hs_sig_out7
    m_gpio->m_matrixOut[79] = { m_leds, m_leds->getPinPtr( 8 )      , "Ll0" }; // ledc_ls_sig_out0
    m_gpio->m_matrixOut[80] = { m_leds, m_leds->getPinPtr( 9 )      , "Ll1" }; // ledc_ls_sig_out1
    m_gpio->m_matrixOut[81] = { m_leds, m_leds->getPinPtr( 10 )     , "Ll2" }; // ledc_ls_sig_out2
    m_gpio->m_matrixOut[82] = { m_leds, m_leds->getPinPtr( 11 )     , "Ll3" }; // ledc_ls_sig_out3
    m_gpio->m_matrixOut[83] = { m_leds, m_leds->getPinPtr( 12 )     , "Ll4" }; // ledc_ls_sig_out4
    m_gpio->m_matrixOut[84] = { m_leds, m_leds->getPinPtr( 13 )     , "Ll5" }; // ledc_ls_sig_out5
    m_gpio->m_matrixOut[85] = { m_leds, m_leds->getPinPtr( 14 )     , "Ll6" }; // ledc_ls_sig_out6
    m_gpio->m_matrixOut[86] = { m_leds, m_leds->getPinPtr( 15 )     , "Ll7" }; // ledc_ls_sig_out7
    m_gpio->m_matrixOut[87] = { nullptr, nullptr                    , "Rmt0" }; // rmt_sig_out0
    m_gpio->m_matrixOut[88] = { nullptr, nullptr                    , "Rmt1" }; // rmt_sig_out1
    m_gpio->m_matrixOut[89] = { nullptr, nullptr                    , "Rmt2" }; // rmt_sig_out2
    m_gpio->m_matrixOut[90] = { nullptr, nullptr                    , "Rmt3" }; // rmt_sig_out3
    m_gpio->m_matrixOut[91] = { nullptr, nullptr                    , "Rmt4" }; // rmt_sig_out4
    m_gpio->m_matrixOut[92] = { nullptr, nullptr                    , "Rmt5" }; // rmt_sig_out5
    m_gpio->m_matrixOut[93] = { nullptr, nullptr                    , "Rmt6" }; // rmt_sig_out6
    m_gpio->m_matrixOut[94] = { nullptr, nullptr                    , "Rmt7" }; // rmt_sig_out7
    m_gpio->m_matrixOut[95] = { m_i2cs[1], m_i2cs[1]->getSclPinPtr(), "Scl1"}; // I2CEXT1_SCL
    m_gpio->m_matrixOut[96] = { m_i2cs[1], m_i2cs[1]->getSdaPinPtr(), "Sda1"}; // I2CEXT1_SDA

    m_gpio->m_matrixOut[97]  = { nullptr, nullptr, "HOST_CCMD_OD_PULLUP_EN_N" }; // HOST_CCMD_OD_PULLUP_EN_N
    m_gpio->m_matrixOut[98]  = { nullptr, nullptr, "HOST_RST_N_1" }; // HOST_RST_N_1
    m_gpio->m_matrixOut[99]  = { nullptr, nullptr, "HOST_RST_N_2" }; // HOST_RST_N_2
    m_gpio->m_matrixOut[100] = { nullptr, nullptr, "GPIO_SD0" }; // GPIO_SD0_OUT
    m_gpio->m_matrixOut[101] = { nullptr, nullptr, "GPIO_SD1" }; // GPIO_SD1_OUT
    m_gpio->m_matrixOut[102] = { nullptr, nullptr, "GPIO_SD2" }; // GPIO_SD2_OUT
    m_gpio->m_matrixOut[103] = { nullptr, nullptr, "GPIO_SD3" }; // GPIO_SD3_OUT
    m_gpio->m_matrixOut[104] = { nullptr, nullptr, "GPIO_SD4" }; // GPIO_SD4_OUT
    m_gpio->m_matrixOut[105] = { nullptr, nullptr, "GPIO_SD5" }; // GPIO_SD5_OUT
    m_gpio->m_matrixOut[106] = { nullptr, nullptr, "GPIO_SD6" }; // GPIO_SD6_OUT
    m_gpio->m_matrixOut[107] = { nullptr, nullptr, "GPIO_SD7" }; // GPIO_SD7_OUT
    m_gpio->m_matrixOut[108] = { nullptr, nullptr, "PWM1_0A" }; // PWM1_OUT0A
    m_gpio->m_matrixOut[109] = { nullptr, nullptr, "PWM1_0B" }; // PWM1_OUT0B
    m_gpio->m_matrixOut[110] = { nullptr, nullptr, "PWM1_1A" }; // PWM1_OUT1A
    m_gpio->m_matrixOut[111] = { nullptr, nullptr, "PWM1_1B" }; // PWM1_OUT1B
    m_gpio->m_matrixOut[112] = { nullptr, nullptr, "PWM1_2A" }; // PWM1_OUT2A
    m_gpio->m_matrixOut[113] = { nullptr, nullptr, "PWM1_2B" }; // PWM1_OUT2B
    m_gpio->m_matrixOut[114] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[115] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[116] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[117] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[118] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[119] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[120] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[121] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[122] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[123] = { nullptr, nullptr, "CAN_TX" }; // CAN_TX
    m_gpio->m_matrixOut[124] = { nullptr, nullptr, "CAN_BUS_OFF_ON" }; // CAN_BUS_OFF_ON
    m_gpio->m_matrixOut[125] = { nullptr, nullptr, "CAN_CLKOUT" }; // CAN_CLKOUT
    m_gpio->m_matrixOut[126] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[127] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[128] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[129] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[130] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[131] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[132] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[133] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[134] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[135] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[136] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[137] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[138] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[139] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[140] = { nullptr, nullptr, "I2S0O_D0" }; // I2S0O_DATA_OUT0
    m_gpio->m_matrixOut[141] = { nullptr, nullptr, "I2S0O_D1" }; // I2S0O_DATA_OUT1
    m_gpio->m_matrixOut[142] = { nullptr, nullptr, "I2S0O_D2" }; // I2S0O_DATA_OUT2
    m_gpio->m_matrixOut[143] = { nullptr, nullptr, "I2S0O_D3" }; // I2S0O_DATA_OUT3
    m_gpio->m_matrixOut[144] = { nullptr, nullptr, "I2S0O_D4" }; // I2S0O_DATA_OUT4
    m_gpio->m_matrixOut[145] = { nullptr, nullptr, "I2S0O_D5" }; // I2S0O_DATA_OUT5
    m_gpio->m_matrixOut[146] = { nullptr, nullptr, "I2S0O_D6" }; // I2S0O_DATA_OUT6
    m_gpio->m_matrixOut[147] = { nullptr, nullptr, "I2S0O_D7" }; // I2S0O_DATA_OUT7
    m_gpio->m_matrixOut[148] = { nullptr, nullptr, "I2S0O_D8" }; // I2S0O_DATA_OUT8
    m_gpio->m_matrixOut[149] = { nullptr, nullptr, "I2S0O_D9" }; // I2S0O_DATA_OUT9
    m_gpio->m_matrixOut[150] = { nullptr, nullptr, "I2S0O_D10" }; // I2S0O_DATA_OUT10
    m_gpio->m_matrixOut[151] = { nullptr, nullptr, "I2S0O_D11" }; // I2S0O_DATA_OUT11
    m_gpio->m_matrixOut[152] = { nullptr, nullptr, "I2S0O_D12" }; // I2S0O_DATA_OUT12
    m_gpio->m_matrixOut[153] = { nullptr, nullptr, "I2S0O_D13" }; // I2S0O_DATA_OUT13
    m_gpio->m_matrixOut[154] = { nullptr, nullptr, "I2S0O_D14" }; // I2S0O_DATA_OUT14
    m_gpio->m_matrixOut[155] = { nullptr, nullptr, "I2S0O_D15" }; // I2S0O_DATA_OUT15
    m_gpio->m_matrixOut[156] = { nullptr, nullptr, "I2S0O_D16" }; // I2S0O_DATA_OUT16
    m_gpio->m_matrixOut[157] = { nullptr, nullptr, "I2S0O_D17" }; // I2S0O_DATA_OUT17
    m_gpio->m_matrixOut[158] = { nullptr, nullptr, "I2S0O_D18" }; // I2S0O_DATA_OUT18
    m_gpio->m_matrixOut[159] = { nullptr, nullptr, "I2S0O_D19" }; // I2S0O_DATA_OUT19
    m_gpio->m_matrixOut[160] = { nullptr, nullptr, "I2S0O_D20" }; // I2S0O_DATA_OUT20
    m_gpio->m_matrixOut[161] = { nullptr, nullptr, "I2S0O_D21" }; // I2S0O_DATA_OUT21
    m_gpio->m_matrixOut[162] = { nullptr, nullptr, "I2S0O_D22" }; // I2S0O_DATA_OUT22
    m_gpio->m_matrixOut[163] = { nullptr, nullptr, "I2S0O_D23" }; // I2S0O_DATA_OUT23
    m_gpio->m_matrixOut[164] = { nullptr, nullptr, "I2S1I_BCK" }; // I2S1I_BCK_OUT
    m_gpio->m_matrixOut[165] = { nullptr, nullptr, "I2S1I_WS" }; // I2S1I_WS_OUT
    m_gpio->m_matrixOut[166] = { nullptr, nullptr, "I2S1O_D0" }; // I2S1O_DATA_OUT0
    m_gpio->m_matrixOut[167] = { nullptr, nullptr, "I2S1O_D1" }; // I2S1O_DATA_OUT1
    m_gpio->m_matrixOut[168] = { nullptr, nullptr, "I2S1O_D2" }; // I2S1O_DATA_OUT2
    m_gpio->m_matrixOut[169] = { nullptr, nullptr, "I2S1O_D3" }; // I2S1O_DATA_OUT3
    m_gpio->m_matrixOut[170] = { nullptr, nullptr, "I2S1O_D4" }; // I2S1O_DATA_OUT4
    m_gpio->m_matrixOut[171] = { nullptr, nullptr, "I2S1O_D5" }; // I2S1O_DATA_OUT5
    m_gpio->m_matrixOut[172] = { nullptr, nullptr, "I2S1O_D6" }; // I2S1O_DATA_OUT6
    m_gpio->m_matrixOut[173] = { nullptr, nullptr, "I2S1O_D7" }; // I2S1O_DATA_OUT7
    m_gpio->m_matrixOut[174] = { nullptr, nullptr, "I2S1O_D8" }; // I2S1O_DATA_OUT8
    m_gpio->m_matrixOut[175] = { nullptr, nullptr, "I2S1O_D9" }; // I2S1O_DATA_OUT9
    m_gpio->m_matrixOut[176] = { nullptr, nullptr, "I2S1O_D10" }; // I2S1O_DATA_OUT10
    m_gpio->m_matrixOut[177] = { nullptr, nullptr, "I2S1O_D11" }; // I2S1O_DATA_OUT11
    m_gpio->m_matrixOut[178] = { nullptr, nullptr, "I2S1O_D12" }; // I2S1O_DATA_OUT12
    m_gpio->m_matrixOut[179] = { nullptr, nullptr, "I2S1O_D13" }; // I2S1O_DATA_OUT13
    m_gpio->m_matrixOut[180] = { nullptr, nullptr, "I2S1O_D14" }; // I2S1O_DATA_OUT14
    m_gpio->m_matrixOut[181] = { nullptr, nullptr, "I2S1O_D15" }; // I2S1O_DATA_OUT15
    m_gpio->m_matrixOut[182] = { nullptr, nullptr, "I2S1O_D16" }; // I2S1O_DATA_OUT16
    m_gpio->m_matrixOut[183] = { nullptr, nullptr, "I2S1O_D17" }; // I2S1O_DATA_OUT17
    m_gpio->m_matrixOut[184] = { nullptr, nullptr, "I2S1O_D18" }; // I2S1O_DATA_OUT18
    m_gpio->m_matrixOut[185] = { nullptr, nullptr, "I2S1O_D19" }; // I2S1O_DATA_OUT19
    m_gpio->m_matrixOut[186] = { nullptr, nullptr, "I2S1O_D20" }; // I2S1O_DATA_OUT20
    m_gpio->m_matrixOut[187] = { nullptr, nullptr, "I2S1O_D21" }; // I2S1O_DATA_OUT21
    m_gpio->m_matrixOut[188] = { nullptr, nullptr, "I2S1O_D22" }; // I2S1O_DATA_OUT22
    m_gpio->m_matrixOut[189] = { nullptr, nullptr, "I2S1O_D23" }; // I2S1O_DATA_OUT23
    m_gpio->m_matrixOut[190] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[191] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[192] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[193] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[194] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[195] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[196] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[197] = { nullptr, nullptr, "---" }; // (not assigned)

    m_gpio->m_matrixOut[198] = { m_usarts[2], m_usarts[2]->getTxPinPtr(), "Tx2" }; // U2RTXD

    m_gpio->m_matrixOut[199] = { nullptr, nullptr, "U2RTS_OUT" }; // U2RTS_OUT
    m_gpio->m_matrixOut[200] = { nullptr, nullptr, "EMAC_MDC_O" }; // EMAC_MDC_O
    m_gpio->m_matrixOut[201] = { nullptr, nullptr, "EMAC_MDO_O" }; // EMAC_MDO_O
    m_gpio->m_matrixOut[202] = { nullptr, nullptr, "EMAC_CRS_O" }; // EMAC_CRS_O
    m_gpio->m_matrixOut[203] = { nullptr, nullptr, "EMAC_COL_O" }; // EMAC_COL_O
    m_gpio->m_matrixOut[204] = { nullptr, nullptr, "BT_AUDIO0_IRQ" }; // BT_AUDIO0_IRQ
    m_gpio->m_matrixOut[205] = { nullptr, nullptr, "BT_AUDIO1_IRQ" }; // BT_AUDIO1_IRQ
    m_gpio->m_matrixOut[206] = { nullptr, nullptr, "BT_AUDIO2_IRQ" }; // BT_AUDIO2_IRQ
    m_gpio->m_matrixOut[207] = { nullptr, nullptr, "BLE_AUDIO0_IRQ" }; // BLE_AUDIO0_IRQ
    m_gpio->m_matrixOut[208] = { nullptr, nullptr, "BLE_AUDIO1_IRQ" }; // BLE_AUDIO1_IRQ
    m_gpio->m_matrixOut[209] = { nullptr, nullptr, "BLE_AUDIO2_IRQ" }; // BLE_AUDIO2_IRQ
    m_gpio->m_matrixOut[210] = { nullptr, nullptr, "PCMFSYNC_OUT" }; // PCMFSYNC_OUT
    m_gpio->m_matrixOut[211] = { nullptr, nullptr, "PCMCLK_OUT" }; // PCMCLK_OUT
    m_gpio->m_matrixOut[212] = { nullptr, nullptr, "PCMDOUT" }; // PCMDOUT
    m_gpio->m_matrixOut[213] = { nullptr, nullptr, "BLE_AUDIO_SYNC0_P" }; // BLE_AUDIO_SYNC0_P
    m_gpio->m_matrixOut[214] = { nullptr, nullptr, "BLE_AUDIO_SYNC1_P" }; // BLE_AUDIO_SYNC1_P
    m_gpio->m_matrixOut[215] = { nullptr, nullptr, "BLE_AUDIO_SYNC2_P" }; // BLE_AUDIO_SYNC2_P
    m_gpio->m_matrixOut[216] = { nullptr, nullptr, "ANT_SEL0" }; // ANT_SEL0
    m_gpio->m_matrixOut[217] = { nullptr, nullptr, "ANT_SEL1" }; // ANT_SEL1
    m_gpio->m_matrixOut[218] = { nullptr, nullptr, "ANT_SEL2" }; // ANT_SEL2
    m_gpio->m_matrixOut[219] = { nullptr, nullptr, "ANT_SEL3" }; // ANT_SEL3
    m_gpio->m_matrixOut[220] = { nullptr, nullptr, "ANT_SEL4" }; // ANT_SEL4
    m_gpio->m_matrixOut[221] = { nullptr, nullptr, "ANT_SEL5" }; // ANT_SEL5
    m_gpio->m_matrixOut[222] = { nullptr, nullptr, "ANT_SEL6" }; // ANT_SEL6
    m_gpio->m_matrixOut[223] = { nullptr, nullptr, "ANT_SEL7" }; // ANT_SEL7
    m_gpio->m_matrixOut[224] = { nullptr, nullptr, "SIG_IN_FUNC224" }; // SIG_IN_FUNC224
    m_gpio->m_matrixOut[225] = { nullptr, nullptr, "SIG_IN_FUNC225" }; // SIG_IN_FUNC225
    m_gpio->m_matrixOut[226] = { nullptr, nullptr, "SIG_IN_FUNC226" }; // SIG_IN_FUNC226
    m_gpio->m_matrixOut[227] = { nullptr, nullptr, "SIG_IN_FUNC227" }; // SIG_IN_FUNC227
    m_gpio->m_matrixOut[228] = { nullptr, nullptr, "SIG_IN_FUNC228" }; // SIG_IN_FUNC228
    m_gpio->m_matrixOut[229] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[230] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[231] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[232] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[233] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[234] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[235] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[236] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[237] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[238] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[239] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[240] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[241] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[242] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[243] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[244] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[245] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[246] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[247] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[248] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[249] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[250] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[251] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[252] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[253] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[254] = { nullptr, nullptr, "---" }; // (not assigned)
    m_gpio->m_matrixOut[255] = { nullptr, nullptr, "---" }; // (not assigned)
}

