Question
NVIC_ISPR ''set-pending'' bit to force ISR entry
Posted on May 25, 2015 at 03:50
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;
}