11 namespace log = satcat5::log;
29 static constexpr
unsigned DEBUG_VERBOSE = 0;
32 #ifndef SATCAT5_PTRK_FASTACQ
33 #define SATCAT5_PTRK_FASTACQ 1
39 , m_tref(SATCAT5_CLOCK->now())
43 , m_lock_state(LockState::ACQUIRE)
59 Filter* filter = m_filters.head();
62 filter = m_filters.
next(filter);
69 m_lock_state = linear ? LockState::LINEAR : LockState::RESET;
70 m_tref = SATCAT5_CLOCK->now();
78 elapsed_usec = min_u32(1000000, elapsed_usec);
79 m_lock_usec = min_u32(1000000000, m_lock_usec + elapsed_usec);
82 s64 input = coarse(delta);
83 filter(elapsed_usec, input);
86 s64 TrackingController::coarse(
const Time& delta)
88 constexpr
Time ADJ_COARSE(SUBNS_PER_MSEC * 10);
89 constexpr
Time ADJ_FREQ(SUBNS_PER_USEC * 1000);
90 constexpr
Time ADJ_FINE(SUBNS_PER_USEC * 10);
92 Time filter_input = delta;
93 if (m_lock_state == LockState::LINEAR) {
95 }
else if (delta.
abs() > ADJ_COARSE) {
98 if (m_lock_state == LockState::RESET || m_lock_alarm >= 3) {
101 m_lock_state = LockState::ACQUIRE;
102 filter_input = clock_adjust(delta);
103 }
else if (m_lock_usec >= 1000000) {
108 }
else if (SATCAT5_PTRK_FASTACQ && m_lock_state == LockState::ACQUIRE) {
111 if (delta.
abs() < ADJ_FREQ) {
112 filter_input = clock_adjust(delta);
113 m_freq_accum += (delta - filter_input).delta_subns();
117 if (m_lock_usec >= 1000000) {
118 log::Log(log::INFO,
"PTP-Track: Adjust")
120 Filter* filter = m_filters.head();
122 filter->
rate(m_freq_accum, m_lock_usec);
123 filter = m_filters.
next(filter);
125 m_lock_state = LockState::TRACK;
127 }
else if (delta.
abs() < ADJ_FINE) {
130 m_lock_state = LockState::TRACK;
136 void TrackingController::filter(u32 elapsed_usec, s64 delta_subns)
139 Filter* filter = m_filters.head();
140 s64 result = delta_subns;
142 result = filter->
update(result, elapsed_usec);
143 filter = m_filters.
next(filter);
147 if (result != INT64_MAX) clock_rate(result);
150 if (DEBUG_VERBOSE > 1) {
151 log::Log(log::DEBUG,
"PTP-Track: Update")
155 }
else if (DEBUG_VERBOSE > 0) {
156 log::Log(log::DEBUG,
"PTP-Track: Update")
161 Time TrackingController::clock_adjust(
const Time& amount)
168 item = m_clocks.
next(item);
173 void TrackingController::clock_rate(s64 offset)
178 item = m_clocks.
next(item);
188 , m_ctrl(DEFAULT_TIME_CONSTANT)
The Log class creates and formats one log message.
Log & write10(s32 val)
Print integer as a decimal value with no leading zeros.
Log & write_obj(const T &obj)
Templated wrapper for custom output formatting.
Log & write(const char *str)
Formatting methods for various data types.
PTP callback accepts each complete measurement from the Source.
Define the basic chain-of-filters API.
virtual void rate(s64 delta_subns, u32 elapsed_usec)
Optional handler for fast-acquisition; override if required.
virtual void reset()=0
Flush previous inputs and reset to a neutral state.
virtual s64 update(s64 next, u32 elapsed_usec)=0
Method called for each new input sample.
A source for ptp::Measurement events, usually a ptp::Client.
High-precision timestamp for use with PTP / IEEE1588.
s64 delta_subns() const
Convert time-differences to the designated unit.
satcat5::ptp::Time abs() const
Standard arithmetic operations.
Generic interface to a numerically-controlled reference clock.
virtual void clock_rate(s64 offset)=0
Adjust rate by a normalized frequency offset.
virtual satcat5::ptp::Time clock_adjust(const satcat5::ptp::Time &amount)=0
Make a one-time adjustment of the specified magnitude.
Bang-bang alternative to TrackingController.
void ptp_ready(const satcat5::ptp::Measurement &data) override
Event handler for ptp::Callback.
TrackingCoarse(satcat5::ptp::TrackingClock *clk, satcat5::ptp::Source *source)
Constructor links to a specific TrackingClock target.
Clock controller handling coarse and fine discipline.
void update(const satcat5::ptp::Time &delta)
Update filter state with a new measurement from the PTP client.
void ptp_ready(const satcat5::ptp::Measurement &data) override
Event handler for ptp::Callback.
void add_filter(satcat5::ptp::Filter *filter)
Add to the chain of processing filters.
void reset(bool linear=false)
Reset tracking filter(s) and begin free-wheeling.
Simple all-in-one implementation of TrackingController.
TrackingSimple(satcat5::ptp::TrackingClock *clk, satcat5::ptp::Source *source)
Constructor links to a specific TrackingClock target.
T * next(const T *item) const
Fetch pointer to the next item.
Diagnostic logging to UART and/or Ethernet ports.
Generic network Dispatch API.
constexpr s64 SUBNS_PER_MSEC
Define commonly used scaling factors.
constexpr s64 USEC_PER_SEC
Define commonly used scaling factors.
constexpr s64 SUBNS_PER_USEC
Define commonly used scaling factors.
Closed-loop time-tracking clocks and tracking control.
Loop-filter coefficients for use with the "ControllerPII" class.
Timestamps and metadata for a two-way time-transfer handshake.
satcat5::ptp::Time offset_from_master() const
Calculate PTP "offsetFromMaster".
unsigned increment_usec()
Measure elapsed time in microseconds, then increment by the returned quantized value.
Miscellaneous mathematical utility functions.
constexpr T modulo(T a, T b)
Portability wrapper for platforms with signed division and modulo:
constexpr u32 min_u32(u32 a, u32 b)
Min and max functions.
constexpr T divide(T a, T b)
Portability wrapper for platforms with signed division and modulo: