One clock knob across probes instead of per-driver names:
- jtag_open mirrors JTAG_TCK_FREQ_KHZ into PROBE_FTDI_TCK_FREQ_KHZ for
the Viveris FTDI driver (read-only at init); unset leaves the existing
value untouched
- the Digilent driver reads JTAG_TCK_FREQ_KHZ directly instead of
hardcoding 4 MHz (falls back to 4 MHz when unset)
- documented in probes.yaml; CLAUDE.md design note marks phase A done
FTDI path validated on the IGLOO2/FlashPro (250 kHz, mirror confirmed);
Digilent path not hardware-tested.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The TX/TXRX functions used fixed ~1-2 KB stack buffers and rejected
anything larger, so any big shift failed: bscan_idle_cycles(10000) and
above all the ~19 Mbit bitstream load for the BSCAN proxy. Size the
pack/capture buffers to the shift on the heap instead.
This is what unblocked the proxy load — see next commit.
Drop the get_/set_/_pin/_list noise from the JTAG commands (e.g.
jtag_get_probes_list -> jtag_probes, jtag_set_spi_cs_pin -> jtag_spi_cs,
jtag_spi_rd_wr -> jtag_spi_xfer). jtag_open_probe -> jtag_open (not
jtag_probe, which would clash with jtag_probes under tab-completion).
Hard rename, no aliases. Updates the state-dump emitter, help text,
example script and docs accordingly.
DmgrEnumDevices builds an internal device table that must be released
with DmgrFreeDvcEnum, otherwise a second enumeration (e.g. opening a
probe by index, which re-runs Detect) fails.
TMS-only shifts go through DjtgPutTmsBits with TDI held to 0. Pure data
shifts use DjtgPutTdiBits with TMS held to 0. Mixed shifts (e.g. last
bit of Shift-IR/DR with TMS=1) fall back to DjtgPutTmsTdiBits — note
that within each pair the encoding is TDI(low) then TMS(high),
LSB-first, despite the function name (verified against the SDK
DjtgDemo sample).
Init also gained a lazy call to Detect: jtag_open_probe can be invoked
without first running jtag_get_probes_list.
Validated on KCU105: jtag_autoinit returns IDCODE 0x13822093
(XCKU040 rev1) through the Digilent SMT2-NC.
DmgrOpen + DjtgEnable + DjtgSetSpeed at 4 MHz (Adept rounds to the
nearest supported, e.g. 3.75 MHz on SMT2-NC). DeInit does the reverse.
An atexit hook also forces Close on process shutdown — leaving an open
HIF when libdjtg's C++ static destructors run triggers "pure virtual
method called".
Loads the Adept .so files lazily and resolves the symbols we need.
Detect() enumerates devices via DmgrEnumDevices/DmgrGetDvc and exposes
each as a Viveris probe slot. If Adept Runtime is missing, the driver
silently reports 0 probes.