mbv: small refactor interrupts
This commit is contained in:
		@@ -25,9 +25,8 @@ void SetupTimer() {
 | 
				
			|||||||
    timer->SetupAsWdt(100'000'000);
 | 
					    timer->SetupAsWdt(100'000'000);
 | 
				
			||||||
    timer->EnableT1();
 | 
					    timer->EnableT1();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SetIsr(TIMER0_IRQN, Timer0Isr);
 | 
					    intc::SetIsr(TIMER0_IRQN, Timer0Isr);
 | 
				
			||||||
    SetIrqEnabled(TIMER0_IRQN, true);
 | 
					    intc::SetIrqEnabled(TIMER0_IRQN, true);
 | 
				
			||||||
    EnableInterrupts();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace
 | 
					}  // namespace
 | 
				
			||||||
@@ -37,8 +36,10 @@ int main() {
 | 
				
			|||||||
    leds->data = 0xa0;
 | 
					    leds->data = 0xa0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SetupTimer();
 | 
					    SetupTimer();
 | 
				
			||||||
    SetExternalInterruptHandler(InterruptHandler);
 | 
					    intc::EnableInterrupts();
 | 
				
			||||||
 | 
					    SetExternalInterruptHandler(intc::InterruptHandler);
 | 
				
			||||||
    EnableExternalInterrupts();
 | 
					    EnableExternalInterrupts();
 | 
				
			||||||
 | 
					    EnableInterrupts(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    leds->data = 0xa1;
 | 
					    leds->data = 0xa1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,8 +41,8 @@ void InitUarts() {
 | 
				
			|||||||
    XUartLite_SetRecvHandler(uart0, HandleUartRxFromIsr, nullptr);
 | 
					    XUartLite_SetRecvHandler(uart0, HandleUartRxFromIsr, nullptr);
 | 
				
			||||||
    XUartLite_EnableInterrupt(uart0);
 | 
					    XUartLite_EnableInterrupt(uart0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SetIsr(UART0_IRQN, Uart0Isr);
 | 
					    intc::SetIsr(UART0_IRQN, Uart0Isr);
 | 
				
			||||||
    SetIrqEnabled(UART0_IRQN, true);
 | 
					    intc::SetIrqEnabled(UART0_IRQN, true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}  // namespace
 | 
					}  // namespace
 | 
				
			||||||
@@ -52,9 +52,10 @@ int main() {
 | 
				
			|||||||
    leds->data = 0xa0;
 | 
					    leds->data = 0xa0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    InitUarts();
 | 
					    InitUarts();
 | 
				
			||||||
    EnableInterrupts();
 | 
					    intc::EnableInterrupts();
 | 
				
			||||||
    SetExternalInterruptHandler(InterruptHandler);
 | 
					    SetExternalInterruptHandler(intc::InterruptHandler);
 | 
				
			||||||
    EnableExternalInterrupts();
 | 
					    EnableExternalInterrupts();
 | 
				
			||||||
 | 
					    EnableInterrupts(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    int counter = 0;
 | 
					    int counter = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,9 @@
 | 
				
			|||||||
#include "intc.h"
 | 
					#include "intc.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// this interrupt controller is tied to the pol0 design
 | 
				
			||||||
#include "pol0.h"
 | 
					#include "pol0.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace intc {
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct IntC {
 | 
					struct IntC {
 | 
				
			||||||
@@ -22,7 +24,7 @@ struct IntC {
 | 
				
			|||||||
IntC* intc = reinterpret_cast<IntC*>(INTC_BASE);
 | 
					IntC* intc = reinterpret_cast<IntC*>(INTC_BASE);
 | 
				
			||||||
Isr isrs[NIRQ] = {};
 | 
					Isr isrs[NIRQ] = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}  // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool SetIrqEnabled(uint8_t irqn, bool enabled) {
 | 
					bool SetIrqEnabled(uint8_t irqn, bool enabled) {
 | 
				
			||||||
    uint32_t mask = 1 << irqn;
 | 
					    uint32_t mask = 1 << irqn;
 | 
				
			||||||
@@ -60,3 +62,5 @@ void InterruptHandler() {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace intc
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <cstdint>
 | 
					#include <cstdint>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace intc {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using Isr = void(*)(void);
 | 
					using Isr = void(*)(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Returns: true if the IRQ was previously enabled
 | 
					/// Returns: true if the IRQ was previously enabled
 | 
				
			||||||
@@ -14,3 +16,5 @@ void EnableInterrupts();
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Feed this to the CPU's interrupt handler
 | 
					// Feed this to the CPU's interrupt handler
 | 
				
			||||||
void InterruptHandler();
 | 
					void InterruptHandler();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}  // namespace intc
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
#include <cstdint>
 | 
					#include <cstdint>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "bios.h"
 | 
				
			||||||
#include "interrupts.h"
 | 
					#include "interrupts.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
@@ -26,27 +27,40 @@ void TrapHandler() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        mip &= ~(kMieExternalInterruptMask);
 | 
					        mip &= ~(kMieExternalInterruptMask);
 | 
				
			||||||
        asm volatile("csrw mip, %0" :: "r"(mip));
 | 
					        asm volatile("csrw mip, %0" :: "r"(mip));
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        BiosWozmon();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}  // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void SetExternalInterruptHandler(Isr handler) {
 | 
					void SetExternalInterruptHandler(Isr handler) {
 | 
				
			||||||
    external_handler = handler;
 | 
					    external_handler = handler;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void EnableExternalInterrupts() {
 | 
					void EnableExternalInterrupts() {
 | 
				
			||||||
    uint32_t mstatus;
 | 
					 | 
				
			||||||
    uint32_t mie;
 | 
					    uint32_t mie;
 | 
				
			||||||
    Isr trap = TrapHandler;
 | 
					    Isr trap = TrapHandler;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    asm volatile("csrr %0, mstatus" : "=r"(mstatus));
 | 
					 | 
				
			||||||
    asm volatile("csrr %0, mie" : "=r"(mie));
 | 
					    asm volatile("csrr %0, mie" : "=r"(mie));
 | 
				
			||||||
 | 
					 | 
				
			||||||
    asm volatile("csrw mtvec, %0" :: "r"(trap));
 | 
					    asm volatile("csrw mtvec, %0" :: "r"(trap));
 | 
				
			||||||
 | 
					 | 
				
			||||||
    mie |= kMieExternalInterruptMask;
 | 
					    mie |= kMieExternalInterruptMask;
 | 
				
			||||||
    asm volatile("csrw mie, %0" :: "r"(mie));
 | 
					    asm volatile("csrw mie, %0" :: "r"(mie));
 | 
				
			||||||
    mstatus |= kMstatusMieMask;
 | 
					}
 | 
				
			||||||
    asm volatile("csrw mstatus, %0" :: "r"(mstatus));
 | 
					
 | 
				
			||||||
 | 
					bool EnableInterrupts(bool on) {
 | 
				
			||||||
 | 
					    uint32_t mstatus;
 | 
				
			||||||
 | 
					    bool was_on;
 | 
				
			||||||
 | 
					    asm volatile("csrr %0, mstatus" : "=r"(mstatus));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    was_on = (mstatus & kMstatusMieMask) > 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (on) {
 | 
				
			||||||
 | 
					        mstatus |= kMstatusMieMask;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        mstatus &= ~kMstatusMieMask;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    asm volatile("csrw mstatus, %0" :: "r"(mstatus));
 | 
				
			||||||
 | 
					    return was_on;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,3 +4,6 @@ using Isr = void(*)();
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void SetExternalInterruptHandler(Isr handler);
 | 
					void SetExternalInterruptHandler(Isr handler);
 | 
				
			||||||
void EnableExternalInterrupts();
 | 
					void EnableExternalInterrupts();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/** Returns true if interrupts were enabled, false otherwise */
 | 
				
			||||||
 | 
					bool EnableInterrupts(bool on);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user