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

#include <QDebug>

#include "esp32iomux.h"
#include "esp32gpio.h"

Esp32IoMux::Esp32IoMux( QemuDevice* mcu, QString name, int n, uint32_t* clk, uint64_t memStart, uint64_t memEnd)
          : QemuModule( mcu, name, n, clk, memStart, memEnd )
{
    m_gpio = nullptr; 
}
Esp32IoMux::~Esp32IoMux() {}

void Esp32IoMux::reset()
{
    for( int i=0;  i<40;  ++i ) m_iomuxReg[i] = 0; 
}

void Esp32IoMux::readRegister()
{
    // uint64_t offset = m_eventAddress - m_memStart; 
    // uint16_t val = 0; 

    // uint32_t index = offset/4; 
    // if( index < 40 ) val = m_iomuxReg[index]; 

    // m_arena->regData = val; 
    // m_arena->qemuAction = SIM_READ; 
}

void Esp32IoMux::writeRegister()
{
    //qDebug() << "Esp32IoMux::writeRegister"<< m_name << m_eventAddress << m_eventValue; 
    uint64_t offset = m_eventAddress - m_memStart; 

    int pin = getMuxGpio( offset ); 
    if( pin < 0 ) return; 

    uint32_t index = offset/4; 
    if( m_iomuxReg[index] == m_eventValue ) return; 
    m_iomuxReg[index] = m_eventValue; 

    m_gpio->writeIoMuxReg( pin, m_eventValue ); 
}

int Esp32IoMux::getMuxGpio( uint64_t addr )
{
    switch( addr ) {
    case 0x04: return 36; 
    case 0x08: return 37; 
    case 0x0C: return 38; 
    case 0x10: return 39; 
    case 0x1C: return 32; 
    case 0x14: return 34; 
    case 0x18: return 35; 
    case 0x20: return 33; 
    case 0x24: return 25; 
    case 0x28: return 26; 
    case 0x2C: return 27; 
    case 0x30: return 14;   //MTMS
    case 0x34: return 12;   //MTDI
    case 0x38: return 13;   //MTCK
    case 0x3C: return 15;   //MTDO
    case 0x40: return  2; 
    case 0x44: return  0; 
    case 0x48: return  4; 
    case 0x4C: return 16; 
    case 0x50: return 17; 
    case 0x54: return  9;   //SD_DATA2
    case 0x58: return 10;   //SD_DATA3
    case 0x5C: return 11;   //SD_CMD
    case 0x60: return  6;   //SD_CLK
    case 0x64: return  7;   //SD_DATA0
    case 0x68: return  8;   //SD_DATA1
    case 0x6C: return  5; 
    case 0x70: return 18; 
    case 0x74: return 19; 
    case 0x78: return 20; 
    case 0x7C: return 21; 
    case 0x80: return 22; 
    case 0x84: return  3;   //U0RXD
    case 0x88: return  1;   //U0TXD
    case 0x8C: return 23; 
    case 0x90: return 24; 
    default: break; 
    }
    return -1; 
}
