From 9f28e53c71d28d04e2775c59944d2887a99f1e86 Mon Sep 17 00:00:00 2001 From: Josh Rahm Date: Sun, 22 Nov 2020 01:06:30 -0700 Subject: Large reorganization. What was in core/ is now moved to arch/stm34l4xxx/peripherals. This new directory is *supposed to* to contain raw header files defining just the pertinent register structures for the various peripherals. Peripheral management belongs somewhere in the new `kern/..` directories. This is not completely the case at the moment, so more refactoring needs to be done. What was sitting in the root has now been moved into the kern/ directory. The kern/ directory is to contain everything else other than raw device register definitions. The root of the kern/ tree is reserved for standard library-esque headers. The kern/ directory contains management systems for that peripheral. (At the moment DMA is the only peripheral with a decent management system.) Preferably these peripheral systems should only include their correlating header in arch/stm34l4xxx/peripherals, and use other management systems for handling other peripherals rather than manipulating their raw registers directly. (Though this ideal will require much more critical mass of management systems.) --- 02-usart/include/arch/stm32l4xxx/peripherals/irq.h | 89 ++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 02-usart/include/arch/stm32l4xxx/peripherals/irq.h (limited to '02-usart/include/arch/stm32l4xxx/peripherals/irq.h') 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 + +/* + * 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_ */ -- cgit