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
tick.c@30:212ca42b8779, 2018-02-16 (annotated)
- 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?
| User | Revision | Line number | New 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 | } |