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-25
- Revision:
- 28:b4aa41fdeb68
- Parent:
- 26:0421132e6eaf
- Child:
- 29:9332cf906aad
File content as of revision 28:b4aa41fdeb68:
#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"
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 TickIsSet() { return countIsSet; }
bool Ticked() { return ticked; }
int64_t Ticks() { return ticksThisScan; } //30th bit is one second
int32_t TickGetSlew() { return slew; }
void TickSetSlew(int32_t value) { slew = value; }
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; }
void TicksToTmUtc (int64_t ticks, struct tm* ptm)
{
time_t t = ticks >> TICK_ONE_SECOND_SHIFT;
TimeToTmUtc(t, ptm);
}
int64_t TicksFromTmUtc(struct tm* ptm)
{
time_t t = TimeFromTmUtc(ptm);
return t << TICK_ONE_SECOND_SHIFT;
}
/*
+---------+---------------+
| Seconds | Base count |
+---------+---------------+
| 0 | 0 |
| 1 | 96,000,000 |
| ... | ... |
| 44 | 4,224,000,000 |
| 44.74 | 2^32 |
| 45 | 25,032,704 |
| ... | ... |
+---------+---------------+
*/
void TickSet(int64_t extClock)
{
int64_t timerCountSinceLastSecond = TimerCountSinceLastSecond();
int64_t fraction = (timerCountSinceLastSecond << TICK_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 TickMain()
{
//Update the times whenever there has been a system second
if (TimerTicked)
{
__disable_irq();
tickCount += TICK_ONE_SECOND + ppb;
slewCount += slew;
slew = 0;
__enable_irq();
}
//Update TickTime
ticksThisScan = tickCount + slewCount + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb + slew, TimerCountSinceLastSecond());
//Update the ticked flag
static bool lastTick = false;
bool thisTick = ticksThisScan & TICK_ONE_SECOND;
ticked = thisTick != lastTick;
lastTick = thisTick;
}
static volatile int64_t tickSnapshot;
static volatile int64_t slewSnapshot;
static volatile uint32_t timerSnapshot;
void TickSaveSnapshot()
{
timerSnapshot = TimerCountSinceLastSecond();
tickSnapshot = tickCount;
slewSnapshot = slewCount;
}
void TickGetTimesFromSnapshot(int64_t* pInt, int64_t* pAbs)
{
*pInt = tickSnapshot + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb, timerSnapshot);
*pAbs = tickSnapshot + slewSnapshot + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb + slew, timerSnapshot);
}
void TickGetTimes(int64_t* pInt, int64_t* pAbs)
{
uint32_t timerCount = TimerCountSinceLastSecond();
*pInt = tickCount + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb, timerCount);
*pAbs = tickCount + slewCount + TimerMultiplyFractionalPart(TICK_ONE_SECOND + ppb + slew, timerCount);
}
void TickInit(void)
{
ppb = LPC_RTC->GPREG0; //This is saved each time Tickppb is updated
}