Uses Timer 0 and the RTC to keep accurate time. It can accept a PPS from an external source like a GPS or a regular time stamp from an external source like an NTP server. It also provides timer functions to 96MHz up to 44 seconds using the CPU clock.

Dependents:   oldheating gps motorhome heating

Description

The clock library provides a number of separate functions:

  • hrtimer An unsigned 32bit high resolution timer which wraps around every 44 seconds from which all the time is derived.
  • mstimer An unsigned 32bit low resolution timer which wraps around every 49 days
  • clktimer A signed 64bit timer (TAI) which doesn't wrap (or not until 2242 when clock time breaks)
  • scan Calculates the max, min and average scan times.
  • rtc A real time clock to provide backup
  • tm Routines to manipulate struct tm local and utc times
  • clk A clock which is synchronised to an external source

High resolution timer

hrtimer uses TIM0 as a 32bit timer which counts at the cpu frequency 96MHz and rolls over after about 44s.
It has an init routine called from ClkInit to start it, thereafter it free runs.
No dependencies.

Millisecond timer

mstimer uses the high resolution timer to count the number of ms since power up. Its unsigned 32bit count rolls over after about 49 days.
It has a main routine called from ClkMain.
Depends on timer.

Clock timer

clktimer uses the signed 64 bit clock time.
Depends on clock and hence hrtimer.

Scan times

scan uses the high resolution timer to calculate the max, min and average scan times.
It has a main routine called from ClkMain.
Depends on hrtimer.

Real time clock

rtc contains routines to save and restore the time in the battery backed real time clock.
Parameters are struct tm.
No dependencies.

Local and UTC manipulation

tm contains

  • the typedef time64 which contains the count of seconds since 1970; just like time_t but based on int64_t to avoid the 2038 problem
  • a number of functions for manipulating time64 and struct tm times

No dependencies.

Clk

clk contains

  • settings
  • functions to save and restore the time to the RTC. Depends on timer, rtc and tm.

clktime increments the time by 1 each second via clk.c from timer.c.
It increments the signed 64 bit time count using the ppb and slew (governed by clkgov.c).
When the time is requested it uses its count and a proportion of the elapsed second from the high resolution timer to calculate the exact time.
See time-formats.text for the clock time format.

clkgov governs the ppb and slew to synchronise the clock time with an external source.
PPB is stored in GPREG0 whenever it is set and retrieved during initialisation.
It takes external time from either:

  • a long term source such as NTP
  • a pulse per second (PPS) such as GPS

clkntp converts clock time to NTP time and vice versa.

clktm converts clock time to struct tm and vice versa

clkutc maintains the era offset (leap seconds count).
The era offset and other information is stored in GPREG1 whenever it is set and retrieved during initialisation.
It contains:

  • the current era offset
  • for the next epoch:
    • its start month (as year and month since 1970)
    • its state: normal; waiting to leap forward; waiting to leap back; leaping forward (second 60)
  • conversion routines between tai and utc (clk time is tai)

Clock time formats

Criteria

Resolution

PPS
We get an interrupt each second which we can resolve to a microsecond. The divisor is 1000. To carry this resolution into the governor we need 1 ppb.
NTP
Suppose we are adding compensation every second, sampling every 4 hours and want to represent 3ms of error with a divisor of 10: that would need a resolution of 23 ppb.
The best temperature compensated crystal oscillators can manage about 1ppm (see Wikipedia) long term or 10 ppb short term.

Lifetime

Needs to keep going during the lifetime of this, or other related, projects. At least a century (so 2100) but more than a few centuries is likely to be pointless

Ease of transforming to NTP, time_t

A count of decimal times - ms, us, ns or ps - can only be transformed using multiplication or division by 1000s. NTP and time_t use binary fractions about a fixed decimal point.

Ease of representing ppm or ppb

A count of decimal times is best but a count of fractions is near enough as 10 bits (1024) is very close to being 1000. As long as it is only needed for a correction such as ppb the approximation would only manifest itself as a 7% error.

The version chosen

1 bit sign, 33 bits for seconds, 30 bits for fraction

+/- 272 years at 1ns or 1 ppb per second
Clock era is 1970

Advantages:

  • adequately representing the freq adjustments for pps
  • simple transformation to NTP and time_t
  • approximates to ns or, with a bit shift, to us or ms
  • adequately covers the next two centuries
  • one unit represents 1 ppb for display

Disadvantage:

  • none

Alternatives considered

1 bit sign, 43 bits for seconds, 20 bits for fraction

+/- 278,731 years at 1us or 1 ppm per second

Advantages:

  • a wide coverage
  • simple transformation to NTP and time_t
  • approximates to us or, with a bitwise shift, to ms
  • one unit represents 1 ppm for display

Disadvantage:

  • not able to reflect the freq adjustments for pps.

1 bit sign, 35bits for seconds, 28bits for fraction

+/- 1089 years at 3ns or 3ppb per second
looks like SSSS SSSS S.FFF FFFF in hex

Advantages:

  • easily represented in hex
  • a wide coverage
  • simple transformation to NTP and time_t

Disadvantage:

  • one unit doesn't approximate to anything simple

32 bits for seconds, 32 bits for fraction

Ntp time with an era of 1900
1900 to 2036 with a resolution of 250ps or 0.25 ppb

Advantages:

  • Already NTP and easily converted to time_t

Disadvantage:

  • Will rollover in 2036

Use 96MHz int64 count

+/- 3044 years with a resolution of 10ns or 10ppb per second

Advantages:

  • a wide coverage

Disadvantage:

  • cannot use simple bit shifts to transform to NTP and time_t
  • not transferable to a system with a different clock rate

Use a count of ns

+/- 292 years at 1ns or 1ppb per second

Advantages:

  • adequately representing the freq adjustments for pps
  • easily usable with ppb and ns
  • a wide coverage

Disadvantage:

  • cannot use simple bit shifts to transform to NTP and time_t

Changes

