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-16
- Revision:
- 18:207dd1474cd9
- Parent:
- 17:927fc1eceb9d
- Child:
- 19:e537bacd1478
File content as of revision 18:207dd1474cd9:
#include <stdint.h>
#include <stdbool.h>
#include "peripherals.h"
#include "rtc.h"
#include "time.h"
#include "tick.h"
#include "led.h"
#include "log.h"
#define ONE_BILLION 1000000000
static volatile int64_t nsTickCount;
static volatile int64_t nsFreqCount;
static volatile int64_t nsTimeCount;
static bool nsCountIsSet = false;
bool TickIsSet() { return nsCountIsSet; }
void TickSet(int64_t extClock)
{
nsTickCount = 0;
nsFreqCount = 0;
nsTimeCount = extClock - LPC_TIM1->TC;
nsCountIsSet = true;
}
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; }
static uint32_t lastCall = 0;
void TickMain()
{
uint32_t sinceLastCall = LPC_TIM1->TC - lastCall;
if (sinceLastCall > TICK_COUNT_PER_SECOND)
{
__disable_irq();
lastCall += TICK_COUNT_PER_SECOND;
nsTickCount += ONE_BILLION;
nsFreqCount += ppb;
nsTimeCount += slew;
slew = 0;
__enable_irq();
}
}
static volatile int64_t nsTickSnapshot;
static volatile int64_t nsFreqSnapshot;
static volatile int64_t nsTimeSnapshot;
static volatile uint32_t timerSnapshot;
void TickSaveSnapshotI()
{
timerSnapshot = LPC_TIM1->TC - lastCall;
nsTickSnapshot = nsTickCount;
nsFreqSnapshot = nsFreqCount;
nsTimeSnapshot = nsTimeCount;
}
static void makeTimesFromCounts(uint32_t timerCount, int64_t tickNs, int64_t freqNs, int64_t timeNs, 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;
nsBase += freqNs;
nsPerTick += ppb;
nsFraction = (nsPerTick * fraction) >> 32;
*pNsInt = nsBase + nsFraction;
nsBase += timeNs;
nsPerTick += slew;
nsFraction = (nsPerTick * fraction) >> 32;
*pNsAbs = nsBase + nsFraction;
}
void TickRetrieveSnapshot(int64_t* pNsInt, int64_t* pNsAbs)
{
makeTimesFromCounts(timerSnapshot, nsTickSnapshot, nsFreqSnapshot, nsTimeSnapshot, pNsInt, pNsAbs);
}
void TickGetTimes(int64_t* pNsInt, int64_t* pNsAbs)
{
uint32_t timerCount;
int64_t tickNs;
int64_t freqNs;
int64_t timeNs;
__disable_irq();
timerCount = LPC_TIM1->TC - lastCall;
tickNs = nsTickCount;
freqNs = nsFreqCount;
timeNs = nsTimeCount;
__enable_irq();
makeTimesFromCounts(timerCount, tickNs, freqNs, timeNs, pNsInt, pNsAbs);
}
void TickInit(void)
{
nsTickCount = 0;
nsFreqCount = 0;
nsTimeCount = 0;
ppb = LPC_RTC->GPREG0; //This is saved each time Tickppb is updated
slew = 0;
nsCountIsSet = false;
LPC_SC->PCONP |= 4; // 4.8.9 Power Control for Peripherals register - Timer1 Power On
LPC_TIM1->TCR = 2; // 21.6.2 Timer Control Register - Reset TC and PC.
LPC_TIM1->CTCR = 0; // 21.6.3 Count Control Register - Timer mode
LPC_TIM1->PR = 0; // 21.6.5 Prescale register - Don't prescale 96MHz clock (divide by PR+1).
LPC_TIM1->MCR = 0; // 21.6.8 Match Control Register - no interrupt or reset
LPC_TIM1->TCR = 1; // 21.6.2 Timer Control Register - Enable TC and PC
}
uint32_t TickElapsed(uint32_t* pLastTime)
{
uint32_t thisTime = LPC_TIM1->TC;
uint32_t elapsed = thisTime - *pLastTime;
*pLastTime = thisTime;
return elapsed;
}