cancel
Showing results for 
Search instead for 
Did you mean: 

NVIC_ISPR ''set-pending'' bit to force ISR entry

fenugrec
Associate II
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;
}

3 REPLIES 3
Posted on May 25, 2015 at 22:00

> 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

How?
 
 I am not familiar with the M0, but in M3/M4, the processor has to be in privileged mode to be able to write into certain NVIC registers. Also, the NVIC in M3/M4 has a NVIC_STIR register intended to invoke an interrupt in software (this may be absent in M0).
 
 JW
 

fenugrec
Associate II
Posted on May 26, 2015 at 01:27

Hi Jan,


Sorry, I should have specified : I set NVIC_ISPR and NVIC_ISER to 0xffff ffff from within gdb with ''set var *0xe000e100 ...'', stepping 1 instruction, and making sure they were written properly with ''x/xw 0xe000e200'' etc. I confirmed I had the correct regs by breaking on a normal TIM6 overflow int, and verifying the NVIC_ISPR and ICSR (''int control & status'') registers.
Thanks for the suggestion, but unfortunately there's no STIR register, nor any mention of priviledged modes on the M0 ! I'm beginning to think what I want to do just isn't possible, but it doesn't make sense...

fenugrec
Associate II
Posted on May 27, 2015 at 22:34

Hi,

for the record, here was the problem : 

Single-stepping, with openocd + ST-Link , apparently masks interrupts. As soon as I ''c''ontinue in gdb, the interrupt gets serviced immediately !