diff --git a/include/libopencm3/cm3/nvic.h b/include/libopencm3/cm3/nvic.h index 0bd51340..c967f15d 100644 --- a/include/libopencm3/cm3/nvic.h +++ b/include/libopencm3/cm3/nvic.h @@ -92,10 +92,15 @@ /** IPR: Interrupt Priority Registers * @note 240 8bit Registers - * @@note 32 8bit Registers on CM0 + * @note 32 8bit Registers on CM0, requires word access */ +#if defined(__ARM_ARCH_6M__) +#define NVIC_IPR32(ipr_id) MMIO32(NVIC_BASE + 0x300 + \ + ((ipr_id) * 4)) +#else #define NVIC_IPR(ipr_id) MMIO8(NVIC_BASE + 0x300 + \ (ipr_id)) +#endif #if defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) /** STIR: Software Trigger Interrupt Register */ diff --git a/include/libopencm3/cm3/scs.h b/include/libopencm3/cm3/scs.h index 27f6093f..cb0a6ddb 100644 --- a/include/libopencm3/cm3/scs.h +++ b/include/libopencm3/cm3/scs.h @@ -52,8 +52,14 @@ /** System Handler Priority 8 bits Registers, SHPR1/2/3. * Note: 12 8bit Registers + * Note: 3 32bit Registers on CM0, requires word access */ +#if defined(__ARM_ARCH_6M__) +#define SCS_SHPR32(ipr_id) MMIO32(SCS_BASE + 0xD18 + ((ipr_id) * 4)) +#else #define SCS_SHPR(ipr_id) MMIO8(SCS_BASE + 0xD18 + (ipr_id)) +#endif + /** * Debug Halting Control and Status Register (DHCSR). diff --git a/lib/cm3/nvic.c b/lib/cm3/nvic.c index 7b20941f..37f473b1 100644 --- a/lib/cm3/nvic.c +++ b/lib/cm3/nvic.c @@ -156,10 +156,27 @@ void nvic_set_priority(uint8_t irqn, uint8_t priority) * handling would mean signed integers. */ if (irqn >= NVIC_IRQ_COUNT) { /* Cortex-M system interrupts */ +#if defined(__ARM_ARCH_6M__) + /* ARM6M supports only 32bit word access to SHPR registers */ + irqn = (irqn & 0xF) - 4; + uint8_t shift = (irqn & 0x3) << 3; + uint8_t reg = irqn >> 2; + SCS_SHPR32(reg) = ((SCS_SHPR32(reg) & ~(0xFFUL << shift)) | + ((uint32_t) priority) << shift); +#else SCS_SHPR((irqn & 0xF) - 4) = priority; +#endif } else { /* Device specific interrupts */ +#if defined(__ARM_ARCH_6M__) + /* ARM6M supports only 32bit word access to IPR registers */ + uint8_t shift = (irqn & 0x3) << 3; + uint8_t reg = irqn >> 2; + NVIC_IPR32(reg) = ((NVIC_IPR32(reg) & ~(0xFFUL << shift)) | + ((uint32_t) priority) << shift); +#else NVIC_IPR(irqn) = priority; +#endif } }