Skip to content

Conversation

eggersn
Copy link

@eggersn eggersn commented Sep 18, 2025

While ENET_Ptp1588SetTimer provides a mechanism to set the clock to an absolute time value, this often introduces additional software delays. In contrast, ENET_Ptp1588JumpTimer uses a relative offset in case we already have two hardware timestamps.

The main motivation for this extension is to avoid usages like here, where both ingress and egress timestamps are given (hence the relative error is known) but one still has to perform a ptp_clock_getand ptp_clock_set.

Moreover, this can drastically improve the accuracy when aiming to synchronize with a 1PPS signal (e.g., generated by a GNSS module).

/** Adjust the PTP clock by jumping (if the difference exceeds a configured
 * threshold) or by increasing/decreasing the clock rate. */
static void synchronize(uint64_t ingress, uint64_t egress) {
  int64_t offset =
      (int64_t)(ingress - (int64_t)CONFIG_PTP_INGRESS_LATENCY - egress);

  /* If diff is too big, ptp_clk needs to be set first. */
  if ((offset > (int64_t)CONFIG_PTP_SYNC_JUMP_THRES) ||
      (offset < -(int64_t)CONFIG_PTP_SYNC_JUMP_THRES)) {
    LOG_WRN("Clock offset exceeds jump threshold: %lldns", offset);
    ptp_clock_jump(PTP_CLOCK, (int32_t)offset);
    return;
  }

  double ppb = ptp_clock_servo_pi(offset);
  ptp_clock_rate_adjust(PTP_CLOCK, 1.0 + (ppb / 1000000000.0));
}

static void ptp_clock_synchronize_pps(uint32_t tm) {
  if (tm % NSEC_PER_SEC > 500 * NSEC_PER_MSEC) {
    LOG_INF("offset: %d ns", (int)(tm % NSEC_PER_SEC) - NSEC_PER_SEC);
    synchronize(NSEC_PER_SEC, tm % NSEC_PER_SEC);
  } else {
    LOG_INF("offset: %u ns", tm % NSEC_PER_SEC);
    synchronize(0, tm % NSEC_PER_SEC);
  }
}

// ...
// e.g., register ptp_clock_synchronize_pps as IRQ for ENET_1588_EVENT_IN

For the IMXRT1060, ENET_Ptp1588JumpTimer yielded an accuracy in the range of < 12us, whereas the analogous approach from the previous example often yielded clock skews > 100ms. Latter is especially critical as subsequent rate adjustments are often done without validation (e.g., as described in this issue).

I'm of course happy to extend the proposed functionality if you have further suggestions.

While ENET_Ptp1588SetTimer provides a mechanism to set the clock to an
absolute time value, this often introduces additional software delays.
In contrast, ENET_Ptp1588JumpTimer uses a relative offset in case we
already have to hardware timestamps.

Signed-off-by: Simon Egger <[email protected]>
@mmahadevan108
Copy link
Collaborator

@eggersn, thanks for you contribution, could you please also create a PR to repo nxp-mcuxpresso/mcuxsdk-core? That ensure the patches in hal_nxp and SDK are in sync.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants