synth/mbv/hal/intc.cc
2025-06-25 08:38:46 -07:00

63 lines
1.2 KiB
C++

#include "intc.h"
// this interrupt controller is tied to the pol0 design
#include "pol0.h"
namespace intc {
namespace {
struct IntC {
volatile uint32_t ISR;
volatile uint32_t IPR;
volatile uint32_t IER;
volatile uint32_t IAR;
volatile uint32_t SIE;
volatile uint32_t CIE;
volatile uint32_t IVR;
volatile uint32_t MER;
volatile uint32_t IMR;
volatile uint32_t ILR;
// the rest is not enabled
};
IntC* intc = reinterpret_cast<IntC*>(INTC_BASE);
Isr isrs[NIRQ] = {};
} // namespace
bool SetIrqEnabled(uint8_t irqn, bool enabled) {
uint32_t mask = 1 << irqn;
uint32_t ier = intc->IER;
bool was_enabled = (ier & (~mask)) > 0;
if (enabled) {
intc->IER = ier | mask;
} else {
intc->IER = ier & (~mask);
}
return was_enabled;
}
void SetIsr(uint8_t irqn, Isr isr) { isrs[irqn] = isr; }
void EnableInterrupts() { intc->MER = 0x3; }
void InterruptHandler() {
uint32_t ipr = intc->IPR;
for (int i = 0; i < NIRQ; i++) {
uint32_t mask = 1 << i;
if ((ipr & mask) > 0) {
// interrupt pending
if (isrs[i] != nullptr) {
isrs[i]();
}
intc->IAR = mask; // ack
}
}
}
} // namespace intc