Commit Graph

7 Commits

Author SHA1 Message Date
bsncubed 5bd1a20e43 Step 6.3: PTP hybrid mode (unicast Delay_Req/Resp), step 6 done
- As TimeReceiver in ptp.mode hybrid: Delay_Req unicast to the GM (IP
  from its Announce, MAC recorded by the RX hook from its Sync frames),
  unicastFlag set.
- As TimeTransmitter: a Delay_Req with the unicastFlag gets a unicast
  Delay_Resp; multicast requests get multicast replies.
- EMAC timestamps every received frame (en_ts4all): its PTP filter left
  unicast Delay_Req unstamped ("no HW RX timestamp").
- A unicast Delay_Resp's logMessageInterval 0x7F is ignored (use
  ptp.log_delay_req); log_us() clamps to -7..6 (the shift was undefined).
- Verified vs ptp4l --hybrid_e2e 1: board hybrid TimeReceiver 18
  Delay_Req in 20 s, all answered, locked; board TimeTransmitter
  (p1 100): tcpdump shows Sync/Follow_Up/Announce to 224.0.1.129,
  Delay_Req 192.168.192.233 -> .244 [unicast] and Delay_Resp .244 ->
  .233 [unicast] within 0.4 ms; ptp4l s2.
- Docs: TimeTransmitter/hybrid notes; step 6 ticked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 08:21:09 +10:00
bsncubed 08b83a069c Step 6.1: PTP TimeTransmitter with BMCA (multicast)
- Own dataset from config: slave -> class 255, never TimeTransmitter;
  auto/master -> class 248 with ptp.priority1/2; accuracy 0xFE, variance
  0xFFFF, timeSource 0xA0, clockIdentity EUI-64 from MAC.
- BMCA: a foreign TimeTransmitter is followed only if its Announce beats
  our dataset (always for slave-only); if the followed one turns worse we
  take over; a better one makes us step down. LISTENING -> MASTER after
  announceReceiptTimeout x our announce interval.
- MASTER: Announce (PTP timescale flag) every 2^log_announce, two-step
  Sync every 2^log_sync (raw frame, HW TX time in Follow_Up), Delay_Resp
  for each Delay_Req with its HW RX time and logMessageInterval =
  log_delay_req. Frequency correction kept (holdover).
- ptp config applies live (role, priorities, intervals, domain, DSCP).
- status.ptp: state MASTER, gm_id = own, TX Sync/Announce intervals,
  Delay_Req/Resp counters; locked is true as master so AES67 TX keeps
  running; SDP ts-refclk and SAP follow.
- Verified: with ptp4l GM p1 128 the board (auto, p1 250) stays SLAVE;
  ptp4l stopped -> board MASTER; ptp4l -s --priority1 255 locks to it
  (s2) in ~4 s, offset within +-320 ns, path delay 10.3 us.
  Known: Sync send times jitter ~10 ms (FreeRTOS tick); accuracy is not
  affected (two-step Follow_Up carries the exact HW time).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 07:42:43 +10:00
bsncubed 2522901918 PTP: don't report the pre-step offset
After a clock step, status.ptp showed the whole step (~1.79e18 ns) as
offset_ns until the next Sync, and the 60 s summary reported it as
max |offset|. Offset is reset to 0 and the summary restarts on a step.
Verified: status goes 0 -> pull-in values; first summary max 24960 ns.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 07:08:42 +10:00
bsncubed 3d05768f00 Step 4.1: /stream.sdp from the live config and PTP GM
- aes67_sdp_sap: aes67_sdp_build() builds the AES67 SDP (RFC 4566 +
  RFC 7273) with the same lines and order as the web UI preview;
  GET /stream.sdp serves it as application/sdp.
- aes67_ptp: public aes67_ptp_gm_id(), aes67_ptp_locked(),
  aes67_ptp_now_ns(). Clock IDs are now uppercase (RFC 7273 style), also
  in status.ptp, which the UI copies into ts-refclk.
- aes67_net: aes67_net_netif() returns the AES67 interface.
- Verified on board: /stream.sdp byte-identical to the UI's sdp() for
  the same config/status; mono, L16, ptime 0.333, ttl 8, clk_offset
  4294967295 and session_ver all follow the config.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 06:38:55 +10:00
bsncubed 9af6c53294 Step 3.3b: status.ptp for the web UI
- ptp_clock_status() adds status.ptp: state (LISTENING / UNCALIBRATED /
  SLAVE), locked, gm_id, offset_ns, freq_ppb, path_delay_ns +
  path_delay_sd_ns (window of 64, from lock on), steps_removed,
  gm_time/freq_traceable, version, own_class (255 slave / 248 auto,
  master), clock_id, gm_class/accuracy/p1/p2, sync_avg/min/max_ms and
  sync_jitter_us (HW Sync intervals), announce_avg_ms, delay_req/resp
  counters, hw_ts, window. Snapshot under a mutex shared with the PTP task.
- Per-Sync log moved to debug; info level logs state changes plus a
  60 s summary (max |offset|, freq, delay).
- Verified vs ptp4l: LISTENING -> UNCALIBRATED -> SLAVE in ~35 s;
  locked offset within a few hundred ns, delay 10.27 us +-0.20 us,
  Delay_Req/Resp 69/69, Sync avg 1000.097 ms, Announce avg 2000 ms.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 06:22:41 +10:00
bsncubed 685060e12c Step 3.3a: PTP servo, clock locks to the GM
- ptp_hw: ptp_hw_adj_freq() (ETH_MAC_ESP_CMD_ADJ_PTP_TIME, absolute ppb
  vs nominal, clamped +-500 ppm, retried while the addend update is
  busy) and ptp_hw_step() (read + write time).
- ptp_clock: first Sync after a GM is selected seeds the integral with
  the measured rate and steps the clock; then linuxptp-style PI (kp/ki
  from the Sync interval: 0.7/0.3 at 1 s). Re-step above 1 ms. Locked
  after 8 Syncs with |offset| < 1 us, unlocked after 3 above; GM change
  or loss unlocks and keeps the frequency (holdover).
- Verified vs ptp4l: stepped to GM time, locked after ~19 s; locked
  offset within +-510 ns (mostly < 300 ns), correction +39.9 ppm
  (crystal -39.8 ppm), path delay ~10.2 us.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 06:15:26 +10:00
bsncubed e2f4d81326 Step 3.2: TimeReceiver measurement (GM selection, Delay_Req/Resp, path delay)
- ptp_clock.c replaces the 3.1 logger: UDP/IPv4 multicast, E2E.
  Announce: IEEE 1588 dataset comparison picks the best GM, dropped after
  announceReceiptTimeout x its announce interval. Sync/Follow_Up (two-step
  and one-step) with HW t2 and correctionField. Delay_Req sent as a raw
  frame (DSCP ptp.dscp, TTL 1, clockIdentity = EUI-64 from MAC) with HW
  TX timestamp t3, randomised at the GM's Delay_Resp interval; Delay_Resp
  matched on requestingPortIdentity + seq.
- Path delay corrected for offset drift between t2 and t3 (rate from
  consecutive Syncs) so it is right before the clock is syntonised.
- ptp_hw: ptp_hw_send_event() builds Eth/IPv4/UDP 319 and returns the HW
  TX timestamp.
- Verified vs ptp4l (i210 GM, HP 2530 non-PTP switch, PC 1G / board 100M):
  GM selected, path delay settles at ~10.3 us and stays flat, rate
  -39.8 +-0.4 ppm, offset drifts at -40 us/s (no servo yet).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:50:46 +10:00