updates
This commit is contained in:
@@ -48,10 +48,16 @@ LP11_SPEC_MAX_V = 1.45 # V — LP-11 maximum voltage spec
|
||||
LP_LOW_DUR_MIN_NS = 50.0 # ns — minimum LP-low duration per D-PHY spec (LP-01 + LP-00 combined)
|
||||
HS_OSC_STD_V = 0.045 # V — rolling-std threshold above which a region is classified as HS
|
||||
|
||||
# Flicker detection threshold
|
||||
# Flicker detection thresholds
|
||||
# LP-low plateau below this → SoT sequence too brief for receiver to detect → flicker risk
|
||||
FLICKER_LP_LOW_MAX_NS = 50.0 # ns
|
||||
|
||||
# HS burst amplitude below this (single-ended p-p / 2, mV) → HS burst absent after LP transition.
|
||||
# On this hardware normal HS = 105–122 mV; confirmed flicker = 14–32 mV (DC / LP-11 recovery).
|
||||
# Captures where LP-01/LP-00 completed normally but the bridge never entered HS mode show
|
||||
# essentially zero amplitude (the burst window is DC LP-11), so lp_low alone cannot detect this.
|
||||
HS_BURST_AMPLITUDE_MIN_MV = 50.0 # mV — below this, no real HS burst is present
|
||||
|
||||
|
||||
@dataclass
|
||||
class ChannelMetrics:
|
||||
@@ -670,7 +676,18 @@ class LPMetrics:
|
||||
if self.hs_amplitude_mv is not None:
|
||||
lines.append(f" HS amplitude : {self.hs_amplitude_mv:.0f} mV (single-ended p-p/2)")
|
||||
if self.flicker_suspect:
|
||||
lines.append(f" *** FLICKER SUSPECT: LP-low plateau absent or < {FLICKER_LP_LOW_MAX_NS:.0f} ns ***")
|
||||
if (self.hs_amplitude_mv is not None
|
||||
and self.hs_amplitude_mv < HS_BURST_AMPLITUDE_MIN_MV
|
||||
and (self.lp_low_duration_ns is None
|
||||
or self.lp_low_duration_ns >= FLICKER_LP_LOW_MAX_NS)):
|
||||
lines.append(
|
||||
f" *** FLICKER SUSPECT: HS burst absent "
|
||||
f"(amplitude {self.hs_amplitude_mv:.0f} mV < {HS_BURST_AMPLITUDE_MIN_MV:.0f} mV) ***"
|
||||
)
|
||||
else:
|
||||
lines.append(
|
||||
f" *** FLICKER SUSPECT: LP-low plateau absent or < {FLICKER_LP_LOW_MAX_NS:.0f} ns ***"
|
||||
)
|
||||
for w in self.warnings:
|
||||
lines.append(f" WARNING: {w}")
|
||||
return "\n".join(lines)
|
||||
@@ -732,7 +749,8 @@ def analyze_lp_file(path: Path) -> "LPMetrics":
|
||||
lp11_voltage_v = round(float(np.concatenate(
|
||||
[volts[s:e] for s, e in lp11_regions]).mean()), 3)
|
||||
lp11_duration_us = round(
|
||||
sum((times[e] - times[s]) for s, e in lp11_regions) * 1e6, 3)
|
||||
sum((times[min(e, len(times) - 1)] - times[s])
|
||||
for s, e in lp11_regions) * 1e6, 3)
|
||||
|
||||
# ── HS burst detection ────────────────────────────────────────────────
|
||||
# On DAT0+ with a uniform-colour display, HS data can look DC (no bit
|
||||
@@ -758,8 +776,9 @@ def analyze_lp_file(path: Path) -> "LPMetrics":
|
||||
for i, (lp11_s, lp11_e) in enumerate(lp11_regions):
|
||||
# Burst ends at start of next LP-11, or at window end
|
||||
burst_end = lp11_regions[i + 1][0] if i + 1 < len(lp11_regions) else len(times) - 1
|
||||
burst_dur_ns = round((times[burst_end] - times[lp11_e]) * 1e9, 1)
|
||||
hs_bursts.append((lp11_e, burst_end, burst_dur_ns))
|
||||
lp11_e_idx = min(lp11_e, len(times) - 1) # guard: region end can == len(times)
|
||||
burst_dur_ns = round((times[burst_end] - times[lp11_e_idx]) * 1e9, 1)
|
||||
hs_bursts.append((lp11_e_idx, burst_end, burst_dur_ns))
|
||||
|
||||
if hs_bursts:
|
||||
n_hs_bursts = len(hs_bursts)
|
||||
@@ -776,12 +795,15 @@ def analyze_lp_file(path: Path) -> "LPMetrics":
|
||||
# LP-low plateau: look for a contiguous region in the exit window
|
||||
# where voltage < LP_LOW_V and std is low (true LP-01/LP-00 plateau)
|
||||
lp_low_mask = (volts < LP_LOW_V) & (rstd < HS_OSC_STD_V)
|
||||
lp_low_regions = _find_contiguous_regions(lp_low_mask, min_samples=5)
|
||||
# Time-based minimum: reject glitches shorter than 5 ns.
|
||||
# At ~40 GSa/s (25 ps/sample) the old min_samples=5 admitted 125 ps noise spikes.
|
||||
_min_lp_low = max(5, int(5e-9 / dt))
|
||||
lp_low_regions = _find_contiguous_regions(lp_low_mask, min_samples=_min_lp_low)
|
||||
exit_window = int(1e-6 / dt)
|
||||
for lplow_s, lplow_e in lp_low_regions:
|
||||
if s_end <= lplow_s <= s_end + exit_window:
|
||||
lp_low_duration_ns = round(
|
||||
(times[lplow_e] - times[lplow_s]) * 1e9, 1)
|
||||
(times[min(lplow_e, len(times) - 1)] - times[lplow_s]) * 1e9, 1)
|
||||
break
|
||||
|
||||
# HS single-ended amplitude from the first burst (where data may vary)
|
||||
@@ -818,13 +840,31 @@ def analyze_lp_file(path: Path) -> "LPMetrics":
|
||||
if n_hs_bursts == 0:
|
||||
warnings.append("No HS bursts detected after LP transition")
|
||||
|
||||
# Flicker suspect: LP→HS sequence detected but LP-low plateau is absent or too short.
|
||||
# Normal captures show ~340 ns; the confirmed flicker capture showed 0 ns.
|
||||
# Flicker suspect: either the LP-low plateau is absent/short, OR the HS burst
|
||||
# amplitude is too low (indicating the HS burst never actually started).
|
||||
#
|
||||
# The second condition catches the confirmed failure mode on this hardware:
|
||||
# LP-11 → LP-01/LP-00 preamble (normal ~342 ns) → bridge misses SoT
|
||||
# → driver returns to LP-11 without entering HS mode
|
||||
# → burst window is DC LP-11, hs_amplitude ≈ 15–30 mV (vs normal 105–122 mV).
|
||||
# In this case lp_low_duration_ns = ~342 ns (above threshold), so the LP-low
|
||||
# check alone produces a false negative.
|
||||
#
|
||||
# Only flag DAT lane (CLK is continuous HS — LP states not expected).
|
||||
# NOTE: lp11_to_hs_ns is NOT used here — on this hardware a consistent noise spike
|
||||
# at LP-11 exit causes the rolling-std gate to fire at ~3 ns for every capture,
|
||||
# making it indistinguishable from a genuine flicker (2.8 ns confirmed flicker).
|
||||
hs_burst_absent = (
|
||||
hs_amplitude_mv is not None
|
||||
and hs_amplitude_mv < HS_BURST_AMPLITUDE_MIN_MV
|
||||
)
|
||||
flicker_suspect = (
|
||||
channel == "dat"
|
||||
and lp_transition_valid
|
||||
and (lp_low_duration_ns is None or lp_low_duration_ns < FLICKER_LP_LOW_MAX_NS)
|
||||
and (
|
||||
(lp_low_duration_ns is None or lp_low_duration_ns < FLICKER_LP_LOW_MAX_NS)
|
||||
or hs_burst_absent
|
||||
)
|
||||
)
|
||||
|
||||
return LPMetrics(
|
||||
|
||||
Reference in New Issue
Block a user