CortexM0: IPR and SHPR are only word addressable

For ARMv6M, the IPR and SHPR registers are accessible only when
adddressed with a 32bit word read or write.

Currently in libopencm3 all NVIC interrupt priority register accesses
are made using an 8bit read or write, which results in the hardware
ignoring the write or always returning 0 on read.

Address this by introducing NVIC_IPR32() and SCS_SHPR32() macro and
conditional implementation of nvic_set_priority when building for
cortex-m0.

See ARMv6M developer documentation:
IPR: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/Cihgjeed.html
SHPR: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0497a/CIAGECDD.html
This commit is contained in:
Matt Anderson
2019-06-19 04:01:37 -04:00
committed by Karl Palsson
parent baa2f13592
commit d8579dde95
3 changed files with 29 additions and 1 deletions

View File

@@ -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
}
}