Repository navigation
Conversation
A DSLogic Plus with USB PID 0x0034 (the Pango PGL12 board revision) is not detected: the pinned DSView submodule's profile table in libsigrok4DSL/hardware/DSL/dsl.h stops at 0x0030, so the native scan skips the device and `devices list` comes back empty. The submodule already ships the bitstream the 0x0034 profile refers to -- DSView/res/DSLogicPlus-pgl12-2.bin is byte-identical (blob ce921c35) to the one in DSView master -- so no submodule bump is needed. Only the table entry is missing. This adds the 0x0034 and 0x0035 profiles verbatim from DSView master (2e9e2c8), as a patch rather than a submodule bump: the bump would drag in 94 files and roughly eight months of unrelated decoder and UI churn to fix a lookup table, where this is 55 additive lines. Verified on hardware. With the patch applied the device enumerates and capture works; the device's own internal test pattern decodes as an exact binary counter, and UART, SPI and I2C traffic decode correctly through sigrok's protocol decoders. Refs: LISTENAI#11
DSView logs the *successful* security-check branch with sr_err():
if (ret != SR_OK){
sr_err("Security check failed!");
} else {
sr_err("Security check pass!"); // success, logged as an error
}
The check is gated on CAPS_FEATURE_SECURITY, which the PGL12 profiles set,
so affected boards print three spurious error lines on every capture. Being
logged at error level, they survive any sane log-level setting.
Demoted to sr_info so the failure branch stays visible and the success
branch stops shouting.
The runtime exports a full simple-trigger API and a log-verbosity setter, and none of it was reachable: dsview-sys bound neither. This adds the FFI layer only -- typedefs, dsview_bridge_api members, dlsym resolution, and the dsview_bridge_ds_* wrappers, plus the safe Rust methods over them. The features that use these land in the following commits. Symbols bound: ds_log_level native stderr verbosity (0 none .. 5 detail) ds_trigger_reset clear trigger state ds_trigger_probe_set per-probe condition ds_trigger_set_en arm/disarm ds_trigger_set_mode simple vs staged ds_trigger_set_pos pre/post-trigger ratio ds_trigger_set_stage staged-trigger count Trigger conditions are the uppercase characters libsigrok4DSL matches on -- 'X' don't care, '0'/'1' level, 'R' rising, 'F' falling, 'C' either edge -- and ds_trigger_probe_set() writes into the slot past the staged-trigger array, which is what the driver reads for SIMPLE_TRIGGER.
Every command printed a dozen-plus lines of scan chatter to stderr:
sr: lib_main: Init libsigrok.
sr: lib_main: Scan all connected hardware device.
sr: dslogic: Scan DSLogic device...
...
libsigrok4DSL defaults to its `info` level and nothing lowered it, which is
noise in a tool whose output is meant to be piped. Discovery now defaults to
`warn` and `--log-level none|error|warn|info|debug|detail` raises it again
for diagnosing a device that will not enumerate.
The level has to be set between loading the library and calling init(): the
device scan happens inside init(), so setting it afterwards suppresses
nothing. Hence connect_with_log_level() rather than a setter on Discovery.
A plain `devices list` goes from 14 lines of stderr to 0.
…e wait
Three cases where the tool knew something and did not say it.
Unsupported device on the bus
`devices list` returned an empty list and exit 0 whether nothing was
plugged in or a DreamSourceLab device was present that this build cannot
drive. The native scan does log the skip, but at `info`, which is below the
default log level -- so quieting the logger hid the only clue. The bus is
now probed separately (Linux, via sysfs) and the difference reported:
code: devices_present_but_unsupported
"found DreamSourceLab USB device(s) [2a0e:0034] that this build does
not recognise..."
with a non-zero exit. An empty bus still exits 0.
Coerced settings
The device silently overrides values it cannot meet; selecting
`internal-test` forces its own sample rate, turning a requested 1 MHz into
100 MHz. Both figures were already in the JSON, but only for a caller who
thought to diff them. Mismatches are now reported on stderr and in a
`warnings` array.
Buffer-limit alignment (200000 -> 200704) happens on essentially every
capture and is not a surprise, so the sample-limit check uses a 1%
tolerance. A warning that always fires is one nobody reads; a clamp that
matters, such as hitting hardware capacity, is far larger than the
alignment step.
Wait timeout
--wait-timeout-ms defaulted to a flat 10 s, which aborts a large capture
while it is still running. It now defaults to 0, meaning derive it from
sample rate and limit, with 3x headroom for upload and a 10 s floor.
Add --trigger and --trigger-position so a capture can be armed on an event
instead of grabbing an arbitrary window and hoping the event is inside it.
--trigger 0=r,1=1 0 low, 1 high, r rising, f falling,
c either edge, x don't care
channels may be written 0 or D0
--trigger-position N percent of the buffer kept from before the trigger
Conditions map onto the uppercase characters libsigrok4DSL matches on.
SIMPLE_TRIGGER evaluates two comparator banks per probe, so both are set to
the same character to express one condition.
Two things worth knowing for review:
- The trigger is programmed at the point the two capture-preparation paths
converge, immediately before start_collect(). Putting it in
apply_capture_config() silently skips every capture that supplies device
options, because those take the other path through apply_device_options().
That failure mode looks exactly like a trigger that does not work.
- libsigrok4DSL keeps trigger state in a process global, so apply always
resets first; otherwise a probe armed by an earlier capture in the same
process is still live.
A trigger naming a channel that --channels does not enable is rejected up
front: the device cannot trigger on a channel it is not sampling, so it
would simply never fire.
Verified on hardware against a UART source emitting one frame per ~10 ms,
captured in a 2 ms window: untriggered caught the frame in 1 of 5 runs,
--trigger 1=r caught it in 3 of 3 with correct framing.
seasonyuu
left a comment
There was a problem hiding this comment.
Review findings
I found two issues worth addressing:
[P1] Clean up the capture session when trigger setup fails
crates/dsview-core/src/lib.rs:2673 calls apply_trigger() after the device has been opened, streaming VCD has started, and acquisition callbacks have been registered. If any trigger FFI call fails, the ? return bypasses the cleanup path below, so callbacks and the temporary streaming output can remain active. Please handle this error like a start failure by calling session.cleanup(&self.runtime, true) and aborting streaming VCD before returning.
[P2] Report coercions for all device options
crates/dsview-cli/src/main.rs:3054-3092 only compares sample rate, sample limit, enabled channels, and channel mode. CaptureDeviceOptionSnapshot also contains operation_mode_id, stop_option_id, threshold_volts, and filter_id; coercions in those fields are currently silent. The PR description says setting mismatches are reported on stderr and in warnings, so these fields should be compared too (with an appropriate float comparison for threshold voltage).
The new trigger parsing/programming path also has no focused tests for parsing, position validation, or cleanup on FFI failure. cargo test --workspace could not complete in this environment because pkg-config --cflags glib-2.0 is unavailable.
I found no separate repository standards violations.
Six commits from getting a PGL12-revision DSLogic Plus working headlessly. Each
builds on its own, and the whole branch is verified on hardware.
Happy to split this into separate PRs if you would rather review the device
support, the trigger work and the UX changes independently — the commits are
already cut along those lines.
Device support (closes #11)
patches: add DSLogic Plus / U2Basic PGL12-2 device profilesA DSLogic Plus with PID
0x0034is not detected: the pinned submodule'sprofile table stops at
0x0030. The submodule already ships the bitstreamthe
0x0034profile refers to —DSView/res/DSLogicPlus-pgl12-2.binisbyte-identical (blob
ce921c35) to the one in DSView master — so only the tableentry is missing and no submodule bump is needed. A bump would pull in 94 files
and ~8 months of unrelated churn to fix a lookup table; this is 55 additive
lines.
patches: security check pass is not an errorDSView logs the successful security-check branch with
sr_err(). It is gatedon
CAPS_FEATURE_SECURITY, which the PGL12 profiles set, so affected boardsprint three spurious error lines per capture that survive any log-level setting.
Triggers
feat(sys): bind ds_log_level and ds_trigger_* from the DSView runtimefeat(capture): simple trigger supportThe runtime exports a complete simple-trigger API and none of it was reachable.
This wires it through:
Two review notes:
just before
start_collect(). Putting it inapply_capture_config()silentlyskips every capture that passes device options, because those go through
apply_device_options()instead. That failure mode is indistinguishable froma trigger that does not work, and it cost me a debugging cycle.
first.
A trigger naming a channel
--channelsdoes not enable is rejected up front,since the device cannot trigger on a channel it is not sampling.
Usability
feat(cli): quiet the native logger by default, add --log-levelEvery command printed 14 lines of scan chatter to stderr. libsigrok4DSL defaults
to
infoand nothing lowered it. Now defaults towarn, with--log-leveltoraise it. The level must be set between loading the library and
init()— thescan happens inside
init(), so setting it afterwards suppresses nothing.feat(cli): surface unsupported devices, coerced settings, and size the waitdevices listreturned empty + exit 0 whether nothing was plugged in or anunsupported DreamSourceLab device was present. The native scan logs the skip
at
info, so quieting the logger hid the only clue. The bus is now probedseparately (Linux/sysfs) and the difference reported with a non-zero exit. An
empty bus still exits 0.
internal-testturnsa requested 1 MHz into 100 MHz. Mismatches are now reported on stderr and in a
warningsarray. Buffer alignment (200000 → 200704) is within a 1% toleranceand stays quiet, because a warning that always fires is one nobody reads.
--wait-timeout-msdefaulted to a flat 10 s, which aborts large capturesmid-flight. Default
0now derives it from sample rate and limit.Verification
Hardware: DSLogic Plus
2a0e:0034(PGL12), Ubuntu 24.04, rustc 1.98.1.Stimulus: a Trion T20 FPGA driving known UART / SPI / I2C / counter patterns.
cargo test --workspace: 285 passed, 0 failedHello LA!\r\n,SPI MOSI
A5 3C 00 FF/ MISO5A C3 FF 00, I2CStart, Addr 42, ACK, DE, ACK, AD, ACK, Stop, and the device's internal test pattern as an exactbinary counter
2 ms window: untriggered caught the frame in 1 of 5 runs;
--trigger 1=rcaught it in 3 of 3 with correct framing
and rebuilding, which reproduces the original empty-list failure and now
reports
devices_present_but_unsupportedwith exit 1Known limitation
feat(sys)binds both the trigger and log-level symbols in one commit. Myadditions to
bridge_runtime.care textually interleaved and cannot be split byhunk; separating them means editing the C file rather than re-staging. Say the
word if you want that split.