cancel
Showing results for 
Search instead for 
Did you mean: 

STMN32F407 TIM5 UIF interrupts

will
Associate II
Posted on August 05, 2015 at 19:55

Hello:

I am using a stm32F407 and working on getting the timer overflow working correctly and I am seeing a strange thing. Basically, I seem to be getting two TIM5 interrupts for each overflow of the counter. Nothing really happens with the second interrupt as the UIF flag is cleared but I really dont want to get two interrupts. Do I need to clear the NVIC Pending flag for this interrupt for some reason? I did not think I needed to do that.

Here is a gdb dump of TIM5:

gdb) p {TIM_TypeDef}0x40000c00

$3 = {CR1 = 5, CR2 = 0, SMCR = 0, DIER = 1, SR = 0, EGR = 0, CCMR1 = 0, CCMR2 = 0, CCER = 0,

  CNT = 54834720, PSC = 83, ARR = 100000000, RCR = 0, CCR1 = 0, CCR2 = 0, CCR3 = 0, CCR4 = 0,

  BDTR = 0, DCR = 0, DMAR = 5, OR = 0}

NOTE: in the above example I have the ARR set to 100000000 but in my real code I set it to 0xFFFFFFFF as I just want to get an interrupt when the timer counter overflows. Same issue in both cases: tim5_isrs is always twice the uif_ints count.

Here is the interrupt handler I am using:

static

void

tim5_isr

(

void

)

{

uint32_t

sr

;

/* Count ♯ of interrupts */

++tim5_isrs

;

sr

=

TIM5

->

SR

;

if

(

sr

&

TIM_SR_UIF

)

{

++

uif_ints

;

}

/* Clear the interrupt sources */

TIM5

->

SR

&=

~

sr

;

}

Thanks in advance to anyone that can help.

#stm32f407 #timer
5 REPLIES 5
Posted on August 05, 2015 at 20:15

ARM-CortexM gotcha #1... Put

/* Clear the interrupt sources */

TIM5

->

SR

&=

~

sr

;

at the beginning of the ISR.

JW

will
Associate II
Posted on August 05, 2015 at 20:29

Thanks Jan. I appreciate the quick response although I have to say I don't understand why it would make a difference although I am no cortex-M expert. I do a similar thing when using an external GPIO interrupt and I don't get multiple GPIO interrupts. Do you know off the top of your head where this is discussed in the cortex-M documentation?

Will

Posted on August 05, 2015 at 21:09

TIM5->SR = ~sr; // more ideally

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
will
Associate II
Posted on August 05, 2015 at 22:24

Thanks Clive! I just passed over the rc_w0 in the description of the SR register. Always like to save some code/cycles. 🙂

Will

Posted on August 06, 2015 at 11:09

The reason is that these chips are not microcontrollers but SoC, stitched together more or less loosely from a processor core, peripherals, and an interconnection mesh (data and signalling).

Particularly, while the write of word which clears the interrupt passes from processor through the buses (mainly the AHB/APB bridge) to the timer, and then while the timer's cleared output signal reaches NVIC (there may/probably will be a resynchronizer in the path as they are in different clock domain), the processor starts to exit the ISR, and as due to the tail-chaining feature it starts to check for new interrupts quite early, it still sees the timer interrupt active, so it kicks in again.

I missed the |= but that can't escape Clive's eyes - the issue is not just the extra clocks spared, but the possibility to inadvertently clear bits you don't intended to - you'd read 0 and after the or write 0 back, but the flag might've been changed by hardware meantime (not issue in your simplistic case but in cases several interrupt sources are enabled).

JW