Low-level PTP clock peripheral driver.
More...
Low-level PTP clock peripheral driver.
Introduction
The Precision Time Protocol (PTP) can be used to synchronize clocks with hardware support in an Ethernet PHY, that allows to precisely estimate (and, thus, compensate) network delay between time server and client. This allows PTP synchronization to be highly accurate (<< 1 µs offset between server and client), but requires hardware support on each synchronized node and the PTP server, all nodes to be connected to the same* Ethernet network, and (for best results) hardware support in all intermediate switches.
(No) Synchronization Using This API
This API is intended to provide basic access to a PTP hardware clock. This does not cover any synchronization. Some PTP hardware clocks (e.g. on the STM32) can be used without synchronization by manually setting the time. Thus, the PTP clock can be useful even without synchronization implemented.
It is intended that the actual synchronization is implemented externally later on. The functions ptp_clock_adjust and ptp_clock_adjust_speed are specified with the needs of a synchronization solution in mind.
Clock vs Timer
This API provides both ptp_clock_*()
and ptp_timer_*()
functions, to distinguish between the feature set being used. A PTP peripheral might only support the feature periph_ptp
, but not periph_ptp_timer
.
(Lack of) Power Considerations
It is assumed that a board connected to a wired network is also powered from mains. Additionally, a high-resolution high-accuracy clock that is periodically synced over network is just not going to play well with low-power application scenarios.
|
file | ptp.h |
| Low-level PTP clock peripheral driver interface definitions.
|
|
|
typedef uint32_t | ptp_seconds_t |
| Unsigned integer type to store seconds since epoch for use in PTP.
|
|
◆ ptp_seconds_t
Unsigned integer type to store seconds since epoch for use in PTP.
The PTP protocol defines the seconds part of PTP timestamps as an 48 bit unsigned integer. We go for 32 bit for now (works until year 2106) and will later extend this type to 64 bit. Users are highly encouraged to use this type instead of uint32_t
, if they intent that their software still works in a couple of decades.
Definition at line 93 of file ptp.h.
◆ ptp_add()
Add a given offset onto the given timestamp.
- Parameters
-
[in,out] | t | Timestamp to add offset to |
[in] | offset | Offset to apply |
Definition at line 145 of file ptp.h.
◆ ptp_clock_adjust()
void ptp_clock_adjust |
( |
int64_t |
offset | ) |
|
Adjust the PTP clock as given.
- Parameters
-
offset | Offset to add onto current system time |
Same as ptp_clock_set_u64(ptp_clock_read_u64() + offset)
, but implemented to introduce as little error as possible while setting the offset. This is intended to be used by clock synchronization implementations.
◆ ptp_clock_adjust_speed()
void ptp_clock_adjust_speed |
( |
int32_t |
correction | ) |
|
Adjust the PTP clock speed as given.
- Parameters
-
correction | Specification of the clock speed adjustment |
- Note
- This implies feature
periph_ptp_speed_adjustment
The clock speed is adjusted in regard to its nominal clock speed. This means that calls with the same value in correction
are idempotent.
- A call with
correction
set to 0
restores the nominal clock speed.
- A call with a positive value for
correction
speeds the clock up by correction / (1 << 32)
(so up to ~50% for INT32_MAX
).
- A call with a negative value for
correction
slows the clock down by -correction / (1 << 32)
(so up to 50% for INT32_MIN
).
This allows the clock speed to be adjusted in steps ± 2.3284E-08 % in relation to its nominal clock speed, thus, allowing to counter systematic clock drift. In addition, this is intended to "smoothly" synchronize the clock over time to avoid jumps in the system time. (Especially calling ptp_clock_adjust with negative values might be something to avoid, when applications are not prepared with clocks going backwards.)
◆ ptp_clock_read()
Get the current system time as PTP timestamp.
- Parameters
-
[out] | timestamp | The timestamp will be written here |
- Precondition
- The PTP clock is initialized
Definition at line 356 of file ptp.h.
◆ ptp_clock_read_u64()
static uint64_t ptp_clock_read_u64 |
( |
void |
| ) |
|
|
inline |
Get the current system time in nanosecond since UNIX epoch.
- Returns
- Nanoseconds since 1. 1. 1970 0:00:00 UTC
- Precondition
- The PTP clock is initialized
- Note
- An
uint64_t
allows nanosecond timestamps within 1970-01-01 and 2554-07-21 to be represented.
Definition at line 363 of file ptp.h.
◆ ptp_clock_set()
Set the current system time.
- Parameters
-
- Precondition
- The PTP clock is initialized
Definition at line 372 of file ptp.h.
◆ ptp_clock_set_u64()
static void ptp_clock_set_u64 |
( |
uint64_t |
ns_since_epoch | ) |
|
|
inline |
Set the current system time in nanosecond since UNIX epoch.
- Parameters
-
ns_since_epoch | New time to set |
- Precondition
- The PTP clock is initialized
Definition at line 379 of file ptp.h.
◆ ptp_cmp()
Compare two PTP timestamps.
- Parameters
-
a | First timestamp |
b | Second timestamp |
- Return values
-
Definition at line 118 of file ptp.h.
◆ ptp_init()
Initialize the given PTP peripheral.
- Note
- Implementations of this functions have to use
assert()
to make the configuration is valid.
- Precondition
- This function must be called at most once
After calling this, the PTP clock (and the PTP timer, if the feature periph_ptp_timer
is used in addition to periph_ptp_clock
) can be used.
◆ ptp_ns2ts()
Convert time from nanoseconds since epoch to ptp_timestamp_t format.
- Parameters
-
[out] | dest | The timestamp will be written here |
[in] | ns_since_epoch | Time in nanoseconds since epoch to convert |
Definition at line 176 of file ptp.h.
◆ ptp_timer_cb()
void ptp_timer_cb |
( |
void |
| ) |
|
External function to call when the PTP clock timer fired.
- Note
- This function needs to be implemented by the user of this API
-
This function implies feature
periph_ptp_timer
Since at most one PTP clock is expected on each board, we can avoid the overhead of indirect function calls here and let users of this API just implement this function.
◆ ptp_timer_clear()
void ptp_timer_clear |
( |
void |
| ) |
|
Clears any pending timeout on the PTP timer.
- Note
- This function implies feature
periph_ptp_timer
◆ ptp_timer_set_absolute()
Set an absolute timeout value, possibly overwriting an existing timeout.
- Parameters
-
target | Timestamp when the timeout should fire |
- Note
- Only a single timeout is supported by the PTP timer
-
This function implies feature
periph_ptp_timer
If the target time is in the past or equal to the current time, the IRQ should trigger right away.
Definition at line 388 of file ptp.h.
◆ ptp_timer_set_absolute_u64()
static void ptp_timer_set_absolute_u64 |
( |
uint64_t |
target | ) |
|
|
inline |
Set an absolute timeout value, possibly overwriting an existing timeout.
- Parameters
-
target | Timestamp when the timeout should fire (ns since epoch) |
- Note
- Only a single timeout is supported by the PTP timer
-
This function implies feature
periph_ptp_timer
If the target time is in the past or equal to the current time, the IRQ should trigger right away.
Definition at line 395 of file ptp.h.
◆ ptp_timer_set_u64()
void ptp_timer_set_u64 |
( |
uint64_t |
target | ) |
|
Set an relative timeout value, possibly overwriting an existing timeout.
- Parameters
-
target | Number of nanoseconds after which the timeout should fire |
- Note
- Only a single timeout is supported by the PTP timer
-
This function implies feature
periph_ptp_timer
◆ ptp_ts2ns()
Convert time from nanoseconds since epoch to ptp_timestamp_t format.
- Parameters
-
[in] | t | Time to convert to nanoseconds since epoch |
- Returns
- The time specified by
t
in nanoseconds since epoch
Definition at line 189 of file ptp.h.