cancel
Showing results for 
Search instead for 
Did you mean: 

timer0_delay bug?

tod_02
Associate II
Posted on April 26, 2005 at 13:03

timer0_delay bug?

4 REPLIES 4
tod_02
Associate II
Posted on May 17, 2011 at 12:06

I am a newbie to uPSD3300 programming so I have been reviewing the supplied demo programs and trying to learn. A lot of the demos rely on some timing loops using Timer1. The file upsd3300_timer.c has the following method which I think has a problem when the counter maintained by timer0_count() rolls over from 65535 to 0. If the user asked for a 1 second delay and they were within 1 second counts of 0xFFFF then they are in for a 10 minute wait aren't they? Is this the case or am I missing something?

Code:

void timer0_delay (unsigned int count)

{

unsigned int start_count;

start_count = timer0_count(); /* get the start count */

while ((timer0_count() - start_count) <= count) /* wait for count ''ticks'' */

{

PCON |= 0x01; // Idle MCU to wait for timer tick

}

}

-Tod

jdaniel
Associate II
Posted on May 17, 2011 at 12:06

Tod_,

It's no problem. It's generally a good idea to question how things work. For instance, having learned this lesson, you probably won't forget it, but you WILL see code at some point in your life where people explicitly WASTE processor time checking if a variable has rolled over and switching around the comparison. So.. you're not alone, and the fact that you asked means there will hopefully be one less system wasting time doing useless operations.

jdaniel
Associate II
Posted on May 17, 2011 at 12:06

Tod,

You've missed something. I think this timer rollover thing confuses many people initially. The problem is that you're considering the width of the timer counter (i.e. that it will roll over), but not the width of the variables performing the subtraction.

For instance, imagine that the current counter that's loaded into start_count is 0xFFFE and that the user has requested 4 counts of delay. After one more timer tick, the comparison yields:

(0xFFFF - 0xFFFE) = 0x0001 <= 4

It's after the next tick that you're getting confused. Now, the timer counter will roll over to 0x0000 and the comparison will yield:

(0x0000 - 0xFFFE) which would normally be -2, but this is an UNSIGNED integer. What the machine will do, internally, to subtract two numbers is take the twos complement of the subtrahend and then add them. Here's how it would look in binary:

0xFFFE = 1111 1111 1111 1110

2's comp = 0000 0000 0000 0010 = 2

So, when we add these numbers, we find that the answer will be two, which is the correct number of ticks since the start of the counter. The upshot of this is that you never really need to care in a situation like this whether the clock rolls over, but only if the number of counts you're requesting is greater than the width of the ticker can accomodate. Hope that helps.

tod_02
Associate II
Posted on May 17, 2011 at 12:06

Phaze,

Thanks for pointing out the error of my ways. Your example was cyrstal clear. Next time I am tempted to worry about this type of thing I will use the debugger to understand better before I post. Thanks again.