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
Diff: time.c
- Revision:
- 32:f915ccb1ece3
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/time.c Thu Nov 29 18:43:27 2018 +0000
@@ -0,0 +1,122 @@
+#include <stdint.h>
+#include <stdbool.h>
+
+#include "rtc.h"
+#include "tm.h"
+#include "time.h"
+#include "timer.h"
+#include "led.h"
+#include "log.h"
+
+#define GPREG0 (*((volatile unsigned *) 0x40024044))
+
+static int64_t tickCount = 0;
+static int64_t slewCount = 0;
+static bool countIsSet = false;
+//static bool ticked = false;
+static int64_t ticksThisScan = 0;
+static volatile int32_t slew = 0; //ns - up to +/- 2.147s of slew
+static volatile int32_t ppb = 0; //This gets set to the last recorded ppb in TickInit
+
+bool TimeIsSet() { return countIsSet; }
+//bool TimeTicked(){ return ticked; }
+int64_t TimeNow() { return ticksThisScan; } //30th bit is one second
+
+int32_t TimeGetSlew() { return slew; }
+void TimeSetSlew(int32_t value) { slew = value; }
+
+int32_t TimeGetPpb () { return ppb; }
+void TimeSetPpb (int32_t value) { ppb = value; GPREG0 = ppb; }
+void TimeAddPpb (int32_t value) { ppb += value; GPREG0 = ppb; }
+
+void TimeToTmUtc (int64_t ticks, struct tm* ptm)
+{
+ time_t t = ticks >> TIME_ONE_SECOND_SHIFT;
+ TmUtcFromTimeT(t, ptm);
+}
+int64_t TimeFromTmUtc(struct tm* ptm)
+{
+ time_t t = TmUtcToTimeT(ptm);
+ return t << TIME_ONE_SECOND_SHIFT;
+}
+
+
+/* Timer counts like this:
++---------+---------------+
+| Seconds | Base count |
++---------+---------------+
+| 0 | 0 |
+| 1 | 96,000,000 |
+| ... | ... |
+| 44 | 4,224,000,000 |
+| 44.74 | 2^32 |
+| 45 | 25,032,704 |
+| ... | ... |
++---------+---------------+
+Tick counts as a signed 64 bit integer
+1 bit sign, 33 bits for seconds, 30 bits for fraction
+giving +/- 272 years with a resolution of around approximately 1ns or 1 ppb per second (2^30 == 1024x1024x1024)
+*/
+
+void TimeSet(int64_t extClock)
+{
+ int64_t timerCountSinceLastSecond = TimerCountSinceLastSecond();
+ int64_t fraction = (timerCountSinceLastSecond << TIME_ONE_SECOND_SHIFT) / TIMER_COUNT_PER_SECOND;
+ int64_t ticks = extClock - fraction;
+
+ __disable_irq();
+ tickCount = ticks;
+ slewCount = 0;
+ __enable_irq();
+
+ ticksThisScan = extClock;
+
+ countIsSet = true;
+}
+void TimeMain()
+{
+ //Update the times whenever there has been a system second
+ if (TimerHadSecond)
+ {
+ __disable_irq();
+ tickCount += TIME_ONE_SECOND + ppb;
+ slewCount += slew;
+ slew = 0;
+ __enable_irq();
+ }
+
+ //Update TickTime
+ ticksThisScan = tickCount + slewCount + TimerMultiplyFractionalPart(TIME_ONE_SECOND + ppb + slew, TimerCountSinceLastSecond());
+
+ //Update the ticked flag
+// static bool lastTick = false;
+// bool thisTick = ticksThisScan & TIME_ONE_SECOND;
+// ticked = thisTick != lastTick;
+// lastTick = thisTick;
+
+}
+static volatile int64_t tickSnapshot;
+static volatile int64_t slewSnapshot;
+static volatile uint32_t timerSnapshot;
+
+void TimeSaveSnapshot()
+{
+ timerSnapshot = TimerCountSinceLastSecond();
+ tickSnapshot = tickCount;
+ slewSnapshot = slewCount;
+}
+void TimesGetFromSnapshot(int64_t* pInt, int64_t* pAbs)
+{
+ *pInt = tickSnapshot + TimerMultiplyFractionalPart(TIME_ONE_SECOND + ppb, timerSnapshot);
+ *pAbs = tickSnapshot + slewSnapshot + TimerMultiplyFractionalPart(TIME_ONE_SECOND + ppb + slew, timerSnapshot);
+}
+void TimesGet(int64_t* pInt, int64_t* pAbs)
+{
+ uint32_t timerCount = TimerCountSinceLastSecond();
+ *pInt = tickCount + TimerMultiplyFractionalPart(TIME_ONE_SECOND + ppb, timerCount);
+ *pAbs = tickCount + slewCount + TimerMultiplyFractionalPart(TIME_ONE_SECOND + ppb + slew, timerCount);
+}
+void TimeInit(void)
+{
+ ppb = GPREG0; //This is saved each time Tickppb is updated
+}
\ No newline at end of file