How do I interrupt an ISR with a higher-priority ISR on an STM32F105?
The priorities are not being initialized correctly.

The code in the question initializes the NVIC like so:

// IRQHigh, enabled immediately
NVIC_InitStructure.NVIC_IRQChannel = IRQHIGH_EXTI_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&amp;NVIC_InitStructure);

// IRQLow, to be enabled later:
NVIC_InitStructure.NVIC_IRQChannel = IRQLOW_EXTI_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 5;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE;
NVIC_Init(&amp;NVIC_InitStructure);


Then, later, IRQLow is explicitly enabled with NVIC_EnableIRQ().

The problem is that the NVIC_Init() function (from the SPL) doesn't actually initialize anything (!) if IRQChannelCmd = DISABLE. It simply sets the ICER register to disable that interrupt.

This seems like a bug to me, but so be it.  Now I need to go and check the other xxx_Init() functions in the SPL and see if anything else might bite me later :)

There are a few solutions. The one I prefer is to leave out all five lines of the IRQLow init sequence and replace them with this:

NVIC_SetPriority(IRQLOW_EXTI_IRQn, 5);


Then, when it is time, NVIC_EnableIRQ() can be used as intended.

Note that this works because the NVIC is configured with NVIC_PriorityGroup_4 (no subpriorities).  Different PriorityGroup settings would require you'd to configure the subpriority, too.