This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to make sure, that a compare event will be generated

Hello, I want to generate timer events as exact as possible, based on a time base that is defined by a runing timer. For example, I've setup timer0 to count up every 1µs and the time point, where I've started the timer is my anchor/T0 in time. When I want to have an interrupt that is 600µs after T0, I could simply load 600 into a capture/compare register and wait for the coresponding compare event.

When the value of the counter is already very close to my target time, it could be that I load the capture/compare register with a value that is smaller than the counter value. Checking for the counter before loading the capture compare register would introduce a race condition.

What would be the best / idomatic way to prevent a race condition here? Best without stopping the timer, disabling interrupts and so on.... How about this:

NRF_TIMER0->EVENTS_COMPARE[ 0 ] = 0;
NRF_TIMER0->CC[ 0 ]             = target_time;
NRF_TIMER0->TASKS_CAPTURE[ 1 ]  = 1;

/* manually triggering event for timer beeing already behind target time */
NRF_TIMER0->EVENTS_COMPARE[ 0 ] = NRF_TIMER0->EVENTS_COMPARE[ 0 ] || NRF_TIMER0->CC[ 1 ] >= NRF_TIMER0->CC[ 0 ];
NRF_TIMER0->INTENSET            = TIMER_INTENSET_COMPARE0_Msk;

would that work? Does someone of you have a better approache to cope with possible race conditions here?

Best regards, Torsten

Parents Reply Children
  • Hi Øyvind,

    thank you very much for your input. So your basic idea is, to just look, if the current state of the timer and the destination compare state have a distance that is large enough to be sure, that when setting the cc register, the cc register will still be in front of the timer? As my timer is not going to wrap, that would be fairly easy.

    But I would have to disable interrupts before making the check (or do it in an interrupt handler; like in your PWM example), right? For me it’s not so important to hit the requested time very precisely, but to make sure that my event machine does not stop because an interrupt gets not generated.

    Do you think my approach, to unconditional set the cc register and check afterwards whether the counter overrun the cc register could work? I think I have to make sure, the state machine can cope with double generated interrupts.

    Thanks, Torsten

  • This should work. Be careful about what priorities you give to the different things you need to do though, since you will still generate an interrupt if the cc has higher priority than the function you want to use to unconditionally reset it.

Related