Andrew Boyson / clock

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Thu Nov 29 16:51:19 2018 +0000
Revision:
31:f6ff7fdb9c67
Parent:
30:212ca42b8779
Changed time.c to tm.c

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