This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CC1310 clock tick and power management

Other Parts Discussed in Thread: CC1310

Hi all,

I'm very confused about how RTOS and cc1310 works:

I need a very simple timer that trigger a callback function every 50ms, with the power management enabled to put the device in standby between every trigger. I saw that RTOS implements Clock module or/and Timer module. In the technical pdf there is written that Clock module is the main reference for the Kernel's timeout and counting functions, and it run under Swi context. The Timer module manages generic instances that source ticks from Clock module. The question is: which source RTOS use in the CC1310 for the Clock Module ??? I thought that it used the RTC module 'cause, if the power management put the device in standby mode, only the RTC is running, but when I saw that the Clock module can have a resolution of 10us I went into confusion (RTC is supplied by a 32KHz oscillator and it can't have a 10us resolution!!!), 'cause this resolution means that the RTOS use the main clock as source (48MHz), that is powered down by power manager.....I'm going in loop....

Also I saw that power policy doesn't put the device in standby if the next wake up is less than 1ms (with 10us the device is always on......).

Which is the main differences using Clock instances or Timer instances ? Only a priority reason ?

In the examples in the CCS the power management isn't treated in depth

  • I'm talking to the local expert here. I should have some update soon.
  • Hi Riccardo,

    The Clock module does use the RTC. It's a rather special RTC though. It is a 32KHz timer, but it has 32 bits for seconds and 32 bits for sub-seconds and interrupts can be generated based on the middle 32-bits of count.

    The tick does not equal an interrupt. Some of the radio stacks wanted a 10usec granularity on ticks, so that's why it is the default. We could have smaller granularity, but the handling of the wrap case would have caused more power usage.

    Let's look at the following simplified case (with no power management going on):
    System boots up and the RTC is initialized via the Clock Module. if you call Clock_getTick, it would return 0.
    10usec later : if you call Clock_getTick, it would return 1. Note: the interrupt has not fired
    10usec later: if you call Clock_getTick again, it would return 2. Note: the interrupt has not fired
    10usec later: if you call Clock_getTick again, it would return 3. Note: the interrupt has not fired
    10usec later: if you call Clock_getTick again, it would return 4. Note: the interrupt would have fired and any Clock functions that should have been executed would have.

    Please note that the Clock module has some variance in it already. The exact time of execution of the functions depends on the number and order of clock functions, priority of the Clock Swi, other interrupts running, etc.. So if you ask for a task to sleep for 1ms (Task_sleep(100)…100 * 10us = 1ms), your task will wake-up no sooner than .976576ms (32 interrupts * 30.518us). Note: we truncate instead of round...that's why is it s not 1.00708us (33 * 30.518us).

    Todd
  • Hi Todd,
    Thanks for your reply, I need to make a few order in my ideas:

    1) you told the Clock module use RTC timer, this is always true (active,wfi and standby mode)?

    2) if the RTC period is 1/32768 (about 30us), which is the reason to set Clock module period to 10us?

    3)what the kernel exactly does when I create (with the Clock module enable) a Clock Instance? How can the kernel check the clock count for every tick if the core is in standby for example? The core awake every tick? I saw the I can create more then one Clock instance....

    4) I need to know all this informations 'cause my application need a "background" timer that must always run, in active and standby mode, without stop (giving me an irq every 50 ms where I increment a variable). Every time I get the irq, after ++ my variable, i check it and if it reach a certain value, i need to fire an autonomous task and exit from the IRQ function (I want to execute the minimal code in the IRQ function, for this reason I want to fire an autonomous task, or set a semaphore to let run this autonomous task in waiting state, for example). All this is to let the cc1310 in standby mode for the max time possible, but having this "background" counter always on, 'cause I use it to syncronize varius cc1310 (for this reason this timer must never stop).

    Thanks
    Riccardo
  • Hi Riccardo,

    Riccardo Cardinali said:

    1) you told the Clock module use RTC timer, this is always true (active,wfi and standby mode)?

    Yes, the RTC continues to run.  This is the primary reason why we chose the RTC as the underlying timer for the Clock module.  There is no need to resynchronize and start a different timer on wake from sleep modes.

    Riccardo Cardinali said:

    2) if the RTC period is 1/32768 (about 30us), which is the reason to set Clock module period to 10us?

    There were several tradeoffs that led to this number (and I don't remember them all at the moment).  The primary reason was that the radio stack teams wanted to compute timeouts internally with higher accuracy than 30.5 microsecond resolution, and they wanted to be sure to wake on a specific RTC increment, rather than +/- one RTC period.

    Riccardo Cardinali said:

    3)what the kernel exactly does when I create (with the Clock module enable) a Clock Instance? How can the kernel check the clock count for every tick if the core is in standby for example? The core awake every tick? I saw the I can create more then one Clock instance....

    The Clock module maintains a queue of instance objects that represent scheduled work at specific timeouts.  When there is an RTC interrupt the Clock software interrupt (Swi) will be triggered  to run, and it will process the objects in its queue.  As it walks the queue, it keeps track of the next soonest timeout.  So, after processing the queue, it knows what interrupt threshold to next program in the RTC (that is, the time the next interrupt should be generated).  Also, as new Clock instance objects are started, we check if the corresponding timeout is sooner that the previously computed next tick for wakeup.  If it is, then the RTC interrupt threshold is moved sooner; if it is not sooner, there is nothing to do other than put the new Clock object in the queue.  

    No, the RTC does not generate an interrupt for Clock on each tick period.  It only generates interrupts when there is work scheduled, based on the objects in its queue.  We call this mode of operation “DYNAMIC” mode, as the underlying timer is dynamically reprogrammed to interrupt only when necessary, allowing the processor to go to sleep for as long as possible.

    In the traditional “PERIODIC” mode, the timer triggering Clock will generate an interrupt on each tick period.

    In PERIODIC mode, a call to Clock_getTicks() simply returns a count that increments on each interrupt.  In DYNAMIC mode, Clock_getTicks() computes the tick count based upon the current RTC count, and the Clock tick period (Clock.tickPeriod).

    When the power policy runs in the idle loop, it will query the Clock module for the next tick where there is work to do.  If there is enough intervening time (and no other constraints declared to prohibit a transition to standby), it will initiate a transition into standby.  Because Clock is using the RTC, the device would wake ‘naturally’ when the RTC interrupt fires.  But to accommodate wakeup latency, the policy will create another Clock instance with a timeout sooner than the tick where there is work scheduled.  So the device will wakeup a bit early, and then when the “work” tick timeout occurs, then the Clock object’s function is executed.

    Riccardo Cardinali said:

    4) I need to know all this informations 'cause my application need a "background" timer that must always run, in active and standby mode, without stop (giving me an irq every 50 ms where I increment a variable). Every time I get the irq, after ++ my variable, i check it and if it reach a certain value, i need to fire an autonomous task and exit from the IRQ function (I want to execute the minimal code in the IRQ function, for this reason I want to fire an autonomous task, or set a semaphore to let run this autonomous task in waiting state, for example). All this is to let the cc1310 in standby mode for the max time possible, but having this "background" counter always on, 'cause I use it to syncronize varius cc1310 (for this reason this timer must never stop)

    I think the simplest way to do this is for you to create a periodic (not a one-shot) Clock instance object, with a 50ms timeout.  When the instance’s function runs, it can increment the count, and optionally post the Semaphore to trigger your task to run.

    There are a lot of details here, and beyond what I'm writing, but I hope the above answers your questions.

    Regards,
    Scott

  • Hi Scott,

    Thanks for your reply, I' ve understood a lot of things by your reply, only some little specifications:

    1) about the 10us question: the radio request this accurancy, but working with the RTC how can get 10us? Or you mean that the 10us are obtain only in active mode (with 48MHz oscillator) and in standby the accurancy go to 30,5? What I don't understand is: the 10us value how works respect the RTC, is written in the compare register or is a simple value used only to do tick calculation by the kernel? Is there any example or document the explain well Clock module and RTC implementation?

    2) the clock istance struct and contructor function have two parameter, the period , and the timeout (as parameter of constructor function), which is the difference ?

    3) as you told, the clock module is the base that the kernel use to calculate next awake by power management and states. When you told "the underlyng timer is dinamically reprogrammed", you talk about clock istance or RTC timer? Cause in the second option it is a big problem cause the reprogrammation every time could cause drift and jitter in counting, I hope you are talking of clock istance:)
  • Hi Riccardo,

    Riccardo Cardinali said:

    1) about the 10us question: the radio request this accurancy, but working with the RTC how can get 10us? Or you mean that the 10us are obtain only in active mode (with 48MHz oscillator) and in standby the accurancy go to 30,5? What I don't understand is: the 10us value how works respect the RTC, is written in the compare register or is a simple value used only to do tick calculation by the kernel? Is there any example or document the explain well Clock module and RTC implementation?

    It is a value used for tick calculations.  No, sorry, there isn’t a specific document yet to describe this RTC usage for Clock.

    Riccardo Cardinali said:

    2) the clock istance struct and contructor function have two parameter, the period , and the timeout (as parameter of constructor function), which is the difference ?

    The “timeout” is the initial start delay for the first tick, and the “period” is the repeating period for subsequent ticks after the start delay.

    Riccardo Cardinali said:

    3) as you told, the clock module is the base that the kernel use to calculate next awake by power management and states. When you told "the underlyng timer is dinamically reprogrammed", you talk about clock istance or RTC timer? Cause in the second option it is a big problem cause the reprogrammation every time could cause drift and jitter in counting, I hope you are talking of clock istance:)

    Actually I was referring to the RTC timer.  But here “reprogramming” for the RTC is a just matter of setting the next interrupt match value - the timer always continues to tick, in phase, we are just setting the match register value to indicate when we want the next interrupt.

    Regards,
    Scott

  • Hi
    how can i reduce the RTC ticks? thanks
  • Can you open a new thread since this one has been marked as "answered". Please include the device and version of software you are using.

    Todd