AnsweredAssumed Answered

Pending interrupt in NVIC "reappears" after being cleared

Question asked by waclawek.jan on Aug 22, 2012
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

Outcomes