SatCat5
cfgbus_ptpref.cc
1 // Copyright 2023-2024 The Aerospace Corporation.
3 // This file is a part of SatCat5, licensed under CERN-OHL-W v2 or later.
5 
7 #include <satcat5/ptp_time.h>
8 
14 using satcat5::ptp::Time;
15 
16 // Register map and opcodes for real-time clock.
17 static constexpr unsigned RTC_SEC_MSB = 0;
18 static constexpr unsigned RTC_SEC_LSB = 1;
19 static constexpr unsigned RTC_NSEC = 2;
20 static constexpr unsigned RTC_SUBNS = 3;
21 static constexpr unsigned RTC_COMMAND = 4;
22 static constexpr unsigned RTC_RATE = 5;
23 static constexpr u32 OPCODE_READ = 0x01000000u;
24 static constexpr u32 OPCODE_WRITE = 0x02000000u;
25 static constexpr u32 OPCODE_INCR = 0x04000000u;
26 
27 // Rate register requires multiple operations to write.
28 static inline u32 wide_write(Register& reg, s64 offset) {
29  u64 tmp = (u64)offset;
30  *reg = u32(tmp >> 32); // Write MSBs
31  *reg = u32(tmp >> 0); // Write LSBs
32  return *reg; // Read + Discard
33 }
34 
35 Time PtpReference::clock_adjust(const Time& amount) {
36  // Note: This clock doesn't support coarse adjustments,
37  // so the residual error is equal to the requested shift.
38  return amount;
39 }
40 
41 void PtpReference::clock_rate(s64 offset) {
42  // Note: Cast to void prevents unused-value warnings.
43  (void)wide_write(m_reg, m_rate.convert(offset));
44  m_offset = offset;
45 }
46 
48  return satcat5::ptp::TIME_ZERO; // Not supported
49 }
50 
52  // Note: Cast to void prevents unused-value warnings.
53  (void)wide_write(m_reg, rate);
54  m_offset = m_rate.invert(rate);
55 }
56 
58  // Note: Full-precision shift, so residual error is zero.
59  load(amount);
60  m_reg[RTC_COMMAND] = OPCODE_INCR;
61  return Time(0);
62 }
63 
64 void PtpRealtime::clock_rate(s64 offset) {
65  // Note: Cast to void prevents unused-value warnings.
66  Register tmp = m_reg + RTC_RATE;
67  (void)wide_write(tmp, m_rate.convert(offset));
68  m_offset = offset;
69 }
70 
72  // Note: Cast to void prevents unused-value warnings.
73  Register tmp = m_reg + RTC_RATE;
74  (void)wide_write(tmp, rate);
75  m_offset = m_rate.invert(rate);
76 }
77 
79  u64 sec_msb = m_reg[RTC_SEC_MSB];
80  u64 sec_lsb = m_reg[RTC_SEC_LSB];
81  u32 nsec = m_reg[RTC_NSEC];
82  u32 subns = m_reg[RTC_SUBNS];
83  u64 sec = (sec_msb << 32) + sec_lsb;
84  return Time(sec, nsec, (u16)subns);
85 }
86 
88  m_reg[RTC_COMMAND] = OPCODE_READ;
89  return clock_ext();
90 }
91 
92 void PtpRealtime::clock_set(const Time& new_time) {
93  load(new_time);
94  m_reg[RTC_COMMAND] = OPCODE_WRITE;
95 }
96 
97 void PtpRealtime::load(const Time& time) {
98  u64 sec = (u64)time.field_secs();
99  u64 sub = time.field_subns();
100  m_reg[RTC_SEC_MSB] = (u32)(sec >> 32);
101  m_reg[RTC_SEC_LSB] = (u32)(sec >> 0);
102  m_reg[RTC_NSEC] = (u32)(sub / SUBNS_PER_NSEC);
103  m_reg[RTC_SUBNS] = (u32)(sub % SUBNS_PER_NSEC);
104 }
ConfigBus-controlled PTP reference counter (ptp_counter_gen.vhd).
Generic ConfigBus API.
Definition: cfgbus_core.h:124
PTP reference with rate-control and coarse-adjust command.
Definition: cfgbus_ptpref.h:53
void clock_set(const satcat5::ptp::Time &new_time)
Coarse adjustment of the current time.
satcat5::ptp::Time clock_adjust(const satcat5::ptp::Time &amount) override
Make a one-time adjustment of the specified magnitude.
void clock_rate_raw(s64 rate)
Legacy API for rate-control without additional scaling.
satcat5::ptp::Time clock_ext()
Read timestamp of external rising-edge signal.
satcat5::ptp::Time clock_now() override
Return the current time if available, TIME_ZERO otherwise.
void clock_rate(s64 offset) override
Adjust rate by a normalized frequency offset.
PTP reference counter with rate-control only.
Definition: cfgbus_ptpref.h:27
satcat5::ptp::Time clock_now() override
Return the current time if available, TIME_ZERO otherwise.
void clock_rate_raw(s64 rate)
Legacy API for rate-control without additional scaling.
void clock_rate(s64 offset) override
Adjust rate by a normalized frequency offset.
Pointer-like wrapper for one or more ConfigBus registers.
Definition: cfgbus_core.h:76
s64 invert(s64 rate) const
Inverse conversion (ticks-per-clock ==> normalized rate)
Definition: ptp_filters.cc:500
s64 convert(s64 offset) const
Forward conversion (normalized rate ==> ticks-per-clock)
Definition: ptp_filters.cc:495
High-precision timestamp for use with PTP / IEEE1588.
Definition: ptp_time.h:41
s64 field_secs() const
Read the "seconds" field without intermediate rounding.
Definition: ptp_time.h:62
u64 field_subns() const
Read the raw "subnanoseconds" field.
Definition: ptp_time.h:70
High-precision "Time" object for use with PTP / IEEE1588.
constexpr s64 SUBNS_PER_NSEC
Define commonly used scaling factors.
Definition: ptp_time.h:28