RevisionDateWhoCommit message
76:c2035b7754fe 2020-07-27 andrewboyson Corrected haveFullTime in sync time PPS default tip
75:09d473b1a67f 2020-04-14 andrewboyson Removed bug whereby a difference of over 0.5 second prevented the governor from aligning the clock
74:9d336a47ab84 2020-04-08 andrewboyson Added 'CLK' in front of log messages. Gave some internal functions better names.
73:286a739f7c05 2020-02-27 andrewboyson Added a method to allow the UTC offset to be changed with a corresponding adjustment to TAI so that the resulting UTC time was not changed. This was used in the clock web page.
72:8f15a8b142ab 2020-02-27 andrewboyson Prevent clock from being set if only PPS is coming through; clock sets once PPS+NMEA or NTP is used.
71:f621d2127216 2020-02-26 andrewboyson Added initialisation for the case where the RTC has lost power
70:d04775a75597 2019-10-21 andrewboyson Minor tweaks to allow a pps signal with the time (in utc seconds)
69:4e48d3859b87 2019-10-18 andrewboyson Changed clkgovsync routines to accept an offset time in seconds rather than an absolute time.
68:807c1c7b2c22 2019-10-07 andrewboyson Include arm_compat.h to allow the use of the __[en/dis]able_irq intrinsics.
67:c44c5c90e35a 2019-09-27 andrewboyson Changed __disable_irq and __enable_irq to equivalent in line asm
66:466803ec48d0 2019-05-27 andrewboyson Moved all the timer , random and scan modules into the lpc1768 library
65:c48eb31e030d 2019-05-07 andrewboyson Moved RandomInit into ClockInit where it fits better with the random module being in the Clock library.
64:d1b9e47aa754 2019-04-12 andrewboyson Added random from lpc1768
63:28738aaad2a8 2019-03-21 andrewboyson Improved pro rata calculation of clktime
62:d382c178399e 2019-03-20 andrewboyson Renamed MsTimer functions to absolute, relative and repetitive to better reflect their purpose.
61:05bc814bf20b 2019-03-20 andrewboyson Introduced a delay timer and renamed the existing timer to interval
60:7e3185a6ffa6 2019-02-22 andrewboyson Modified gov.h int64 to clktime
59:070262625fb0 2019-02-22 andrewboyson Moved NTP conversion routines to net library
58:ad2bfd0345de 2019-02-21 andrewboyson Forgot to rename the end of some conversion routines from 'XxxxTimeT' to 'XxxxTime64'.
57:4daf2e423b27 2019-02-21 andrewboyson Two changes: defined typedef for clktime from int64_t; created new typedef time64 from int64_t to replace time_t to avoid the 2038 problem.
56:3e4fe2d3db4e 2019-02-21 andrewboyson Tidied formatting
55:e18983651004 2019-02-21 andrewboyson Optimised conversion between utc and tai.
54:a3c018ceca77 2019-02-21 andrewboyson Two changes:; Added method to governor module to allow pps to synchronise to the nearest second if the full time is not available.; Added UTC conversion to the governor synchronisation input and to the NTP timestamp conversions.
53:2605da6cf1c7 2019-02-13 andrewboyson Refactored the Ppb settings
52:333a0822a06d 2019-02-12 andrewboyson Refactered some gov setting names
51:826c58fbfaed 2019-01-10 andrewboyson Modified UTC concept from leap seconds to change to epoch
50:b804e93ccc1e 2019-01-09 andrewboyson Fixed bug in next leap second start time
49:e4424cc18bcb 2019-01-09 andrewboyson Improved handling of negative leap seconds (even if they will never happen)
48:b0f38e523552 2019-01-08 andrewboyson Corrected name of ClkUtcInit routine
47:fd2af868c10a 2019-01-08 andrewboyson Rearranged state into the owner modules. Renamed ClkSync to ClkGov.
46:d3d56cb47940 2019-01-08 andrewboyson Changed main name from clock to clk
45:1d8d5b312f72 2018-12-31 andrewboyson Added ClkSyncIsReceivingTime to allow display of whether an external reference is providing time for the clock to synchronise to (PPS for the GPS clock and NTP for others).
44:aa45226d118e 2018-12-29 andrewboyson Made TAI with conversion to UTC as required
43:45b11d2c5490 2018-12-05 andrewboyson Put explanatory text into the library page wiki instead of text files.
42:849060aec279 2018-12-04 andrewboyson update comments on chosen clock time format
41:8cd859cd1475 2018-12-04 andrewboyson Changed names to always start with Clk or Clock
40:53666b1a5848 2018-12-04 andrewboyson Renamed timer to hrtimer; added clktimer to handle utc based times.
39:5b594b1b6a0a 2018-12-03 andrewboyson Minor changes to names in timer
38:25b2a3c494aa 2018-12-02 andrewboyson Removed ClockTicked to force the use of the ms timer instead.; Also reintroduced time_t in the expectation that it will made unsigned or 64bit before 2038.
37:330b844f54b6 2018-12-01 andrewboyson Modified to remove dependence on time_t (32bit) and used an int64 instead.
36:6a8a8e1951d4 2018-12-01 andrewboyson Made the scan time routines separate
35:ba9f575aa3c6 2018-12-01 andrewboyson Tidied and separated the library into high res timer; low res tick counter rtc; tm local and utc; and clock folders
34:aeb58975e61a 2018-11-30 andrewboyson Corrected unsigned comparison in TimerIntervalHasElapsed.
33:b9e3c06e7dab 2018-11-30 andrewboyson Made clktime.c instead of tick.c; made tick.c for 20ms ticks. Lots of tidying.
32:f915ccb1ece3 2018-11-29 andrewboyson Renamed Tick to Time
31:f6ff7fdb9c67 2018-11-29 andrewboyson Changed time.c to tm.c
30:212ca42b8779 2018-02-16 andrewboyson Removed need for defs.h
29:9332cf906aad 2018-01-27 andrewboyson libraries updated
28:b4aa41fdeb68 2018-01-25 andrewboyson Corrected PPS problem
27:3d191d41e867 2018-01-25 andrewboyson Corrected clock.h
26:0421132e6eaf 2018-01-25 andrewboyson Changed ticks from a count of ns to a fixed fraction of 30bits. This makes it much easier to convert to and from NTP and time_t
25:81014a201736 2018-01-22 andrewboyson Moved timer defines from tick to timer
24:6c9833e2a049 2018-01-22 andrewboyson Moved timer stuff into its own file
23:07b19cd5f6d0 2018-01-20 andrewboyson Combined the freq and ticks per second count
22:df0b906bda26 2018-01-19 andrewboyson Corrected the tick to occur on the second
21:48fe75bcde84 2018-01-19 andrewboyson Swapped timer from TIM1 to TIM0
20:62e0760cae13 2018-01-18 andrewboyson Corrected an error in the Tick Set routine
19:e537bacd1478 2018-01-17 andrewboyson Moved power enable out of init. Added timer functions.
18:207dd1474cd9 2018-01-16 andrewboyson Made counter work continuously without the need for interrupts
17:927fc1eceb9d 2018-01-11 andrewboyson Removed dependence on Mbed OS