From: George Wright Date: Sun, 8 Dec 2024 20:01:55 +0000 (-0800) Subject: Fix GPIO interrupt status more correctly, and handle ASIC14's pin connection more... X-Git-Url: http://git.gwright.org.uk/?a=commitdiff_plain;h=56cb212a89eefa55202427042482d6e5ebd9b781;p=WindEmu.git Fix GPIO interrupt status more correctly, and handle ASIC14's pin connection more correctly --- diff --git a/WindCore/sa1100.cpp b/WindCore/sa1100.cpp index 5693bcb..e2e8cd2 100644 --- a/WindCore/sa1100.cpp +++ b/WindCore/sa1100.cpp @@ -13,8 +13,6 @@ Emulator::Emulator() : EmuBase(false) { resetController = new ResetController(); rtc = new RTC(); intController = new IntController(lcdController, osTimer, gpioController, serial3, rtc); - gpioController->setIntController(intController); - osTimer->setIntController(intController); powerManager = new PowerManager(); MemoryBlockC0 = new uint8_t[memoryMask+1]; MemoryBlockC8 = new uint8_t[memoryMask+1]; diff --git a/WindCore/sa1100/asic14.h b/WindCore/sa1100/asic14.h index f901774..a43f6ef 100644 --- a/WindCore/sa1100/asic14.h +++ b/WindCore/sa1100/asic14.h @@ -113,7 +113,9 @@ class ASIC14 { //m_IRQ_STATUS = IRQ_CFCARD_CHANGE | IRQ_PCMCIA_CHANGE; m_IRQ_STATUS = m_IRQ_MASK; if (m_IRQ_STATUS != 0) { - mGPIOController->trigger_asic14_gpio(); + mGPIOController->pull_pin(10, false); + } else { + mGPIOController->pull_pin(10, true); } } }; diff --git a/WindCore/sa1100/gpio_controller.cpp b/WindCore/sa1100/gpio_controller.cpp index 477d328..ec26152 100644 --- a/WindCore/sa1100/gpio_controller.cpp +++ b/WindCore/sa1100/gpio_controller.cpp @@ -17,7 +17,6 @@ #include "gpio_controller.h" -#include "interrupt_controller.h" namespace SA1100 { void GPIOController::reset() { m_GPLR &= 0xFFFFFFF; @@ -127,8 +126,11 @@ namespace SA1100 { // GEDR status bits are cleared by writing a one to them. // Writing a zero to a GEDR status bit has no effect. m_GEDR &= ~(value & 0xFFFFFFF); - printf("GEDR write %08x [%08x]\n", value, m_GEDR); - mIntController->clear_interrupt(IntController::GPIO_0_10_EDGE_BIT_MASK); + // Probably not the best way to handle this, as reading GPLR will result in incorrect + // data + m_GPLR &= ~(value & 0xFFFFFFF); + m_GPLR_backup &= ~(value & 0xFFFFFFF); + //printf("GEDR write %08x [%08x]\n", value, m_GEDR); break; case GAFR: diff --git a/WindCore/sa1100/gpio_controller.h b/WindCore/sa1100/gpio_controller.h index d9668c5..0c3b75b 100644 --- a/WindCore/sa1100/gpio_controller.h +++ b/WindCore/sa1100/gpio_controller.h @@ -88,8 +88,6 @@ class GPIOController { m_GEDR = 0; m_GAFR = 0; } - - IntController* mIntController; public: @@ -98,10 +96,6 @@ class GPIOController { GPIOController() { init_register(); } - - void setIntController(IntController* intController) { - mIntController = intController; - } // Operation @@ -134,28 +128,27 @@ class GPIOController { } } - inline void trigger_asic14_gpio() { - printf("Triggering ASIC14 GPIO\n"); + inline void pull_pin(int pin, int high) { + printf("GPIO: pull pin %d %s\n", pin, high ? "high" : "low"); // :SA-1110 Developer's Manual: p.80: Wei 2004-Jul-1: // // A zero in GAFR indicates that the corresponding GPIO pin is to be used for its normal GPIO function. - if (0 == (m_GAFR & GAFR_ASIC14)) + if (0 == (m_GAFR & (1 << pin))) { - // if (high) { - // m_GPLR |= GAFR_ASIC14; - // } else { - // m_GPLR &= ~GAFR_ASIC14; - // } - m_GEDR |= GAFR_ASIC14; + if (high) { + m_GPLR |= (1 << pin); + } else { + m_GPLR &= ~(1 << pin); + } } } inline void flip_gpio() { - if (m_GPLR & 0x400) { - m_GPLR &= ~0x400; - } else { - m_GPLR |= 0x400; - } + // if (m_GPLR & 0x400) { + // m_GPLR &= ~0x400; + // } else { + // m_GPLR |= 0x400; + // } } inline void release_action_button() { diff --git a/WindCore/sa1100/interrupt_controller.cpp b/WindCore/sa1100/interrupt_controller.cpp index c375be4..df929e1 100644 --- a/WindCore/sa1100/interrupt_controller.cpp +++ b/WindCore/sa1100/interrupt_controller.cpp @@ -72,19 +72,63 @@ namespace SA1100 { { uint32_t const gpio_status = mGPIOController->get_interrupt_status(); - + // clear all GPIO bits in pending interrupts + m_ICPR &= ~(GPIO_0_10_EDGE_BIT_MASK | GPIO_11_27_EDGE_BIT_MASK); + if (gpio_status != 0) { - m_ICPR &= ~GPIO_0_10_EDGE_BIT_MASK; - m_ICPR |= (gpio_status & GPIO_0_10_EDGE_BIT_MASK); - - if ((gpio_status & ~GPIO_0_10_EDGE_BIT_MASK) != 0) - { - m_ICPR |= GPIO_11_27_EDGE_BIT_MASK; + if (gpio_status & GPIO_0_EDGE_BIT_MASK) { + m_ICPR |= GPIO_0_EDGE_BIT_MASK; } - else - { - m_ICPR &= ~GPIO_11_27_EDGE_BIT_MASK; + if (gpio_status & GPIO_1_EDGE_BIT_MASK) { + m_ICPR |= GPIO_1_EDGE_BIT_MASK; + } + if (gpio_status & GPIO_2_EDGE_BIT_MASK) { + m_ICPR |= GPIO_2_EDGE_BIT_MASK; + } + if (gpio_status & GPIO_3_EDGE_BIT_MASK) { + m_ICPR |= GPIO_3_EDGE_BIT_MASK; + } + if (gpio_status & GPIO_4_EDGE_BIT_MASK) { + m_ICPR |= GPIO_4_EDGE_BIT_MASK; + } + if (gpio_status & GPIO_5_EDGE_BIT_MASK) { + m_ICPR |= GPIO_5_EDGE_BIT_MASK; + } + if (gpio_status & GPIO_6_EDGE_BIT_MASK) { + m_ICPR |= GPIO_6_EDGE_BIT_MASK; + } + if (gpio_status & GPIO_7_EDGE_BIT_MASK) { + m_ICPR |= GPIO_7_EDGE_BIT_MASK; + } + if (gpio_status & GPIO_8_EDGE_BIT_MASK) { + m_ICPR |= GPIO_8_EDGE_BIT_MASK; + } + if (gpio_status & GPIO_9_EDGE_BIT_MASK) { + m_ICPR |= GPIO_9_EDGE_BIT_MASK; + } + if (gpio_status & GPIO_10_EDGE_BIT_MASK) { + m_ICPR |= GPIO_10_EDGE_BIT_MASK; + } + constexpr uint32_t GPIO_11_27_BITS = (1 << 11) | + (1 << 12) | + (1 << 13) | + (1 << 14) | + (1 << 15) | + (1 << 16) | + (1 << 17) | + (1 << 18) | + (1 << 19) | + (1 << 20) | + (1 << 21) | + (1 << 22) | + (1 << 23) | + (1 << 24) | + (1 << 25) | + (1 << 26) | + (1 << 27); + if (gpio_status & GPIO_11_27_BITS) { + m_ICPR |= GPIO_11_27_EDGE_BIT_MASK; } } } diff --git a/WindCore/sa1100/interrupt_controller.h b/WindCore/sa1100/interrupt_controller.h index cbb0fc2..bcd6c59 100644 --- a/WindCore/sa1100/interrupt_controller.h +++ b/WindCore/sa1100/interrupt_controller.h @@ -146,13 +146,7 @@ class IntController { uint32_t get_data(uint32_t const address) const; void put_data(uint32_t const address, uint32_t const value); - - void clear_interrupt(uint32_t const mask) { - m_ICIP = m_ICIP & ~mask; - m_ICFP = m_ICFP & ~mask; - m_ICPR = m_ICPR & ~mask; - printf("Clear interrupt %08x [%08x, %08x]\n", mask, m_ICIP, m_ICFP); - } + inline bool have_pending_irq() const { return (0 == m_ICIP) ? false : true; } diff --git a/WindCore/sa1100/os_timer.cpp b/WindCore/sa1100/os_timer.cpp index d55ef7e..10bc5e5 100644 --- a/WindCore/sa1100/os_timer.cpp +++ b/WindCore/sa1100/os_timer.cpp @@ -16,7 +16,6 @@ // #include "os_timer.h" -#include "interrupt_controller.h" namespace SA1100 { @@ -140,7 +139,6 @@ namespace SA1100 { break; default: m_OSSR &= ~(value & 0xF); - mIntController->clear_interrupt((value & 0xF) << 26); break; } break; diff --git a/WindCore/sa1100/os_timer.h b/WindCore/sa1100/os_timer.h index ac66ce6..9529fd2 100644 --- a/WindCore/sa1100/os_timer.h +++ b/WindCore/sa1100/os_timer.h @@ -23,8 +23,6 @@ namespace SA1100 { -class IntController; - class OsTimer { private: @@ -80,8 +78,6 @@ class OsTimer { } } } - - IntController* mIntController; public: enum { @@ -104,10 +100,6 @@ class OsTimer { OsTimer(); - void setIntController(IntController* intController) { - mIntController = intController; - } - void reset(); void tick();