aboutsummaryrefslogtreecommitdiff
path: root/02-usart/include
diff options
context:
space:
mode:
Diffstat (limited to '02-usart/include')
-rw-r--r--02-usart/include/arch/arm/arch.h2
-rw-r--r--02-usart/include/arch/x86_64/arch.h2
-rw-r--r--02-usart/include/core/irq.h58
-rw-r--r--02-usart/include/core/nvic.h46
4 files changed, 105 insertions, 3 deletions
diff --git a/02-usart/include/arch/arm/arch.h b/02-usart/include/arch/arm/arch.h
index a3b93dc..175c984 100644
--- a/02-usart/include/arch/arm/arch.h
+++ b/02-usart/include/arch/arm/arch.h
@@ -7,7 +7,7 @@
#define CORTEX_M4
-#define enable_interrupts() \
+#define enable_all_interrupts() \
asm volatile(" cpsie i ")
diff --git a/02-usart/include/arch/x86_64/arch.h b/02-usart/include/arch/x86_64/arch.h
index a39df9a..a93425d 100644
--- a/02-usart/include/arch/x86_64/arch.h
+++ b/02-usart/include/arch/x86_64/arch.h
@@ -4,7 +4,7 @@
#include "fake_env.h"
#define ARCH_PC
-#define enable_interrupts() do {} while(0)
+#define enable_all_interrupts() do {} while(0)
#define DMA1_BASE (load_fake_ahb1__() + 0x0)
#define DMA2_BASE (load_fake_ahb1__() + 0x400)
diff --git a/02-usart/include/core/irq.h b/02-usart/include/core/irq.h
index ae1126d..f2fe8d9 100644
--- a/02-usart/include/core/irq.h
+++ b/02-usart/include/core/irq.h
@@ -16,6 +16,42 @@ typedef enum {
#undef IRQ_RESERVED
} interrupt_t;
+/* Defines a set of interrupts so they may be enabled all at once. */
+typedef struct {
+ uint32_t sysirqs; /* System iterrupts. */
+ uint32_t irqs[8];
+} interrupt_set_t;
+
+inline static void interrupt_set_add(
+ interrupt_set_t* interrupt_set, interrupt_t interrupt)
+{
+ if (interrupt < 16) {
+ interrupt_set->sysirqs |= 1 << interrupt;
+ return;
+ }
+
+ interrupt -= 16;
+ int loc = interrupt / 32;
+ int off = interrupt % 32;
+
+ interrupt_set->irqs[loc] |= 1 << off;
+}
+
+inline static void interrupt_set_remove(
+ interrupt_set_t* interrupt_set, interrupt_t interrupt)
+{
+ if (interrupt < 16) {
+ interrupt_set->sysirqs &= ~(1 << interrupt);
+ return;
+ }
+
+ interrupt -= 16;
+ int loc = interrupt / 32;
+ int off = interrupt % 32;
+
+ interrupt_set->irqs[loc] &= ~(1 << off);
+}
+
/*
* The interrupt service routines. These link in the function `main` as the
* main function.
@@ -28,6 +64,26 @@ extern const void* vectors[];
*/
void unhandled_isr(uint8_t val);
-void isr_simple_pin_on();
+#define enable_interrupt(val) \
+ {interrupt_set_t itrset = { 0 }; \
+ interrupt_set_add(&itrset, val); \
+ enable_interrupts(&itrset);}
+
+#define disable_interrupt(val) \
+ {interrupt_set_t itrset = { 0 }; \
+ interrupt_set_add(&itrset, val); \
+ disable_interrupts(&itrset);}
+
+/*
+ * Enables the provided interrupt. Note that if the interrupt is one of the
+ * system interrupts (first 16) this function has no effect because those
+ * interrupts are always enabled.
+ */
+void enable_interrupts(interrupt_set_t* interrupts);
+
+/*
+ * Enables the provided interrupt
+ */
+void disable_interrupts(interrupt_set_t* interrupts);
#endif /* CORE_IRQ_H_ */
diff --git a/02-usart/include/core/nvic.h b/02-usart/include/core/nvic.h
new file mode 100644
index 0000000..c761574
--- /dev/null
+++ b/02-usart/include/core/nvic.h
@@ -0,0 +1,46 @@
+#ifndef NVIC_H_
+#define NVIC_H_
+
+#include "arch.h"
+#include "common.h"
+
+typedef __IO struct {
+#define nvic_intlinesnum (0x0F << 0)
+ uint32_t ict_r; /* Interrupt control type register. */
+
+ uint8_t reserved0[0xF8];
+
+ uint32_t ise_r[8];
+
+ uint8_t reserved1[0x60];
+
+ uint32_t ice_r[8];
+
+ uint8_t reserved2[0x60];
+
+ uint32_t isp_r[8];
+
+ uint8_t reserved3[0x60];
+
+ uint32_t icp_r[8];
+
+ uint8_t reserved4[0x60];
+
+ uint32_t iab_r[8];
+
+ uint8_t reserved5[0xE0];
+
+ uint32_t ip_r[60];
+} nvic_t;
+
+static_assert(offsetof(nvic_t, ise_r) == 0x00FC, "Offset check failed");
+static_assert(offsetof(nvic_t, ice_r) == 0x017C, "Offset check failed");
+static_assert(offsetof(nvic_t, isp_r) == 0x01FC, "Offset check failed");
+static_assert(offsetof(nvic_t, icp_r) == 0x027C, "Offset check failed");
+static_assert(offsetof(nvic_t, iab_r) == 0x02FC, "Offset check failed");
+static_assert(offsetof(nvic_t, ip_r) == 0x03FC, "Offset check failed");
+
+#define NVIC (* (nvic_t*) NVIC_BASE)
+
+
+#endif /* NVIC_H_ */