cancel
Showing results for 
Search instead for 
Did you mean: 

Huge repetitive LPTIM interrupts

Andres Cao
Associate III
Posted on November 30, 2017 at 10:53

Hi everyone!

I've been recently using the LPTIMER, along with the compare and autoreload interrupts. Microcontroller is an STM32L073.

It has been working fine, mostly, but I realized that if I remove a delay (which used to be a printf to uart) I get thousands of interrupts one after the other.

To be honest I don't see how I could get so many interrupts if flags are being cleared, and what does it have to do with the delay (race condition?).

Let me show you some code:

This is the init function. Default values for autoreload are 1 second (32767) and half of that for the compare.

// Initializes the Low Power Timer with default values. Timer is ready to be used after calling this function.

void lpTim_Init(void)

{

//Enable clock to the Low Power Timer

RCC->APB1ENR |= RCC_APB1ENR_LPTIM1EN;

//Settings can only be changed when the LPTIM is disabled

LPTIM1->CR = 0x00000000;

//Set the Configuration Register

//Encoder mode disabled, Registers updated after write access, normal polarity,

//Set-once deactivated, trigger while running is ignored, Software trigger selected,

//ext_trig_0 selcted (though ignored), Divide by 1 prescaler, No digital filter for trigger,

//No digital filter for external clock, rising edge of clock polarity, use internal clock

LPTIM1->CFGR = 0x00000000;

//Clear interrupt clear register from previous use

LPTIM1->ICR |= 0x3F;

//Enable LPTIM. LPTIM ready to start

LPTIM1->CR = LPTIM_CR_ENABLE;

//Set the autoreload register to its default value.

//Must only be modified when the LPTIM is enabled

LPTIM1->ARR = LPTIM_DEFAULT_ARR;

//Set compare value

//Must only be modified when the LPTIM is enabled

LPTIM1->CMP = LPTIM_DEFAULT_CMP;

//Autoreload match and compare interrupt enable

LPTIM1->IER = LPTIM_IER_ARRMIE | LPTIM_IER_CMPMIE;

//Set the interrupt priority

NVIC_SetPriority(LPTIM1_IRQn,0);

//Enable interrupt

NVIC_EnableIRQ(LPTIM1_IRQn);

TRACE_DBG_H('LPTIMER initialized\n');

}

And this is my interrupt handler, where I put some pin up/down just to see the interrupts being triggered.

//Interrupt handler

void LPTIM1_IRQHandler(void)

{

GPIOH->BSRR = GPIO_PIN_0;

//If there was an autoreload

if(LPTIM1->ISR & LPTIM_ISR_ARRM)

{ //If the interrupt was enabled

   if(LPTIM1->IER & LPTIM_IER_ARRMIE)

   { //Clear interrupt bit

      LPTIM1->ICR = LPTIM_ICR_ARRMCF;

      //Timer_OverflowCallback();

   }

}

//If there was a compare match

if(LPTIM1->ISR & LPTIM_ISR_CMPM)

{ //If the interrupt was enabled

   if(LPTIM1->IER & LPTIM_IER_CMPMIE)

   { //Clear interrupt bit

      LPTIM1->ICR = LPTIM_ICR_CMPMCF;

      //Timer_CompareCallback();

   }

}

GPIOH->BRR = GPIO_PIN_0;

}

If I do this, it works fine. 

void main(void)

{

//Some init..

lpTim_init();

//Start timer

LPTIM1->CR = LPTIM_CR_ENABLE | LPTIM_CR_CNTSTRT;

while(1);

}

If I do this I get a bazilion interrupts one after the other:

void main(void)

{

//Some init..

lpTim_init();

LPTIM1->ARR = 28000; //Random value 28000

//Start timer

LPTIM1->CR = LPTIM_CR_ENABLE | LPTIM_CR_CNTSTRT;

while(1);

}

But if I do this, it works fine again:

void main(void)

{

//Some init..

lpTim_init();

HAL_Delay(1);

LPTIM1->ARR = 28000; //Random value 28000

//Start timer

LPTIM1->CR = LPTIM_CR_ENABLE | LPTIM_CR_CNTSTRT;

while(1);

}

Any clues as to why I might have this behavior? Seems pretty strange to me. Maybe doing LPTIM1->ARR modifications right after interrupt enable ruins everything?

Cheers, and thanks for your help!

Andrés

4 REPLIES 4
Andres Cao
Associate III
Posted on November 30, 2017 at 11:53

Another thing that I find very curious:

During init I might set the CMP value at 1000. After init I set the value at 2000.

In the interrupt I see the following:

-CNT value is 1000, meaning the interrupt occured at 1000)

-CMP value is 2000, so it seems that the compare value updated but somehow the interrupt is still firing at 1000 forever, it never changes. 

Posted on January 18, 2018 at 20:29

Likely because there is an interrupt pending that you are not clearing, and it reenters endlessly. ie IRQ storm

Check what's flagging, and make sure it gets cleared.

ie expect (

LPTIM1->ISR & 

LPTIM1->IER) != 0

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
Posted on January 18, 2018 at 19:55

Hi.

You must wait flags arrok or cntok when arr or cnt changed. When this flags is set you must clear its. This values changed after long times... 1-2ms.  

BR.

Darius

Posted on January 18, 2018 at 22:39

Hi,

I think that, Andreas have interrupt storm with LPTIM->ISR == 0  !!!

Possible cause is that  secondary write 

LPTIM->ARR register.

BR.

Darius