Andrew Boyson / clock

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Sat Jan 27 12:17:09 2018 +0000
Revision:
29:9332cf906aad
Parent:
28:b4aa41fdeb68
Child:
30:212ca42b8779
libraries updated

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andrewboyson 18:207dd1474cd9 1 #include <stdint.h>
andrewboyson 18:207dd1474cd9 2 #include <stdbool.h>
andrewboyson 18:207dd1474cd9 3
andrewboyson 29:9332cf906aad 4 #include "defs.h"
andrewboyson 24:6c9833e2a049 5 #include "rtc.h"
andrewboyson 14:7ef557918bb1 6 #include "time.h"
andrewboyson 14:7ef557918bb1 7 #include "tick.h"
andrewboyson 24:6c9833e2a049 8 #include "timer.h"
andrewboyson 18:207dd1474cd9 9 #include "led.h"
andrewboyson 18:207dd1474cd9 10 #include "log.h"
andrewboyson 0:33686e88f09a 11
andrewboyson 26:0421132e6eaf 12 static int64_t tickCount = 0;
andrewboyson 26:0421132e6eaf 13 static int64_t slewCount = 0;
andrewboyson 26:0421132e6eaf 14 static bool countIsSet = false;
andrewboyson 26:0421132e6eaf 15 static bool ticked = false;
andrewboyson 28:b4aa41fdeb68 16 static int64_t ticksThisScan = 0;
andrewboyson 26:0421132e6eaf 17 static volatile int32_t slew = 0; //ns - up to +/- 2.147s of slew
andrewboyson 26:0421132e6eaf 18 static volatile int32_t ppb = 0; //This gets set to the last recorded ppb in TickInit
andrewboyson 0:33686e88f09a 19
andrewboyson 26:0421132e6eaf 20 bool TickIsSet() { return countIsSet; }
andrewboyson 26:0421132e6eaf 21 bool Ticked() { return ticked; }
andrewboyson 28:b4aa41fdeb68 22 int64_t Ticks() { return ticksThisScan; } //30th bit is one second
andrewboyson 0:33686e88f09a 23
andrewboyson 5:a3e37ce4975d 24 int32_t TickGetSlew() { return slew; }
andrewboyson 5:a3e37ce4975d 25 void TickSetSlew(int32_t value) { slew = value; }
andrewboyson 5:a3e37ce4975d 26
andrewboyson 5:a3e37ce4975d 27 int32_t TickGetPpb () { return ppb; }
andrewboyson 5:a3e37ce4975d 28 void TickSetPpb (int32_t value) { ppb = value; LPC_RTC->GPREG0 = ppb; }
andrewboyson 5:a3e37ce4975d 29 void TickAddPpb (int32_t value) { ppb += value; LPC_RTC->GPREG0 = ppb; }
andrewboyson 0:33686e88f09a 30
andrewboyson 26:0421132e6eaf 31 void TicksToTmUtc (int64_t ticks, struct tm* ptm)
andrewboyson 26:0421132e6eaf 32 {
andrewboyson 26:0421132e6eaf 33 time_t t = ticks >> TICK_ONE_SECOND_SHIFT;
andrewboyson 26:0421132e6eaf 34 TimeToTmUtc(t, ptm);
andrewboyson 26:0421132e6eaf 35 }
andrewboyson 26:0421132e6eaf 36 int64_t TicksFromTmUtc(struct tm* ptm)
andrewboyson 26:0421132e6eaf 37 {
andrewboyson 26:0421132e6eaf 38 time_t t = TimeFromTmUtc(ptm);
andrewboyson 26:0421132e6eaf 39 return t << TICK_ONE_SECOND_SHIFT;
andrewboyson 26:0421132e6eaf 40 }
andrewboyson 26:0421132e6eaf 41
andrewboyson 20:62e0760cae13 42
andrewboyson 20:62e0760cae13 43 /*
andrewboyson 20:62e0760cae13 44 +---------+---------------+
andrewboyson 20:62e0760cae13 45 | Seconds | Base count |
andrewboyson 20:62e0760cae13 46 +---------+---------------+
andrewboyson 20:62e0760cae13 47 | 0 | 0 |
andrewboyson 20:62e0760cae13 48 | 1 | 96,000,000 |
andrewboyson 20:62e0760cae13 49 | ... | ... |
andrewboyson 20:62e0760cae13 50 | 44 | 4,224,000,000 |
andrewboyson 20:62e0760cae13 51 | 44.74 | 2^32 |
andrewboyson 20:62e0760cae13 52 | 45 | 25,032,704 |
andrewboyson 20:62e0760cae13 53 | ... | ... |
andrewboyson 20:62e0760cae13 54 +---------+---------------+
andrewboyson 20:62e0760cae13 55 */
andrewboyson 24:6c9833e2a049 56
andrewboyson 20:62e0760cae13 57 void TickSet(int64_t extClock)
andrewboyson 28:b4aa41fdeb68 58 {
andrewboyson 26:0421132e6eaf 59 int64_t timerCountSinceLastSecond = TimerCountSinceLastSecond();
andrewboyson 26:0421132e6eaf 60 int64_t fraction = (timerCountSinceLastSecond << TICK_ONE_SECOND_SHIFT) / TIMER_COUNT_PER_SECOND;
andrewboyson 26:0421132e6eaf 61 int64_t ticks = extClock - fraction;
andrewboyson 26:0421132e6eaf 62
andrewboyson 20:62e0760cae13 63 __disable_irq();
andrewboyson 26:0421132e6eaf 64 tickCount = ticks;
andrewboyson 26:0421132e6eaf 65 slewCount = 0;
andrewboyson 20:62e0760cae13 66 __enable_irq();
andrewboyson 20:62e0760cae13 67
andrewboyson 28:b4aa41fdeb68 68 ticksThisScan = extClock;
andrewboyson 26:0421132e6eaf 69
andrewboyson 26:0421132e6eaf 70 countIsSet = true;
andrewboyson 20:62e0760cae13 71 }
andrewboyson 18:207dd1474cd9 72 void TickMain()
andrewboyson 26:0421132e6eaf 73 {
andrewboyson 24:6c9833e2a049 74 //Update the times whenever there has been a system second
andrewboyson 26:0421132e6eaf 75 if (TimerTicked)
andrewboyson 18:207dd1474cd9 76 {
andrewboyson 18:207dd1474cd9 77 __disable_irq();
andrewboyson 26:0421132e6eaf 78 tickCount += TICK_ONE_SECOND + ppb;
andrewboyson 26:0421132e6eaf 79 slewCount += slew;
andrewboyson 24:6c9833e2a049 80 slew = 0;
andrewboyson 18:207dd1474cd9 81 __enable_irq();
andrewboyson 18:207dd1474cd9 82 }
andrewboyson 24:6c9833e2a049 83
andrewboyson 24:6c9833e2a049 84 //Update TickTime
andrewboyson 28:b4aa41fdeb68 85 ticksThisScan = tickCount + slewCount + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb + slew, TimerCountSinceLastSecond());
andrewboyson 24:6c9833e2a049 86
andrewboyson 24:6c9833e2a049 87 //Update the ticked flag
andrewboyson 24:6c9833e2a049 88 static bool lastTick = false;
andrewboyson 28:b4aa41fdeb68 89 bool thisTick = ticksThisScan & TICK_ONE_SECOND;
andrewboyson 26:0421132e6eaf 90 ticked = thisTick != lastTick;
andrewboyson 26:0421132e6eaf 91 lastTick = thisTick;
andrewboyson 24:6c9833e2a049 92
andrewboyson 0:33686e88f09a 93 }
andrewboyson 26:0421132e6eaf 94 static volatile int64_t tickSnapshot;
andrewboyson 26:0421132e6eaf 95 static volatile int64_t slewSnapshot;
andrewboyson 26:0421132e6eaf 96 static volatile uint32_t timerSnapshot;
andrewboyson 0:33686e88f09a 97
andrewboyson 22:df0b906bda26 98 void TickSaveSnapshot()
andrewboyson 0:33686e88f09a 99 {
andrewboyson 26:0421132e6eaf 100 timerSnapshot = TimerCountSinceLastSecond();
andrewboyson 26:0421132e6eaf 101 tickSnapshot = tickCount;
andrewboyson 26:0421132e6eaf 102 slewSnapshot = slewCount;
andrewboyson 0:33686e88f09a 103 }
andrewboyson 26:0421132e6eaf 104 void TickGetTimesFromSnapshot(int64_t* pInt, int64_t* pAbs)
andrewboyson 16:933cbe190bb0 105 {
andrewboyson 26:0421132e6eaf 106 *pInt = tickSnapshot + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb, timerSnapshot);
andrewboyson 26:0421132e6eaf 107 *pAbs = tickSnapshot + slewSnapshot + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb + slew, timerSnapshot);
andrewboyson 0:33686e88f09a 108 }
andrewboyson 26:0421132e6eaf 109 void TickGetTimes(int64_t* pInt, int64_t* pAbs)
andrewboyson 23:07b19cd5f6d0 110 {
andrewboyson 26:0421132e6eaf 111 uint32_t timerCount = TimerCountSinceLastSecond();
andrewboyson 26:0421132e6eaf 112 *pInt = tickCount + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb, timerCount);
andrewboyson 26:0421132e6eaf 113 *pAbs = tickCount + slewCount + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb + slew, timerCount);
andrewboyson 0:33686e88f09a 114 }
andrewboyson 17:927fc1eceb9d 115 void TickInit(void)
andrewboyson 0:33686e88f09a 116 {
andrewboyson 5:a3e37ce4975d 117 ppb = LPC_RTC->GPREG0; //This is saved each time Tickppb is updated
andrewboyson 24:6c9833e2a049 118 }