Commit Graph

70 Commits

Author SHA1 Message Date
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
bsncubed 880437948d Enable ETH transmit mutex (LLDP/PTP raw TX next to lwIP)
CONFIG_ETH_TRANSMIT_MUTEX was off, so LLDP (esp_timer task) could hit the
EMAC TX descriptors at the same time as lwIP. PTP adds a third sender.
Verified: OTA-installed build passes its self-test, web/status fine.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:47:31 +10:00
bsncubed 6090ceb239 Step 3.1: EMAC hardware timestamps for PTP over UDP/IPv4
- aes67_ptp/ptp_hw.c: start the EMAC IEEE 1588 clock (IDF
  ETH_MAC_ESP_CMD_PTP_ENABLE) and additionally enable snapshots for
  PTP over UDP/IPv4 (IDF only enables PTP over Ethernet/L2). An RX hook
  on the driver's info input path records {type, seq, sourcePortId, HW
  timestamp} of port-319 PTPv2 event messages, then hands every frame to
  lwIP unchanged.
- aes67_ptp.c: temporary 3.1 logger joins 224.0.1.129:319/320 and pairs
  Sync HW RX timestamps with Follow_Up origin timestamps.
- Checked against linuxptp ptp4l (-4 -E -H, Intel igb) as GM: every Sync
  has a HW timestamp; HW Sync intervals track the GM intervals with a
  constant -39.8 us/s (+-0.3 us), i.e. local clock -39.8 ppm vs GM.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:44:11 +10:00
bsncubed f259c5d554 Step 2b verified: OTA update, rejections and rollback on board
Test on board (ESP32-P4 rev v1.3):
- Rejected with 400 and nothing booted differently: garbage, wrong
  project, min chip rev v3.0, truncated image.
- A (USB, ota_0) -> B via /api/ota: self-test passed, confirmed.
- Manual rollback B -> A; A -> B again.
- B -> C (forced self-test failure): C boots on trial in ota_0, fails,
  rolls back to B in ota_1.
- D installed over the network; a later truncated upload hides
  'previous' and clears can_rollback.

Docs: network flash command, serial-reset caveat, rollback test build,
OTA details in aes67-core-base.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:28:55 +10:00
bsncubed ad5a8b7545 OTA: report previous slot only when it is bootable
GET /api/ota listed a half-written upload or a rolled-back image as
'previous'. Only report it when esp_ota_check_rollback_is_possible().

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:27:49 +10:00
bsncubed bbc5729cc1 OTA rollback test build config (sdkconfig.selftest_fail)
Builds an image whose self-test always fails, in its own build directory
(build-*/ ignored), for the step 2b rollback test.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:20:20 +10:00
bsncubed 2403a6b64b Step 2b: firmware upload (/api/ota) with image checks and rollback self-test
- aes67_ota: GET /api/ota (version, project, build_date, idf, running,
  previous, previous_version, pending_verify, can_rollback), POST
  /api/ota streamed into the inactive slot (4 KiB chunks), POST
  /api/ota/confirm and /api/ota/rollback.
- Rejected before any flash write: bad magic, wrong chip, wrong
  project_name, chip revision outside the image's min/max range.
  esp_ota_end verifies the whole image.
- Self-test on a pending image: IP address plus HTTP 200 from our own
  /api/status within 60 s marks it valid; otherwise mark invalid and
  reboot into the previous slot. A crash before that is rolled back by
  the bootloader.
- CONFIG_AES67_OTA_SELFTEST_FORCE_FAIL (test builds only) forces a
  failed self-test.
- aes67_web: web_reboot_later() shared by /api/reboot and OTA.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:20:04 +10:00
bsncubed cbfc37cde6 Rebuild picks up the git version after each commit
PROJECT_VER was only read at CMake configure time, so builds kept the
previous commit's version. CMake now re-runs when .git/logs/HEAD or
.git/index change. Needed for OTA tests (step 2b), which rely on the
version changing between builds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:17:13 +10:00
bsncubed 07e16e6163 DHCP hostname: send net.hostname in DHCP requests
- aes67_net: esp_netif_set_hostname() before the interface starts, and
  in the net apply callback (takes effect at the next lease renewal).
- Verified: the router's DNS (lan.apointless.space) resolves p4-aes67
  to 192.168.192.244.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:16:39 +10:00
bsncubed 30c32e702b Step 2a (2/2): LLDP transmit, switch shows name and IP
- aes67_net/lldp.c: IEEE 802.1AB LLDPDU sent as a raw frame with
  esp_eth_transmit every 30 s (TTL 120 s) and immediately on a new IP
  or hostname change. TLVs: chassis/port ID (MAC), port description,
  system name (net.hostname), system description (project + version),
  capabilities station-only, IPv4 management address.
- Docs: LLDP in the core Network section; step 2a ticked.
- Verified on an HP 2530-8G-PoE+ (show lldp info remote-device 2): all
  fields shown, management address 192.168.192.244.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:14:09 +10:00
bsncubed 979420a6bb Step 2a (1/2): mDNS hostname.local and _http._tcp
- aes67_net: espressif/mdns 1.13.1 (managed component, pinned in
  dependencies.lock). Advertises <net.hostname>.local and the web UI as
  _http._tcp port 80. net apply callback renames live.
- First config value actually applied: net.hostname.
- Docs: mDNS in the core Network section; build order gets step 2a
  (mDNS, then LLDP).
- Verified on board: p4-aes67.local resolves via raw mDNS and getent,
  http://p4-aes67.local/ answers, service shows in _http._tcp browse;
  live rename to p4-rename and back works (after ~1 s probing).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:08:51 +10:00
bsncubed 8e52401e9c Step 2 verified: web UI checked in browser
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:05:10 +10:00
bsncubed c2621f192a Step 2.2: config registry and NVS store, GET/POST /api/config
- aes67_web/cfg.c: cfg_register(group, defaults, validate, apply),
  cfg_override_defaults() for project defaults, cfg_get(). Stored values
  are loaded on register and merged over defaults (known keys, matching
  types). NVS keeps only keys that differ from defaults, one JSON string
  per group, so new firmware defaults still reach untouched settings.
- POST /api/config: type check against defaults, per-group validation,
  nothing stored unless every group passes; 400 "group.key: reason".
  Unknown keys/groups are ignored. Returns the new config.
- Core groups registered by their components with the UI's ranges:
  ptp (aes67_ptp), aes67 (aes67_tx, incl. multicast range and mono_sum
  => 1 channel), net/inet (aes67_net), log (aes67_syslog).
- Project: PROJECT.def overrides (hostname p4-aes67, name P4 AES67) and
  the "source" group in main/project_cfg.c.
- Config is stored only; nothing is applied live yet.
- Verified on board: defaults, valid save, 8 rejected values (nothing
  stored), persistence across reboot, restore to defaults.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 23:00:55 +10:00
bsncubed 35275b8ccf Step 2.1: web server, embedded UI, /api/status, /api/reboot
- aes67_web: httpd (wildcard URI matching), serves web/index.html embedded
  via EMBED_TXTFILES, status registry (status_register) and route registry
  (web_register_uri), GET /api/status, POST /api/reboot (restarts 0.5 s
  after the response).
- Status fields come from each core component: aes67_net (ip, aes67_ip,
  mac, link), aes67_health (fw, uptime_s, heap_free, psram_free),
  aes67_tx stub (tx_packets, underruns = 0). No ptp object yet, so the UI
  shows "no data".
- Verified on board: / serves index.html byte-identical (27601 B),
  /api/status returns live values, reboot via API returns in ~12 s.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 22:56:06 +10:00
bsncubed 69b4e18118 Step 1: Ethernet up (IP101/RMII), DHCP, link and IP logged
- aes67_board: Waveshare ESP32-P4-ETH pin profile and EMAC + IP101 driver
  install (PHY addr 1, reset GPIO51, ref clock in on GPIO50).
- aes67_net: Ethernet netif with DHCP client; logs link up/down (speed,
  duplex, MAC) and the DHCP lease.
- Verified on board: 100 Mbps full duplex, DHCP lease in ~8 s, ping
  0% loss, ~0.2 ms RTT.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 22:52:08 +10:00
bsncubed b391b962a7 Step 0 verified on board: boots rev v1.3 build, 32 MB, OTA layout
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 22:48:46 +10:00
bsncubed bbfd3506bf Step 0: IDF project skeleton for esp32p4 with core component stubs
- Board checked with esptool: ESP32-P4 rev v1.3 (engineering silicon),
  32 MB GigaDevice flash. Rev <3 support and 32 MB set in sdkconfig.defaults.
- OTA partition layout: nvs, otadata, phy_init, ota_0/ota_1 (6 MB each,
  below 16 MB), coredump; no factory app. Partition table at 0x10000 so
  the bootloader can grow.
- App rollback enabled in the bootloader from the start.
- PROJECT_VER from git describe --tags --always --dirty.
- Empty stubs for the nine aes67_* core components; main logs version
  and chip revision.
- Built with ESP-IDF v5.5.5; not yet flashed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-24 22:47:21 +10:00
bsncubed 221b95a950 Upload files to "web" 2026-09-23 21:52:46 +10:00
bsncubed 67f76aed93 Upload files to "docs" 2026-09-23 21:52:22 +10:00
bsncubed 07f44f2ccc Upload files to "/" 2026-09-23 21:51:44 +10:00