Thu Dec 26 14:49:08 CET 2019

Interrupt priorities

I want TIMER and UART interrupts to arrive in the same handler to be
able to order events.

If one pre-empts the other, there is a race condition where a byte can
arrive and at the same time a timeout can happen.

I believe this can be solved by ensuring the same priority level for
interrupts.  That way the timer interrupt can be disabled in the UART

See chapter 10: interrupts and events.

Interrupt table:

       POS   PRI   ADDR
TIM2   28    35    B0
USART1 37    44    D4

So by default, the TIM2 preempts the USART1, which is not what I want.

However, if this is only using the upper 4 bits of an 8-bit priority,
then the levels are the same:

Both 35 and 44 are 2 after >>4.

So let's assume for now that there is no pre-emption between the two

Additionally, the code in libopencm3:

void nvic_set_priority(uint8_t irqn, uint8_t priority)
	/* code from lpc43xx/nvic.c -- this is quite a hack and alludes to the
	 * negative interrupt numbers assigned to the system interrupts. better
	 * handling would mean signed integers. */
	if (irqn >= NVIC_IRQ_COUNT) {
		/* Cortex-M  system interrupts */
		SCS_SHPR((irqn & 0xF) - 4) = priority;
	} else {
		/* Device specific interrupts */
		NVIC_IPR(irqn) = priority;


Interrupt Priority Registers

Use the Interrupt Priority Registers to assign a priority from 0 to
255 to each of the available interrupts. 0 is the highest priority,
and 255 is the lowest.

The priority registers are stored with the Most Significant Bit (MSB)
first. This means that if there are four bits of priority, the
priority value is stored in bits [7:4] of the byte. However, if there
are three bits of priority, the priority value is stored in bits [7:5]
of the byte. This means that an application can work even if it does
not know how many priorities are possible.

The register address, access type, and Reset state are:



/** System Handler Priority 8 bits Registers, SHPR1/2/3.
 * Note: 12 8bit Registers
#define SCS_SHPR(ipr_id)		MMIO8(SCS_BASE + 0xD18 + (ipr_id))

/* NVIC_BASE + 0x220 (0xE000 E320 - 0xE000 E3FF): Reserved */

/** IPR: Interrupt Priority Registers
 * @note 240 8bit Registers
 * @@note 32 8bit Registers on CM0
#define NVIC_IPR(ipr_id)		MMIO8(NVIC_BASE + 0x300 + \

#define NVIC_BASE                       (SCS_BASE + 0x0100)
#define SCS_BASE                        (PPBI_BASE + 0xE000)
#define PPBI_BASE                       (0xE0000000U)

PPBI_BASE E0000000
SCS_BASE  E000E000
NVIC_IPR  E000E400 + 0-239

Let's search online for nvic_set_priority()

This has defines: include/libopencm3/stm32/f1/nvic.h

#define NVIC_TIM2_IRQ 28
#define NVIC_USART1_IRQ 37

Let's just assert them?