Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: oldheating gps motorhome heating
sync.c
- Committer:
- andrewboyson
- Date:
- 2018-01-25
- Revision:
- 26:0421132e6eaf
- Parent:
- 22:df0b906bda26
- Child:
- 28:b4aa41fdeb68
File content as of revision 26:0421132e6eaf:
#include <stdlib.h>
#include <stdbool.h>
#include "log.h"
#include "tick.h"
#include "time.h"
#include "clock.h"
bool SyncTrace = false;
bool SyncedTime = false;
bool SyncedRate = false;
static void setSyncedTime(int64_t diff)
{
int64_t absDiff = llabs(diff);
int64_t limit = ClockSyncedLimitNs;
int64_t hysterisis = ClockSyncedHysterisNs;
if (absDiff < limit - hysterisis) SyncedTime = true;
if (absDiff > limit + hysterisis) SyncedTime = false;
}
static void setSyncedRate(int64_t diff)
{
int64_t absDiff = llabs(diff);
int64_t limit = ClockSyncedLimitPpb;
int64_t hysterisis = ClockSyncedHysterisPpb;
if (absDiff < limit - hysterisis) SyncedRate = true;
if (absDiff > limit + hysterisis) SyncedRate = false;
}
static void setSlew(int64_t diff)
{
int64_t slew = -diff / ClockSlewDivisor;
int32_t slewMaxTicks = ClockSlewMaxMs << 20;
if (slew > slewMaxTicks) slew = slewMaxTicks;
if (slew < -slewMaxTicks) slew = -slewMaxTicks;
TickSetSlew(slew);
if (SyncTrace) LogTimeF("Sync setSlew diff %lld gives slew %lld gives TickSlew %ld\r\n", diff, slew, TickGetSlew());
}
static void adjustPpb(int64_t diff)
{
int64_t toAdd = diff / ClockPpbDivisor;
int32_t maxAdd = ClockPpbChangeMax;
if (toAdd > maxAdd) toAdd = maxAdd;
if (toAdd < -maxAdd) toAdd = -maxAdd;
TickAddPpb(-toAdd);
if (SyncTrace) LogTimeF("Sync setPpb diff %lld gives toAdd %lld gives TickPpb %ld\r\n", diff, toAdd, TickGetPpb());
}
static int64_t lastIntClock = -1; //-1 indicates invalid value. 0 is a valid value.
static int64_t lastExtClock = -1;
static void reset(int64_t thisExtClock)
{
TickSet(thisExtClock);
TickSetPpb(0);
lastIntClock = 0;
lastExtClock = 0;
}
static void sync(int64_t thisExtClock)
{
if (!TickIsSet()) //Cold start - only ever true if the RTC was not set.
{
LogTimeF("Sync - cold start of clock so resetting\r\n");
reset(thisExtClock);
return;
}
//Get the time at the time of the interrupt
int64_t thisIntClock;
int64_t thisAbsClock;
TickGetTimesFromSnapshot(&thisIntClock, &thisAbsClock);
//Calulate the time error
int64_t absDiff = thisAbsClock - thisExtClock;
if (llabs(absDiff) > ((int64_t)ClockMaxOffsetSecs << TICK_ONE_SECOND_SHIFT))
{
LogTimeF("Sync - offset is greater than %d seconds so resetting\r\n", ClockMaxOffsetSecs);
reset(thisExtClock);
return;
}
setSlew(absDiff);
setSyncedTime(absDiff);
//Calculate the rate error
if (lastExtClock > -1)
{
int64_t extPeriod = thisExtClock - lastExtClock;
int64_t intPeriod = thisIntClock - lastIntClock;
int64_t periodDiff = intPeriod - extPeriod;
int64_t ppb;
if (extPeriod == TICK_ONE_SECOND) ppb = periodDiff; //This saves a 64bit shift and division for PPS
else ppb = (periodDiff << TICK_ONE_SECOND_SHIFT) / extPeriod;
adjustPpb(ppb);
setSyncedRate(ppb);
}
//Save last values
lastIntClock = thisIntClock;
lastExtClock = thisExtClock;
}
void SyncPpsI ( ) { TickSaveSnapshot(); }
void SyncPpsN (time_t t ) { int64_t ticks = t << TICK_ONE_SECOND_SHIFT; sync(ticks); }
void SyncTicks(int64_t ticks) { TickSaveSnapshot(); sync(ticks); }