diff options
Diffstat (limited to '02-usart/include')
-rw-r--r-- | 02-usart/include/arch/arm/arch.h | 2 | ||||
-rw-r--r-- | 02-usart/include/arch/x86_64/arch.h | 2 | ||||
-rw-r--r-- | 02-usart/include/core/irq.h | 58 | ||||
-rw-r--r-- | 02-usart/include/core/nvic.h | 46 |
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_ */ |