aboutsummaryrefslogtreecommitdiff
path: root/02-usart/include/arch/stm32l4xxx/peripherals/irq.h
diff options
context:
space:
mode:
Diffstat (limited to '02-usart/include/arch/stm32l4xxx/peripherals/irq.h')
-rw-r--r--02-usart/include/arch/stm32l4xxx/peripherals/irq.h89
1 files changed, 89 insertions, 0 deletions
diff --git a/02-usart/include/arch/stm32l4xxx/peripherals/irq.h b/02-usart/include/arch/stm32l4xxx/peripherals/irq.h
new file mode 100644
index 0000000..52878ca
--- /dev/null
+++ b/02-usart/include/arch/stm32l4xxx/peripherals/irq.h
@@ -0,0 +1,89 @@
+#ifndef CORE_IRQ_H__
+#define CORE_IRQ_H__
+
+#include <stdint.h>
+
+/*
+ * Include file for interrupt service routines.
+ */
+
+typedef enum {
+#define IRQ_RESERVED(n)
+#define IRQ(name_, uname, num) \
+ IRQ_##uname = num,
+#include "arch/stm32l4xxx/peripherals//isrs.inc"
+#undef IRQ
+#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.
+ */
+extern const void* vectors[];
+
+/*
+ * Defines an error state. This loops forever and defines a distinct flashing
+ * pattern to let the user know an unhandled ISR happened.
+ */
+void unhandled_isr(uint8_t val);
+
+#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_ */