mbv: now with functioning timer interrupts!
And a few other nice things. The bootloader now has an embedded wozmon! If you know its offset, you can jump to it from the app.
This commit is contained in:
62
mbv/hal/intc.cc
Normal file
62
mbv/hal/intc.cc
Normal file
@@ -0,0 +1,62 @@
|
||||
#include "intc.h"
|
||||
|
||||
#include "pol0.h"
|
||||
|
||||
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] = {};
|
||||
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user