This commit is contained in:
david rice
2026-04-22 09:56:51 +01:00
parent de632c68d0
commit 4f45ff5a20
2 changed files with 36 additions and 5 deletions

View File

@@ -65,6 +65,10 @@ CLK_LP_LOW_MIN_NS = 300.0
HS_BURST_AMPLITUDE_MIN_MV = 40.0 # mV — below this, no real HS burst is present
# Lowered from 50 mV: 48 mV capture (0001) was a false alarm; true flicker (0008) at 34 mV.
HS_BURST_AMPLITUDE_HIGH_MV = 70.0 # mV — above this with short LP-low → anomalous LP states
# Normal HS (dynamic video) = ~1540 mV P95-P5/2 on LP probe (RC-filtered).
# LP-01/LP-10 states in the burst window (cap 0042 type) produce 130+ mV → flag these.
# Mode A minimum amplitude: LP-11-return edge artifacts produce near-zero amplitude in the
# burst window (burst is pure LP-low DC between two LP-11 regions). Require ≥ this to
# distinguish a genuine weak-HS attempt from a false rolling-std trigger on LP-11 return.
@@ -752,6 +756,7 @@ class LPMetrics:
# Flicker detection
# A capture is flagged when the LP-low plateau is absent or shorter than
# FLICKER_LP_LOW_MAX_NS. Normal captures show ~340 ns; flicker shows 050 ns.
hs_rolling_std_found: bool = False # rolling-std fired in HS window after LP-low ended
flicker_suspect: bool = False
warnings: list = field(default_factory=list)
@@ -891,6 +896,9 @@ def analyze_lp_file(path: Path) -> "LPMetrics":
n_hs_bursts = 0
hs_burst_dur_ns = None
hs_amplitude_mv = None
hs_rolling_std_found = False
s_end = None
rstd = None
if len(lp11_regions) >= 1:
# Measure LP-11 → HS exit gap (LP-01 + LP-00 combined) using a rolling
@@ -943,6 +951,17 @@ def analyze_lp_file(path: Path) -> "LPMetrics":
float(np.percentile(burst_volts, 5))) / 2 * 1000, 1
)
# Did rolling-std fire in the actual HS window (after LP-low ended)?
# With dynamic display content (video), genuine HS keeps rolling-std above
# threshold; absent HS does not. Used to gate Mode B/D false positives.
if lp_low_duration_ns is not None:
lp_low_end_idx = s_end + int((lp_low_duration_ns + 50.0) * 1e-9 / dt)
hs_check_end = min(lp_low_end_idx + int(1000e-9 / dt), len(rstd))
if lp_low_end_idx < len(rstd):
hs_rolling_std_found = bool(
np.any(rstd[lp_low_end_idx:hs_check_end] >= HS_OSC_STD_V)
)
# ── Warnings ─────────────────────────────────────────────────────────
warnings = []
continuous_hs_clk = (not lp11_regions) and (channel == "clk") and (float(volts.max()) < LP11_HIGH_V)
@@ -1027,16 +1046,27 @@ def analyze_lp_file(path: Path) -> "LPMetrics":
# Mode A2: rolling-std never fired — HS absent or amplitude below HS_OSC_STD_V;
# weak oscillations are misclassified as LP-low, masking the true HS failure
or lp11_to_hs_ns is None
# Mode B: LP-low anomalously short + low amplitude = marginal HS launch
or _lp_low_short
# Mode B: LP-low anomalously short + low amplitude = marginal HS launch.
# Gated by hs_rolling_std_found: if HS actually launched (rolling-std fires
# after LP-low ends), LP-low being short is a timing anomaly but not a flicker.
or (_lp_low_short and not hs_rolling_std_found)
# Mode D: LP-low normal, noise-spike lp11_to_hs (< 50 ns), low HS amplitude.
# Requires dynamic display content (video) during the test — with static/DC content
# the probe noise floor is 1535 mV regardless of HS health, making this unreliable.
# Requires video/dynamic content. Gate: if rolling-std fires after LP-low ends,
# HS launched normally and the early lp11_to_hs was just the LP-low edge trigger.
or (lp11_to_hs_ns is not None
and lp11_to_hs_ns < LP_LOW_DUR_MIN_NS
and not _lp_low_short)
and not _lp_low_short
and not hs_rolling_std_found)
)
)
# Mode E: short LP-low with anomalously HIGH amplitude — LP-01/LP-10 states in the
# burst window (link failed to launch HS cleanly). Normal LP probe HS = 1540 mV;
# LP-01/LP-10 DC levels produce 70+ mV. Confirmed: cap 0042 (lp_low=61 ns, amp=133 mV).
hs_burst_anomalous = (
_lp_low_short
and hs_amplitude_mv is not None
and hs_amplitude_mv > HS_BURST_AMPLITUDE_HIGH_MV
)
# Mode C: no LP-11 at all → link silent (but exclude CLK which is always HS)
link_silent = (
channel == "dat"
@@ -1056,6 +1086,7 @@ def analyze_lp_file(path: Path) -> "LPMetrics":
# positives when noise triggers gave lp_low < 50 ns with normal HS.
lp_low_duration_ns is None
or hs_burst_absent
or hs_burst_anomalous
)
)
)