interface Leds;
interface TimeSyncPacket<precision_tag,uint32_t>;
interface LocalTime<precision_tag> as LocalTime;
+
+
+#ifdef LOW_POWER_LISTENING
+ interface LowPowerListening;
+#endif
+
}
}
implementation
IGNORE_ROOT_MSG = 4, // after becoming the root ignore other roots messages (in send period)
ENTRY_VALID_LIMIT = 4, // number of entries to become synchronized
ENTRY_SEND_LIMIT = 3, // number of entries to send sync messages
- ENTRY_THROWOUT_LIMIT = 100, // if time sync error is bigger than this clear the table
+ ENTRY_THROWOUT_LIMIT = 500, // if time sync error is bigger than this clear the table
};
typedef struct TableItem
float newSkew = skew;
uint32_t newLocalAverage;
int32_t newOffsetAverage;
+ int32_t localAverageRest;
+ int32_t offsetAverageRest;
int64_t localSum;
int64_t offsetSum;
newOffsetAverage = table[i].timeOffset;
localSum = 0;
+ localAverageRest = 0;
offsetSum = 0;
+ offsetAverageRest = 0;
while( ++i < MAX_ENTRIES )
if( table[i].state == ENTRY_FULL ) {
+ /*
+ This only works because C ISO 1999 defines the signe for modulo the same as for the Dividend!
+ */
localSum += (int32_t)(table[i].localTime - newLocalAverage) / tableEntries;
+ localAverageRest += (table[i].localTime - newLocalAverage) % tableEntries;
offsetSum += (int32_t)(table[i].timeOffset - newOffsetAverage) / tableEntries;
+ offsetAverageRest += (table[i].timeOffset - newOffsetAverage) % tableEntries;
}
- newLocalAverage += localSum;
- newOffsetAverage += offsetSum;
+ newLocalAverage += localSum + localAverageRest / tableEntries;
+ newOffsetAverage += offsetSum + offsetAverageRest / tableEntries;
localSum = offsetSum = 0;
for(i = 0; i < MAX_ENTRIES; ++i)
uint32_t age, oldestTime = 0;
int32_t timeError;
- tableEntries = 0;
-
// clear table if the received entry's been inconsistent for some time
timeError = msg->localTime;
call GlobalTime.local2Global((uint32_t*)(&timeError));
{
if (++numErrors>3)
clearTable();
+ return; // don't incorporate a bad reading
}
- else
- numErrors = 0;
+ tableEntries = 0; // don't reset table size unless you're recounting
+ numErrors = 0;
for(i = 0; i < MAX_ENTRIES; ++i) {
age = msg->localTime - table[i].localTime;
if( diff < -16 || diff > 16 )
return msg;
#endif
- if( (state & STATE_PROCESSING) == 0 ) {
+ if( (state & STATE_PROCESSING) == 0
+ && call TimeSyncPacket.isValid(msg)) {
message_t* old = processedMsg;
processedMsg = msg;
outgoingMsg->globalTime = globalTime;
+#ifdef LOW_POWER_LISTENING
+ call LowPowerListening.setRxSleepInterval(&outgoingMsgBuffer, LPL_INTERVAL);
+#endif
// we don't send time sync msg, if we don't have enough data
if( numEntries < ENTRY_SEND_LIMIT && outgoingMsg->rootID != TOS_NODE_ID ){
++heartBeats;
if (mode == mode_)
return SUCCESS;
- if (mode_ == TS_USER_MODE){
+ if (mode_ == TS_TIMER_MODE){
call Timer.startPeriodic((uint32_t)1000 * BEACON_RATE);
}
else