This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Atomic/relative timer compare update

We have a timer with a number of variably sized intervals as illustrated below operating on a single capture/compare channel (CC):

   |-----------|-----|-----------------|--|----------|
 Start         A     B                 C  D          E

Currently the method we use to set the next time interval (i.e. Start->A, A->B, etc), assuming the previous interrupt is already processed, is the following:


uint32_t now, next_interval;
...
next_interval = <some_amount>
...
now = nrfx_timer_capture_get( &timer, NRF_TIMER_CC_CHANNEL0 );
nrfx_timer_compare( &timer, NRF_TIMER_CC_CHANNEL1, now + next_interval, true );

What we would like to do is omit the step (even implicitly) of performing a capture and instead setting the compare to the future by X amount of ticks. Is there a mode or way of doing this?

As a side/bonus question are the "best practices" way of updating a timer different from the above example, and if so what are the best practices?

Many Thanks

Parents
  • Hi

    Do you know in advance how long the intervals will be, or is this something you don't know until the previous interval expires?

    Otherwise it should be possible to use several CC registers in order to prepare multiple intervals ahead of time, giving you more time to write to the CC registers. 

    Also, do you have any numbers on how small or large the intervals can be?

    Best regards
    Torbjørn

  • Hi Torbjørn,

    Thank you for the reply and confirmation that a capture and set is required.

    With regards to the solution you suggested to our issue:

    Alternatively, you might need to run a timer capture at the end of the interrupt to check how far the timer has come, and if there is a risk that you have lost any interrupts. 

    As an example, say you have the CC register set to 10, but you also need to schedule an interrupt at 11. When the interrupt fires at 10 you first schedule the callback associated with 10, and then you do a timer capture and check the current state. If the current state is 11 or more you will need to fire the callback for 11 also. 

    If you have multiple callbacks scheduled very close together you should probably do all this in a loop, in case your interrupt is delayed by something else in the system (like the SoftDevice).

    This is pretty much the route we have gone and you are absolutely correct that we can tolerate some jitter. We have also added an additional tick to reduce the probability of this issue occurring in the first place while using something similar to the above as a fallback.

    Thank you for all your help

    Alex

Reply
  • Hi Torbjørn,

    Thank you for the reply and confirmation that a capture and set is required.

    With regards to the solution you suggested to our issue:

    Alternatively, you might need to run a timer capture at the end of the interrupt to check how far the timer has come, and if there is a risk that you have lost any interrupts. 

    As an example, say you have the CC register set to 10, but you also need to schedule an interrupt at 11. When the interrupt fires at 10 you first schedule the callback associated with 10, and then you do a timer capture and check the current state. If the current state is 11 or more you will need to fire the callback for 11 also. 

    If you have multiple callbacks scheduled very close together you should probably do all this in a loop, in case your interrupt is delayed by something else in the system (like the SoftDevice).

    This is pretty much the route we have gone and you are absolutely correct that we can tolerate some jitter. We have also added an additional tick to reduce the probability of this issue occurring in the first place while using something similar to the above as a fallback.

    Thank you for all your help

    Alex

Children
No Data
Related