24#define S (gPtpCoreState)
35#ifdef PTP_ADDEND_INTERFACE
37 S.hwclock.addend =
MIN(compAddend, 0xFFFFFFFF);
39#elif defined(PTP_HLT_INTERFACE)
40 S.hwclock.tuning_ppb += tuning_ppb;
45#define PTP_FC_SKEW_CORRECTION_CYCLES (4)
46#define PTP_FC_TIME_CORRECTION_CYCLES (1)
47#define PTP_FC_TIME_PROPAGATION_CYCLES (2)
54 if (!
nonZeroI(&S.network.meanPathDelay)) {
59 TimestampI d, syncMa, syncSl, delReqSl, delReqMa;
62 syncMa = S.slave.scd.t[
T1];
63 syncSl = S.slave.scd.t[
T2];
64 delReqSl = S.slave.scd.t[
T3];
65 delReqMa = S.slave.scd.t[
T4];
69 CLILOG(S.logging.timestamps,
71 "T1: %d.%09d <- Sync TX (master)\n"
72 "T2: %d.%09d <- Sync RX (slave) \n"
73 "T3: %d.%09d <- Del_Req TX (slave) \n"
74 "T4: %d.%09d <- Del_Req RX (master)\n\n",
75 (uint32_t)S.slave.messaging.sequenceID,
80 }
else if (S.profile.delayMechanism ==
PTP_DM_P2P) {
81 CLILOG(S.logging.timestamps,
83 "T1: %d.%09d <- Sync TX (master)\n"
84 "T2: %d.%09d <- Sync RX (slave)\n"
85 "t1: %d.%09d <- PDel_Req TX (our clock)\n"
86 "t2: %d.%09d <- PDel_Req RX (their clock)\n"
87 "t3: %d.%09d <- PDel_Resp TX (their clock)\n"
88 "t4: %d.%09d <- PDel_Resp RX (our clock)\n\n",
89 (uint32_t)S.slave.messaging.sequenceID,
90 (int32_t)S.slave.scd.t[0].sec, S.slave.scd.t[0].nanosec,
91 (int32_t)S.slave.scd.t[1].sec, S.slave.scd.t[1].nanosec,
92 (int32_t)S.slave.scd.t[2].sec, S.slave.scd.t[2].nanosec,
93 (int32_t)S.slave.scd.t[3].sec, S.slave.scd.t[3].nanosec,
94 (int32_t)S.slave.scd.t[4].sec, S.slave.scd.t[4].nanosec,
95 (int32_t)S.slave.scd.t[5].sec, S.slave.scd.t[5].nanosec);
102 nsToTsI(&cf, S.slave.scd.cf[
T1] + S.slave.scd.cf[
T2]);
106 subTime(&d, &d, &S.network.meanPathDelay);
110 subTime(&d, &d, &S.hwoptions.offset);
119 goto retain_cycle_data;
126 subTime(&measSyncPeriod, &syncMa, &(S.slave.prevSyncMa));
127 int64_t measSyncPeriod_ns =
nsI(&measSyncPeriod);
132 int64_t d_ns =
nsI(&d);
134 if ((llabs(d_ns) > S.slave.coarseLimit) || (fcs !=
PTP_FC_IDLE)) {
140 CLILOG(S.logging.info,
"Time difference has exceeded the coarse correction threshold [%" __PRI64_PREFIX
"dns], compensation commenced!\n", d_ns);
143 uint8_t fccntr = S.slave.fastCompCntr;
172 subTime(&dt2, &syncSl, &S.slave.prevSyncSl);
173 int64_t dt2_ns =
nsI(&dt2);
174 double skew = (double)(dt2_ns - measSyncPeriod_ns) / (double)(measSyncPeriod_ns);
175 double skew_compensation_ppb = -skew * 1E+09;
186 uint64_t t_ns =
nsU(&tu);
199 S.slave.fastCompState = fcs;
200 S.slave.fastCompCntr = fccntr + 1;
203 goto retain_cycle_data;
210 S.slave.messaging.logSyncPeriod,
211 S.slave.messaging.syncPeriodMs,
224#ifdef PTP_ADDEND_INTERFACE
229 S.hwclock.addend, corr_ppb,
nsI(&S.network.meanPathDelay), (uint64_t)measSyncPeriod_ns);
230#elif defined(PTP_HLT_INTERFACE)
234 S.hwclock.tuning_ppb, corr_ppb,
nsI(&S.network.meanPathDelay), (uint64_t)measSyncPeriod_ns);
238 if (S.slave.syncCb != NULL) {
239#ifdef PTP_ADDEND_INTERFACE
240 S.slave.syncCb(
nsI(&d), &S.slave.scd, S.hwclock.addend);
241#elif defined(PTP_HLT_INTERFACE)
242 S.slave.syncCb(
nsI(&d), &S.slave.scd, S.hwclock.tuning_ppb);
249 S.slave.prevSyncMa = syncMa;
250 S.slave.prevSyncSl = syncSl;
251 S.slave.prevTimeError = d;
270 subTime(&d, &S.slave.scd.t[
T2], &S.slave.scd.t[
T1]);
292 S.slave.messaging.lastRespondedDelReqId = pdelRespSeqId;
306 switch (S.slave.messaging.m2sState) {
318 S.slave.scd.t[
T2] = pRawMsg->
ts;
321 S.slave.messaging.sequenceID = pHeader->
sequenceID;
331 S.slave.scd.cf[
T2] = 0;
345 if (pHeader->
sequenceID == S.slave.messaging.sequenceID) {
362 S.slave.messaging.m2sState =
SIdle;
374 if (pHeader->
sequenceID == S.slave.messaging.delay_reqSequenceID) {
397 S.slave.messaging.lastRespondedDelReqId = pHeader->
sequenceID;
418 uint64_t *cf = &S.slave.scd.cf[2];
420 pT[
T4] = pRawMsg->
ts;
426 pT[
T3] = pT[
T2] = zeroTs;
430 S.slave.expectPDelRespFollowUp =
true;
441 if (!S.slave.expectPDelRespFollowUp) {
452 uint64_t *cf = &S.slave.scd.cf[2];
464 CLILOG(S.logging.corr,
"C [PDel_Resp_Follow_Up]: %09" __PRI64_PREFIX
"u\n", pHeader->
correction_ns);
468 S.slave.expectPDelRespFollowUp =
false;
490 S.slave.enabled =
false;
494 S.slave.prevSyncMa = zeroTs;
495 S.slave.prevTimeError = zeroTs;
501#ifdef PTP_ADDEND_INTERFACE
504#elif defined(PTP_HLT_INTERFACE)
505 S.hwclock.tuning_ppb = 0.0;
514 S.slave.fastCompCntr = 0;
517 S.slave.expectPDelRespFollowUp =
false;
521 if (!S.slave.enabled) {
527 if (++S.slave.delReqTmr > S.slave.delReqTickPeriod) {
528 S.slave.delReqTmr = 0;
532 if (S.slave.messaging.delay_reqSequenceID != S.slave.messaging.lastRespondedDelReqId) {
533 CLILOG(S.logging.info,
"(P)Del_Req #%d: no response received!\n", S.slave.messaging.delay_reqSequenceID);
548 S.slave.enabled =
true;
556 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.