This commit is contained in:
david rice
2026-04-20 16:06:01 +01:00
parent 712a42ecb7
commit ac65270cef
6 changed files with 103 additions and 70 deletions

View File

@@ -4,9 +4,9 @@ rigol_scope.py
Controls the Rigol DS1202Z-E at 192.168.45.5 for 1.8 V supply rail monitoring.
Called from dual_capture() in mipi_test.py during the LP pass.
The scope is armed (single trigger) just before the Agilent LP capture.
The scope is armed just before the Agilent LP capture.
The LP→HS current step droops the 1.8 V rail, triggering the Rigol.
The waveform is then read over SCPI and written directly to the local data/ folder.
The CH1 waveform is read over SCPI and written to the local data/ folder.
"""
import csv
@@ -21,14 +21,6 @@ V18_TIMEBASE = 1e-6 # s/div — 1 µs/div = 10 µs total window
V18_TRIG_LEVEL = 1.76 # V — falling-edge trigger on supply droop > 40 mV
TRIG_TIMEOUT_S = 15.0 # s — wait this long for Rigol to capture after arming
# CH2 — SN65DSI83 IRQ pin (CMOS output, active HIGH, high-impedance when IRQ_EN=0)
# CSR 0xE0.0 IRQ_EN=0 (default): pin is high-impedance → reads ~0 V (no pull on PCB, normal)
# IRQ_EN=1, no error: driven LOW (~0 V)
# IRQ_EN=1, error asserted: driven HIGH (~1.25 V min per VOH spec)
# No pull-up required — CMOS output drives both high and low.
INT_V_SCALE = 0.2 # V/div — shows 0~1.8 V range clearly
INT_V_OFFSET = -0.9 # V — centres display on 0.9 V midpoint
rigol: vxi11.Instrument | None = None
@@ -70,7 +62,7 @@ def is_connected() -> bool:
def configure():
"""
Configure Rigol CH1 for 1.8 V supply monitoring and CH2 for SN65DSI83 INTB pin.
Configure Rigol CH1 for 1.8 V supply monitoring.
AUTO trigger sweep: if no droop occurs, scope still captures on timeout
so we always get a supply snapshot even when the rail is healthy.
"""
@@ -84,12 +76,7 @@ def configure():
rigol.write(f":CHANnel1:SCALe {V18_SCALE:.3f}")
rigol.write(f":CHANnel1:OFFSet {V18_OFFSET:.3f}")
# CH2 — SN65DSI83 INTB pin (active-low open-drain, external 10 kΩ pull-up to 1.8 V required)
rigol.write(":CHANnel2:DISPlay 1")
rigol.write(":CHANnel2:COUPling DC")
rigol.write(":CHANnel2:PROBe 1") # direct probe, no attenuation
rigol.write(f":CHANnel2:SCALe {INT_V_SCALE:.3f}")
rigol.write(f":CHANnel2:OFFSet {INT_V_OFFSET:.3f}")
rigol.write(":CHANnel2:DISPlay 0")
rigol.write(f":TIMebase:MAIN:SCALe {V18_TIMEBASE:.2E}")
rigol.write(":TRIGger:MODE EDGE")
@@ -101,7 +88,7 @@ def configure():
rigol.write(":RUN") # start acquiring immediately after configure
time.sleep(0.2)
print(f"[RIGOL] Configured: CH1=1.8 V rail, CH2=INTB pin, {int(V18_TIMEBASE*1e6)} µs/div, "
print(f"[RIGOL] Configured: CH1=1.8 V rail, {int(V18_TIMEBASE*1e6)} µs/div, "
f"trigger <{V18_TRIG_LEVEL} V falling (AUTO sweep, running)")
@@ -197,9 +184,3 @@ def read_waveform_csv(path: Path) -> int:
return _read_channel_csv("CHANnel1", path, stop_first=True)
def read_int_csv(path: Path) -> int:
"""
Read CH2 (SN65DSI83 INTB pin) waveform from Rigol and write to CSV.
Must be called after read_waveform_csv() — scope is already stopped.
"""
return _read_channel_csv("CHANnel2", path, stop_first=False)