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
- Committer:
- andrewboyson
- Date:
- 2018-01-22
- Revision:
- 24:6c9833e2a049
- Parent:
- 23:07b19cd5f6d0
- Child:
- 25:81014a201736
File content as of revision 24:6c9833e2a049:
#include <stdint.h>
#include <stdbool.h>
#include "peripherals.h"
#include "rtc.h"
#include "time.h"
#include "tick.h"
#include "timer.h"
#include "led.h"
#include "log.h"
#define ONE_BILLION 1000000000
static volatile int64_t nsTickCount;
static volatile int64_t nsSlewCount;
static bool nsCountIsSet = false;
bool TickIsSet() { return nsCountIsSet; }
static volatile int32_t slew = 0; //ns - up to +/- 2.147s of slew
int32_t TickGetSlew() { return slew; }
void TickSetSlew(int32_t value) { slew = value; }
static volatile int32_t ppb = 0;
int32_t TickGetPpb () { return ppb; }
void TickSetPpb (int32_t value) { ppb = value; LPC_RTC->GPREG0 = ppb; }
void TickAddPpb (int32_t value) { ppb += value; LPC_RTC->GPREG0 = ppb; }
bool TickTicked = false;
/*
+---------+---------------+
| Seconds | Base count |
+---------+---------------+
| 0 | 0 |
| 1 | 96,000,000 |
| ... | ... |
| 44 | 4,224,000,000 |
| 44.74 | 2^32 |
| 45 | 25,032,704 |
| ... | ... |
+---------+---------------+
*/
static uint32_t secondsBaseCount = 0;
int64_t TickTime = 0; //30th bit is one second
void TickSet(int64_t extClock)
{
uint32_t tc = TimerNowCount();
uint32_t seconds = tc / TICK_COUNT_PER_SECOND; //0 to 44
uint32_t base = seconds * TICK_COUNT_PER_SECOND; //0 to 2^32
uint32_t fraction = tc % TICK_COUNT_PER_SECOND; //0 to 96,000,000
uint32_t fractionNs = fraction / 96 * 1000; //0 to 1,000,000,000 which fits into 32 bits
int64_t ns = extClock - fractionNs;
__disable_irq();
nsTickCount = ns;
nsSlewCount = 0;
secondsBaseCount = base;
__enable_irq();
nsCountIsSet = true;
}
void TickMain()
{
uint32_t sinceSecondsBaseCount = TimerSinceCount(secondsBaseCount);
//Update the times whenever there has been a system second
if (sinceSecondsBaseCount > TICK_COUNT_PER_SECOND)
{
__disable_irq();
secondsBaseCount += TICK_COUNT_PER_SECOND;
nsTickCount += ONE_BILLION + ppb;
nsSlewCount += slew;
slew = 0;
__enable_irq();
sinceSecondsBaseCount -= TICK_COUNT_PER_SECOND;
}
//Update TickTime
int64_t fraction = sinceSecondsBaseCount;
fraction <<= 32;
fraction /= TICK_COUNT_PER_SECOND;
int64_t nsBase = nsTickCount + nsSlewCount;
int64_t nsPerTick = ONE_BILLION + ppb + slew;
int64_t nsFraction = (nsPerTick * fraction) >> 32;
TickTime = nsBase + nsFraction;
//Update the ticked flag
static bool lastTick = false;
bool thisTick = TickTime & (1ULL << 30);
TickTicked = thisTick && !lastTick;
lastTick = TickTicked;
}
static volatile int64_t nsTickSnapshot;
static volatile int64_t nsSlewSnapshot;
static volatile uint32_t timerSnapshot;
void TickSaveSnapshot()
{
timerSnapshot = TimerSinceCount(secondsBaseCount);
nsTickSnapshot = nsTickCount;
nsSlewSnapshot = nsSlewCount;
}
static void makeTimesFromCounts(uint32_t timerCount, int64_t tickNs, int64_t slewNs, int64_t* pNsInt, int64_t* pNsAbs)
{
int64_t fraction = timerCount;
fraction <<= 32;
fraction /= TICK_COUNT_PER_SECOND;
int64_t nsFraction;
int64_t nsBase = tickNs;
int64_t nsPerTick = ONE_BILLION + ppb;
nsFraction = (nsPerTick * fraction) >> 32;
*pNsInt = nsBase + nsFraction;
nsBase += slewNs;
nsPerTick += slew;
nsFraction = (nsPerTick * fraction) >> 32;
*pNsAbs = nsBase + nsFraction;
}
void TickGetTimesFromSnapshot(int64_t* pNsInt, int64_t* pNsAbs)
{
makeTimesFromCounts(timerSnapshot, nsTickSnapshot, nsSlewSnapshot, pNsInt, pNsAbs);
}
void TickGetTimes(int64_t* pNsInt, int64_t* pNsAbs)
{
makeTimesFromCounts(TimerSinceCount(secondsBaseCount), nsTickCount, nsSlewCount, pNsInt, pNsAbs);
}
void TickInit(void)
{
nsTickCount = 0;
nsSlewCount = 0;
ppb = LPC_RTC->GPREG0; //This is saved each time Tickppb is updated
slew = 0;
nsCountIsSet = false;
}