francois bbb99ba35c add CLAUDE.md with project guide
Durable project context (architecture, roadmap, key decisions, external
references, commit conventions) so any Claude Code session on any
machine has the same baseline understanding. Machine-local facts stay
out of the repo, in ~/.claude/.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-20 22:41:13 +02:00
2025-02-18 11:36:18 +01:00
2026-05-20 22:22:05 +02:00
2025-02-18 15:40:58 +01:00
2025-02-16 12:39:24 +01:00
2025-02-18 15:40:58 +01:00
2025-02-18 15:40:58 +01:00
2025-02-12 12:37:38 +01:00
2026-05-20 22:41:13 +02:00
2025-02-18 11:36:18 +01:00
2025-02-11 22:21:56 +01:00
2026-05-20 22:26:35 +02:00

bs_explorer — Boundary Scan Explorer

Command-line tool to explore a JTAG chain, drive an FPGA's pins through boundary scan (BSDL), and — eventually — program SPI memories attached to the FPGA (Xilinx and others) by bit-banging SPI on I/O pins placed in EXTEST.

Based on the jtag-boundary-scanner library by Viveris (LGPL).

Status

  • JTAG chain detection through FTDI / J-Link / Linux GPIO probes: OK
  • Automatic BSDL loading by IDCODE: OK
  • Pin control in SAMPLE / EXTEST: OK
  • SPI bit-bang on 4 FPGA pins (MOSI/MISO/CS/CLK): OK (low-level primitive)
  • SPI flash programming (JEDEC detect, erase, page program, verify): planned
  • Multi-FPGA abstraction (per-target pin → flash mapping): planned

Only one BSDL is bundled so far: Xilinx Kintex UltraScale+ KU15P (bsdl_files/xcku15p_ffve1517.bsd). Add more by dropping .bsd files in bsdl_files/.

Dependencies

  • CMake ≥ 3.10, gcc/clang
  • readline (Arch: readline, Debian/Ubuntu: libreadline-dev)
  • libftd2xx for FTDI probes (vendored in libs/libftd2xx/)

Build

mkdir build && cd build
cmake ..
make

The binary is produced at build/bs/bs.

Run

cd build
./bs/bs

At startup, bs_explorer looks for a config.script file in the current directory to override default settings (FTDI clock, TRST/SRST pin mapping, etc.). See modules/config/config.script for the full list of variables.

REPL

  • <Tab> completes command names.
  • History handled by GNU readline (up/down arrows, Ctrl-R, …).
  • help or ? lists commands; help <cmd> shows details.
  • exit, quit, or Ctrl-D to leave.

Typical flow

# 1. Open a probe (1 = first detected probe)
bs_explorer> jtag_get_probes_list
bs_explorer> jtag_open_probe 1

# 2. Scan the chain and auto-load BSDL files
bs_explorer> jtag_autoinit

# 3. Switch device 0 to EXTEST (direct pin control)
bs_explorer> jtag_set_mode 0 EXTEST

# 4. Wire the 4 SPI pins onto the FPGA's BSDL pins
#    (exact names depend on the loaded BSDL)
bs_explorer> jtag_set_spi_cs_pin   0 <PIN_CS>   0
bs_explorer> jtag_set_spi_clk_pin  0 <PIN_CLK>  0
bs_explorer> jtag_set_spi_mosi_pin 0 <PIN_MOSI> 0
bs_explorer> jtag_set_spi_miso_pin 0 <PIN_MISO> 0

# 5. Read the flash JEDEC ID (0x9F + 3 dummies)
bs_explorer> jtag_spi_rd_wr 9F000000

A minimal example script is provided in scripts/example_script.txt.

Main commands

Category Commands
Script control set, print, print_env_var, if, goto, call, return, rand, init_array, system, pause
Probe / chain jtag_get_probes_list, jtag_open_probe, jtag_init_scan, jtag_autoinit, jtag_get_nb_of_devices, jtag_get_devices_list
BSDL / pins jtag_load_bsdl, jtag_get_pins_list, jtag_set_mode, jtag_set_pin_dir, jtag_set_pin_state, jtag_get_pin_state, jtag_push_pop
I²C / MDIO / SPI over BS pins jtag_set_i2c_*_pin, jtag_i2c_rd, jtag_i2c_wr, jtag_set_mdio_*_pin, jtag_mdio_rd, jtag_mdio_wr, jtag_set_spi_*_pin, jtag_spi_rd_wr
Misc help, ?, version, exit

Use help <command> for per-command help.

Supported probes

  • FTDI MPSSE (FT2232D/H, FT4232H, …) — see the PROBE_FTDI_* block in modules/config/config.script for pin mapping and TCK frequency.
  • SEGGER J-Link
  • Linux GPIO (sysfs; deprecated on recent kernels, libgpiod migration TBD)

Known Xilinx caveats

On 7-Series / UltraScale / UltraScale+, CCLK is not a regular I/O pin and goes through the STARTUPE3 primitive, so it cannot be driven directly in EXTEST. Known workarounds:

  • use the private ISC_DISABLE instruction;
  • route the SPI clock through another user pin of the FPGA.

To be handled when the FPGA abstraction layer is added.

Repository layout

bs/                  Application (readline REPL)
modules/
├── jtag_core/       TAP state machine, IR/DR shifts
├── bsdl_parser/     .bsd loader
├── bus_over_jtag/   SPI / I²C / MDIO / parallel mem bit-bang
├── drivers/         FTDI, J-Link, Linux GPIO, LPT
├── script/          Script engine (40+ commands)
├── config/          Built-in config.script
├── os_interface/    Portable fs/network wrappers
└── natsort/         Natural-order pin-name sorting
bsdl_files/          BSDL files for target FPGAs
scripts/             Example scripts
libs/libftd2xx/      Vendored FTDI SDK

License

modules/jtag_core/ and the original Viveris files are under LGPL 2.1. See LICENSE and modules/jtag_core/COPYING.LESSER.

Description
No description provided
Readme LGPL-2.1 2 MiB
Languages
C 98.7%
CMake 1.3%