summaryrefslogtreecommitdiff
path: root/interrupt/nvic.h
diff options
context:
space:
mode:
Diffstat (limited to 'interrupt/nvic.h')
-rw-r--r--interrupt/nvic.h52
1 files changed, 52 insertions, 0 deletions
diff --git a/interrupt/nvic.h b/interrupt/nvic.h
new file mode 100644
index 0000000..b84a8a9
--- /dev/null
+++ b/interrupt/nvic.h
@@ -0,0 +1,52 @@
+#pragma once
+
+#include "interrupt_enums.h"
+
+#include <mmio/mmio.h>
+
+struct NVIC_reg_t {
+ volatile uint32_t ISER[32];
+ volatile uint32_t ICER[32];
+ volatile uint32_t ISPR[32];
+ volatile uint32_t ICPR[32];
+ volatile uint32_t IABR[64];
+ volatile uint8_t IPR[2816];
+ volatile uint32_t STIR;
+};
+
+struct SCB_reg_t {
+ volatile uint32_t CPUID;
+ volatile uint32_t ICSR;
+ volatile uint32_t VTOR;
+ volatile uint32_t AIRCR;
+ volatile uint32_t SCR;
+ volatile uint32_t CCR;
+ volatile uint8_t SHPR[12];
+ volatile uint32_t SHCSR;
+ volatile uint32_t CFSR;
+ volatile uint32_t HFSR;
+ volatile uint32_t DFSR;
+ volatile uint32_t MMAR;
+ volatile uint32_t BFAR;
+};
+
+class NVIC_t : public mmio_ptr<NVIC_reg_t> {
+ public:
+ mmio_ptr<SCB_reg_t> SCB;
+
+ constexpr NVIC_t(uintptr_t offset) :
+ mmio_ptr(offset),
+ SCB(offset + 0xc00) {}
+
+ void enable(interrupt::irq n) const {
+ ptr()->ISER[int(n) >> 5] = 1 << (int(n) & 0x1f);
+ }
+
+ void set_priority(interrupt::exception n, uint8_t priority) const {
+ SCB->SHPR[int(n) - 4] = priority;
+ }
+
+ void set_priority(interrupt::irq n, uint8_t priority) const {
+ ptr()->IPR[int(n)] = priority;
+ }
+};