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
  TIM3->DIER |= TIM_DIER_UIE;  // enable interrupt from update event

  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
  TIM3->EGR = TIM_EGR_UG;      // generate an update event

  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
  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
  TIM3->SR &= ~TIM_SR_UIF;  // this clears the status bit

  // 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;                       //


  testA[8] = NVIC_GetPendingIRQ(TIM3_IRQn);  // and it should remain so
  testA[9] = TIM3->SR;                       //

  while(1) {

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

Jan Waclawek