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

  • Hello,

    I realise the question is quite broad and therefore different use cases might do different things for the described scenario above with the intervals.

    Given your suggestion that one can prepare multiple intervals ahead of time, the answer to the main question is that there is no direct way of performing a relative increment of the CC (specifically compare) register. Is this correct?

    To answer your questions,
    1) I do have the maximum interval and could therefore prepare multiple intervals ahead of time, however we are currently using most of the CC channels available across most timers so finding spare resource is not trivial to implement such a solution. For a bit of background on our specific use case we have two types of timers, the critical ones and the software based timers. The critical channels are driven directly off the CC channels while the software timers are all driven off a single CC channel as per the situation described above with multiple (varying) intervals.

    2) The minimum interval size is 1 tick of the timer due to two soft timers being scheduled very close to the expiry of each other. Getting a 1 tick interval is very rare however it does occur and is the prompt for this question. In our case the timer is configured such that it ticks at 125kHz (i.e 8us intervals), where we ended up not getting the interrupt due to the timer already having ticked. The theoretical maximum number of ticks is (0xFFFFFFFF -1) however the practical  maximum is around 6250 ticks (500ms)

    Alex

Reply
  • Hello,

    I realise the question is quite broad and therefore different use cases might do different things for the described scenario above with the intervals.

    Given your suggestion that one can prepare multiple intervals ahead of time, the answer to the main question is that there is no direct way of performing a relative increment of the CC (specifically compare) register. Is this correct?

    To answer your questions,
    1) I do have the maximum interval and could therefore prepare multiple intervals ahead of time, however we are currently using most of the CC channels available across most timers so finding spare resource is not trivial to implement such a solution. For a bit of background on our specific use case we have two types of timers, the critical ones and the software based timers. The critical channels are driven directly off the CC channels while the software timers are all driven off a single CC channel as per the situation described above with multiple (varying) intervals.

    2) The minimum interval size is 1 tick of the timer due to two soft timers being scheduled very close to the expiry of each other. Getting a 1 tick interval is very rare however it does occur and is the prompt for this question. In our case the timer is configured such that it ticks at 125kHz (i.e 8us intervals), where we ended up not getting the interrupt due to the timer already having ticked. The theoretical maximum number of ticks is (0xFFFFFFFF -1) however the practical  maximum is around 6250 ticks (500ms)

    Alex

Children
  • Hi Alex

    Alex Crombie said:
    Given your suggestion that one can prepare multiple intervals ahead of time, the answer to the main question is that there is no direct way of performing a relative increment of the CC (specifically compare) register. Is this correct?

    That is correct. In order to do a relative increment you would need to run some code to read out the current value, calculate the new value, and write it back in. There is no way to have this done automatically, without software intervention. 

    Alex Crombie said:
    Getting a 1 tick interval is very rare however it does occur and is the prompt for this question. In our case the timer is configured such that it ticks at 125kHz (i.e 8us intervals), where we ended up not getting the interrupt due to the timer already having ticked.

    So if I understand you correctly the software based 'non critical' timers could be scheduled 8us apart?

    If this happens, couldn't you combine the two callbacks into one, and have them run at the same time?
    If the timing is non critical I assume that means you could accept a small shift in the timing of one of them?

    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). 

    Best regards
    Torbjørn

Related