cancel
Showing results for 
Search instead for 
Did you mean: 

sysTick stops after a few TIM3 interrupts

bart239955
Associate II
Posted on October 19, 2012 at 16:47

Hello,

I am having problems with the syStick timer. 

The handler for sysTick stops being called after one or two interrupts from TIM3 (set < 1Hz). The TIM3 interrupt has no problem (LED keeps toggling).

I started from the GUI-lib template and added code for TIM3 interrupt to main() and the handler routine in the _it.c file.

I am using a board based on the STM32G322xG evaluation board, and RIDE7 for compilation.

The code is below. When I comment out either the TIM_ITConfig or the TIM_Cmd line the display works ok, but when both are present (TIM3 interrupts generated) the display stops at ''loading..'' because the sysTick stops (used for delaying the appearance of the dots in ''loading...'')

I read somewhere that this could be caused by a bad return of an interrupt. What should I do to return correctly if this is the case?

int main(void)

{

  RCC_ClocksTypeDef RCC_Clocks;

  /* Set the Vector Table base location at 0x08000000 */

  NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000);

  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); // (:) 2

  /* Setup SysTick Timer for 10 msec interrupts  */

  RCC_GetClocksFreq(&RCC_Clocks);

  if (SysTick_Config(RCC_Clocks.SYSCLK_Frequency / 100))

  {

    /* Capture error */

    while (1);

  }

  /* configure Systick priority */

  NVIC_SetPriority(SysTick_IRQn, 0x0B);

  /* Set HW structure parameters */

  HWConfig_SetHardwareParams();

  TIM_Config();

  /* Compute the prescaler value */

  PrescalerValue = (uint16_t) ((SystemCoreClock / 2) / 60000) - 1;

  /* Time base configuration */

  TIM_TimeBaseStructure.TIM_Period = 65535;

  TIM_TimeBaseStructure.TIM_Prescaler = 0;

  TIM_TimeBaseStructure.TIM_ClockDivision = 0;

  TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;

  TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure);

  /* Prescaler configuration */

  TIM_PrescalerConfig(TIM3, PrescalerValue, TIM_PSCReloadMode_Immediate);

  /* Output Compare Timing Mode configuration: Channel1 */

  TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_Timing;

  TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;

  TIM_OCInitStructure.TIM_Pulse = CCR1_Val;

  TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;

  TIM_OC1Init(TIM3, &TIM_OCInitStructure);

  TIM_OC1PreloadConfig(TIM3, TIM_OCPreload_Disable);  

     

    /* TIM Interrupts enable */

  TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);

  /* TIM3 enable counter */

  TIM_Cmd(TIM3, ENABLE);  // (!) calibration stops if TIM3 interrupt is called

/* If the LCD Panel has a resolution of 320x240 this command is not needed, it's set by default */

  /* Set_LCD_Resolution( 320, 240 ); */

  /* Initialize the LCD */

  GL_LCD_Init();

  GL_Clear(GL_White);

  InputInterface_Init();

&sharpif TOUCH_SCREEN_CAPABILITY

  /* Check if Calibration has been done*/

  TS_CheckCalibration();

&sharpendif

  /*Initialize cursor*/

  GL_Clear(White);

  CursorInit(GL_NULL);

  /* Menu Initialisation*/

  Show_HomeScreen();

  CursorShow(195, 80);

 

 

 

  /* Infinite main loop ------------------------------------------------------*/

  while (1)

  {

&sharpif defined(USE_STM3210C_EVAL) || defined(USE_STM32100E_EVAL)

    /* Catching touch events */

    if ( TS_IsCalibrationDone() == SET )

&sharpendif

    {

      ProcessInputData();

    }

    /* Time out calculate for power saving mode */

    TimeOutCalculate();

    CatchInputEvents();

  }

}

void TIM_Config(void)

{

  NVIC_InitTypeDef NVIC_InitStructure;

  /* TIM3 clock enable */

  RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);

  /* Enable the TIM3 gloabal Interrupt */

  NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;

  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;

  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1;

  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

  NVIC_Init(&NVIC_InitStructure);

  /* Initialize Leds mounted on STM322xG-EVAL board */

  STM_EVAL_LEDInit(LED1);

  STM_EVAL_LEDInit(LED2);

  STM_EVAL_LEDInit(LED3);

  STM_EVAL_LEDInit(LED4);

  /* Turn off LED1, LED2, LED3 and LED4 */

  STM_EVAL_LEDOff(LED1);

  STM_EVAL_LEDOff(LED2);

  STM_EVAL_LEDOff(LED3);

  STM_EVAL_LEDOff(LED4);

}

void SysTick_Handler(void)

{

  TimingDelay_Decrement();

}

void TIM3_IRQHandler(void)

{

  if (TIM_GetITStatus(TIM3, TIM_IT_CC1) != RESET)

  {

    TIM_ClearITPendingBit(TIM3, TIM_IT_CC1);

    /* LED1 toggling with frequency = 73.24 Hz */

    STM_EVAL_LEDToggle(LED1);

    capture = TIM_GetCapture1(TIM3);

    TIM_SetCompare1(TIM3, capture + CCR1_Val);

  }

}

#systick #nvic
3 REPLIES 3
Posted on October 19, 2012 at 16:51

If you don't service them, or clear them, stop enabling them!

TIM_ITConfig(TIM3, TIM_IT_CC1 | TIM_IT_CC2 | TIM_IT_CC3 | TIM_IT_CC4, ENABLE);

Just enable to one you service

TIM_ITConfig(TIM3, TIM_IT_CC1, ENABLE);

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
bart239955
Associate II
Posted on October 19, 2012 at 17:00

Thanks for the fast reply.

That solved the problem!

Posted on October 19, 2012 at 17:21

The Cortex-M3 will repeatedly enter the service routine (Tail-Chain) if the interrupt source remains pending.

Lower priority interrupts, and foreground execution, will appear to cease.

Another potential issue is if you clear the interrupt source immediately prior to returning you get a race condition where the NVIC has not cleared by the time it decides where to go next, and it re-enters a second time with nothing apparently pending. Clear sources early in the routine, not the last thing before leaving.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..