Andrew Boyson / clock

Dependents:   oldheating gps motorhome heating

clock.c

Committer:
andrewboyson
Date:
2018-01-11
Revision:
17:927fc1eceb9d
Parent:
clock.cpp@ 16:933cbe190bb0
Child:
18:207dd1474cd9

File content as of revision 17:927fc1eceb9d:

#include <stdint.h>
#include <stdio.h>

#include  "log.h"
#include "tick.h"
#include "sync.h"
#include "time.h"
#include  "rtc.h"

#define ONE_BILLION 1000000000

void    ClockNsToTmUtc  (int64_t ns, struct tm* ptm)
{
    time_t t = ns / ONE_BILLION;
    TimeToTmUtc(t, ptm);
}
int64_t ClockNsFromTmUtc(struct tm* ptm)
{
    time_t t = TimeFromTmUtc(ptm);
    return t * ONE_BILLION;
}

int ClockSlewDivisor       = 10;
int ClockSlewMaxMs         = 10;
int ClockPpbDivisor        = 10;
int ClockPpbChangeMax      = 1000;
int ClockSyncedLimitNs     = 10000000;
int ClockSyncedHysterisNs  =  1000000;
int ClockSyncedLimitPpb    = 1000;
int ClockSyncedHysterisPpb =  100;
int ClockMaxOffsetSecs     = 3;

static int64_t nowNs = 0;
static time_t  nowT  = 0;
static void calculateTimes()
{
    int64_t nsInt;
    TickGetTimes(&nsInt, &nowNs);
    nowT = nowNs / ONE_BILLION;
}

static int64_t refNs = 0;
int64_t ClockRefNs()
{
    return refNs;
}
int ClockIsSet()
{
    return TickIsSet();
}
int ClockIsSynced()
{
    return SyncedRate && SyncedTime;
}

int64_t ClockNowNs()
{
    return nowNs;
}

void ClockTmLocal(struct tm* ptm)
{
    TimeToTmLocal(nowT, ptm);
}
void ClockTmUtc(struct tm* ptm)
{
    TimeToTmUtc(nowT, ptm);
}

void ClockAscii(char* p)
{
    struct tm tm;
    TimeToTmUtc(nowT, &tm);
    sprintf(p, "%d-%02d-%02d %02d:%02d:%02d", tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
}
void ClockInit()
{
     RtcInit();
    TickInit();
}

int ClockTicked = 0; //Set to true for one scan each time the second changes

void ClockMain()
{
    //Calculate ns and time_t
    calculateTimes();
    
    static int lastSyncedRate = 0;
    static int lastSyncedTime = 0;
    
    if ( SyncedRate && !lastSyncedRate) LogTimeF("Rate sync acquired\r\n");
    if (!SyncedRate &&  lastSyncedRate) LogTimeF("Rate sync lost\r\n");
    if ( SyncedTime && !lastSyncedTime) LogTimeF("Time sync acquired\r\n");
    if (!SyncedTime &&  lastSyncedTime) LogTimeF("Time sync lost\r\n");
    
    lastSyncedRate = SyncedRate;
    lastSyncedTime = SyncedTime;
         
    //Record the time the clock started
    if (SyncedTime && SyncedRate) refNs = nowNs;

    //Set a one shot memory for having had a tick
    static time_t lastT = 0;
    ClockTicked = lastT > 0 && lastT != nowT;
    lastT = nowT;
        
    if (TickIsSet())
    {
        //Save the time to the RTC on the second
        if (ClockTicked)
        {
            struct tm tm;
            ClockTmUtc(&tm);
            RtcSetTm(&tm);
        }
    }
    else
    {
        //Start the clock from the RTC if not started
        if (RtcIsSet())
        {
            static int lastRtcSecond = -1;
            struct tm tm;
            RtcGetTm(&tm);
            if (lastRtcSecond > 0 && tm.tm_sec != lastRtcSecond)
            {
                time_t t = TimeFromTmUtc(&tm);
                TickSet(t * (int64_t)ONE_BILLION);
                calculateTimes();
                LogTimeF("Clock set from RTC\r\n");
            }
            lastRtcSecond = tm.tm_sec;
        }
    }
}