AnsweredAssumed Answered

NVIC_ISPR "set-pending" bit to force ISR entry

Question asked by B.C.004 on May 25, 2015
Latest reply on May 27, 2015 by B.C.004
Hi,
I'm running some tests on an STM32F072 to verify my understanding of the docs. Apparently I'm missing an important point regarding the NVIC and pending interrupts...
I'm single-stepping through the code below with gdb. I was under the impression that setting a Pending bit (NVIC_ISPR register) would flag the corresponding int as "pending";  if it was also Enabled (NVIC_ISER register), the ISR handler should be called. But I tried forcing NVIC_ISER to 0xffff ffff to enable all interrupts (which is silly), and setting NVIC_ISPR to 0xffff ffff to mark all interrupts as Pending (also silly), yet the core keeps on running as if nothing happened ! (Note, if I set the TIM6 set-pending bit from inside the TIM6 ISR, I get the expected effect of the handler tail-chaining into itself.)

Yet, in PM0215 "Cortex M0 programming manual", p. 74, I read:
"A pending interrupt remains pending until one of the following
     - The processor enters the ISR for the int [...]
     - Software clears the pending bit
"
So what else does the processor need to "enter the ISR for the interrupt" ? Thanks for any enlightenment !

(sorry if the formatting turns out to be ugly, I'm having trouble with this forum's interface)


/* Test for interrupt re-entry / pending status etc */
/* (ab)uses TMR int */
  
#include <stm32f0xx.h>
#include <stm32f0xx_tim.h>
#include <stm32f0xx_rcc.h>
#include <stm32f0xx_dbgmcu.h>
  
void SystemInit(void) {
    NVIC->ICER[0] = -1; //disable all ints
    NVIC->ICPR[0] = -1; //clear pending states
    RCC_DeInit();   //resets to 8MHz HSI, no prescales
    return;
}
  
int state = 0;  //tweak while debugging : 0: normal, 3 sets pending from main loop
  
void TIM6_DAC_IRQHandler(void) {
    if (state != 2)
        TIM_ClearFlag(TIM6, TIM_FLAG_Update);
  
    if (state == 1)
        NVIC_SetPendingIRQ(TIM6_DAC_IRQn);
  
    return;
}
  
int main(void) {
    TIM_TimeBaseInitTypeDef tbi;
    volatile u32 bst=0;
  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_DBGMCU, ENABLE);
    DBGMCU_APB1PeriphConfig(DBGMCU_TIM6_STOP, ENABLE);
  
    TIM_TimeBaseStructInit(&tbi);   //init with defaults; some fields are not applic to TIM6
    TIM_TimeBaseInit(TIM6, &tbi);
  
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6, ENABLE);
  
    TIM_ITConfig(TIM6, TIM_IT_Update, ENABLE);
    TIM_ClearFlag(TIM6, TIM_FLAG_Update);
  
    TIM_Cmd(TIM6, ENABLE);
    NVIC_EnableIRQ(TIM6_DAC_IRQn);
  
    while (1) {
        if ((state == 3) && (bst == 100))
            NVIC_SetPendingIRQ(TIM6_DAC_IRQn);
        bst++;
    }
    return 0;
}

Outcomes