I recently cam across a possible bug in the Timer module for the IRIS
motes. I occasionally noticed that the timer would fire very late thus
causing a whole series of cascading failures in my modules.
After days of debugging, I traced the problem to the routine setInterrupt()
in the module Atm1281AlarmAsyncP.
If the alarm is armed to fire after 1 TCNT tick, in some situations OCR2A
will be loaded with a value that will essentially be in the "past", thus
requiring TCNT2 to wrap around for the compare to occur (about 255 ms late).
Since TCNT2 is a free running timer, if TCNT2 increments after the current
time is captured by the call to Counter.get(), the *fired *flag will not be
set, even though the alarm has technically expired. After this, under some
circumstances, the compare register can be loaded with a wrong value.
Consider the following situation when setInterrupt() is called
to = 24
dt = 1
TCNT2 =1
base = 23
now if TCNT increments (TCNT2 = 2) after the current time is captured
uint32_t now = call Counter.get();
Then the following condition will fail
/* Check if alarm expired */
if ((uint32_t)(now - t0) >= dt)
The following variables will be updated as indicated below, to compute
anew value for OCCR2A
alarm_in = 2
newOcr2A = 1
Since newOcr2A =1 and TCNT2 =2 , When OCCR2A is loaded, it will delay
the next alarm by 255 ms.
As a quick workaround, i added the following code to force the timers to
fire after calling setOcr2A(newOcr2A);
//work around
if(newOcr2A >= TCNT)
{
diff = newOcr2A - TCNT ;
}
else
{
diff = (0xFF - TCNT) + newOcr2A ;
}
if( diff > MAXT)
{
fired = TRUE;
}
_______________________________________________
Tinyos-help mailing list
[email protected]
https://www.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help