Fixed timer period computation when synchronizing for the first time.
@@ -1993,24 +1993,33 @@ void synchronizePacket(PORT_RADIOTIMER_WIDTH timeReceived) {
PORT_SIGNED_INT_WIDTH timeCorrection;
PORT_RADIOTIMER_WIDTH newPeriod;
PORT_RADIOTIMER_WIDTH currentValue;
- PORT_RADIOTIMER_WIDTH currentPeriod;
// record the current timer value and period
currentValue = radio_getTimerValue();
- currentPeriod = radio_getTimerPeriod();
// calculate new period
timeCorrection = (PORT_SIGNED_INT_WIDTH)((PORT_SIGNED_INT_WIDTH)timeReceived - (PORT_SIGNED_INT_WIDTH)TsTxOffset);
- newPeriod = ieee154e_vars.slotDuration;
+
+ // The interrupt beginning a new slot can either occur after the packet has been
+ // or while it is being received, possibly because the mote is not yet synchronized.
+ // In the former case we simply take the usual slotLength and correct it.
+ // In the latter case the timer did already roll over and
+ // currentValue < timeReceived. slotLength did then already pass which is why
+ // we need the new slot to end after the remaining time which is timeCorrection
+ // and in this constellation is guaranteed to be positive.
+ if (currentValue < timeReceived) {
+ newPeriod = (PORT_RADIOTIMER_WIDTH)timeCorrection;
+ } else {
+ newPeriod = (PORT_RADIOTIMER_WIDTH)((PORT_SIGNED_INT_WIDTH)ieee154e_vars.slotDuration + timeCorrection);
+ }
// detect whether I'm too close to the edge of the slot, in that case,
// skip a slot and increase the temporary slot length to be 2 slots long
- if (currentValue<timeReceived || currentPeriod-currentValue<RESYNCHRONIZATIONGUARD) {
+ if ((PORT_SIGNED_INT_WIDTH)newPeriod - (PORT_SIGNED_INT_WIDTH)currentValue < (PORT_SIGNED_INT_WIDTH)RESYNCHRONIZATIONGUARD) {
newPeriod += ieee154e_vars.slotDuration;
incrementAsnOffset();
}
- newPeriod = (PORT_RADIOTIMER_WIDTH)((PORT_SIGNED_INT_WIDTH)newPeriod+timeCorrection);
// resynchronize by applying the new period
radio_setTimerPeriod(newPeriod);
