24#define S (gPtpCoreState)
38 if (!isfinite(tuning_ppb)) {
42#ifdef PTP_ADDEND_INTERFACE
44 S.hwclock.addend =
MIN(compAddend, 0xFFFFFFFF);
46#elif defined(PTP_HLT_INTERFACE)
47 S.hwclock.tuning_ppb += tuning_ppb;
52#define PTP_FC_SKEW_CORRECTION_CYCLES (4)
53#define PTP_FC_TIME_CORRECTION_CYCLES (1)
54#define PTP_FC_TIME_PROPAGATION_CYCLES (2)
61 if (!
nonZeroI(&S.network.meanPathDelay)) {
66 TimestampI d, syncMa, syncSl, delReqSl, delReqMa;
69 syncMa = S.slave.scd.t[
T1];
70 syncSl = S.slave.scd.t[
T2];
71 delReqSl = S.slave.scd.t[
T3];
72 delReqMa = S.slave.scd.t[
T4];
75 const char * logIdStr = S.logging.logid ?
"[LOG-TS:S] " :
"";
79 CLILOG(S.logging.timestamps,
81 "%sT1: %d.%09d <- Sync TX (master)\n"
82 "%sT2: %d.%09d <- Sync RX (slave) \n"
83 "%sT3: %d.%09d <- Del_Req TX (slave) \n"
84 "%sT4: %d.%09d <- Del_Req RX (master)\n\n",
85 logIdStr, (uint32_t)S.slave.messaging.sequenceID,
88 logIdStr, (int32_t)delReqSl.
sec, delReqSl.
nanosec,
89 logIdStr, (int32_t)delReqMa.
sec, delReqMa.
nanosec);
90 }
else if (S.profile.delayMechanism ==
PTP_DM_P2P) {
91 CLILOG(S.logging.timestamps,
93 "%sT1: %d.%09d <- Sync TX (master)\n"
94 "%sT2: %d.%09d <- Sync RX (slave)\n"
95 "%st1: %d.%09d <- PDel_Req TX (our clock)\n"
96 "%st2: %d.%09d <- PDel_Req RX (their clock)\n"
97 "%st3: %d.%09d <- PDel_Resp TX (their clock)\n"
98 "%st4: %d.%09d <- PDel_Resp RX (our clock)\n\n",
99 logIdStr, (uint32_t)S.slave.messaging.sequenceID,
100 logIdStr, (int32_t)S.slave.scd.t[0].sec, S.slave.scd.t[0].nanosec,
101 logIdStr, (int32_t)S.slave.scd.t[1].sec, S.slave.scd.t[1].nanosec,
102 logIdStr, (int32_t)S.slave.scd.t[2].sec, S.slave.scd.t[2].nanosec,
103 logIdStr, (int32_t)S.slave.scd.t[3].sec, S.slave.scd.t[3].nanosec,
104 logIdStr, (int32_t)S.slave.scd.t[4].sec, S.slave.scd.t[4].nanosec,
105 logIdStr, (int32_t)S.slave.scd.t[5].sec, S.slave.scd.t[5].nanosec);
112 nsToTsI(&cf, S.slave.scd.cf[
T1] + S.slave.scd.cf[
T2]);
116 subTime(&d, &d, &S.network.meanPathDelay);
120 subTime(&d, &d, &S.hwoptions.offset);
129 goto retain_cycle_data;
136 subTime(&measSyncPeriod, &syncMa, &(S.slave.prevSyncMa));
137 int64_t measSyncPeriod_ns =
nsI(&measSyncPeriod);
143 if (measSyncPeriod_ns <= 0) {
144 CLILOG(S.logging.info,
"Sync cycle did not advance in master time; cycle skipped.\n");
145 goto retain_cycle_data;
151 int64_t d_ns =
nsI(&d);
153 if ((llabs(d_ns) > S.slave.coarseLimit) || (fcs !=
PTP_FC_IDLE)) {
159 CLILOG(S.logging.logid && S.logging.info,
"[LOG-INFO] ");
160 CLILOG(S.logging.info,
"Time difference has exceeded the coarse correction threshold [%" __PRI64_PREFIX
"dns], compensation commenced!\n", d_ns);
163 uint8_t fccntr = S.slave.fastCompCntr;
192 subTime(&dt2, &syncSl, &S.slave.prevSyncSl);
193 int64_t dt2_ns =
nsI(&dt2);
194 double skew = (double)(dt2_ns - measSyncPeriod_ns) / (double)(measSyncPeriod_ns);
195 double skew_compensation_ppb = -skew * 1E+09;
201 CLILOG(S.logging.logid && S.logging.info,
"[LOG-INFO] ");
207 uint64_t t_ns =
nsU(&tu);
214 CLILOG(S.logging.logid && S.logging.info,
"[LOG-INFO] ");
217 CLILOG(S.logging.logid && S.logging.info,
"[LOG-INFO] ");
222 S.slave.fastCompState = fcs;
223 S.slave.fastCompCntr = fccntr + 1;
226 goto retain_cycle_data;
233 S.slave.messaging.logSyncPeriod,
234 S.slave.messaging.syncPeriodMs,
247#ifdef PTP_ADDEND_INTERFACE
248 CLILOG(S.logging.logid && S.logging.def,
"[LOG-DEF:S:A] ")
253 S.hwclock.addend, corr_ppb,
nsI(&S.network.meanPathDelay), (uint64_t)measSyncPeriod_ns);
254#elif defined(PTP_HLT_INTERFACE)
255 CLILOG(S.logging.logid && S.logging.def,
"[LOG-DEF:S:H] ")
259 S.hwclock.tuning_ppb, corr_ppb,
nsI(&S.network.meanPathDelay), (uint64_t)measSyncPeriod_ns);
263 if (S.slave.syncCb != NULL) {
264#ifdef PTP_ADDEND_INTERFACE
265 S.slave.syncCb(
nsI(&d), &S.slave.scd, S.hwclock.addend);
266#elif defined(PTP_HLT_INTERFACE)
267 S.slave.syncCb(
nsI(&d), &S.slave.scd, S.hwclock.tuning_ppb);
274 S.slave.prevSyncMa = syncMa;
275 S.slave.prevSyncSl = syncSl;
276 S.slave.prevTimeError = d;
295 subTime(&d, &S.slave.scd.t[
T2], &S.slave.scd.t[
T1]);
317 S.slave.messaging.lastRespondedDelReqId = pdelRespSeqId;
331 switch (S.slave.messaging.m2sState) {
343 S.slave.scd.t[
T2] = pRawMsg->
ts;
346 S.slave.messaging.sequenceID = pHeader->
sequenceID;
356 S.slave.scd.cf[
T2] = 0;
370 if (pHeader->
sequenceID == S.slave.messaging.sequenceID) {
378 CLILOG(S.logging.logid && S.logging.corr,
"[LOG-CORR] ");
388 S.slave.messaging.m2sState =
SIdle;
400 if (pHeader->
sequenceID == S.slave.messaging.delay_reqSequenceID) {
423 S.slave.messaging.lastRespondedDelReqId = pHeader->
sequenceID;
434 CLILOG(S.logging.logid && S.logging.corr,
"[LOG-CORR] ");
445 uint64_t *cf = &S.slave.scd.cf[2];
447 pT[
T4] = pRawMsg->
ts;
453 pT[
T3] = pT[
T2] = zeroTs;
457 S.slave.expectPDelRespFollowUp =
true;
464 CLILOG(S.logging.logid && S.logging.corr,
"[LOG-CORR] ");
469 if (!S.slave.expectPDelRespFollowUp) {
480 uint64_t *cf = &S.slave.scd.cf[2];
492 CLILOG(S.logging.logid && S.logging.corr,
"[LOG-CORR] ");
493 CLILOG(S.logging.corr,
"C [PDel_Resp_Follow_Up]: %09" __PRI64_PREFIX
"u\n", pHeader->
correction_ns);
497 S.slave.expectPDelRespFollowUp =
false;
519 S.slave.enabled =
false;
523 S.slave.prevSyncMa = zeroTs;
524 S.slave.prevTimeError = zeroTs;
530#ifdef PTP_ADDEND_INTERFACE
533#elif defined(PTP_HLT_INTERFACE)
534 S.hwclock.tuning_ppb = 0.0;
543 S.slave.fastCompCntr = 0;
546 S.slave.expectPDelRespFollowUp =
false;
550 if (!S.slave.enabled) {
556 if (++S.slave.delReqTmr > S.slave.delReqTickPeriod) {
557 S.slave.delReqTmr = 0;
561 if (S.slave.messaging.delay_reqSequenceID != S.slave.messaging.lastRespondedDelReqId) {
562 CLILOG(S.logging.logid && S.logging.info,
"[LOG-INFO] ");
563 CLILOG(S.logging.info,
"(P)Del_Req #%d: no response received!\n", S.slave.messaging.delay_reqSequenceID);
578 S.slave.enabled =
true;
586 S.slave.enabled =
false;
void ptp_compute_mean_path_delay_p2p(const TimestampI *pTs, const uint64_t *pCf, TimestampI *pMPD)
void ptp_compute_mean_path_delay_e2e(const TimestampI *pTs, const uint64_t *pCf, TimestampI *pMPD)
void ptp_send_delay_req_message()
This module defines messaging functions for both the slave and master modules.
@ PTP_UEV_DELAY_RESP_RECVED
A Delay_Resp had been received (slave)
@ PTP_UEV_DELAY_REQ_SENT
A Delay_Req had been sent (slave)
@ PTP_UEV_PDELAY_RESP_FOLLOW_UP_RECVED
A PDelay_Resp_Follow_Up had been received (master/slave)
@ PTP_UEV_PDELAY_REQ_SENT
A PDelay_Req had been sent (master/slave)
@ PTP_UEV_PDELAY_RESP_RECVED
A PDelay_Resp had been received (master/slave)
@ PTP_UEV_SYNC_RECVED
A Sync message has been received (slave)
@ PTP_UEV_FOLLOW_UP_RECVED
A Follow_Up message has been received (slave)
@ PTP_UEV_NETWORK_ERROR
Indication of lost messages or the absence of expected responses.
#define PTP_SET_CLOCK(s, ns)
#define PTP_SET_ADDEND(addend)
#define PTP_SERVO_RESET()
#define PTP_HW_GET_TIME(pt)
#define PTP_SERVO_RUN(d, pscd)
#define PTP_SET_TUNING(tuning)
void ptp_extract_timestamps(TimestampI *ts, void *pPayload, uint8_t n)
void ptp_read_delay_resp_id_data(PtpDelay_RespIdentification *pDRData, void *pPayload)
This module defines functions that deal with actual PTP messages; they can extract or insert headers,...
Core of the PTP implementation. Defines functions for message processing, clock tuning,...
In here reside a multitude of fundamental PTP-related constants and definitions.
#define PTP_HEARTBEAT_TICKRATE_MS
Heartbeat ticking period.
#define PTP_CLOCK_TICK_FREQ_HZ
Rated clock tick frequency.
#define PTP_ADDEND_CORR_PER_PPB_F
Addend/ppb ratio.
#define PTP_COLOR_BYELLOW
Bright yellow.
#define PTP_ADDEND_INIT
Initial addend value.
#define PTP_PORT_ID
PTP port ID on the device.
#define PTP_DEFAULT_COARSE_TRIGGER_NS
Coarse correction kick-in threshold.
#define PTP_COLOR_RESET
Reset colors.
This module defines the fundamental PTP message and state machine type, flags, bitfields and the PTP ...
@ PTP_LOGPER_SYNCMATCHED
Messaging occurs whenever a Sync arrives.
@ PTP_FC_TIME_CORRECTION_PROPAGATION
Waiting for the effects of time correction to propagate.
@ PTP_FC_SKEW_CORRECTION
Skew correction is running.
@ PTP_FC_TIME_CORRECTION
Time correction is running.
@ PTP_FC_IDLE
Fast correction algorithm is IDLE.
@ SWaitFollowUp
Waiting for a Follow_Up message.
PtpMessageType
PTP packet type enumeration.
@ PTP_MT_Delay_Resp
Delay Response.
@ PTP_MT_PDelay_Resp
Peer Delay Response.
@ PTP_MT_PDelay_Resp_Follow_Up
Peer Delay Response Follow Up.
@ PTP_MT_Follow_Up
Follow Up.
PtpDelayMechanism
PTP Delay mechanism enumeration.
@ PTP_DM_E2E
End-to-End Delay Mechanism.
@ PTP_DM_P2P
Peer-to-Peer Delay Mechanism.
@ RPMT_DELAY_REQ
(P)Delay_Req tag
void ptp_set_coarse_threshold(uint64_t ns)
This module features functions to tweak around the PTP engine's almost every property.
static void ptp_commence_p2p_correction(uint32_t pdelRespSeqId)
#define PTP_FC_TIME_CORRECTION_CYCLES
Fast compensation: no. of time correction cycles.
void ptp_slave_process_message(RawPtpMessage *pRawMsg, PtpHeader *pHeader)
#define PTP_FC_SKEW_CORRECTION_CYCLES
Fast compensation: no. of skew correction cycles.
#define PTP_FC_TIME_PROPAGATION_CYCLES
static void ptp_tune_clock(float tuning_ppb)
static void ptp_commence_e2e_correction()
static void ptp_perform_correction()
This module implements the slave clock functionality.
void ptp_collect_stats(int64_t d)
This is the statistics module that gathers data of the operating PTP-engine.
Identification carrying Delay_Resp message.
uint64_t requestingSourceClockIdentity
Requesting Source Clock Identity.
uint16_t requestingSourcePortIdentity
Requesting Source Port Identity.
bool PTP_TWO_STEP
Two Step.
PTP slave messaging state structure.
PTP synchronization cycle data.
uint8_t data[(128)]
raw packet data
int32_t nanosec
nanoseconds
bool ptp_read_and_clear_transmit_timestamp(uint32_t tag, TimestampI *pTs)
The entry point of the whole PTP-implementation. Calling reg_task_ptp() initializes the PTP-engine,...
uint64_t nsU(const TimestampU *t)
void normTime(TimestampI *t)
int64_t tsToTick(const TimestampI *ts, uint32_t tps)
TimestampI * nsToTsI(TimestampI *r, int64_t ns)
TimestampI * subTime(TimestampI *r, const TimestampI *a, const TimestampI *b)
bool nonZeroI(const TimestampI *a)
int64_t nsI(const TimestampI *t)
This module defines storage classes for timestamps and operations on time values.