# Systick interruption doesn't trigger when handling another interrupt

I am experimenting with the STM32f4 discovery and i tried to use a delay (based on SYSTICK) in an EXTI_IRQ handler but i figured out that while the EXTI handler is triggered the the systick handler doesn't trigger , here's my code :

extern volatile int del ;
void EXTI0_IRQHandler(void) {

if (EXTI_GetITStatus(EXTI_Line0) != RESET ) {
/* Do your stuff when PD0 is changed */
del=1000 ;
while(del)
{
//do something
}

/* Clear interrupt flag */
EXTI_ClearITPendingBit(EXTI_Line0);
}
}


And the systick handler :

void SysTick_Handler(void)
{
if (del--)
;
}


So how can i solve this problem .

• on most CPUs, interrupts have an order of precedence. A higher precedence interrupt will mask a lower precedence interrupt while the higher precedence interrupt is being handled. – user3629249 Mar 25 '16 at 19:54

You can, if your processor allows it (it should, since I believe all of that series are Cortex M4 based), set the Systick Interrupt to a higher priority than the other interrupts and then find out if you can make your compiler/processor not turn off interrupts globally while processing an interrupt.

That is, if you want to have delays in your interrupts.

Hint: You shouldn't want that.

Interrupts are meant to run efficiently and quickly to handle important events that are critical. If something needs a delay beyond a couple of ASM("__volatile__ NOP\n NOP\n NOP\n")'s, it's probably not something you want in your interrupt.

If you have a "heavy task" that gets triggered by an interrupt it's much neater to write:

uint32_t taskFlags;  // semafore register, can also be any other data type that fits your flags (1ul --> uint32_t or larger!)
#define HANDLE_MY_INTERRUPT_STUFF    (1ul<<0) // Define a flag for interrupt things.

void main(void) {
while(1) {
if(taskFlags & HANDLE_MY_INTERRUPT_STUFF) { // Check the flag
// Do your interrupt stuff
// Allowed to have many delays and other weird stuff

taskFlags &= ~HANDLE_MY_INTERRUPT_STUFF; // Clear the flag.
}
}
}

InterruptHandler(void) {
taskFlags |= HANDLE_MY_INTERRUPT_STUFF;  // set the flag
}


And now suddenly all that heavy processing gets done in the main loop, where it can be interrupted and all and won't harm any other time-critical things. But only triggered by the interrupt source, through the flags.

Although through the flags you will of course risk a slight variable delay in execution, it's always a balancing act.

Between processor types the delay will usually be between 4 and 40 clock cycles + average other interrupt code execution, so at a couple MHz using a 10ms delay will usually already marginalise that delay and its variation.)

• but what if it's the case when you need to denounce a button ( the case of interruption triggered with push button ) with a delay i know i can make delay with a for loop but it's a bad solution . – starter Mar 24 '16 at 1:21
• @starter see the second part. Anything you do inside the interrupt can be done in the main with a flag. It's that simple. – Asmyldof Mar 24 '16 at 1:58
• thank you that was helpful , i was over complicating life . – starter Mar 24 '16 at 7:28

This is the simplest solution to do:

extern __IO uint32_t TimmingDelay;

void Delay(__IO uint32_t time)
{
TimmingDelay = time;
while(TimmingDelay != 0);
}


This is in stm32f4xx_it.c:

void SysTick_Handler(void)
{
if(TimmingDelay != 0)
{
TimmingDelay --;
}
}


In main don't forget to add this line:

  SysTick_Config(SystemCoreClock/1000000);


and then use Delay("AddDelayHere"); and spam all over your code.

• This isn't guaranteed to solve the interrupt conflict – Asmyldof Mar 24 '16 at 0:40