Andrew Boyson / clock

Dependents:   oldheating gps motorhome heating

Committer:
andrewboyson
Date:
Fri Feb 16 17:30:46 2018 +0000
Revision:
30:212ca42b8779
Parent:
29:9332cf906aad
Child:
31:f6ff7fdb9c67
Removed need for defs.h

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 14:7ef557918bb1 5 #include "time.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 28:b4aa41fdeb68 23 int64_t Ticks() { 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 26:0421132e6eaf 35 TimeToTmUtc(t, ptm);
andrewboyson 26:0421132e6eaf 36 }
andrewboyson 26:0421132e6eaf 37 int64_t TicksFromTmUtc(struct tm* ptm)
andrewboyson 26:0421132e6eaf 38 {
andrewboyson 26:0421132e6eaf 39 time_t t = TimeFromTmUtc(ptm);
andrewboyson 26:0421132e6eaf 40 return t << TICK_ONE_SECOND_SHIFT;
andrewboyson 26:0421132e6eaf 41 }
andrewboyson 26:0421132e6eaf 42
andrewboyson 20:62e0760cae13 43
andrewboyson 20:62e0760cae13 44 /*
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 20:62e0760cae13 56 */
andrewboyson 24:6c9833e2a049 57
andrewboyson 20:62e0760cae13 58 void TickSet(int64_t extClock)
andrewboyson 28:b4aa41fdeb68 59 {
andrewboyson 26:0421132e6eaf 60 int64_t timerCountSinceLastSecond = TimerCountSinceLastSecond();
andrewboyson 26:0421132e6eaf 61 int64_t fraction = (timerCountSinceLastSecond << TICK_ONE_SECOND_SHIFT) / TIMER_COUNT_PER_SECOND;
andrewboyson 26:0421132e6eaf 62 int64_t ticks = extClock - fraction;
andrewboyson 26:0421132e6eaf 63
andrewboyson 20:62e0760cae13 64 __disable_irq();
andrewboyson 26:0421132e6eaf 65 tickCount = ticks;
andrewboyson 26:0421132e6eaf 66 slewCount = 0;
andrewboyson 20:62e0760cae13 67 __enable_irq();
andrewboyson 20:62e0760cae13 68
andrewboyson 28:b4aa41fdeb68 69 ticksThisScan = extClock;
andrewboyson 26:0421132e6eaf 70
andrewboyson 26:0421132e6eaf 71 countIsSet = true;
andrewboyson 20:62e0760cae13 72 }
andrewboyson 18:207dd1474cd9 73 void TickMain()
andrewboyson 26:0421132e6eaf 74 {
andrewboyson 24:6c9833e2a049 75 //Update the times whenever there has been a system second
andrewboyson 26:0421132e6eaf 76 if (TimerTicked)
andrewboyson 18:207dd1474cd9 77 {
andrewboyson 18:207dd1474cd9 78 __disable_irq();
andrewboyson 26:0421132e6eaf 79 tickCount += TICK_ONE_SECOND + ppb;
andrewboyson 26:0421132e6eaf 80 slewCount += slew;
andrewboyson 24:6c9833e2a049 81 slew = 0;
andrewboyson 18:207dd1474cd9 82 __enable_irq();
andrewboyson 18:207dd1474cd9 83 }
andrewboyson 24:6c9833e2a049 84
andrewboyson 24:6c9833e2a049 85 //Update TickTime
andrewboyson 28:b4aa41fdeb68 86 ticksThisScan = tickCount + slewCount + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb + slew, TimerCountSinceLastSecond());
andrewboyson 24:6c9833e2a049 87
andrewboyson 24:6c9833e2a049 88 //Update the ticked flag
andrewboyson 24:6c9833e2a049 89 static bool lastTick = false;
andrewboyson 28:b4aa41fdeb68 90 bool thisTick = ticksThisScan & TICK_ONE_SECOND;
andrewboyson 26:0421132e6eaf 91 ticked = thisTick != lastTick;
andrewboyson 26:0421132e6eaf 92 lastTick = thisTick;
andrewboyson 24:6c9833e2a049 93
andrewboyson 0:33686e88f09a 94 }
andrewboyson 26:0421132e6eaf 95 static volatile int64_t tickSnapshot;
andrewboyson 26:0421132e6eaf 96 static volatile int64_t slewSnapshot;
andrewboyson 26:0421132e6eaf 97 static volatile uint32_t timerSnapshot;
andrewboyson 0:33686e88f09a 98
andrewboyson 22:df0b906bda26 99 void TickSaveSnapshot()
andrewboyson 0:33686e88f09a 100 {
andrewboyson 26:0421132e6eaf 101 timerSnapshot = TimerCountSinceLastSecond();
andrewboyson 26:0421132e6eaf 102 tickSnapshot = tickCount;
andrewboyson 26:0421132e6eaf 103 slewSnapshot = slewCount;
andrewboyson 0:33686e88f09a 104 }
andrewboyson 26:0421132e6eaf 105 void TickGetTimesFromSnapshot(int64_t* pInt, int64_t* pAbs)
andrewboyson 16:933cbe190bb0 106 {
andrewboyson 26:0421132e6eaf 107 *pInt = tickSnapshot + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb, timerSnapshot);
andrewboyson 26:0421132e6eaf 108 *pAbs = tickSnapshot + slewSnapshot + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb + slew, timerSnapshot);
andrewboyson 0:33686e88f09a 109 }
andrewboyson 26:0421132e6eaf 110 void TickGetTimes(int64_t* pInt, int64_t* pAbs)
andrewboyson 23:07b19cd5f6d0 111 {
andrewboyson 26:0421132e6eaf 112 uint32_t timerCount = TimerCountSinceLastSecond();
andrewboyson 26:0421132e6eaf 113 *pInt = tickCount + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb, timerCount);
andrewboyson 26:0421132e6eaf 114 *pAbs = tickCount + slewCount + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb + slew, timerCount);
andrewboyson 0:33686e88f09a 115 }
andrewboyson 17:927fc1eceb9d 116 void TickInit(void)
andrewboyson 0:33686e88f09a 117 {
andrewboyson 30:212ca42b8779 118 ppb = GPREG0; //This is saved each time Tickppb is updated
andrewboyson 24:6c9833e2a049 119 }