d86b8275ec
The clock adjustments made when waking up from PM1/2 were very inaccurate. If relying on ContikiMAC's rtimer to sleep, this led to Contiki's software clock time, seconds and etimers to be 2.5 s slower after each min, i.e. 1 hour slower after each day, which is a show stopper issue for most real-life applications. This was caused by a lack of accuracy in several pieces of code during sleep entry and wake-up: - It was difficult to synchronize the calls to RTIMER_NOW() before and after sleep with the deactivation and activation of the SysTick peripheral caused by PM1/2. This caused an inaccuracy in the corrective number of ticks passed to clock_adjust(). - The value passed to clock_adjust() was truncated from an rtimer_clock_t value, but the accumulated error caused by these truncated bits was ignored. - The SysTick peripheral had to be stopped during the call to clock_adjust(). Rather than creating even more complicated clock adjustment mechanisms that would probably still have mixed results as to accuracy, this change simply uses the Sleep Timer counter as a base value for Contiki's clock and seconds counters. The tick from the Systick peripheral is still used as the interrupt source to update Contiki's clocks and timers. When running, the SysTick peripheral and the Sleep Timer are synchronized, so combining both is not an issue, and this allows not to alter the rtimer interrupt mechanism using the Sleep Timer. The purpose of the Sleep Timer is to be an RTC, so it is the perfect fit for the clock module, all the more it can not be disturbed by PM1/2. If the 32-kHz XOSC is used, the Sleep Timer is also very accurate. If the 32-kHZ RCOSC is used, it is calibrated from the 32-MHz XOSC, so it is also accurate, and the 32753-Hz vs. 32768-Hz systematic error in that case is negligible, all the more one would use the 32-kHz XOSC for better accuracy. Besides fixing this time drift issue, this change has several benefits: - clock_time(), clock_seconds() and RTIMER_NOW() start synchronized, and they change at the same source pace. - If clock_set_seconds() is called, then clock_seconds() indicates one more second almost exactly one second later, then exactly each second. Before this change, clock_seconds() was not synchronized with clock_set_seconds(), so the value returned by the former could be incremented immediately after the call to the latter in some cases. - The code tied to the clock module is simpler and more robust. Signed-off-by: Benoît Thébaudeau <benoit.thebaudeau@advansee.com> |
||
---|---|---|
.. | ||
dev | ||
usb | ||
cc2538.lds | ||
clock.c | ||
cpu.c | ||
cpu.h | ||
dbg.c | ||
dbg.h | ||
debug-uart.h | ||
ieee-addr.c | ||
ieee-addr.h | ||
lpm.c | ||
lpm.h | ||
Makefile.cc2538 | ||
mtarch.h | ||
reg.h | ||
rtimer-arch.c | ||
rtimer-arch.h | ||
slip-arch.c | ||
spi-arch.h |