doc: document Digilent backend and probe-open by index
CLAUDE.md/README/tutorial: optional BS_ENABLE_DIGILENT backend, why SMT2 modules need libdjtg, and the new jtag_open_probe index. Mark phases 2 and 2.5 done.
This commit is contained in:
25
CLAUDE.md
25
CLAUDE.md
@@ -28,7 +28,7 @@ modules/ — Viveris's library (LGPL, unchanged) —
|
|||||||
├── jtag_core/ TAP state machine, IR/DR shifts
|
├── jtag_core/ TAP state machine, IR/DR shifts
|
||||||
├── bsdl_parser/ .bsd loader
|
├── bsdl_parser/ .bsd loader
|
||||||
├── bus_over_jtag/ SPI/I²C/MDIO/parallel mem bit-bang over EXTEST
|
├── bus_over_jtag/ SPI/I²C/MDIO/parallel mem bit-bang over EXTEST
|
||||||
├── drivers/ FTDI, J-Link, Linux GPIO, LPT
|
├── drivers/ FTDI, J-Link, Linux GPIO, LPT, Digilent (optional)
|
||||||
├── script/ Script engine (40+ commands, the real UI)
|
├── script/ Script engine (40+ commands, the real UI)
|
||||||
├── config/ Built-in config.script
|
├── config/ Built-in config.script
|
||||||
├── os_interface/ Portable fs/network wrappers
|
├── os_interface/ Portable fs/network wrappers
|
||||||
@@ -49,8 +49,8 @@ Adding a feature usually means adding a new script command in
|
|||||||
| Phase | Module | Status | Summary |
|
| Phase | Module | Status | Summary |
|
||||||
|-------|--------|--------|---------|
|
|-------|--------|--------|---------|
|
||||||
| 1 | `bs/` cleanup, REPL polish, README | **done** (commit `7cb3627`) | Fix format-strings, delete dead code, tab-completion, banner |
|
| 1 | `bs/` cleanup, REPL polish, README | **done** (commit `7cb3627`) | Fix format-strings, delete dead code, tab-completion, banner |
|
||||||
| 2 | `fpga/` | planned | Per-target descriptor (IDCODE, BSDL, IR codes, proxy path, quirks). Compile-time registry. |
|
| 2 | `fpga/` | **done** (commit `545fe09`) | Per-target descriptor (IDCODE, BSDL, IR codes, proxy path, quirks). Compile-time registry. |
|
||||||
| 2.5 | `bscan_spi/` | planned | Load BSCAN proxy bitstream via `CFG_IN`, expose fast `bscan_spi_xfer()` via `USER1`. Required for realistic flashing speeds. |
|
| 2.5 | `bscan_spi/` | **done** (commit `dec0d14`) | Load BSCAN proxy bitstream via `CFG_IN`, expose fast `bscan_spi_xfer()` via `USER1`. Required for realistic flashing speeds. |
|
||||||
| 3 | `spi_flash/` | planned | Chip database (JEDEC ID → page/sector/cmd set). Generic `read/erase/program/verify` over either backend. |
|
| 3 | `spi_flash/` | planned | Chip database (JEDEC ID → page/sector/cmd set). Generic `read/erase/program/verify` over either backend. |
|
||||||
| 4 | script commands | planned | `flash_detect`, `flash_read/write/erase/verify`. |
|
| 4 | script commands | planned | `flash_detect`, `flash_read/write/erase/verify`. |
|
||||||
|
|
||||||
@@ -92,6 +92,21 @@ derived from the BSDL alone:
|
|||||||
Registry is a compile-time array. Adding a part = one entry + its
|
Registry is a compile-time array. Adding a part = one entry + its
|
||||||
`.bsd` in `bsdl_files/` + its proxy `.bit` in `bscan_proxies/`.
|
`.bsd` in `bsdl_files/` + its proxy `.bit` in `bscan_proxies/`.
|
||||||
|
|
||||||
|
### Digilent SMT2 modules need libdjtg, not raw MPSSE
|
||||||
|
|
||||||
|
Several Xilinx dev boards (KCU105, ZCU102, …) embed a Digilent
|
||||||
|
JTAG-SMT2 / SMT2-NC for USB-JTAG. Even though it presents a stock
|
||||||
|
FTDI FT232H over USB (VID:PID 0403:6014), it runs a proprietary
|
||||||
|
firmware that **does not respond to plain MPSSE commands** — TCK
|
||||||
|
toggles but the level-shifters/buffers stay disabled, so TDO floats
|
||||||
|
high ("all ones" symptom). Standard FTDI driver path is dead on these
|
||||||
|
boards.
|
||||||
|
|
||||||
|
Workaround: `modules/drivers/digilent_jtag/` wraps libdjtg/libdmgr
|
||||||
|
(Digilent Adept Runtime). Built only when `-DBS_ENABLE_DIGILENT=ON`,
|
||||||
|
loaded via `dlopen` at runtime — no Digilent binary or header in the
|
||||||
|
repo. End-user just needs the Adept Runtime package installed.
|
||||||
|
|
||||||
### Xilinx caveats
|
### Xilinx caveats
|
||||||
|
|
||||||
On 7-Series / UltraScale / UltraScale+, `CCLK` is not a regular I/O
|
On 7-Series / UltraScale / UltraScale+, `CCLK` is not a regular I/O
|
||||||
@@ -123,6 +138,10 @@ mkdir build && cd build && cmake .. && make
|
|||||||
./bs/bs # interactive REPL
|
./bs/bs # interactive REPL
|
||||||
```
|
```
|
||||||
|
|
||||||
|
For Digilent SMT2-based boards, configure with
|
||||||
|
`cmake -DBS_ENABLE_DIGILENT=ON ..` and install the Adept Runtime
|
||||||
|
system-wide (provides `libdjtg.so` + `libdmgr.so`).
|
||||||
|
|
||||||
No automated tests yet. Smoke test = banner appears, `exit` works.
|
No automated tests yet. Smoke test = banner appears, `exit` works.
|
||||||
After changes touching `jtag_core`, `drivers/ftdi_jtag`, or the
|
After changes touching `jtag_core`, `drivers/ftdi_jtag`, or the
|
||||||
`autoinit` flow, manual hardware test required: probe + KU15P board
|
`autoinit` flow, manual hardware test required: probe + KU15P board
|
||||||
|
|||||||
25
README.md
25
README.md
@@ -10,7 +10,7 @@ library by Viveris (LGPL).
|
|||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
- JTAG chain detection through FTDI / J-Link / Linux GPIO probes: OK
|
- JTAG chain detection through FTDI / J-Link / Linux GPIO / Digilent SMT2 probes: OK
|
||||||
- Automatic BSDL loading by IDCODE: OK
|
- Automatic BSDL loading by IDCODE: OK
|
||||||
- Pin control in SAMPLE / EXTEST: OK
|
- Pin control in SAMPLE / EXTEST: OK
|
||||||
- SPI bit-bang on 4 FPGA pins (MOSI/MISO/CS/CLK): OK (low-level primitive)
|
- SPI bit-bang on 4 FPGA pins (MOSI/MISO/CS/CLK): OK (low-level primitive)
|
||||||
@@ -26,6 +26,11 @@ in `bsdl_files/`.
|
|||||||
- CMake ≥ 3.10, gcc/clang
|
- CMake ≥ 3.10, gcc/clang
|
||||||
- `readline` (Arch: `readline`, Debian/Ubuntu: `libreadline-dev`)
|
- `readline` (Arch: `readline`, Debian/Ubuntu: `libreadline-dev`)
|
||||||
- `libftd2xx` for FTDI probes (vendored in `libs/libftd2xx/`)
|
- `libftd2xx` for FTDI probes (vendored in `libs/libftd2xx/`)
|
||||||
|
- *Optional, for Digilent SMT2/SMT2-NC boards:* the Digilent
|
||||||
|
[Adept Runtime](https://digilent.com/shop/software/digilent-adept/)
|
||||||
|
installed system-wide (provides `libdjtg.so` + `libdmgr.so`).
|
||||||
|
Nothing from Digilent is vendored — the backend is `dlopen`'d at
|
||||||
|
runtime.
|
||||||
|
|
||||||
## Build
|
## Build
|
||||||
|
|
||||||
@@ -37,6 +42,12 @@ make
|
|||||||
|
|
||||||
The binary is produced at `build/bs/bs`.
|
The binary is produced at `build/bs/bs`.
|
||||||
|
|
||||||
|
To enable the Digilent SMT2 backend:
|
||||||
|
|
||||||
|
```sh
|
||||||
|
cmake -DBS_ENABLE_DIGILENT=ON ..
|
||||||
|
```
|
||||||
|
|
||||||
## Run
|
## Run
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -59,9 +70,10 @@ list of variables.
|
|||||||
## Typical flow
|
## Typical flow
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
# 1. Open a probe (1 = first detected probe)
|
# 1. List probes, then open one by its index (the [N] in the list)
|
||||||
bs_explorer> jtag_get_probes_list
|
bs_explorer> jtag_get_probes_list
|
||||||
bs_explorer> jtag_open_probe 1
|
[0] 0x00000000 <probe description>
|
||||||
|
bs_explorer> jtag_open_probe 0 # or the raw 0x id shown next to it
|
||||||
|
|
||||||
# 2. Scan the chain and auto-load BSDL files
|
# 2. Scan the chain and auto-load BSDL files
|
||||||
bs_explorer> jtag_autoinit
|
bs_explorer> jtag_autoinit
|
||||||
@@ -102,6 +114,11 @@ Use `help <command>` for per-command help.
|
|||||||
in `modules/config/config.script` for pin mapping and TCK frequency.
|
in `modules/config/config.script` for pin mapping and TCK frequency.
|
||||||
- **SEGGER J-Link**
|
- **SEGGER J-Link**
|
||||||
- **Linux GPIO** (sysfs; deprecated on recent kernels, libgpiod migration TBD)
|
- **Linux GPIO** (sysfs; deprecated on recent kernels, libgpiod migration TBD)
|
||||||
|
- **Digilent JTAG-SMT2 / SMT2-NC** — optional, built when
|
||||||
|
`-DBS_ENABLE_DIGILENT=ON`. Required for the USB-JTAG on Xilinx eval
|
||||||
|
boards like the KCU105: those modules ship a Digilent-proprietary
|
||||||
|
firmware that does not respond to plain MPSSE, so the FTDI driver
|
||||||
|
appears to enumerate them but the JTAG chain stays silent.
|
||||||
|
|
||||||
## Known Xilinx caveats
|
## Known Xilinx caveats
|
||||||
|
|
||||||
@@ -121,7 +138,7 @@ modules/
|
|||||||
├── jtag_core/ TAP state machine, IR/DR shifts
|
├── jtag_core/ TAP state machine, IR/DR shifts
|
||||||
├── bsdl_parser/ .bsd loader
|
├── bsdl_parser/ .bsd loader
|
||||||
├── bus_over_jtag/ SPI / I²C / MDIO / parallel mem bit-bang
|
├── bus_over_jtag/ SPI / I²C / MDIO / parallel mem bit-bang
|
||||||
├── drivers/ FTDI, J-Link, Linux GPIO, LPT
|
├── drivers/ FTDI, J-Link, Linux GPIO, LPT, Digilent (optional)
|
||||||
├── script/ Script engine (40+ commands)
|
├── script/ Script engine (40+ commands)
|
||||||
├── config/ Built-in config.script
|
├── config/ Built-in config.script
|
||||||
├── os_interface/ Portable fs/network wrappers
|
├── os_interface/ Portable fs/network wrappers
|
||||||
|
|||||||
@@ -17,6 +17,12 @@ the IDCODE and BSDL filename change.
|
|||||||
- For SPI flashing, eventually: a BSCAN proxy bitstream — see the
|
- For SPI flashing, eventually: a BSCAN proxy bitstream — see the
|
||||||
[Phase 2.5 caveat](#phase-25-bscan-proxy) at the end.
|
[Phase 2.5 caveat](#phase-25-bscan-proxy) at the end.
|
||||||
|
|
||||||
|
If your board uses a Digilent JTAG-SMT2 / SMT2-NC module (KCU105,
|
||||||
|
ZCU102, …), you need the optional Digilent backend: install the Adept
|
||||||
|
Runtime system-wide and configure with `cmake -DBS_ENABLE_DIGILENT=ON
|
||||||
|
..`. Plain MPSSE does not work on those modules — see the README and
|
||||||
|
the `Digilent SMT2` block in `CLAUDE.md` for the why.
|
||||||
|
|
||||||
## Build & launch
|
## Build & launch
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -45,17 +51,21 @@ Ctrl-D or `exit` quits.
|
|||||||
|
|
||||||
```
|
```
|
||||||
bs_explorer> jtag_get_probes_list
|
bs_explorer> jtag_get_probes_list
|
||||||
|
[0] 0x00000000 Digilent USB Device 210308AB06A6
|
||||||
|
[1] 0x00000300 Digilent: JtagSmt2NC
|
||||||
```
|
```
|
||||||
|
|
||||||
Lists each probe the loaded drivers can see. With an FTDI cable
|
Open a probe by the index in brackets:
|
||||||
plugged in, you should get at least one entry. Pick its index (1-based
|
|
||||||
in the output) and open it:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
bs_explorer> jtag_open_probe 1
|
bs_explorer> jtag_open_probe 1
|
||||||
```
|
```
|
||||||
|
|
||||||
If `jtag_open_probe` fails: check `lsusb` for the FTDI VID:PID, make
|
The `0x…` value next to each index is the raw probe id and is also
|
||||||
|
accepted (`jtag_open_probe 0x300`) — handy in scripts where you'd
|
||||||
|
rather pin the exact backend than rely on enumeration order.
|
||||||
|
|
||||||
|
If `jtag_open_probe` fails: check `lsusb` for the probe VID:PID, make
|
||||||
sure the user has access to the USB device (udev rule or group), and
|
sure the user has access to the USB device (udev rule or group), and
|
||||||
confirm no other process holds the probe (e.g. `openocd`).
|
confirm no other process holds the probe (e.g. `openocd`).
|
||||||
|
|
||||||
@@ -103,7 +113,7 @@ the BSDL state (so `jtag_core` doesn't fight us on IR caching) and
|
|||||||
shift IDCODE manually:
|
shift IDCODE manually:
|
||||||
|
|
||||||
```
|
```
|
||||||
bs_explorer> jtag_open_probe 1
|
bs_explorer> jtag_open_probe 0 # index from jtag_get_probes_list
|
||||||
bs_explorer> jtag_init_scan # detects devices, does NOT load BSDL
|
bs_explorer> jtag_init_scan # detects devices, does NOT load BSDL
|
||||||
bs_explorer> bscan_set_ir 9 6 # IDCODE opcode (KU15P: 0x09, IR=6 bits)
|
bs_explorer> bscan_set_ir 9 6 # IDCODE opcode (KU15P: 0x09, IR=6 bits)
|
||||||
bs_explorer> bscan_shift_dr 32
|
bs_explorer> bscan_shift_dr 32
|
||||||
@@ -215,7 +225,7 @@ end-to-end.
|
|||||||
|---------|--------------|
|
|---------|--------------|
|
||||||
| `jtag_get_probes_list` returns nothing | FTDI not enumerated. Check `lsusb`, udev permissions, conflicting process. |
|
| `jtag_get_probes_list` returns nothing | FTDI not enumerated. Check `lsusb`, udev permissions, conflicting process. |
|
||||||
| `jtag_autoinit` finds 0 devices | TDI/TDO swap, TRST held low, voltage mismatch, or chain broken. |
|
| `jtag_autoinit` finds 0 devices | TDI/TDO swap, TRST held low, voltage mismatch, or chain broken. |
|
||||||
| All IDCODEs read `0xFFFFFFFF` | TDO floats high — broken TDO link or wrong voltage reference. |
|
| All IDCODEs read `0xFFFFFFFF` | TDO floats high — broken TDO link, wrong voltage reference, or a Digilent SMT2 module being driven via raw FTDI MPSSE (use the Digilent backend instead). |
|
||||||
| All IDCODEs read `0x00000000` | TDO tied low or no clock reaching the target. |
|
| All IDCODEs read `0x00000000` | TDO tied low or no clock reaching the target. |
|
||||||
| `fpga_info` says "not in registry" | Add the part to `fpga_registry[]`. |
|
| `fpga_info` says "not in registry" | Add the part to `fpga_registry[]`. |
|
||||||
| `bscan_shift_dr 32` doesn't return the expected IDCODE | Wrong IR opcode/length, wrong device index, or a multi-device chain (current primitives assume single device). |
|
| `bscan_shift_dr 32` doesn't return the expected IDCODE | Wrong IR opcode/length, wrong device index, or a multi-device chain (current primitives assume single device). |
|
||||||
|
|||||||
Reference in New Issue
Block a user