AnsweredAssumed Answered

Avoiding spurious interrupt

Question asked by ismirlian.diego on Oct 12, 2016
Latest reply on Oct 12, 2016 by ismirlian.diego
Hello all,

I'm trying to measure the frequency of a signal using the input capture. I'm using the STM32F030's timer 3, which is a 16 bit timer. I want to extend the resolution to 32 bits, using the Capture interrupt and the Overflow interrupt.

The frequency measurement works OK, but I'm having a problem with spurious interrupts. Please look at the code below. The only interrupts I have activated are UIE and CC1IE. In the ISR, I check both bits, and take appropriate actions. However, sometimes,  the code marked "THIS PATH IS EXECUTED" is run, which means that the relevant status flags (UIF and CC1IF) are 0.

I know that there can be a race condition involving the pipeline and/or the APB->AHB bridge/write buffer which may be causing the processor to tail-chain the interrupts. But I'd like to avoid these spurious interrupts, because they unnecessarily overload the processor.

Any ideas or explanations?

Note: I can't use linked timers to extend the resolution, because I'm already using other resources.

Thank you very much,
Diego.

Here is the code for the initialization (TOP is defined as 65536):

01.TIM3->SR   = 0;
02.TIM3->DIER = 0;
03.TIM3->PSC  = 47;
04.TIM3->ARR  = TOP - 1;
05. 
06.TIM3->CCMR1 = STM32_TIM_CCMR1_CC1S(1) | STM32_TIM_CCMR1_IC1F(3);
07.TIM3->CCER = TIM_CCER_CC1E;
08.TIM3->DIER = TIM_DIER_CC1IE | TIM_DIER_UIE;
09.TIM3->CR1 = TIM_CR1_CEN;

Here is the ISR code:

01.#define TOP   65536
02. 
03.void isr(TIM_TypeDef *TIMx) {
04.    static bool enabled;
05.    static uint16_t last_capture;
06.    static uint32_t overflow;
07.    int current_capture;
08. 
09.    uint16_t sr = TIMx->SR;
10. 
11.    if (sr & TIM_SR_CC1IF) {
12.        current_capture = TIMx->CCR1;
13.        if (sr & TIM_SR_CC1OF) {
14.            TIMx->SR = ~TIM_SR_CC1OF;
15.            enabled = FALSE;
16.            return;
17.        }
18. 
19.        if (sr & TIM_SR_UIF) {
20.            TIMx->SR = ~TIM_SR_UIF;
21.            if (current_capture < TOP / 2) {
22.                overflow += TOP;
23.            }
24.        }
25. 
26.        if (enabled) {
27.            period = current_capture - last_capture + overflow;
28.        }
29.        enabled = TRUE;
30.        overflow = 0;
31.        last_capture = current_capture;
32. 
33.        if (sr & TIM_SR_UIF) {
34.            if (current_capture >= TOP / 2) {
35.                overflow += TOP;
36.            }
37.        }
38. 
39.    } else if (sr & TIM_SR_UIF) {
40.        TIMx->SR = ~TIM_SR_UIF;
41.        overflow += TOP;
42.    } else {
43.     //THIS PATH IS EXECUTED!
44.        GPIOB->BSRR.H.clear = (1 << 13);
45.        GPIOB->BSRR.H.set = (1 << 13);
46.    }
47. 
48.}


Outcomes