cancel
Showing results for 
Search instead for 
Did you mean: 

Pending interrupt in NVIC ''reappears'' after being cleared

Posted on August 22, 2012 at 14:09

The following code (TIM3 has clock enabled in RCC but otherwise is in its reset state):

#define TEST_TG

#ifdef TEST_TG

  TIM3->DIER |= TIM_DIER_TIE;  // enable interrupt from trigger TRGI

#else

  TIM3->DIER |= TIM_DIER_UIE;  // enable interrupt from update event

#endif

  testA[0] = NVIC_GetPendingIRQ(TIM3_IRQn);  // there's no pending IRQ at the moment

  testA[1] = TIM3->SR;

#ifdef TEST_TG

  TIM3->EGR = TIM_EGR_TG;      // generate a trigger event

#else

  TIM3->EGR = TIM_EGR_UG;      // generate an update event

#endif

  testA[2] = NVIC_GetPendingIRQ(TIM3_IRQn);  // there should be a pending IRQ here in NVIC

  testA[3] = TIM3->SR;                       // and we should see it also on the status register

    __asm(''nop'');     // okay, it may take time until the interrupt flags ''propagate'' to the

    __asm(''nop'');

  testA[4] = NVIC_GetPendingIRQ(TIM3_IRQn);  // there should still be a pending IRQ in the NVIC

  testA[5] = TIM3->SR;                       // but not in the status register of the timer

#ifdef TEST_TG

  TIM3->SR &= ~TIM_SR_TIF;  // this clears the status bit

#else

  TIM3->SR &= ~TIM_SR_UIF;  // this clears the status bit

#endif

  // the key to the problem is the number of cycles elapsed between these two events - >6 is needed to remove the problem in this snippet

  __asm(''nop \n\t nop \n\t nop \n\t nop \n\t nop \n\t nop \n\t'');

  // __asm(''nop'');

  NVIC_ClearPendingIRQ(TIM3_IRQn);  // and this should clear the pending interrupt

  testA[6] = NVIC_GetPendingIRQ(TIM3_IRQn);  // there should be no pending IRQ in the NVIC by now

  testA[7] = TIM3->SR;                       //

    __asm(''nop'');

    __asm(''nop'');

    __asm(''nop'');

    __asm(''nop'');

  testA[8] = NVIC_GetPendingIRQ(TIM3_IRQn);  // and it should remain so

  testA[9] = TIM3->SR;                       //

  while(1) {

    __asm(''nop'');

  }

results in

(gdb) p /x testA

$26 = {0x0, 0x0, 0x0, 0x40, 0x1, 0x40, 0x0, 0x0, 0x1, 0x0}

i.e. the ''pending'' bit ''reappears'' several cycles after having been cleared.

If the ISR is enabled in NVIC after this sequence, this results in the respective ISR being fired without any bit indicating the source of interrupt set in the _SR.

This is similar to the DMA pending problem I reported earlier in

https://my.st.com/public/STe2ecommunities/mcu/Lists/cortex_mx_stm32/Flat.aspx?RootFolder=%2fpublic%2fSTe2ecommunities%2fmcu%2fLists%2fcortex_mx_stm32%2fHow%20to%20clear%20pending%20DMA%20request&FolderCTID=0x01200200770978C69A1141439FE559EB459D7580009C4E14902C3CDE46A77F0FFD06506F5B&currentviews=35

Jan Waclawek

0 REPLIES 0