timer: Fix a subtle off-by-one bug in TCNT reading.
authorSami Liedes <sliedes@cc.hut.fi>
Thu, 17 Feb 2011 19:47:00 +0000 (21:47 +0200)
committerSami Liedes <sliedes@cc.hut.fi>
Thu, 17 Feb 2011 19:57:53 +0000 (21:57 +0200)
There's a subtle bug in TCNT (timer counter) reading which only causes
the counter to ever run from 0 to TOP-1, while it should stay in the
TOP value for a full timer cycle before resetting to 0 (but the
interrupt needs to come when TOP is first reached).

Interestingly, this causes Arduino's micros() function to occasionally
return incorrect values. micros() function relies on TCNT0 not
transitioning from <= 254 to 0 in only a few cycles with /64
prescaler.

Signed-off-by: Sami Liedes <sliedes@cc.hut.fi>
simavr/sim/avr_timer.c

index a218a67..b01b76f 100644 (file)
@@ -126,7 +126,7 @@ static uint16_t _avr_timer_get_current_tcnt(avr_timer_t * p)
        if (p->tov_cycles) {
                uint64_t when = avr->cycle - p->tov_base;
 
-               return (when * p->tov_top) / p->tov_cycles;
+               return (when * (((uint32_t)p->tov_top)+1)) / p->tov_cycles;
        }
        return 0;
 }