2015-05-24 06:50 PM
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;
}
2015-05-25 01:00 PM
> 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
2015-05-25 04:27 PM
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...
2015-05-27 01:34 PM
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 !