11# Sigrok Driver
22
3- ` jumpstarter-driver-sigrok ` wraps ` sigrok-cli ` to provide logic analyzer and oscilloscope capture from Jumpstarter exporters. It supports:
4- - ** Logic analyzers** (digital channels) - with protocol decoding (SPI, I2C, UART, etc.)
3+ ` jumpstarter-driver-sigrok ` wraps [ sigrok-cli] ( https://sigrok.org/wiki/Sigrok-cli ) to provide logic analyzer and oscilloscope capture from Jumpstarter exporters. It supports:
4+ - ** Logic analyzers** (digital channels)
55- ** Oscilloscopes** (analog channels) - voltage waveform capture
66- One-shot and streaming capture
7- - Decoder-friendly channel mappings
8- - Real-time protocol decoding
7+ - Multiple output formats with parsing (VCD, CSV, Bits, ASCII)
98
109## Installation
1110
@@ -19,44 +18,34 @@ pip3 install --extra-index-url https://pkg.jumpstarter.dev/simple/ jumpstarter-d
1918export :
2019 sigrok :
2120 type : jumpstarter_driver_sigrok.driver.Sigrok
22- driver : demo # sigrok driver (demo, fx2lafw, etc.)
23- conn : null # optional: USB VID.PID or serial path
24- executable : null # optional: path to sigrok-cli (auto-detected)
25- channels : # channel mappings (device_name: semantic_name)
26- D0 : vcc
27- D1 : cs
21+ driver : fx2lafw # sigrok driver (demo, fx2lafw, rigol-ds, etc.)
22+ conn : null # optional: USB VID.PID, serial path, or null for auto
23+ channels : # optional: map device channels to friendly names
24+ D0 : clk
25+ D1 : mosi
2826 D2 : miso
29- D3 : mosi
30- D4 : clk
31- D5 : sda
32- D6 : scl
27+ D3 : cs
3328` ` `
3429
35- ## CaptureConfig (client-side)
30+ ### Configuration Parameters
3631
37- ` ` ` python
38- from jumpstarter_driver_sigrok.common import CaptureConfig, DecoderConfig
32+ | Parameter | Description | Type | Required | Default |
33+ |-----------|-------------|------|----------|---------|
34+ | ` driver` | Sigrok driver name (e.g., `demo`, `fx2lafw`, `rigol-ds`) | str | yes | - |
35+ | `conn` | Connection string (USB VID.PID, serial path, or `null` for auto-detect) | str \| None | no | None |
36+ | `executable` | Path to `sigrok-cli` executable | str | no | Auto-detected from PATH |
37+ | `channels` | Channel mapping from device names (D0, A0) to semantic names (clk, voltage) | dict[str, str] | no | {} (empty) |
3938
40- config = CaptureConfig(
41- sample_rate="8MHz",
42- samples=20000,
43- pretrigger=5000,
44- triggers={"cs" : " falling" },
45- decoders=[
46- DecoderConfig(
47- name="spi",
48- channels={"clk" : " clk" , "mosi": "mosi", "miso": "miso", "cs": "cs"},
49- annotations=["mosi-data"],
50- )
51- ],
52- )
53- ```
39+ # # CaptureConfig Parameters (client-side)
5440
55- This maps to:
56- ``` bash
57- sigrok-cli -d fx2lafw -c samplerate=8MHz,samples=20000,pretrigger=5000 --triggers D1=falling \
58- -P spi:clk=D4:mosi=D3:miso=D2:cs=D1 -A spi=mosi-data
59- ```
41+ | Parameter | Description | Type | Required | Default |
42+ |-----------|-------------|------|----------|---------|
43+ | `sample_rate` | Sampling rate (e.g., `"1M"`, `"8MHz"`, `"24000000"`) | str | no | "1M" |
44+ | `samples` | Number of samples to capture (`None` for continuous) | int \| None | no | None |
45+ | `pretrigger` | Number of samples to capture before trigger | int \| None | no | None |
46+ | `triggers` | Trigger conditions by channel name (e.g., `{"cs" : " falling" }`) | dict[str, str] \| None | no | None |
47+ | `channels` | List of channel names to capture (overrides defaults) | list[str] \| None | no | None |
48+ | `output_format` | Output format (vcd, csv, bits, ascii, srzip, binary) | str | no | "vcd" |
6049
6150# # Client API
6251
@@ -67,23 +56,107 @@ sigrok-cli -d fx2lafw -c samplerate=8MHz,samples=20000,pretrigger=5000 --trigger
6756- ` get_channel_map()` — device-to-semantic name mappings
6857- ` list_output_formats()` — supported formats (csv, srzip, vcd, binary, bits, ascii)
6958
59+ # # Output Formats
60+
61+ The driver supports multiple output formats. **VCD (Value Change Dump) is the default** because :
62+ - ✅ **Efficient** : Only records signal changes (not every sample)
63+ - ✅ **Precise timing** : Includes exact timestamps in nanoseconds
64+ - ✅ **Widely supported** : Standard format for signal analysis tools
65+ - ✅ **Mixed signals** : Handles both digital and analog data
66+
67+ # ## Available Formats
68+
69+ | Format | Use Case | Decoded By |
70+ |--------|----------|------------|
71+ | `vcd` (default) | Change-based signals with timing | `result.decode()` → `list[Sample]` |
72+ | `csv` | All samples with timing | `result.decode()` → `list[Sample]` |
73+ | `bits` | Bit sequences by channel | `result.decode()` → `dict[str, list[int]]` |
74+ | `ascii` | ASCII art visualization | `result.decode()` → `str` |
75+ | `srzip` | Raw sigrok session (for PulseView) | `result.data` (raw bytes) |
76+ | `binary` | Raw binary data | `result.data` (raw bytes) |
77+
78+ # ## Output Format Constants
79+
80+ ` ` ` python
81+ from jumpstarter_driver_sigrok.common import OutputFormat
82+
83+ config = CaptureConfig(
84+ sample_rate="1MHz",
85+ samples=1000,
86+ output_format=OutputFormat.VCD, # or CSV, BITS, ASCII, SRZIP, BINARY
87+ )
88+ ` ` `
89+
7090# # Examples
7191
72- ### Logic Analyzer (Digital Channels)
92+ # ## Example 1: Simple Capture (VCD format - default)
93+
94+ **Python client code:**
95+ ` ` ` python
96+ from jumpstarter_driver_sigrok.common import CaptureConfig
97+
98+ # Capture with default VCD format (efficient, change-based with timing)
99+ config = CaptureConfig(
100+ sample_rate="1MHz",
101+ samples=1000,
102+ channels=["D0", "D1", "D2"], # Use device channel names or mapped names
103+ )
104+ result = client.capture(config)
73105
74- One-shot with trigger:
106+ # Decode VCD to get samples with timing
107+ samples = result.decode() # list[Sample]
108+ for sample in samples[:5]:
109+ print(f"Time: {sample.time_ns}ns, Values: {sample.values}")
110+ ` ` `
111+
112+ **Equivalent sigrok-cli command:**
75113` ` ` bash
76- sigrok-cli -d fx2lafw -c samplerate=8MHz,samples=20000,pretrigger=5000 --triggers D0=rising -o out.sr
114+ sigrok-cli -d fx2lafw -C D0,D1,D2 \
115+ -c samplerate=1MHz --samples 1000 \
116+ -O vcd -o /tmp/capture.vcd
77117` ` `
78118
79- Real-time decode (SPI):
119+ ---
120+
121+ # ## Example 2: Triggered Capture with Pretrigger
122+
123+ **Python client code:**
124+ ` ` ` python
125+ from jumpstarter_driver_sigrok.common import CaptureConfig
126+
127+ # Capture with trigger and pretrigger buffer (VCD format - default)
128+ config = CaptureConfig(
129+ sample_rate="8MHz",
130+ samples=20000,
131+ pretrigger=5000, # Capture 5000 samples before trigger
132+ triggers={"D0": "rising"}, # Trigger on D0 rising edge
133+ channels=["D0", "D1", "D2", "D3"],
134+ # output_format defaults to VCD (efficient change-based format)
135+ )
136+ result = client.capture(config)
137+
138+ # Decode to analyze signal changes with precise timing
139+ samples = result.decode() # list[Sample] - only changes recorded
140+ print(f"Captured {len(samples)} signal changes")
141+
142+ # Access timing and values
143+ for sample in samples[:3]:
144+ print(f"Time: {sample.time_ns}ns, Changed: {sample.values}")
145+ ` ` `
146+
147+ **Equivalent sigrok-cli command:**
80148` ` ` bash
81- sigrok-cli -d fx2lafw -c samplerate=1M --continuous \
82- -P spi:clk=D4:mosi=D3:miso=D2:cs=D1 -A spi=mosi-data
149+ sigrok-cli -d fx2lafw -C D0,D1,D2,D3 \
150+ -c samplerate=8MHz,samples=20000,pretrigger=5000 \
151+ --triggers D0=rising \
152+ -O vcd -o /tmp/capture.vcd
83153` ` `
84154
85- ### Oscilloscope (Analog Channels)
155+ ---
86156
157+ # ## Example 3: Oscilloscope (Analog Channels)
158+
159+ **Exporter configuration:**
87160` ` ` yaml
88161export:
89162 oscilloscope:
@@ -95,16 +168,60 @@ export:
95168 A1: CH2
96169` ` `
97170
171+ **Python client code:**
98172` ` ` python
99- from jumpstarter_driver_sigrok.common import CaptureConfig
173+ from jumpstarter_driver_sigrok.common import CaptureConfig, OutputFormat
100174
101175# Capture analog waveforms
102176config = CaptureConfig(
103177 sample_rate="1MHz",
104178 samples=10000,
105179 channels=["CH1", "CH2"], # Analog channels
106- output_format="csv" , # or "vcd" for waveform viewers
180+ output_format=OutputFormat.CSV , # CSV for voltage values
107181)
108182result = client.capture(config)
109- waveform_data = result.data # bytes with voltage measurements
183+
184+ # Parse voltage data
185+ samples = result.decode() # list[Sample]
186+ for sample in samples[:5]:
187+ print(f"Time: {sample.time_ns}ns")
188+ print(f" CH1: {sample.values.get('A0', 'N/A')}V")
189+ print(f" CH2: {sample.values.get('A1', 'N/A')}V")
190+ ` ` `
191+
192+ **Equivalent sigrok-cli command:**
193+ ` ` ` bash
194+ sigrok-cli -d rigol-ds:conn=usb -C A0=CH1,A1=CH2 \
195+ -c samplerate=1MHz --samples 10000 \
196+ -O csv -o /tmp/capture.csv
197+ ` ` `
198+
199+ ---
200+
201+ # ## Example 4: Bits Format (Simple Bit Sequences)
202+
203+ **Python client code:**
204+ ` ` ` python
205+ from jumpstarter_driver_sigrok.common import CaptureConfig, OutputFormat
206+
207+ # Capture in bits format (useful for visual inspection)
208+ config = CaptureConfig(
209+ sample_rate="100kHz",
210+ samples=100,
211+ channels=["D0", "D1", "D2"],
212+ output_format=OutputFormat.BITS,
213+ )
214+ result = client.capture(config)
215+
216+ # Get bit sequences per channel
217+ bits_by_channel = result.decode() # dict[str, list[int]]
218+ for channel, bits in bits_by_channel.items():
219+ print(f"{channel}: {''.join(map(str, bits[:20]))}") # First 20 bits
220+ ` ` `
221+
222+ **Equivalent sigrok-cli command:**
223+ ` ` ` bash
224+ sigrok-cli -d demo -C D0,D1,D2 \
225+ -c samplerate=100kHz --samples 100 \
226+ -O bits -o /tmp/capture.bits
110227` ` `
0 commit comments