module LocalTimeP {
provides {
interface LocalTime<T32khz> as LocalTime32kHz;
+ interface WideLocalTime<T32khz> as WideLocalTime;
}
uses {
interface Counter<T32khz,uint16_t> as Counter32khz16;
implementation {
typedef union
{
- uint32_t op;
+ int64_t op;
struct {
- uint16_t lo;
- uint16_t hi;
+ uint32_t lo;
+ int32_t hi;
};
- } ui32parts_t;
+ } i64parts_t;
- uint16_t counter2sec = 127;
-
+ uint16_t counter2sec = 126;
+ int32_t dayCounter = 0;
+ bool increaseDay = FALSE;
async command uint32_t LocalTime32kHz.get() {
- ui32parts_t time;
+ uint32_t time;
+ unsigned t;
+ bool dirty1;
+ bool dirty2;
atomic {
- time.lo = call Counter32khz16.get();
- time.hi = counter2sec;
- if(call Counter32khz16.isOverflowPending()) ++time.hi;
+ increaseDay = FALSE;
+ do {
+ dirty1 = call Counter32khz16.isOverflowPending();
+ t = call Counter32khz16.get();
+ dirty2 = call Counter32khz16.isOverflowPending();
+ } while (dirty1 != dirty2);
+ time = counter2sec;
+ if(dirty1) {
+ ++time;
+ if(time == 0) {
+ increaseDay = TRUE;
+ }
+ }
+ time = (time << 16) + t;
}
- return time.op;
+ return time;
}
+ async command int64_t WideLocalTime.get() {
+ i64parts_t time;
+ uint32_t t;
+ atomic {
+ t = call LocalTime32kHz.get();
+ time.hi = dayCounter;
+ if(increaseDay) time.hi++;
+ if(time.hi < 0) time.hi = 0;
+ time.lo = t;
+ }
+ return time.op;
+ }
+
async event void Counter32khz16.overflow() {
++counter2sec;
- }
+ if(counter2sec == 0) ++dayCounter;
+ if(dayCounter < 0) dayCounter = 0;
+ }
}