summaryrefslogtreecommitdiff
path: root/hal
diff options
context:
space:
mode:
Diffstat (limited to 'hal')
-rw-r--r--hal/interrupt.cpp14
-rw-r--r--hal/interrupt.h23
2 files changed, 35 insertions, 2 deletions
diff --git a/hal/interrupt.cpp b/hal/interrupt.cpp
index e9e7b24..611b09c 100644
--- a/hal/interrupt.cpp
+++ b/hal/interrupt.cpp
@@ -1,9 +1,21 @@
#include "interrupt.h"
+namespace Interrupt {
+ MFP mf_vectors[16 + NUM_IRQs];
+};
+
void entry();
+void member_function_interrupt_gate() {
+ uint32_t interrupt_num;
+ asm ("mrs %0, ipsr" : "=r" (interrupt_num));
+
+ Interrupt::mf_vectors[interrupt_num].func_p(Interrupt::mf_vectors[interrupt_num].instance_p);
+}
+
extern "C" void unused_interrupt() {
- while(1) {}
+ member_function_interrupt_gate();
+ //while(1);
}
template<> void interrupt<Interrupt::NMI>() __attribute__ ((weak, alias ("unused_interrupt")));
diff --git a/hal/interrupt.h b/hal/interrupt.h
index f817103..34651f2 100644
--- a/hal/interrupt.h
+++ b/hal/interrupt.h
@@ -75,7 +75,8 @@ namespace Interrupt {
DMA2_Channel1,
DMA2_Channel2,
DMA2_Channel3,
- DMA2_Channel4_5
+ DMA2_Channel4_5,
+ NUM_IRQs
};
inline void enable(IRQ n) {
@@ -89,6 +90,26 @@ namespace Interrupt {
inline void set_priority(IRQ n, uint8_t priority) {
NVIC.IPR[n] = priority;
}
+
+ struct MFP {
+ void (*func_p)(void*);
+ void* instance_p;
+ };
+
+ extern MFP mf_vectors[];
+
+ template<class T>
+ inline void set_handler(IRQ n, void (T::*f)(), T* i) {
+ MFP& mfp = mf_vectors[16 + n];
+ mfp.func_p = reinterpret_cast<void (*)(void*)>(f);
+ mfp.instance_p = i;
+ }
+
+ template<class T>
+ inline void enable(IRQ n, void (T::*f)(), T* i) {
+ set_handler(n, f, i);
+ enable(n);
+ }
};
template<Interrupt::Exception>