Skip to content

Packaging, CLI and MCP agent#899

Open
nmenon wants to merge 4 commits intoDreamSourceLab:masterfrom
nmenon:nm-package-deb-cli-mcp
Open

Packaging, CLI and MCP agent#899
nmenon wants to merge 4 commits intoDreamSourceLab:masterfrom
nmenon:nm-package-deb-cli-mcp

Conversation

@nmenon
Copy link

@nmenon nmenon commented Mar 16, 2026

Add a CLI, MCP Agent and debian packaging option

nmenon added 4 commits May 29, 2025 11:15
Signed-off-by: Nishanth Menon <nm@ti.com>
Add a headless CLI bridge (dsview-cli) and Python MCP server
(dsview_mcp.py) that expose DreamSourceLab USB instruments -- logic
analyzers (DSLogic) and oscilloscopes (DSCope) -- as Model Context
Protocol tools for AI-assisted hardware debugging.

The C bridge (dsview_cli.c) links against the existing libsigrok4DSL
sources and provides three subcommands:
  - scan:    enumerate connected USB instruments
  - info:    query device capabilities, channel modes, analog config
  - capture: record logic or DSO waveforms to binary files with
             JSON metadata sidecars

The Python MCP server wraps the CLI and exposes seven tools:
  - scan_devices / device_info: instrument discovery
  - capture_logic: digital capture with triggers, named channels,
    voltage threshold, duration mode, and .sr/.vcd/.csv export
  - capture_dso: analog capture with per-channel vdiv, coupling,
    probe factor, hardware trigger, and voltage export
  - signal_summary: per-channel activity report with Nyquist hints
  - decode_capture / decode_analog: per-sample waveform analysis

Key features:
  - Multi-device support (logic analyzer + oscilloscope simultaneously)
  - Device-busy detection when GUI holds the USB handle
  - Samplerate optimization hints based on measured signal frequency
  - I2C/SPI/UART protocol decode via sigrok .sr export path
  - Analog timing compliance analysis (rise/fall time at VIL/VIH)

Logic analyzer channel mode and data format handling:
  - Auto-select the smallest hardware channel mode that fits the
    requested channels (e.g. 3-channel mode for 2 channels), which
    also unlocks higher samplerates (500MHz/6ch, 1GHz/3ch)
  - Handle LA_CROSS_DATA format from the FPGA: the DSLogic sends
    data interleaved at 64-bit boundaries per enabled channel rather
    than parallel bit-per-sample.  cross_to_parallel() in the datafeed
    callback converts to standard parallel format for sigrok and the
    MCP Python layer.

Build integration: cli/CMakeLists.txt builds dsview-cli alongside the
GUI; the top-level CMakeLists.txt includes it via add_subdirectory().

Tested with DSLogic U3Pro16 (16-ch logic analyzer) and DSCope U3P100
(2-ch oscilloscope).  I2C decode verified byte-identical between
LA+sigrok and DSO+VIL/VIH analog decode paths.

Assisted-By: Claude Opus 4.6 <noreply@anthropic.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
Both tools previously hardcoded a 180-second timeout for the
dsview-cli subprocess. The timeout is now a user-controllable
parameter (default 180s) so callers can increase it when waiting for
infrequent trigger events.

Assisted-By: Claude Sonnet <noreply@anthropic.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
Three bugs caused CLI logic-analyzer captures to corrupt after ~10ms
while the DSView GUI captured correctly:

1. cross_to_parallel() dropped partial groups when USB bulk transfers
   or receive_transfer() truncation delivered data not aligned to
   nch*8 byte boundaries. Add a static leftover buffer that accumulates
   partial groups across callbacks, matching the GUI's
   append_cross_payload() behavior in logicsnapshot.cpp.

2. The CLI only enabled user-requested channels, but the FPGA packs
   cross-format data for ALL enabled channels. When the hardware mode
   provides more channels than requested, the FPGA sends data for the
   full mode width. Enable all channels in the selected mode range
   (matching GUI behavior) and use g_hw_nch for unitsize and header.

3. Mode selection used only the count of enabled channels, ignoring
   their indices. For non-contiguous channels (e.g. 0,3,7 = 3 channels
   but max index 7), the mode must cover the highest index. Use
   max(channel_count, max_channel_index+1) for mode selection.

Tested with DSLogic U3Pro16 across all four channel modes (3, 6, 12,
16 channels) with static signals and triggered JTAG captures. No
spurious inversions observed.

Assisted-By: Claude Opus <noreply@anthropic.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant