From e69572ff99e5fd1fcf789e575e7c7a689fbd7579 Mon Sep 17 00:00:00 2001 From: ruv Date: Sat, 23 May 2026 12:47:06 -0400 Subject: [PATCH] fix(csi): ADR-018 byte 19 bit 4 now signals ESP-NOW sync too (not just broken 15.4) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit WITNESS-LOG-110 prior state had byte 19 bit 4 (cross-node sync valid) only being set from c6_timesync_is_valid() — but c6_timesync is the 802.15.4 path that D1 documented as unfixable in IDF v5.4 (rx=0 across every soak we've run). The working transport is c6_sync_espnow (§A0.7, §A0.10: 99.43-99.56% RX cross-board, 104 µs smoothed-offset stdev), yet frames from sync'd nodes had bit 4 cleared because the ESP-NOW path didn't OR into the flag. Fix: also set bit 4 when c6_sync_espnow_is_valid() — the OR semantic means a node signals sync from whichever transport is healthy. Host sees bit 4 set, knows to pair the frame against the most recent sync packet (§A0.12) from this node_id. Side effect: this also enables S3 boards to set bit 4 (c6_sync_espnow works on both targets, c6_timesync is C6-only). So a multi-target mesh of S3+C6 boards now correctly signals cross-node alignment regardless of which chips are in the fleet. Build evidence: C6 image 1019 KB (+16 bytes for the new check), 45% slack unchanged. Co-Authored-By: claude-flow --- firmware/esp32-csi-node/main/csi_collector.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/firmware/esp32-csi-node/main/csi_collector.c b/firmware/esp32-csi-node/main/csi_collector.c index 48279e0d..484b40cc 100644 --- a/firmware/esp32-csi-node/main/csi_collector.c +++ b/firmware/esp32-csi-node/main/csi_collector.c @@ -217,9 +217,16 @@ size_t csi_serialize_frame(const wifi_csi_info_t *info, uint8_t *buf, size_t buf if (info->rx_ctrl.cwb) flags |= 0x1; /* bw 40 MHz */ if (info->rx_ctrl.stbc) flags |= (1 << 2); /* STBC */ #endif /* CONFIG_SOC_WIFI_HE_SUPPORT */ + /* ADR-018 byte 19 bit 4 = "cross-node sync valid". Two transports can + * set it: the original 802.15.4 c6_timesync (broken in IDF v5.4 — D1) + * and the ESP-NOW workaround c6_sync_espnow (measured working in §A0.7- + * §A0.10). OR them together so frames signal sync from whichever + * transport is alive on this node. Host can pair against the sync + * packet (§A0.12) once it sees this bit. */ #if defined(CONFIG_IDF_TARGET_ESP32C6) && defined(CONFIG_C6_TIMESYNC_ENABLE) if (c6_timesync_is_valid()) flags |= (1 << 4); /* 15.4 sync valid */ #endif + if (c6_sync_espnow_is_valid()) flags |= (1 << 4); /* ESP-NOW sync valid (D1 workaround) */ buf[18] = ppdu_type; buf[19] = flags; #else