From 479b56bee7685ae5d34c28bd6c1ee05337de577e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Hru=C5=A1ka?= Date: Tue, 29 Dec 2015 14:16:06 +0100 Subject: [PATCH] usart handler example + nvic code --- Makefile | 2 + blink.c | 8 +- blink.h | 4 +- init.c | 31 ++++ lib/common.c | 11 ++ lib/common.h | 89 ++++++----- lib/defs_nvic.h | 388 ++++++++++++++++++++++++++++++++++++++++++++++++ main.c | 18 +++ proj.pro | 8 +- utils/nvic.c | 64 ++++++++ utils/nvic.h | 24 +++ 11 files changed, 605 insertions(+), 42 deletions(-) create mode 100644 lib/common.c create mode 100644 lib/defs_nvic.h create mode 100644 utils/nvic.c create mode 100644 utils/nvic.h diff --git a/Makefile b/Makefile index 58ea054..76f527c 100644 --- a/Makefile +++ b/Makefile @@ -20,8 +20,10 @@ OBJS += utils/gpio.o OBJS += utils/usart.o OBJS += utils/timebase.o OBJS += utils/debounce.o +OBJS += utils/nvic.o OBJS += init.o OBJS += blink.o +OBJS += lib/common.o ################################################################ diff --git a/blink.c b/blink.c index 2aa5b20..bfc933f 100644 --- a/blink.c +++ b/blink.c @@ -9,14 +9,14 @@ void blue_toggle(void) { GPIOC_ODR ^= BIT8; } void blue_on(void) { GPIOC_ODR |= BIT8; } void blue_off(void) { GPIOC_ODR &= ~BIT8; } -void blink_green(void) +void green_blink(void) { green_on(); - schedule_task(green_off, 250); + schedule_task(green_off, 100); } -void blink_blue(void) +void blue_blink(void) { blue_on(); - schedule_task(blue_off, 250); + schedule_task(blue_off, 100); } diff --git a/blink.h b/blink.h index 6083c28..433cf9d 100644 --- a/blink.h +++ b/blink.h @@ -8,5 +8,5 @@ void blue_toggle(void); void blue_on(void); void blue_off(void); -void blink_green(void); -void blink_blue(void); +void green_blink(void); +void blue_blink(void); diff --git a/init.c b/init.c index 5881583..ac23eeb 100644 --- a/init.c +++ b/init.c @@ -2,6 +2,7 @@ #include "utils/gpio.h" #include "utils/usart.h" +#include "utils/nvic.h" void init_gpios(void) @@ -48,6 +49,10 @@ void init_usart(void) // USART enable USART3_CR1 = USART_CR1_UE | USART_CR1_RE | USART_CR1_TE; + + // enable interrupt on data receive + nvic_enable_irq(NVIC_USART3_IRQ); + USART3_CR1 |= USART_CR1_RXNEIE; } @@ -64,3 +69,29 @@ void init_adc(void) { // TODO } + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/common.c b/lib/common.c new file mode 100644 index 0000000..729b031 --- /dev/null +++ b/lib/common.c @@ -0,0 +1,11 @@ +#include "common.h" + +__attribute__((always_inline)) +inline uint32_t __RBIT(uint32_t value) +{ + register uint32_t result; + + __asm__ volatile("rbit %0, %1" : "=r"(result) : "r"(value)); + return (result); +} + diff --git a/lib/common.h b/lib/common.h index 85aeb07..6d8cc63 100644 --- a/lib/common.h +++ b/lib/common.h @@ -6,10 +6,10 @@ #include #include - +// Memory mapped IO pointer types typedef volatile uint8_t* io8_t; typedef volatile uint16_t* io16_t; -typedef volatile uint32_t* io32_t ; +typedef volatile uint32_t* io32_t; typedef volatile uint64_t* io64_t; /* Generic memory-mapped I/O accessor functions */ @@ -25,45 +25,65 @@ typedef volatile uint64_t* io64_t; #define BBIO_PERIPH(addr, bit) \ MMIO32((((uint32_t)addr) & 0x0FFFFF) * 32 + 0x42000000 + (bit) * 4) + +// intrinsics +#define wait_for_interrupt() __asm__("WFI") + +#define __CLZ(div) __builtin_clz(div) +#define count_leading_zeros(div) __CLZ(div) + +#define __REV(x) __builtin_bswap32(x) +#define reverse_bytes(x) __REV(x) + +#define enable_interrupts() __asm__("CPSIE I") +#define disable_interrupts() __asm__("CPSID I"); +#define enable_faults() __asm__("CPSIE F"); +#define disable_faults() __asm__("CPSID F"); + +uint32_t __RBIT(uint32_t value); // defined in c file as inline asm +#define reverse_bits(v) __RBIT(v) + + // i...iterator, m...mask, count...nr of bits #define BitFieldLoop(i, m, count) for (uint32_t i = 0, m = 1; i < count; m <<= 1, i++) +// get a peripheral register pointer #define P_REG(periph_base, reg_offs) ((io32_t) ((periph_base) + (reg_offs))) #define BIT(x) (1 << (x)) -#define BIT0 (1<<0) -#define BIT1 (1<<1) -#define BIT2 (1<<2) -#define BIT3 (1<<3) -#define BIT4 (1<<4) -#define BIT5 (1<<5) -#define BIT6 (1<<6) -#define BIT7 (1<<7) -#define BIT8 (1<<8) -#define BIT9 (1<<9) -#define BIT10 (1<<10) -#define BIT11 (1<<11) -#define BIT12 (1<<12) -#define BIT13 (1<<13) -#define BIT14 (1<<14) -#define BIT15 (1<<15) -#define BIT16 (1<<16) -#define BIT17 (1<<17) -#define BIT18 (1<<18) -#define BIT19 (1<<19) -#define BIT20 (1<<20) -#define BIT21 (1<<21) -#define BIT22 (1<<22) -#define BIT23 (1<<23) -#define BIT24 (1<<24) -#define BIT25 (1<<25) -#define BIT26 (1<<26) -#define BIT27 (1<<27) -#define BIT28 (1<<28) -#define BIT29 (1<<29) -#define BIT30 (1<<30) -#define BIT31 (1<<31) +#define BIT0 BIT(0) +#define BIT1 BIT(1) +#define BIT2 BIT(2) +#define BIT3 BIT(3) +#define BIT4 BIT(4) +#define BIT5 BIT(5) +#define BIT6 BIT(6) +#define BIT7 BIT(7) +#define BIT8 BIT(8) +#define BIT9 BIT(9) +#define BIT10 BIT(10) +#define BIT11 BIT(11) +#define BIT12 BIT(12) +#define BIT13 BIT(13) +#define BIT14 BIT(14) +#define BIT15 BIT(15) +#define BIT16 BIT(16) +#define BIT17 BIT(17) +#define BIT18 BIT(18) +#define BIT19 BIT(19) +#define BIT20 BIT(20) +#define BIT21 BIT(21) +#define BIT22 BIT(22) +#define BIT23 BIT(23) +#define BIT24 BIT(24) +#define BIT25 BIT(25) +#define BIT26 BIT(26) +#define BIT27 BIT(27) +#define BIT28 BIT(28) +#define BIT29 BIT(29) +#define BIT30 BIT(30) +#define BIT31 BIT(31) @@ -79,3 +99,4 @@ typedef volatile uint64_t* io64_t; #include "defs_i2c.h" #include "defs_spi.h" #include "defs_timers.h" +#include "defs_nvic.h" diff --git a/lib/defs_nvic.h b/lib/defs_nvic.h new file mode 100644 index 0000000..247787f --- /dev/null +++ b/lib/defs_nvic.h @@ -0,0 +1,388 @@ +#pragma once +#include "common.h" + +// AUTHOR : Ondrej Hruska +// DATE : 12/2015 +// DESCR : Control registers and bit masks for NVIC (interrupt vector controller) + +//**************************************************************************** +//* +//* REGISTERS +//* +//**************************************************************************** + +// system handler +#define SCS_SHPR(ipr_id) MMIO8(SCS_BASE + 0xD18 + ipr_id) +#define NVIC_NMI_IRQ -14 +#define NVIC_HARD_FAULT_IRQ -13 +#define NVIC_MEM_MANAGE_IRQ -12 +#define NVIC_BUS_FAULT_IRQ -11 +#define NVIC_USAGE_FAULT_IRQ -10 +/* irq numbers -6 to -9 are reserved */ +#define NVIC_SV_CALL_IRQ -5 +#define DEBUG_MONITOR_IRQ -4 +/* irq number -3 reserved */ +#define NVIC_PENDSV_IRQ -2 +#define NVIC_SYSTICK_IRQ -1 + + + +// NVIC + +#define NVIC_ISER_BASE (NVIC + 0x000) +#define NVIC_ISER0 MMIO32(NVIC + 0x000) // (R/W) Interrupt Set Enable Register +#define NVIC_ISER1 MMIO32(NVIC + 0x004) // (R/W) Interrupt Set Enable Register +#define NVIC_ISER2 MMIO32(NVIC + 0x008) // (R/W) Interrupt Set Enable Register +#define NVIC_ISER3 MMIO32(NVIC + 0x00C) // (R/W) Interrupt Set Enable Register +#define NVIC_ISER4 MMIO32(NVIC + 0x010) // (R/W) Interrupt Set Enable Register +#define NVIC_ISER5 MMIO32(NVIC + 0x014) // (R/W) Interrupt Set Enable Register +#define NVIC_ISER6 MMIO32(NVIC + 0x018) // (R/W) Interrupt Set Enable Register +#define NVIC_ISER7 MMIO32(NVIC + 0x01C) // (R/W) Interrupt Set Enable Register +#define NVIC_ISER8 MMIO32(NVIC + 0x020) // (R/W) Interrupt Set Enable Register + +#define NVIC_ICER_BASE (NVIC + 0x080) +#define NVIC_ICER0 MMIO32(NVIC + 0x080) // (R/W) Interrupt Clear Enable Register +#define NVIC_ICER1 MMIO32(NVIC + 0x084) // (R/W) Interrupt Clear Enable Register +#define NVIC_ICER2 MMIO32(NVIC + 0x088) // (R/W) Interrupt Clear Enable Register +#define NVIC_ICER3 MMIO32(NVIC + 0x08C) // (R/W) Interrupt Clear Enable Register +#define NVIC_ICER4 MMIO32(NVIC + 0x090) // (R/W) Interrupt Clear Enable Register +#define NVIC_ICER5 MMIO32(NVIC + 0x094) // (R/W) Interrupt Clear Enable Register +#define NVIC_ICER6 MMIO32(NVIC + 0x098) // (R/W) Interrupt Clear Enable Register +#define NVIC_ICER7 MMIO32(NVIC + 0x09C) // (R/W) Interrupt Clear Enable Register + +#define NVIC_ISPR_BASE (NVIC + 0x100) +#define NVIC_ISPR0 MMIO32(NVIC + 0x100) // (R/W) Interrupt Set Pending Register +#define NVIC_ISPR1 MMIO32(NVIC + 0x104) // (R/W) Interrupt Set Pending Register +#define NVIC_ISPR2 MMIO32(NVIC + 0x108) // (R/W) Interrupt Set Pending Register +#define NVIC_ISPR3 MMIO32(NVIC + 0x10C) // (R/W) Interrupt Set Pending Register +#define NVIC_ISPR4 MMIO32(NVIC + 0x110) // (R/W) Interrupt Set Pending Register +#define NVIC_ISPR5 MMIO32(NVIC + 0x114) // (R/W) Interrupt Set Pending Register +#define NVIC_ISPR6 MMIO32(NVIC + 0x118) // (R/W) Interrupt Set Pending Register +#define NVIC_ISPR7 MMIO32(NVIC + 0x11C) // (R/W) Interrupt Set Pending Register + +#define NVIC_ICPR_BASE (NVIC + 0x180) +#define NVIC_ICPR0 MMIO32(NVIC + 0x180) // (R/W) Interrupt Clear Pending Register +#define NVIC_ICPR1 MMIO32(NVIC + 0x184) // (R/W) Interrupt Clear Pending Register +#define NVIC_ICPR2 MMIO32(NVIC + 0x188) // (R/W) Interrupt Clear Pending Register +#define NVIC_ICPR3 MMIO32(NVIC + 0x18C) // (R/W) Interrupt Clear Pending Register +#define NVIC_ICPR4 MMIO32(NVIC + 0x190) // (R/W) Interrupt Clear Pending Register +#define NVIC_ICPR5 MMIO32(NVIC + 0x194) // (R/W) Interrupt Clear Pending Register +#define NVIC_ICPR6 MMIO32(NVIC + 0x198) // (R/W) Interrupt Clear Pending Register +#define NVIC_ICPR7 MMIO32(NVIC + 0x19C) // (R/W) Interrupt Clear Pending Register + +#define NVIC_IABR_BASE (NVIC + 0x200) +#define NVIC_IABR0 MMIO32(NVIC + 0x200) // (R/W) Interrupt Active bit Register +#define NVIC_IABR1 MMIO32(NVIC + 0x204) // (R/W) Interrupt Active bit Register +#define NVIC_IABR2 MMIO32(NVIC + 0x208) // (R/W) Interrupt Active bit Register +#define NVIC_IABR3 MMIO32(NVIC + 0x20C) // (R/W) Interrupt Active bit Register +#define NVIC_IABR4 MMIO32(NVIC + 0x210) // (R/W) Interrupt Active bit Register +#define NVIC_IABR5 MMIO32(NVIC + 0x214) // (R/W) Interrupt Active bit Register +#define NVIC_IABR6 MMIO32(NVIC + 0x218) // (R/W) Interrupt Active bit Register +#define NVIC_IABR7 MMIO32(NVIC + 0x21C) // (R/W) Interrupt Active bit Register + +#define NVIC_IPR_BASE (NVIC + 0x300) // (R/W) Interrupt Priority Register (8Bit wide) +240 + +#define NVIC_IPR(n) MMIO8(NVIC_IPR_BASE + (n)) +#define NVIC_ISER(n) MMIO32(NVIC_ISER_BASE + (n*4)) +#define NVIC_ICER(n) MMIO32(NVIC_ICER_BASE + (n*4)) +#define NVIC_ISPR(n) MMIO32(NVIC_ISPR_BASE + (n*4)) +#define NVIC_ICPR(n) MMIO32(NVIC_ICPR_BASE + (n*4)) +#define NVIC_IABR(n) MMIO32(NVIC_IABR_BASE + (n*4)) + +#define NVIC_STIR MMIO32(NVIC + 0xE00) // ( /W) Software Trigger Interrupt Register + + + +//**************************************************************************** +//* +//* BIT MASKS AND DEFINITIONS +//* +//**************************************************************************** + + +//***************** Bit definition for NVIC_ISER register ****************** +#define NVIC_ISER_SETENA 0xFFFFFFFF // Interrupt set enable bits +#define NVIC_ISER_SETENA_0 0x00000001 // bit 0 +#define NVIC_ISER_SETENA_1 0x00000002 // bit 1 +#define NVIC_ISER_SETENA_2 0x00000004 // bit 2 +#define NVIC_ISER_SETENA_3 0x00000008 // bit 3 +#define NVIC_ISER_SETENA_4 0x00000010 // bit 4 +#define NVIC_ISER_SETENA_5 0x00000020 // bit 5 +#define NVIC_ISER_SETENA_6 0x00000040 // bit 6 +#define NVIC_ISER_SETENA_7 0x00000080 // bit 7 +#define NVIC_ISER_SETENA_8 0x00000100 // bit 8 +#define NVIC_ISER_SETENA_9 0x00000200 // bit 9 +#define NVIC_ISER_SETENA_10 0x00000400 // bit 10 +#define NVIC_ISER_SETENA_11 0x00000800 // bit 11 +#define NVIC_ISER_SETENA_12 0x00001000 // bit 12 +#define NVIC_ISER_SETENA_13 0x00002000 // bit 13 +#define NVIC_ISER_SETENA_14 0x00004000 // bit 14 +#define NVIC_ISER_SETENA_15 0x00008000 // bit 15 +#define NVIC_ISER_SETENA_16 0x00010000 // bit 16 +#define NVIC_ISER_SETENA_17 0x00020000 // bit 17 +#define NVIC_ISER_SETENA_18 0x00040000 // bit 18 +#define NVIC_ISER_SETENA_19 0x00080000 // bit 19 +#define NVIC_ISER_SETENA_20 0x00100000 // bit 20 +#define NVIC_ISER_SETENA_21 0x00200000 // bit 21 +#define NVIC_ISER_SETENA_22 0x00400000 // bit 22 +#define NVIC_ISER_SETENA_23 0x00800000 // bit 23 +#define NVIC_ISER_SETENA_24 0x01000000 // bit 24 +#define NVIC_ISER_SETENA_25 0x02000000 // bit 25 +#define NVIC_ISER_SETENA_26 0x04000000 // bit 26 +#define NVIC_ISER_SETENA_27 0x08000000 // bit 27 +#define NVIC_ISER_SETENA_28 0x10000000 // bit 28 +#define NVIC_ISER_SETENA_29 0x20000000 // bit 29 +#define NVIC_ISER_SETENA_30 0x40000000 // bit 30 +#define NVIC_ISER_SETENA_31 0x80000000 // bit 31 + +//***************** Bit definition for NVIC_ICER register ****************** +#define NVIC_ICER_CLRENA 0xFFFFFFFF // Interrupt clear-enable bits +#define NVIC_ICER_CLRENA_0 0x00000001 // bit 0 +#define NVIC_ICER_CLRENA_1 0x00000002 // bit 1 +#define NVIC_ICER_CLRENA_2 0x00000004 // bit 2 +#define NVIC_ICER_CLRENA_3 0x00000008 // bit 3 +#define NVIC_ICER_CLRENA_4 0x00000010 // bit 4 +#define NVIC_ICER_CLRENA_5 0x00000020 // bit 5 +#define NVIC_ICER_CLRENA_6 0x00000040 // bit 6 +#define NVIC_ICER_CLRENA_7 0x00000080 // bit 7 +#define NVIC_ICER_CLRENA_8 0x00000100 // bit 8 +#define NVIC_ICER_CLRENA_9 0x00000200 // bit 9 +#define NVIC_ICER_CLRENA_10 0x00000400 // bit 10 +#define NVIC_ICER_CLRENA_11 0x00000800 // bit 11 +#define NVIC_ICER_CLRENA_12 0x00001000 // bit 12 +#define NVIC_ICER_CLRENA_13 0x00002000 // bit 13 +#define NVIC_ICER_CLRENA_14 0x00004000 // bit 14 +#define NVIC_ICER_CLRENA_15 0x00008000 // bit 15 +#define NVIC_ICER_CLRENA_16 0x00010000 // bit 16 +#define NVIC_ICER_CLRENA_17 0x00020000 // bit 17 +#define NVIC_ICER_CLRENA_18 0x00040000 // bit 18 +#define NVIC_ICER_CLRENA_19 0x00080000 // bit 19 +#define NVIC_ICER_CLRENA_20 0x00100000 // bit 20 +#define NVIC_ICER_CLRENA_21 0x00200000 // bit 21 +#define NVIC_ICER_CLRENA_22 0x00400000 // bit 22 +#define NVIC_ICER_CLRENA_23 0x00800000 // bit 23 +#define NVIC_ICER_CLRENA_24 0x01000000 // bit 24 +#define NVIC_ICER_CLRENA_25 0x02000000 // bit 25 +#define NVIC_ICER_CLRENA_26 0x04000000 // bit 26 +#define NVIC_ICER_CLRENA_27 0x08000000 // bit 27 +#define NVIC_ICER_CLRENA_28 0x10000000 // bit 28 +#define NVIC_ICER_CLRENA_29 0x20000000 // bit 29 +#define NVIC_ICER_CLRENA_30 0x40000000 // bit 30 +#define NVIC_ICER_CLRENA_31 0x80000000 // bit 31 + +//***************** Bit definition for NVIC_ISPR register ****************** +#define NVIC_ISPR_SETPEND 0xFFFFFFFF // Interrupt set-pending bits +#define NVIC_ISPR_SETPEND_0 0x00000001 // bit 0 +#define NVIC_ISPR_SETPEND_1 0x00000002 // bit 1 +#define NVIC_ISPR_SETPEND_2 0x00000004 // bit 2 +#define NVIC_ISPR_SETPEND_3 0x00000008 // bit 3 +#define NVIC_ISPR_SETPEND_4 0x00000010 // bit 4 +#define NVIC_ISPR_SETPEND_5 0x00000020 // bit 5 +#define NVIC_ISPR_SETPEND_6 0x00000040 // bit 6 +#define NVIC_ISPR_SETPEND_7 0x00000080 // bit 7 +#define NVIC_ISPR_SETPEND_8 0x00000100 // bit 8 +#define NVIC_ISPR_SETPEND_9 0x00000200 // bit 9 +#define NVIC_ISPR_SETPEND_10 0x00000400 // bit 10 +#define NVIC_ISPR_SETPEND_11 0x00000800 // bit 11 +#define NVIC_ISPR_SETPEND_12 0x00001000 // bit 12 +#define NVIC_ISPR_SETPEND_13 0x00002000 // bit 13 +#define NVIC_ISPR_SETPEND_14 0x00004000 // bit 14 +#define NVIC_ISPR_SETPEND_15 0x00008000 // bit 15 +#define NVIC_ISPR_SETPEND_16 0x00010000 // bit 16 +#define NVIC_ISPR_SETPEND_17 0x00020000 // bit 17 +#define NVIC_ISPR_SETPEND_18 0x00040000 // bit 18 +#define NVIC_ISPR_SETPEND_19 0x00080000 // bit 19 +#define NVIC_ISPR_SETPEND_20 0x00100000 // bit 20 +#define NVIC_ISPR_SETPEND_21 0x00200000 // bit 21 +#define NVIC_ISPR_SETPEND_22 0x00400000 // bit 22 +#define NVIC_ISPR_SETPEND_23 0x00800000 // bit 23 +#define NVIC_ISPR_SETPEND_24 0x01000000 // bit 24 +#define NVIC_ISPR_SETPEND_25 0x02000000 // bit 25 +#define NVIC_ISPR_SETPEND_26 0x04000000 // bit 26 +#define NVIC_ISPR_SETPEND_27 0x08000000 // bit 27 +#define NVIC_ISPR_SETPEND_28 0x10000000 // bit 28 +#define NVIC_ISPR_SETPEND_29 0x20000000 // bit 29 +#define NVIC_ISPR_SETPEND_30 0x40000000 // bit 30 +#define NVIC_ISPR_SETPEND_31 0x80000000 // bit 31 + +//***************** Bit definition for NVIC_ICPR register ****************** +#define NVIC_ICPR_CLRPEND 0xFFFFFFFF // Interrupt clear-pending bits +#define NVIC_ICPR_CLRPEND_0 0x00000001 // bit 0 +#define NVIC_ICPR_CLRPEND_1 0x00000002 // bit 1 +#define NVIC_ICPR_CLRPEND_2 0x00000004 // bit 2 +#define NVIC_ICPR_CLRPEND_3 0x00000008 // bit 3 +#define NVIC_ICPR_CLRPEND_4 0x00000010 // bit 4 +#define NVIC_ICPR_CLRPEND_5 0x00000020 // bit 5 +#define NVIC_ICPR_CLRPEND_6 0x00000040 // bit 6 +#define NVIC_ICPR_CLRPEND_7 0x00000080 // bit 7 +#define NVIC_ICPR_CLRPEND_8 0x00000100 // bit 8 +#define NVIC_ICPR_CLRPEND_9 0x00000200 // bit 9 +#define NVIC_ICPR_CLRPEND_10 0x00000400 // bit 10 +#define NVIC_ICPR_CLRPEND_11 0x00000800 // bit 11 +#define NVIC_ICPR_CLRPEND_12 0x00001000 // bit 12 +#define NVIC_ICPR_CLRPEND_13 0x00002000 // bit 13 +#define NVIC_ICPR_CLRPEND_14 0x00004000 // bit 14 +#define NVIC_ICPR_CLRPEND_15 0x00008000 // bit 15 +#define NVIC_ICPR_CLRPEND_16 0x00010000 // bit 16 +#define NVIC_ICPR_CLRPEND_17 0x00020000 // bit 17 +#define NVIC_ICPR_CLRPEND_18 0x00040000 // bit 18 +#define NVIC_ICPR_CLRPEND_19 0x00080000 // bit 19 +#define NVIC_ICPR_CLRPEND_20 0x00100000 // bit 20 +#define NVIC_ICPR_CLRPEND_21 0x00200000 // bit 21 +#define NVIC_ICPR_CLRPEND_22 0x00400000 // bit 22 +#define NVIC_ICPR_CLRPEND_23 0x00800000 // bit 23 +#define NVIC_ICPR_CLRPEND_24 0x01000000 // bit 24 +#define NVIC_ICPR_CLRPEND_25 0x02000000 // bit 25 +#define NVIC_ICPR_CLRPEND_26 0x04000000 // bit 26 +#define NVIC_ICPR_CLRPEND_27 0x08000000 // bit 27 +#define NVIC_ICPR_CLRPEND_28 0x10000000 // bit 28 +#define NVIC_ICPR_CLRPEND_29 0x20000000 // bit 29 +#define NVIC_ICPR_CLRPEND_30 0x40000000 // bit 30 +#define NVIC_ICPR_CLRPEND_31 0x80000000 // bit 31 + +//***************** Bit definition for NVIC_IABR register ****************** +#define NVIC_IABR_ACTIVE 0xFFFFFFFF // Interrupt active flags +#define NVIC_IABR_ACTIVE_0 0x00000001 // bit 0 +#define NVIC_IABR_ACTIVE_1 0x00000002 // bit 1 +#define NVIC_IABR_ACTIVE_2 0x00000004 // bit 2 +#define NVIC_IABR_ACTIVE_3 0x00000008 // bit 3 +#define NVIC_IABR_ACTIVE_4 0x00000010 // bit 4 +#define NVIC_IABR_ACTIVE_5 0x00000020 // bit 5 +#define NVIC_IABR_ACTIVE_6 0x00000040 // bit 6 +#define NVIC_IABR_ACTIVE_7 0x00000080 // bit 7 +#define NVIC_IABR_ACTIVE_8 0x00000100 // bit 8 +#define NVIC_IABR_ACTIVE_9 0x00000200 // bit 9 +#define NVIC_IABR_ACTIVE_10 0x00000400 // bit 10 +#define NVIC_IABR_ACTIVE_11 0x00000800 // bit 11 +#define NVIC_IABR_ACTIVE_12 0x00001000 // bit 12 +#define NVIC_IABR_ACTIVE_13 0x00002000 // bit 13 +#define NVIC_IABR_ACTIVE_14 0x00004000 // bit 14 +#define NVIC_IABR_ACTIVE_15 0x00008000 // bit 15 +#define NVIC_IABR_ACTIVE_16 0x00010000 // bit 16 +#define NVIC_IABR_ACTIVE_17 0x00020000 // bit 17 +#define NVIC_IABR_ACTIVE_18 0x00040000 // bit 18 +#define NVIC_IABR_ACTIVE_19 0x00080000 // bit 19 +#define NVIC_IABR_ACTIVE_20 0x00100000 // bit 20 +#define NVIC_IABR_ACTIVE_21 0x00200000 // bit 21 +#define NVIC_IABR_ACTIVE_22 0x00400000 // bit 22 +#define NVIC_IABR_ACTIVE_23 0x00800000 // bit 23 +#define NVIC_IABR_ACTIVE_24 0x01000000 // bit 24 +#define NVIC_IABR_ACTIVE_25 0x02000000 // bit 25 +#define NVIC_IABR_ACTIVE_26 0x04000000 // bit 26 +#define NVIC_IABR_ACTIVE_27 0x08000000 // bit 27 +#define NVIC_IABR_ACTIVE_28 0x10000000 // bit 28 +#define NVIC_IABR_ACTIVE_29 0x20000000 // bit 29 +#define NVIC_IABR_ACTIVE_30 0x40000000 // bit 30 +#define NVIC_IABR_ACTIVE_31 0x80000000 // bit 31 + +//***************** Bit definition for NVIC_PRI0 register ****************** +#define NVIC_IPR0_PRI_0 0x000000FF // Priority of interrupt 0 +#define NVIC_IPR0_PRI_1 0x0000FF00 // Priority of interrupt 1 +#define NVIC_IPR0_PRI_2 0x00FF0000 // Priority of interrupt 2 +#define NVIC_IPR0_PRI_3 0xFF000000 // Priority of interrupt 3 + +//***************** Bit definition for NVIC_PRI1 register ****************** +#define NVIC_IPR1_PRI_4 0x000000FF // Priority of interrupt 4 +#define NVIC_IPR1_PRI_5 0x0000FF00 // Priority of interrupt 5 +#define NVIC_IPR1_PRI_6 0x00FF0000 // Priority of interrupt 6 +#define NVIC_IPR1_PRI_7 0xFF000000 // Priority of interrupt 7 + +//***************** Bit definition for NVIC_PRI2 register ****************** +#define NVIC_IPR2_PRI_8 0x000000FF // Priority of interrupt 8 +#define NVIC_IPR2_PRI_9 0x0000FF00 // Priority of interrupt 9 +#define NVIC_IPR2_PRI_10 0x00FF0000 // Priority of interrupt 10 +#define NVIC_IPR2_PRI_11 0xFF000000 // Priority of interrupt 11 + +//***************** Bit definition for NVIC_PRI3 register ****************** +#define NVIC_IPR3_PRI_12 0x000000FF // Priority of interrupt 12 +#define NVIC_IPR3_PRI_13 0x0000FF00 // Priority of interrupt 13 +#define NVIC_IPR3_PRI_14 0x00FF0000 // Priority of interrupt 14 +#define NVIC_IPR3_PRI_15 0xFF000000 // Priority of interrupt 15 + +//***************** Bit definition for NVIC_PRI4 register ****************** +#define NVIC_IPR4_PRI_16 0x000000FF // Priority of interrupt 16 +#define NVIC_IPR4_PRI_17 0x0000FF00 // Priority of interrupt 17 +#define NVIC_IPR4_PRI_18 0x00FF0000 // Priority of interrupt 18 +#define NVIC_IPR4_PRI_19 0xFF000000 // Priority of interrupt 19 + +//***************** Bit definition for NVIC_PRI5 register ****************** +#define NVIC_IPR5_PRI_20 0x000000FF // Priority of interrupt 20 +#define NVIC_IPR5_PRI_21 0x0000FF00 // Priority of interrupt 21 +#define NVIC_IPR5_PRI_22 0x00FF0000 // Priority of interrupt 22 +#define NVIC_IPR5_PRI_23 0xFF000000 // Priority of interrupt 23 + +//***************** Bit definition for NVIC_PRI6 register ****************** +#define NVIC_IPR6_PRI_24 0x000000FF // Priority of interrupt 24 +#define NVIC_IPR6_PRI_25 0x0000FF00 // Priority of interrupt 25 +#define NVIC_IPR6_PRI_26 0x00FF0000 // Priority of interrupt 26 +#define NVIC_IPR6_PRI_27 0xFF000000 // Priority of interrupt 27 + +//***************** Bit definition for NVIC_PRI7 register ****************** +#define NVIC_IPR7_PRI_28 0x000000FF // Priority of interrupt 28 +#define NVIC_IPR7_PRI_29 0x0000FF00 // Priority of interrupt 29 +#define NVIC_IPR7_PRI_30 0x00FF0000 // Priority of interrupt 30 +#define NVIC_IPR7_PRI_31 0xFF000000 // Priority of interrupt 31 + + +//---------- definitions for L100 --------------- +// copied from libopencm3 + +#define NVIC_WWDG_IRQ 0 +#define NVIC_PVD_IRQ 1 +#define NVIC_TAMPER_STAMP_IRQ 2 +#define NVIC_RTC_WKUP_IRQ 3 +#define NVIC_FLASH_IRQ 4 +#define NVIC_RCC_IRQ 5 +#define NVIC_EXTI0_IRQ 6 +#define NVIC_EXTI1_IRQ 7 +#define NVIC_EXTI2_IRQ 8 +#define NVIC_EXTI3_IRQ 9 +#define NVIC_EXTI4_IRQ 10 +#define NVIC_DMA1_CHANNEL1_IRQ 11 +#define NVIC_DMA1_CHANNEL2_IRQ 12 +#define NVIC_DMA1_CHANNEL3_IRQ 13 +#define NVIC_DMA1_CHANNEL4_IRQ 14 +#define NVIC_DMA1_CHANNEL5_IRQ 15 +#define NVIC_DMA1_CHANNEL6_IRQ 16 +#define NVIC_DMA1_CHANNEL7_IRQ 17 +#define NVIC_ADC1_IRQ 18 +#define NVIC_USB_HP_IRQ 19 +#define NVIC_USB_LP_IRQ 20 +#define NVIC_DAC_IRQ 21 +#define NVIC_COMP_IRQ 22 +#define NVIC_EXTI9_5_IRQ 23 +#define NVIC_LCD_IRQ 24 +#define NVIC_TIM9_IRQ 25 +#define NVIC_TIM10_IRQ 26 +#define NVIC_TIM11_IRQ 27 +#define NVIC_TIM2_IRQ 28 +#define NVIC_TIM3_IRQ 29 +#define NVIC_TIM4_IRQ 30 +#define NVIC_I2C1_EV_IRQ 31 +#define NVIC_I2C1_ER_IRQ 32 +#define NVIC_I2C2_EV_IRQ 33 +#define NVIC_I2C2_ER_IRQ 34 +#define NVIC_SPI1_IRQ 35 +#define NVIC_SPI2_IRQ 36 +#define NVIC_USART1_IRQ 37 +#define NVIC_USART2_IRQ 38 +#define NVIC_USART3_IRQ 39 +#define NVIC_EXTI15_10_IRQ 40 +#define NVIC_RTC_ALARM_IRQ 41 +#define NVIC_USB_FS_WAKEUP_IRQ 42 +#define NVIC_TIM6_IRQ 43 +#define NVIC_TIM7_IRQ 44 +#define NVIC_SDIO_IRQ 45 +#define NVIC_TIM5_IRQ 46 +#define NVIC_SPI3_IRQ 47 +#define NVIC_UART4_IRQ 48 +#define NVIC_UART5_IRQ 49 +#define NVIC_DMA2_CH1_IRQ 50 +#define NVIC_DMA2_CH2_IRQ 51 +#define NVIC_DMA2_CH3_IRQ 52 +#define NVIC_DMA2_CH4_IRQ 53 +#define NVIC_DMA2_CH5_IRQ 54 +#define NVIC_AES_IRQ 55 +#define NVIC_COMP_ACQ_IRQ 56 + +#define NVIC_IRQ_COUNT 57 diff --git a/main.c b/main.c index 4cc8f4e..285c931 100644 --- a/main.c +++ b/main.c @@ -13,6 +13,24 @@ void say_hello(void) } +/** IRQ */ +void USART3_IRQHandler(void) +{ + if (USART3_SR & USART_SR_ORE) { + USART3_SR &= ~USART_SR_ORE; + return; + } + + blue_blink(); + + char c = usart_rx_char(USART3); + usart_tx_char(USART3, c); + + USART3_SR ^= USART_SR_RXNE; +} + + + /** Called by startup script, before main() */ void SystemInit(void) { diff --git a/proj.pro b/proj.pro index e625685..682cbe0 100644 --- a/proj.pro +++ b/proj.pro @@ -29,7 +29,9 @@ SOURCES += \ utils/timebase.c \ utils/usart.c \ utils/debounce.c \ - blink.c + blink.c \ + lib/common.c \ + utils/nvic.c HEADERS += \ lib/common.h \ @@ -54,5 +56,7 @@ HEADERS += \ lib/defs_dma.h \ lib/defs_i2c.h \ lib/defs_spi.h \ - lib/defs_timers.h + lib/defs_timers.h \ + lib/defs_nvic.h \ + utils/nvic.h diff --git a/utils/nvic.c b/utils/nvic.c new file mode 100644 index 0000000..c3e4658 --- /dev/null +++ b/utils/nvic.c @@ -0,0 +1,64 @@ +#include "nvic.h" + +// implementation stolen from libopencm3, originally under LGPL + +void nvic_enable_irq(uint8_t irqn) +{ + NVIC_ISER(irqn / 32) = (1 << (irqn % 32)); +} + + +void nvic_disable_irq(uint8_t irqn) +{ + NVIC_ICER(irqn / 32) = (1 << (irqn % 32)); +} + + +uint8_t nvic_get_pending_irq(uint8_t irqn) +{ + return NVIC_ISPR(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0; +} + + +void nvic_set_pending_irq(uint8_t irqn) +{ + NVIC_ISPR(irqn / 32) = (1 << (irqn % 32)); +} + + +void nvic_clear_pending_irq(uint8_t irqn) +{ + NVIC_ICPR(irqn / 32) = (1 << (irqn % 32)); +} + + +uint8_t nvic_get_irq_enabled(uint8_t irqn) +{ + return NVIC_ISER(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0; +} + + +void nvic_set_priority(uint8_t irqn, uint8_t priority) +{ + NVIC_IPR(irqn) = priority; +} + + +void nvic_set_priority_arm(int8_t irqn, uint8_t priority) +{ + SCS_SHPR((irqn & 0xF) - 4) = priority; // maybe wrong +} + + +uint8_t nvic_get_active_irq(uint8_t irqn) +{ + return NVIC_IABR(irqn / 32) & (1 << (irqn % 32)) ? 1 : 0; +} + + +void nvic_generate_software_interrupt(uint16_t irqn) +{ + if (irqn <= 239) { + NVIC_STIR |= irqn; + } +} diff --git a/utils/nvic.h b/utils/nvic.h new file mode 100644 index 0000000..fe47cc2 --- /dev/null +++ b/utils/nvic.h @@ -0,0 +1,24 @@ +#pragma once +#include "common.h" + +// implementation stolen from libopencm3, originally under LGPL + +void nvic_enable_irq(uint8_t irqn); + +void nvic_disable_irq(uint8_t irqn); + +uint8_t nvic_get_pending_irq(uint8_t irqn); + +void nvic_set_pending_irq(uint8_t irqn); + +void nvic_clear_pending_irq(uint8_t irqn); + +uint8_t nvic_get_irq_enabled(uint8_t irqn); + +void nvic_set_priority(uint8_t irqn, uint8_t priority); + +void nvic_set_priority_arm(int8_t irqn, uint8_t priority); // negative numbers (ie SYSTICK) + +uint8_t nvic_get_active_irq(uint8_t irqn); + +void nvic_generate_software_interrupt(uint16_t irqn); // 0-239