From eda3c40013720717dd9f1d266a6748b054ce3d66 Mon Sep 17 00:00:00 2001 From: Edward Viaene Date: Thu, 15 Oct 2026 20:27:34 -0500 Subject: [PATCH 1/2] embeddedci 2.14.0, embeddedci-openhtf 2.4.0; host-clock rate tests allow 3% - embeddedci 2.14.0: Capabilities.scope False on the digital board (#42), DAC waveforms default to the 3.3 V output (#39). - embeddedci-openhtf 2.4.0: its signal phases default to dac_path 3v3 (#39). - e2e: the LA/ADC host-clock rate tests allow 3% instead of 0.5%. Over Wi-Fi the fit scattered to 0.983x/1.009x on a pod whose clock is fine; a wrong rate is off by 5-25%. Co-Authored-By: Claude Opus 5.5 --- packages/embeddedci-openhtf/CHANGELOG.md | 2 +- packages/embeddedci-openhtf/pyproject.toml | 2 +- packages/embeddedci/CHANGELOG.md | 2 +- packages/embeddedci/pyproject.toml | 2 +- packages/embeddedci/tests/e2e/e2e_helpers.py | 8 ++++++++ packages/embeddedci/tests/e2e/test_e2e_pod.py | 10 ++++++---- 6 files changed, 18 insertions(+), 8 deletions(-) diff --git a/packages/embeddedci-openhtf/CHANGELOG.md b/packages/embeddedci-openhtf/CHANGELOG.md index c0b120b..21114f4 100644 --- a/packages/embeddedci-openhtf/CHANGELOG.md +++ b/packages/embeddedci-openhtf/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog — `embeddedci-openhtf` -## Unreleased +## 2.4.0 - `signal_generate`, `signal_generate_phase` and `loopback_measure_phase` default to `dac_path="3v3"` instead of `"5v"`; `dac_replay_phase` now defaults to the path stored with the diff --git a/packages/embeddedci-openhtf/pyproject.toml b/packages/embeddedci-openhtf/pyproject.toml index e9df329..4a42d6b 100644 --- a/packages/embeddedci-openhtf/pyproject.toml +++ b/packages/embeddedci-openhtf/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "embeddedci-openhtf" -version = "2.3.0" +version = "2.4.0" description = "OpenHTF plug for driving an EmbeddedCI BenchPod directly over TCP or serial (no cloud)" readme = "README.md" requires-python = ">=3.10" diff --git a/packages/embeddedci/CHANGELOG.md b/packages/embeddedci/CHANGELOG.md index b53df66..80a65b1 100644 --- a/packages/embeddedci/CHANGELOG.md +++ b/packages/embeddedci/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog — `embeddedci` -## Unreleased +## 2.14.0 - `Capabilities.scope` is False on the digital-only board. Current firmware lists `signal` on every board; it only stands for the scope on firmware without the `analog` flag. diff --git a/packages/embeddedci/pyproject.toml b/packages/embeddedci/pyproject.toml index b99c76b..e50fe2b 100644 --- a/packages/embeddedci/pyproject.toml +++ b/packages/embeddedci/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "embeddedci" -version = "2.13.0" +version = "2.14.0" description = "BenchPod SDK and pytest plugin for EmbeddedCI hardware-in-the-loop testing" readme = "README.md" requires-python = ">=3.10" diff --git a/packages/embeddedci/tests/e2e/e2e_helpers.py b/packages/embeddedci/tests/e2e/e2e_helpers.py index 0a8dd5b..7f52765 100644 --- a/packages/embeddedci/tests/e2e/e2e_helpers.py +++ b/packages/embeddedci/tests/e2e/e2e_helpers.py @@ -99,6 +99,14 @@ def run() -> None: return result["capture"], stamps +# How far the host-clock fit may stray from the reported rate. Over Ethernet or the USB network it +# lands within 0.5%; over Wi-Fi, where packets queue and leave in bursts, it scattered to 0.983x +# and 1.009x on a pod whose clock is fine (the same pod passed over the USB network). A capture +# that really runs at another rate is off by 5-25% (firmware that reports the requested rate +# instead of the achieved one), so 3% still catches that. +HOST_CLOCK_REL = 0.03 + + def host_clock_rate(event_samples: Sequence[int], stamps: Sequence[float]) -> float: """Real samples per second: fit the sample index of each event against the host time it was sent. The host fires at a fixed interval, so events are paired in order; events after the diff --git a/packages/embeddedci/tests/e2e/test_e2e_pod.py b/packages/embeddedci/tests/e2e/test_e2e_pod.py index ec72ebd..10565d9 100644 --- a/packages/embeddedci/tests/e2e/test_e2e_pod.py +++ b/packages/embeddedci/tests/e2e/test_e2e_pod.py @@ -36,7 +36,8 @@ from embeddedci.benchpod.control_loop import CURVE_POINTS from embeddedci.benchpod.decode import decode_uart -from e2e_helpers import ANALOG, SETTLE, adc_levels, events_during, host_clock_rate, p2p, split_levels +from e2e_helpers import (ANALOG, HOST_CLOCK_REL, SETTLE, adc_levels, events_during, host_clock_rate, p2p, + split_levels) pytestmark = pytest.mark.hardware @@ -661,7 +662,8 @@ def test_la_reports_the_rate_it_achieved(pod, bench, samples, rate_hz): # The host clock is the independent reference for the capture clock: events sent at known host # times land at sample indices, and the fitted slope is the real sample rate. The drift a wrong # rate causes grows with the capture length (samples / 24 MHz regardless of rate: ~170 ms for -# the LA test, ~80 ms for the ADC test), far above the few ms of network jitter. +# the LA test, ~80 ms for the ADC test), far above the few ms of wired network jitter; Wi-Fi +# needs the wider HOST_CLOCK_REL (e2e_helpers). def test_la_sample_rate_matches_the_host_clock(pod, bench): np = pytest.importorskip("numpy") ch = bench.free_la[0] @@ -674,7 +676,7 @@ def test_la_sample_rate_matches_the_host_clock(pod, bench): count=18, interval=0.2) bits = np.asarray(la.channel(ch), dtype=np.int8) rate = host_clock_rate(np.flatnonzero(np.diff(bits) == 1) + 1, stamps) - assert rate == pytest.approx(la.sample_rate_hz, rel=0.005), ( + assert rate == pytest.approx(la.sample_rate_hz, rel=HOST_CLOCK_REL), ( f"the LA really samples at {rate:.0f} Hz ({rate / la.sample_rate_hz:.4f}x the reported " f"{la.sample_rate_hz:.0f} Hz)") @@ -701,7 +703,7 @@ def toggle_dac(k): # a 5 kHz burst on even events, flat on odd ones active = (blocks.max(axis=1) - blocks.min(axis=1)) > 800 edges = (np.flatnonzero(np.diff(active.astype(np.int8)) != 0) + 1) * block rate = host_clock_rate(edges, stamps) - assert rate == pytest.approx(cap.sample_rate_hz, rel=0.005), ( + assert rate == pytest.approx(cap.sample_rate_hz, rel=HOST_CLOCK_REL), ( f"the ADC really samples at {rate:.0f} Hz ({rate / cap.sample_rate_hz:.4f}x the reported " f"{cap.sample_rate_hz:.0f} Hz)") From 0de86b24a56ef68c3cc1003e960d5cf4f774506b Mon Sep 17 00:00:00 2001 From: Edward Viaene Date: Thu, 15 Oct 2026 20:32:58 -0500 Subject: [PATCH 2/2] Patch versions: embeddedci 2.13.1, embeddedci-openhtf 2.3.1 Co-Authored-By: Claude Opus 5.5 --- packages/embeddedci-openhtf/CHANGELOG.md | 2 +- packages/embeddedci-openhtf/pyproject.toml | 2 +- packages/embeddedci/CHANGELOG.md | 2 +- packages/embeddedci/pyproject.toml | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/embeddedci-openhtf/CHANGELOG.md b/packages/embeddedci-openhtf/CHANGELOG.md index 21114f4..d44a19c 100644 --- a/packages/embeddedci-openhtf/CHANGELOG.md +++ b/packages/embeddedci-openhtf/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog — `embeddedci-openhtf` -## 2.4.0 +## 2.3.1 - `signal_generate`, `signal_generate_phase` and `loopback_measure_phase` default to `dac_path="3v3"` instead of `"5v"`; `dac_replay_phase` now defaults to the path stored with the diff --git a/packages/embeddedci-openhtf/pyproject.toml b/packages/embeddedci-openhtf/pyproject.toml index 4a42d6b..90dee78 100644 --- a/packages/embeddedci-openhtf/pyproject.toml +++ b/packages/embeddedci-openhtf/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "embeddedci-openhtf" -version = "2.4.0" +version = "2.3.1" description = "OpenHTF plug for driving an EmbeddedCI BenchPod directly over TCP or serial (no cloud)" readme = "README.md" requires-python = ">=3.10" diff --git a/packages/embeddedci/CHANGELOG.md b/packages/embeddedci/CHANGELOG.md index 80a65b1..94d6433 100644 --- a/packages/embeddedci/CHANGELOG.md +++ b/packages/embeddedci/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog — `embeddedci` -## 2.14.0 +## 2.13.1 - `Capabilities.scope` is False on the digital-only board. Current firmware lists `signal` on every board; it only stands for the scope on firmware without the `analog` flag. diff --git a/packages/embeddedci/pyproject.toml b/packages/embeddedci/pyproject.toml index e50fe2b..79e40fc 100644 --- a/packages/embeddedci/pyproject.toml +++ b/packages/embeddedci/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "embeddedci" -version = "2.14.0" +version = "2.13.1" description = "BenchPod SDK and pytest plugin for EmbeddedCI hardware-in-the-loop testing" readme = "README.md" requires-python = ">=3.10"