# Tickless Idle Sleep on SAML21 Xplained Pro - vTaskDelay time error

**URL:** <https://forums.freertos.org/t/tickless-idle-sleep-on-saml21-xplained-pro-vtaskdelay-time-error/6852>\
**Category:** Kernel\
**Created:** [November 9, 2017, 1:55pm UTC](https://forums.freertos.org/t/tickless-idle-sleep-on-saml21-xplained-pro-vtaskdelay-time-error/6852 "2017-11-09T13:55:20Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [November 9, 2017, 1:55pm UTC](https://forums.freertos.org/t/tickless-idle-sleep-on-saml21-xplained-pro-vtaskdelay-time-error/6852/1 "2017-11-09T13:55:20Z")

</div>

**[alvaromuro](https://sourceforge.net/u/alvaromuro/)** wrote on [Thursday, November 09, 2017](https://sourceforge.net/p/freertos/discussion/382005/thread/73f9f0d5/#4c0b):

I am configuring the Atmel SAM L21 Xplained pro A board (ATSAML21J18A), with Atmel Studio 7 and FreeRTOS v8.0.1 to work with Tickless Idle sleep, based on the files of an ASF example called [FreeRTOS tickless demo using OLED1 Xplained Pro][http://asf.atmel.no/docs/3.21.0/common.services.freertos.oled1\_tickless\_xpro\_example.saml21\_xplained\_pro/html/index.html](http://asf.atmel.no/docs/3.21.0/common.services.freertos.oled1_tickless_xpro_example.saml21_xplained_pro/html/index.html)).

I have created a simple task which just blinks a LED and after calls vTaskDelay and blocks for 3000 ms. I run it first without activating tickless mode, and the program works perfectly. The task blinks, then blocks for 3000 ms, and starts again.

When I activate tickless mode, the led Blinks at the same right rate, the system then enters the sleep mode correctly, and wakes up again to blink, but the delay is not what it should be, it’s shorter, around 1000 ms instead of 3000 ms.

In FreeRTOSConfig.h I have:

```auto
#define configUSE_TICKLESS_IDLE 2
#define configCPU_CLOCK_HZ ( system_gclk_gen_get_hz(GCLK_GENERATOR_0) )
#define configTICK_RATE_HZ ( ( portTickType ) 100 )

```

My main Clock is set up at 12MHz from OSC16M:

```auto
/* Configure GCLK generator 0 (Main Clock) */
# define CONF_CLOCK_GCLK_0_ENABLE true
# define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_0_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC16M
# define CONF_CLOCK_GCLK_0_PRESCALER 1
# define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE false

/* SYSTEM_CLOCK_SOURCE_OSC16M configuration - Internal 16MHz oscillator */
# define CONF_CLOCK_OSC16M_FREQ_SEL SYSTEM_OSC16M_12M
# define CONF_CLOCK_OSC16M_ON_DEMAND true
# define CONF_CLOCK_OSC16M_RUN_IN_STANDBY false

```

I have clocked the tick with the ultra low power oscillator ULPOSC32k:  
in conf\_clocks.h

```auto
/* Configure GCLK generator 5 */
# define CONF_CLOCK_GCLK_5_ENABLE true
# define CONF_CLOCK_GCLK_5_RUN_IN_STANDBY false
# define CONF_CLOCK_GCLK_5_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_ULP32K
# define CONF_CLOCK_GCLK_5_PRESCALER 1
# define CONF_CLOCK_GCLK_5_OUTPUT_ENABLE false

```

and modified the vPortSetupTimerInterrupt as follows:

```auto
void vPortSetupTimerInterrupt(void)
{
	// Struct for configuring TC
	struct tc_config tcconf;
	// Set up configuration values
	tc_get_config_defaults(&tcconf);
	tcconf.clock_source = GCLK_GENERATOR_5;   
	tcconf.counter_size = TC_COUNTER_SIZE_32BIT;
	tcconf.run_in_standby = true;
	tcconf.clock_prescaler = TC_CLOCK_PRESCALER_DIV1;
	tcconf.wave_generation = TC_WAVE_GENERATION_MATCH_FREQ;

	// Initialize the TC
	tc_init(&tc, TICK_TC, &tcconf);

	// Register and enable callback for freeRTOS tick handler
	tc_register_callback(&tc, (tc_callback_t) xPortSysTickHandler, TC_CALLBACK_CC_CHANNEL0);
	tc_enable_callback(&tc, TC_CALLBACK_CC_CHANNEL0);

	// Set top value equal to one os tick
	tc_set_top_value(&tc, TIMER_RELOAD_VALUE_ONE_TICK);

	// Enable the timer
	tc_enable(&tc);
}

```

and in FreeRTOSConfig.h the example has the following definitions which I asssume are correct:

```auto
/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS
standard names - or at least those used in the unmodified vector table. */
#define vPortSVCHandler SVC_Handler
#define xPortPendSVHandler PendSV_Handler

#if defined ( __GNUC__ ) || defined ( __ICCARM__ )
#include <portmacro.h>
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime );
#endif
#define portSUPPRESS_TICKS_AND_SLEEP vPortSuppressTicksAndSleep

```

I also have the following timer configuration:

```auto
//! Frequency of timer
//#define TIMER_HZ ( configCPU_CLOCK_HZ )
#define TIMER_HZ ( system_gclk_gen_get_hz(GCLK_GENERATOR_5 ))

//! Value per os tick of timer
#define TIMER_RELOAD_VALUE_ONE_TICK ( TIMER_HZ / configTICK_RATE_HZ )

//! Maximum value of timer
#define TIMER_MAX_COUNT ( 0xffffffff )

//! Maximum possible suppressed ticks with timer
#define TIMER_MAX_POSSIBLE_SUPPRESSED_TICKS ( TIMER_MAX_COUNT / TIMER_RELOAD_VALUE_ONE_TICK )

```

And finally the call to delay the task is:

```auto
/* Block until 3000ms */
		vTaskDelay ( pdMS_TO_TICKS (3000) );

/* Definition of pdMS_TO_TICKS function*/
#ifndef pdMS_TO_TICKS
#define pdMS_TO_TICKS( xTimeInMs ) ( ( TickType_t ) ( ( ( TickType_t ) ( xTimeInMs ) * ( TickType_t ) configTICK_RATE_HZ ) / ( TickType_t ) 1000 ) )
#endif

```

I would very much appreciate any insight on why the vTaskDelay doesn’t respect the given 3000 ms and resumes the task faster than it should.

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [November 9, 2017, 4:27pm UTC](https://forums.freertos.org/t/tickless-idle-sleep-on-saml21-xplained-pro-vtaskdelay-time-error/6852/2 "2017-11-09T16:27:20Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Thursday, November 09, 2017](https://sourceforge.net/p/freertos/discussion/382005/thread/73f9f0d5/#4c0b/8ccc):

I’m not sure that we have M0 code with tickless idle? Maybe I am wrong.

You say you run the code first without tickless idle and the blink rate  
is correct, then with tickless idle, and the blink rate is wrong. Is  
the clock setup the same in both cases - so in both cases you are using  
the low power oscillator to generate the tick interrupt rather than the  
SysTick?

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [November 10, 2017, 9:25am UTC](https://forums.freertos.org/t/tickless-idle-sleep-on-saml21-xplained-pro-vtaskdelay-time-error/6852/3 "2017-11-10T09:25:20Z")

</div>

**[alvaromuro](https://sourceforge.net/u/alvaromuro/)** wrote on [Friday, November 10, 2017](https://sourceforge.net/p/freertos/discussion/382005/thread/73f9f0d5/#13c6):

Thanks for your prompt reply. In Atmel Studio 7 there are tickless mode working examples for SAML21, SAMD20 and D21 and SAM R21 and R30, which use M0. I suppose they are rigth.

No, with tickless idle the LED blink rate is also right, but the delay of the task generated with vTaskDelay is shorter than it should. That is, the time the system is in idle task sleep, should be 3000 ms but instead is just 1000 ms.

In relation of using the low power oscillator in tickless idle, I’m not sure how to check that. This is what I found:

At the beginning of the tickless.c demo file, where vPortSetupTimerInterrupt and vPortSuppressTicksAndSleep are defined, it says:

> The tickless feature is implemented using a timer, configured with the desired timeout value, to wake the device. The same timer is also used to generate the system tick, so that time is kept in the optimal way, eliminating drift in most cases.

And rigth before the definition of vPortSetupTimerInterrupt, it says:

> Function that sets up a timer to use for os tick. The same timer is also used as the sleep timer.

Here is the code of vPortSuppressTicksAndSleep, is there something here that can cause that?:

```auto
* Function to configure timer for sleep, and calculate time slept.
 */ 
void vPortSuppressTicksAndSleep( TickType_t xExpectedIdleTime )
{
	
	// Reconfigure the timer to act as sleep timer
	tc_disable_callback(&tc, TC_CALLBACK_CC_CHANNEL0);
	tc_unregister_callback(&tc, TC_CALLBACK_CC_CHANNEL0);
	tc_register_callback(&tc, empty_callback, TC_CALLBACK_CC_CHANNEL0);
	tc_enable_callback(&tc, TC_CALLBACK_CC_CHANNEL0);

	// Check that the offset is not greater than the range of the timer
	if (xExpectedIdleTime > TIMER_MAX_POSSIBLE_SUPPRESSED_TICKS)
	{
		xExpectedIdleTime = TIMER_MAX_POSSIBLE_SUPPRESSED_TICKS;
	}

	// Set sleep time, -1 because we want to wake up before the last tick
	tc_set_top_value(&tc, (xExpectedIdleTime - 1) * TIMER_RELOAD_VALUE_ONE_TICK);

	// Clear overflow interrupt flag
	tc.hw->COUNT32.INTFLAG.reg = TC_INTFLAG_OVF;

	// Check if we still should sleep
	if (eTaskConfirmSleepModeStatus() == eAbortSleep)
	{
		// Reset the timer to act as SysTick
		tc_disable_callback(&tc, TC_CALLBACK_CC_CHANNEL0);
		tc_unregister_callback(&tc, TC_CALLBACK_CC_CHANNEL0);
		tc_register_callback(&tc, (tc_callback_t) xPortSysTickHandler, TC_CALLBACK_CC_CHANNEL0);
		tc_enable_callback(&tc, TC_CALLBACK_CC_CHANNEL0);
		tc_set_top_value(&tc, TIMER_RELOAD_VALUE_ONE_TICK);
	}
	else
	{
		if (xExpectedIdleTime > 0)
		{
			// Data sync barrier before sleep
			__asm volatile ("dsb");
			// Go to sleep
			__asm volatile ("wfi");

			// If OVF interrupt flag is set, we know the timer has wrapped
			if (tc.hw->COUNT32.INTFLAG.reg & TC_INTFLAG_OVF)
			{
				vTaskStepTick(xExpectedIdleTime - 1);
			}
			// We do not know how long we've slept
			else
			{
				// Calculate from Counter how long we've slept
				// Reset counter to less than one os tick
				// This might result in a tiny drift in time.
				uint32_t count_val = tc_get_count_value(&tc);
				vTaskStepTick(count_val / TIMER_RELOAD_VALUE_ONE_TICK);
				tc_set_count_value(&tc, count_val % TIMER_RELOAD_VALUE_ONE_TICK);
			}
		}
		// Reset the timer to act as SysTick
		tc_disable_callback(&tc, TC_CALLBACK_CC_CHANNEL0);
		tc_unregister_callback(&tc, TC_CALLBACK_CC_CHANNEL0);
		tc_register_callback(&tc, (tc_callback_t) xPortSysTickHandler, TC_CALLBACK_CC_CHANNEL0);
		tc_enable_callback(&tc, TC_CALLBACK_CC_CHANNEL0);
		tc_set_top_value(&tc, TIMER_RELOAD_VALUE_ONE_TICK);

		// Make sure that the counter hasn't passed the CC before callback was registered
		if ( tc_get_count_value(&tc) > TIMER_RELOAD_VALUE_ONE_TICK )
		{
			// If so, reload count value, and step one tick */
			tc_set_count_value(&tc, tc_get_count_value(&tc) % TIMER_RELOAD_VALUE_ONE_TICK);
			vTaskStepTick(1);
		}
	}
}

```

Also, I see another possible cause related with [Tickless Low power ARM RTOS Cortex-M Microcontrollers](http://www.freertos.org/low-power-ARM-cortex-rtos.html), in the following instruction for the cases when you use a clock other than Systick:

> Provide an implementation of vPortSetupTimerInterrupt() that generates an interrupt at the frequency specified by the configTICK\_RATE\_HZ FreeRTOSConfig.h constant.

I’m not sure how to get the interrupt frequency properly configured. My configTICK\_RATE\_HZ is 100. Tracing back the interrupt timer, in vPortSetupTimerInterrupt (at tickless.c), I have the GLCK\_GENERATOR\_5 with DIV 1:

```auto
    tcconf.clock_source = GCLK_GENERATOR_5;   
    tcconf.clock_prescaler = TC_CLOCK_PRESCALER_DIV1;
    //Wavegen function Match Frequency is chosen to reload the count register on every CC0 match.//
    tcconf.wave_generation = TC_WAVE_GENERATION_MATCH_FREQ; 

```

and in conf\_clocks.h, the GCLK\_GENERATOR\_5 has SYSTEM\_CLOCK\_SOURCE\_ULP32K also with prescaler at 1. Thus it looks that the input frequency of the interrupt is 32k, am I right?

Also there is a definition of TIMER\_HZ at tickless.c which I equaled to system\_gclk\_gen\_get\_hz(GCLK\_GENERATOR\_5 ). I’m not sure if this is correct.

So, if the difference between the configTICK\_RATE\_HZ and the interrupt frequency at vPortSetupTimerInterrupt is the cause, how could I configure it? I tried changing the values of both prescalers but with no luck.

Please see the attached files for clarification, I feel I’m getting closer to the solution thanks to your support.

---

<div class="post-metadata">

**Author:** ![rtel](https://d3iykfbgfh8zhg.cloudfront.net/user_avatar/forums.freertos.org/rtel/32/31_2.png) [@rtel](https://forums.freertos.org/u/rtel)\
**Post date:** [November 10, 2017, 3:28pm UTC](https://forums.freertos.org/t/tickless-idle-sleep-on-saml21-xplained-pro-vtaskdelay-time-error/6852/4 "2017-11-10T15:28:10Z")

</div>

**[rtel](https://sourceforge.net/u/rtel/)** wrote on [Friday, November 10, 2017](https://sourceforge.net/p/freertos/discussion/382005/thread/73f9f0d5/#13c6/6282):

> and in conf\_clocks.h, the GCLK\_GENERATOR\_5 has  
> SYSTEM\_CLOCK\_SOURCE\_ULP32K also with prescaler at 1. Thus it looks that  
> the input frequency of the interrupt is 32k, am I right?

No idea - that is way outside the scope of RTOS support.

I’m afraid this is very hard to support that kind of question directly,  
especially as I don’t think this is code we provided, and we can’t get  
into device specific register settings (we run on LOTS of different  
devices and would have to get the data sheets out and experiment with  
settings on real hardware to get into clock settings on individual  
peripherals on individual parts - just not practical).

My advise would be to start at the bottom of the system, ensuring each  
part is working correctly and as expected before working your way up.  
For example, ensure the input frequency of the clock is what you expect  
(probably with an oscilloscope), then set up the clock and check the  
output frequency is what you expect. Then check the variables in the  
software have the frequency that is actually output from the  
clock…and keep working up until you get into the ‘suppress ticks  
and sleep’ function - and see that, given the inputs, a hand calculation  
of the time at which the clock should be programmed to generate an  
interrupt next matches the time actually calculated in the code.

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [November 13, 2017, 7:37am UTC](https://forums.freertos.org/t/tickless-idle-sleep-on-saml21-xplained-pro-vtaskdelay-time-error/6852/5 "2017-11-13T07:37:32Z")

</div>

**[alvaromuro](https://sourceforge.net/u/alvaromuro/)** wrote on [Monday, November 13, 2017](https://sourceforge.net/p/freertos/discussion/382005/thread/73f9f0d5/#89d3):

Yes, I was also thinking this is more related with the atmel code than to the FreeRTOS. I will follow your advise to go from bottom to top, your support has been very helpful, thanks!

---

<div class="post-metadata">

**Author:** ![system](https://d2v6vdsk2p900z.cloudfront.net/original/1X/7fc8fdb729c645aab5b20282bbe34e57cb407be6.jpeg) [@system](https://forums.freertos.org/u/system)\
**Post date:** [November 17, 2017, 1:02pm UTC](https://forums.freertos.org/t/tickless-idle-sleep-on-saml21-xplained-pro-vtaskdelay-time-error/6852/6 "2017-11-17T13:02:24Z")

</div>

**[alvaromuro](https://sourceforge.net/u/alvaromuro/)** wrote on [Friday, November 17, 2017](https://sourceforge.net/p/freertos/discussion/382005/thread/73f9f0d5/#f20d):

Solved. Just in case it helps somebody: It was a problem related with the configuration of the timer that generates the OS tick in vPortSuppressTicksAndSleep: changing the Timer instance from TC4 to TC2 solves the issue.

```auto
// Initialize the TC
   tc_init(&tc, TICK_TC, &tcconf);

 //! Timer/Counter instance to use as tick timer
        //#define TICK_TC TC4 - Commented out as it's not working
 #define TICK_TC TC2

```

Now it generates a correct tick frequency independently of the CPU clock frequency configured, and thus the vTaskDelay works properly.

However, I will still have to see the implications this will have when I activate the low power modes, as it seems the TC4 is the only timer active in Power Domain 0 (PD0)(the lowest power domain).

Thanks for your help.
