AnsweredAssumed Answered

TIM4 Missing Update Interrupt

Question asked by mezzetti.fabrizio.77 on Dec 6, 2011
Latest reply on Dec 12, 2011 by mezzetti.fabrizio.77
The follow ISR capture an event incoming on TIM4_CCP2, and
each 8 of this events the register oldCCP is subtracted from
CCR2, this value is strored in loop_buf[cyc][lb_index], the
value of CCR2 updates oldCCP, and also cyc and lb_index are
updated.
Each update event the counter cntr0 increase of 0x00010000,
in order to manage time intervals greater than 16bits.
Sometimes a missed rollover event occur, so losing the MSB
of the captured value.
I' ve tried to swap the ISR each other, without fixing the
problem.

brief hardware and settings description:

microcontroller: STM32F103V8Tb
compiler: IAR 5.4_2 (maximum balanced compression)
Incoming signal: square wawe at 30KHz and dutycycle 23%
interrupts enabled:
  - Systick every 50 microseconds preemption pr. 1,
    subpriority 0
  - Adconv1 watchdog preemption pr. 1,
    subpriority 0
  - TIM4 preemption pr. 0,
    subpriority 0

TIM4 settings:
  TIM_TimeBaseInitStruct.TIM_Prescaler = 0;
  TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up;
  TIM_TimeBaseInitStruct.TIM_Period = 0xFFFF;
  TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1;
 
  TIM_TimeBaseInit(TIM4, &TIM_TimeBaseInitStruct);  
  TIM_SetClockDivision(TIM4,TIM_CKD_DIV1);
  TIM_UpdateDisableConfig(TIM4, DISABLE);
 
  TIM_ICInitStruct.TIM_Channel = TIM_Channel_2;
  TIM_ICInitStruct.TIM_ICPolarity = TIM_ICPolarity_Falling;
  TIM_ICInitStruct.TIM_ICSelection = TIM_ICSelection_DirectTI;
  TIM_ICInitStruct.TIM_ICPrescaler = TIM_ICPSC_DIV8;
  TIM_ICInitStruct.TIM_ICFilter = 5;  

  TIM_ICInit(TIM4, &TIM_ICInitStruct);


/*******************************************************************

unsigned int  loop_buf[2][8]; //2-dimensions filtering vector
unsigned int  lb_index[2];    //pointer index on loop_buf
unsigned int  oldCCP[2];      //previous CCP value
char s_frq[2] = {2, 1};       //frequency selection (don't care)
int  cyc =0;                  //allowed values: 0 and 1

void TIM4_IRQHandler(void)
{
  static int contaeventi=, cntRO[2]={0,0};
  short pinO;

  //ISR for capture event
  if(TIM_GetFlagStatus(TIM4, TIM_FLAG_CC2))
  {   
    TIM4->SR = 0xFFFB;
    if(--contaeventi<N_meas[cyc])
    {
      if(contaeventi==0)
      {
        cntRO[cyc]=cntRO[cyc+TIM4->CCR2;
        if(TIM4->CCR2==0)
          cntRO[cyc]=cntRO[cyc]+0x00010000;
       
        loop_buf[cyc][lb_index[cyc]]=(cntRO[cyc]-oldCCP[cyc]);
        cntRO[cyc]=0;
        lb_index[cyc]=(lb_index[cyc]+1)&7;
        cyc = (~cyc)&1;
        pinO = ((short)((~s_frq[cyc])&3)<<11)|((short)((2-cyc)&3)<<9);
        GPIOD->BRR = pinO;
        GPIOD->BSRR = (~pinO)&0x1E00;
        contaeventi=((3*N_meas[cyc])>>1)+2;
      }
    }
    else
     oldCCP[cyc]=TIM4->CCR2;
  }

  //ISR for TIM4_CNT rollover event
  if(TIM_GetFlagStatus(TIM4, TIM_FLAG_Update))
  {
   TIM4->SR=0xFFFE);
   cntRO[cyc]=cntRO[cyc]+0x00010000;

    if(cntRO[cyc]==0)
      cntRO[cyc]=0xFFFF0000;
  }

}

Outcomes