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>
This commit is contained in:
2026-09-25 07:42:43 +10:00
parent 6d85eb49f8
commit 08b83a069c
3 changed files with 293 additions and 16 deletions
+6 -1
View File
@@ -27,9 +27,14 @@ static bool ptp_validate(const cJSON *g, char *err, size_t n)
cfg_check_int(g, "dscp", 0, 63, err, n);
}
static void ptp_apply(const cJSON *g)
{
ptp_clock_reconfig();
}
esp_err_t aes67_ptp_init(void)
{
return cfg_register("ptp", PTP_DEFAULTS, ptp_validate, NULL);
return cfg_register("ptp", PTP_DEFAULTS, ptp_validate, ptp_apply);
}
esp_err_t aes67_ptp_start(esp_eth_handle_t eth)