timer overflow

Technical questions regarding the XTC tools and programming with XMOS.
babazaroni
Experienced Member
Posts: 94
Joined: Sun Feb 10, 2013 4:47 am

timer overflow

Post by babazaroni »

What's the best practice in dealing with timer overflow in the following situation:

Code: Select all

timer t;
unsigned int time;

t :> time;

for(;;)
{
    select {
           case t when timerafter(time) :> time:
                time += 1E6;
                do_something();
                break;
     }
}
The problem is when the variable time overflows, the select will fire immediately again, because the timer t value is after time.

I could throw in a bunch of code to check for this, but was wondering if there is an elegant way to handle this?


Guest

Post by Guest »

You can do something like this:

Code: Select all

timer t;
unsigned int time;

t :> time;

for(;;)
{
    select {
           case t when timerafter(time+1E6) :> time:
                do_something();
                break;
     }
}
Hagrid
Active Member
Posts: 44
Joined: Mon Jul 29, 2013 4:33 am

Post by Hagrid »

Why do you need to capture the timestamp into time? Opens the door for creepage.

case t when timerafter(time):
time += 1E6;
Guest

Post by Guest »

Hagrid wrote:Why do you need to capture the timestamp into time? Opens the door for creepage.
In the above post, initially we are taking the time stamp of the timer 't' into variable 'time'. Then in the select statement, we are checking if the current timer value 't' is equal to 'time + 1E6' or not. Only when the timer values is greater than 't+1E6' the timer 't' updated the variable 'time'. This method triggers the timer event periodically. Have a look at the timers and select statements in the XC programming guide.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

If 'do_something()' takes a lot of cycles then this could be safer no?

Code: Select all

timer t;
unsigned int time;

t :> time;

for(;;)
{
    select {
           case t when timerafter(time) :> void:
                do_something();
                t :> time;
                time += 1E6;
                break;
     }
}
I seem to remember this approach being the recommended in a thread from ages ago but I cannot find a reference to it..

regards
Al
babazaroni
Experienced Member
Posts: 94
Joined: Sun Feb 10, 2013 4:47 am

Post by babazaroni »

OK, lets assume do_something always takes much less then 1E6 ticks to finish and to avoid creepage, I've change the code.

Code: Select all

timer t;
unsigned int time;

t :> time;

for(;;)
{
    select {
           case t when timerafter(time) :> void:
                time += 1E6;
                do_something();
                break;
     }
}
But still, when the 32 bit value time overflows, the case will continually fire on entry until the timer overflows, each time bumping up the value time.

Is my understanding correct and if so, what's the elegant way to avoid this?
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm

Post by Folknology »

You would either need to take the time:

Code: Select all

t :> time;
Or capture it on timerafter:

Code: Select all

case t when timerafter(time) :> time
Otherwise time is what it was before and timerafter is auto triggered I think..
babazaroni
Experienced Member
Posts: 94
Joined: Sun Feb 10, 2013 4:47 am

Post by babazaroni »

I'm ok with either taking the time, or capturing it in the case statement, but I'm still wondering about this overflow situation.

Lets assume the case statement fires and 4294E6 is captured in 'time'. Now 1E6 gets added to 'time', but 4295E6 overflows to 32704 in a 32 bit word.

Now, until the actual timer value overflows, the case statement will continue to fire immediately on entry, instead of waiting 1E6 ticks, which is undesired.

I don't want to write a bunch of code which detects the overflow and makes adjustments, if there is a better way to handle this situation.
Guest

Post by Guest »

You don't need to worry about counter overflow. That is taken care by xCore architecture. Timer event will be triggered periodically.
babazaroni
Experienced Member
Posts: 94
Joined: Sun Feb 10, 2013 4:47 am

Post by babazaroni »

If the architecture handles this situation properly, can someone explain how it is done?

The only way I can see the architecture handling this situation is if on entry to the select case statement, the logic sees that the timer value is after the trigger value, and ignores this condition till the timer overflows, then waits till the the timer value is after the trigger value.

I tested this scenario, and the architecture fires immediately, so I doubt that the architecture handles the overflow scenario correctly, unless it is explained to me how this is done.