AnsweredAssumed Answered

Systick occasionally stops triggering

Question asked by Joe Kissell on Feb 29, 2012
Latest reply on Mar 5, 2012 by comsosysarch

I've setup a delay function that relies on the systick counter. In very rare occasions (not yet clearly defined), I get into a situation where my delay function never exits. After further investigation, I've found in these cases it's because SysTick function stopped triggering and therefore stopped incrementing the counter I'm watching in my delay loop as a condition to exit.

 

So, what conditions pause the SysTic timer?

 

I have mine set to trigger every 10us. The interrupt itself doing so little that there shouldn't be any concerns about the interrupt attempting to be re-entrant.

 

/* =================================================================================================  FUNCTION DESCRIPTION:==      SysTick Interrupt. == Interrupts every 10 microseconds and updates timer counters.====  OUTPUTS:== counter_10us==      counter_1ms==      counter_1sec== =============================================================================================*/void TIMERS__INTERRUPT__systick  (  void   )    {    /* Local Variables. */    counter_10us++;        /* Update millisecond counter after each 1000us. */    if( counter_10us % 100 == 0 ) {  counter_1ms++;  /* Update second counter after each 1000ms. */ if( counter_1ms % 1000 == 0 )     {      counter_1sec++;           DIAG_LED_D25( 2 /* TOGGLE */ ); //Toggle Diagnostic LED #25          }     }        } /* TIMERS__INTERRUPT__systick() *//* =================================================================================================  FUNCTION DESCRIPTION:== Configures SysTick interrupt to occur every 10us.== Accepts a variable input so that the SYSTICK_FREQUENCY can be trimmed.==== reload_val - Number of clock cycles (based on the Core Clock) before an interrupt occurs.====  OUTPUTS:==      N/A== =============================================================================================*/void TIMERS__INTERRUPT__initialize_systick  (  u32 reload_val  )    {            /* Configure SysTick     * Reference: Cortex M4 Generic Users Guide (ARM DUI 0553A) - Section 4.4 */    SYST_RVR = reload_val;    SYST_CSR = SysTick_CSR_ENABLE_MASK | SysTick_CSR_TICKINT_MASK | SysTick_CSR_CLKSOURCE_MASK;    }/* =================================================================================================  FUNCTION DESCRIPTION:==      Delays to for specified amount of time.== Allows for a wide variety of delays and avoids rollover errors.==== Example: The following function call will initiate a 1 minutes delay.==   TIMERS__delay( DELAY_TIMER__1sec, 60 )====  OUTPUTS:== N/A== =============================================================================================*/void TIMERS__delay  (  delay_timers_t timer_type,  u32      delay_amount  )    {    /* Local Variables. */    u32  last_count;    u32  current_count = 0;    u32 *timer_ptr;        /* Grab pointer to the specified timer. */    switch( timer_type ) { case DELAY_TIMER__1sec:     timer_ptr = (u32*)&counter_1sec;     break;      case DELAY_TIMER__1ms:     timer_ptr = (u32*)&counter_1ms;     break;      case DELAY_TIMER__10us:     default:     timer_ptr = (u32*)&counter_10us;     break; }        /* Record the current count from the interrupt counter. */    last_count = *timer_ptr;    /* Loop until the local counter matches the specified delay. */    while( current_count < delay_amount )  { /* Check if interrupt counter has been updated. */ if( last_count != *timer_ptr )     {     last_count = *timer_ptr;  //Record current count;     current_count++;  //Increment local counter.     } }    } /* TIMERS__delay() */

 

Outcomes