ArtInChip cJTAG / JTAG Board Debugging: FT232H, OpenOCD and GDB
This article documents a board-verified ArtInChip (匠芯创) D125 E907 / FT232H / SiFive OpenOCD 2020.11.0 connection, with configuration, captured logs and a GDB attach guide. The project confirms physical-board validation of the cJTAG connection: D0 → PA11 (TCKC), D1/D2 → PA10 (TMSC).
This article covers D125 two-wire cJTAG and D213 four-wire JTAG. The board-validation claim and captured log apply to D125; the D213 section is based on the supplied D21x configuration, not a reused D125 test result.
Scope
The project confirms that the cJTAG wiring and OpenOCD connection were tested on hardware; the logs record IDCODE/DTMCS reads and CPU examination. This does not establish validation of every step in the added GDB guide. This setup uses the two-wire mode enabled by ftdi_oscan1_mode on, not ordinary four-wire JTAG. Other OpenOCD builds or FTDI modules are not automatically compatible.
D125: cJTAG hardware connections
D125 pins
The supplied excerpt from the official D125 datasheet lists two pin groups using mux function 8. Select one group according to board routing and firmware pinmux; do not connect both groups simultaneously. Package pin numbers below are not board header numbers.
| cJTAG signal | MCU pin | D125CxS package pin | D125ExS package pin |
|---|---|---|---|
| JTAG_MS / TMSC | PA10 | 79 | 53 |
| JTAG_CK / TCKC | PA11 | 80 | 54 |
| JTAG_MS / TMSC (alternative) | PC0 | 61 | 23 |
| JTAG_CK / TCKC (alternative) | PC5 | 66 | 28 |
FT232H wiring
| FT232H signal | Connection | Purpose |
|---|---|---|
| D0 / ADBUS0 | D125 JTAG_CK: PA11 or PC5 | Debug clock output |
| D1 / ADBUS1 | D125 JTAG_MS: PA10 or PC0 | Data output from FT232H to target |
| D2 / ADBUS2 | Same JTAG_MS node | Data input to FT232H from target |
| GND | D125 GND | Common ground |
In this setup, D1 and D2 are tied at the same JTAG_MS node. Use D0 → PA11 and D1/D2 → PA10 for the PA group, or D0 → PC5 and D1/D2 → PC0 for the PC group.
Wiring correction
The earlier text reversed the PA10/PA11 clock and data assignments. It now correctly states PA11 for clock and PA10 for data. The project confirms physical-board validation of cJTAG debugging; this documentation correction should not be described as an untested connection. Other packages, the PC pin group and different adapters still require hardware-specific checks.
Do not connect D0 and the D1/D2 pair to the same pin. The D1/D2 tie is specific to this adapter and driver mode, not a general JTAG wiring rule.
Power off before wiring. Verify the module's VCCIO and signal levels against the target IO domain. USB supply voltage is not the IO voltage; do not apply 5 V to debug signals or connect an adapter power output without checking the board power design. Power the target normally.
The retained TMS and JTAG_SEL layout definitions do not instruct you to wire D3 or JTAG_SEL to the target JTAG_MS or JTAG_CK. Check the adapter schematic and driver implementation before changing hardware.
Windows prerequisite: install WinUSB for FT232H
Install WinUSB for this FT232H before starting OpenOCD. This prerequisite applies to both D125 cJTAG and D213 JTAG. Skip replacement if WinUSB is already correctly installed.
- Close applications using the adapter, connect it and run Zadig, accepting the administrator prompt.
- If the device is hidden, enable Options → List All Devices.
- Identify the actual FT232H. The screenshot shows
USB <-> Serial Converterwith USB ID 0403 / 6014, matching these configurations. Names vary; use reconnecting or serial identification when several devices are attached. - Select WinUSB as the replacement driver. The screenshot shows FTDIBUS as the existing driver and Replace Driver; a device without a driver may show Install Driver.
- Wait for success and verify that the current driver is WinUSB before launching OpenOCD.

This project screenshot shows installation in progress, not completion. Its software versions document that environment rather than a required version.
Select only the intended adapter
Do not replace drivers for keyboards, mice, hubs or unrelated serial devices. Software relying on the original FTDI driver may lose access; restore the matching FTDI driver to return to that use. This adapter is FT232H, not an arbitrary device labeled FT232.
Reference: official Zadig user guide.
D125 OpenOCD configuration
Save as openocd-d125-ft232h.cfg, or download the configuration.
The configuration is updated from the supplied tmp/openocd-d125-ft232h.cfg, preserving parameters and comments. Both downloads use bindto 0.0.0.0, listening on all network interfaces. Use an isolated, trusted network; for local debugging change it to bindto 127.0.0.1. Prefer an SSH tunnel for remote access rather than exposing debug ports.
# D125 E907 + FT232H,SiFive OpenOCD 2020.11.0。
# 目标走 cJTAG OSCAN1,不是四线 IEEE 1149.1。引脚布局仅适用于当前这块适配器。
adapter driver ftdi
ftdi_vid_pid 0x0403 0x6014
ftdi_channel 0
# 多块 FTDI 同时在线时,取消下一行注释并填入序列号。
# ftdi_serial "YOUR_FT232H_SERIAL"
ftdi_oscan1_mode on
transport select jtag
# ADBUS0=TCK、ADBUS1=TDI、ADBUS2=TDO、ADBUS3=TMS;ACBUS0=JTAG_SEL 输出使能。
ftdi_layout_init 0x0008 0x001b
ftdi_layout_signal TCK -data 0x0001
ftdi_layout_signal TDI -data 0x0002
ftdi_layout_signal TDO -input 0x0004
ftdi_layout_signal TMS -data 0x0008
ftdi_layout_signal JTAG_SEL -data 0x0100 -oe 0x0100
if {![info exists ADAPTER_KHZ]} { set ADAPTER_KHZ 100 }
adapter speed $ADAPTER_KHZ
reset_config none
# RISC-V DTM:IR 长度 5,板上实测 IDCODE=0x10000b6f、DTMCS=0x000040a1。
# 保留默认 IR 校验(init 时可能仍有 capture 告警)。examine 放到后面手动做。
jtag newtap d125 cpu -irlen 5 -expected-id 0x10000b6f
target create d125.cpu riscv -chain-position d125.cpu -defer-examine
bindto 0.0.0.0
gdb_port 3333
telnet_port 4444
tcl_port disabled
gdb_breakpoint_override hard
# 不加载 flash 算法,不做 RAM 初始化、硬件复位或自动 halt。
# 旧驱动在本连接上会在初始 IR 校验失败。先读 IDCODE/DTMCS,匹配后再 examine。
init
irscan d125.cpu 0x01
set d125_id [drscan d125.cpu 32 0]
irscan d125.cpu 0x10
set d125_dtmcs [drscan d125.cpu 32 0]
echo "D125 IDCODE=0x$d125_id DTMCS=0x$d125_dtmcs"
if {$d125_id ne "10000b6f" || $d125_dtmcs ne "000040a1"} {
error "D125 probe mismatch; refusing CPU examination."
}
d125.cpu arp_examine
echo "D125 CPU examination complete; GDB port 3333. Attach GDB to halt."No Flash programming algorithm, RAM initialization or hardware-reset sequence is provided. The script does not explicitly halt the CPU. The recorded 100 kHz is a starting speed, not a maximum-speed claim.
Run OpenOCD
From the configuration directory in Windows PowerShell:
.\OpenOCD-SiFive-0.10.0\bin\openocd.exe -f .\openocd-d125-ft232h.cfgCheck the executable's startup banner: the folder's 0.10.0 name and the build's 2020.11.0 identifier are not interchangeable.
To try a lower clock, define the variable before loading the file:
.\OpenOCD-SiFive-0.10.0\bin\openocd.exe -c "set ADAPTER_KHZ 50" -f .\openocd-d125-ft232h.cfgProject-supplied log
This is the original connection record, not a new test performed for this article:
Open On-Chip Debugger 0.10.0+dev (SiFive OpenOCD 0.10.0-2020.11.0)
Licensed under GNU GPL v2
For bug reports:
https://github.com/sifive/freedom-tools/issues
force hard breakpoints
Info : clock speed 100 kHz
Info : JTAG tap: d125.cpu tap/device found: 0x10000b6f (mfg: 0x5b7 (<unknown>), part: 0x0000, ver: 0x1)
Error: d125.cpu: IR capture error; saw 0x00 not 0x01
Warn : Bypassing JTAG setup events due to errors
Info : starting gdb server for d125.cpu on 3333
Info : Listening on port 3333 for gdb connections
D125 IDCODE=0x10000b6f DTMCS=0x000040a1
Info : datacount=1 progbufsize=2
Info : Examined RISC-V core; found 1 harts
Info : hart 0: XLEN=32, misa=0x40901125
D125 CPU examination complete; GDB port 3333. Attach GDB to halt.
Info : tcl server disabled
Info : Listening on port 4444 for telnet connectionsInterpreting the result
- The recorded IDCODE is
0x10000b6f; the explicit DTMCS read is0x000040a1. - CPU examination is attempted only after both values match. Do not remove the guard to force examination on a mismatch.
- One RV32 hart was examined, but the IR capture error remains. This is not a clean scan-chain validation.
- Successful explicit reads after the initial failure describe this particular session, not a universal workaround for IR errors.
- A listening GDB port does not establish successful halt, register access, breakpoints or Flash programming.
D213: four-wire JTAG hardware and configuration
D125 uses two-wire cJTAG. For D213, this article uses the project's D21x IEEE 1149.1 four-wire JTAG configuration. Do not mix these modes. The configuration filename and TAP name intentionally retain d21x.
| FT232H signal | D213 target signal | Direction relative to adapter |
|---|---|---|
| D0 / ADBUS0 | TCK | Clock output |
| D1 / ADBUS1 | TDI | Data output |
| D2 / ADBUS2 | TDO | Data input |
| D3 / ADBUS3 | TMS | State-control output |
| GND | GND | Common ground |
| D4 / ADBUS4 | nTRST (optional; verify board design) | Reset output, initially high |
| D5 / ADBUS5 | nSRST (optional; verify board design) | Reset output, initially high |
Do not tie D1/D2 together or enable ftdi_oscan1_mode for four-wire JTAG. The supplied material does not identify D213 GPIO names, package pins or header numbers. Check the actual schematic and pinmux before wiring; do not reuse D125 PA10/PA11 assignments.
With reset_config none, this configuration does not actively perform hardware reset. Initial high levels do not guarantee compatibility with every board. Reset wires may remain disconnected for the basic connection.
D213 configuration file
Download openocd-d21x-ft232h.cfg. The configuration below preserves the supplied Chinese comments so it can be compared directly with the project file.
# D21x + FT232H,SiFive OpenOCD 2020.11.0。
# 目标为 IEEE 1149.1 四线 JTAG(TCK/TDI/TDO/TMS),不要开启 cJTAG/OSCAN1。
adapter driver ftdi
ftdi_vid_pid 0x0403 0x6014
ftdi_channel 0
# 多块 FTDI 同时在线时,取消下一行注释并填入序列号。
# ftdi_serial "YOUR_FT232H_SERIAL"
transport select jtag
# ADBUS0=TCK、ADBUS1=TDI、ADBUS3=TMS 输出;ADBUS2=TDO 输入。
# ADBUS4/5 作 nTRST/nSRST,初始拉高,避免上电就把目标按在复位里。
ftdi_layout_init 0x0030 0x003b
# nTRST=ADBUS4,nSRST=ADBUS5;本配置 reset_config none,这两根线不主动翻转。
ftdi_layout_signal ntrst -data 0x0010
# 接到目标 SRST 时使用。
ftdi_layout_signal nsrst -data 0x0020
if {![info exists ADAPTER_KHZ]} { set ADAPTER_KHZ 100 }
adapter speed $ADAPTER_KHZ
reset_config none
# RISC-V DTM:IR 长度 5,IDCODE=0x10000b6f。先建 TAP,examine 放到后面手动做。
jtag newtap d21x cpu -irlen 5 -expected-id 0x10000b6f
target create d21x.cpu riscv -chain-position d21x.cpu -defer-examine
bindto 0.0.0.0
gdb_port 3333
telnet_port 4444
tcl_port disabled
gdb_breakpoint_override hard
# 不加载 flash 算法,不做 RAM 初始化、硬件复位或自动 halt。
# init 时 TDO 空闲电平会被当成后续 TAP,并触发 IR capture 告警。
# 先关掉非 d21x 的 TAP,再读 IDCODE(IR=0x01) 和 DTMCS(IR=0x10),匹配后才 examine。
init
echo "D21x taps after init: [jtag names]"
foreach tap_name [jtag names] {
if {![string match "d21x.*" $tap_name]} {
echo "Disabling extra TAP $tap_name"
jtag tapdisable $tap_name
}
}
runtest 5
irscan d21x.cpu 0x01
set d21x_id [drscan d21x.cpu 32 0]
irscan d21x.cpu 0x10
set d21x_dtmcs [drscan d21x.cpu 32 0]
echo "D21x IDCODE=0x$d21x_id DTMCS=0x$d21x_dtmcs"
if {$d21x_id ne "10000b6f" || $d21x_dtmcs ne "000040a1"} {
error "D21x probe mismatch; refusing CPU examination."
}
d21x.cpu arp_examine
echo "D21x CPU examination complete; GDB port 3333. Attach GDB to halt."Start and check D213
.\OpenOCD-SiFive-0.10.0\bin\openocd.exe -f .\openocd-d21x-ft232h.cfgThe script lists TAPs after initialization, disables names not matching d21x.*, runs runtest 5, and checks IDCODE and DTMCS. This behavior is specific to the project's connection, not a generic multi-TAP setup; do not apply it blindly to a real multi-device chain.
The expected IDCODE is 0x10000b6f and DTMCS is 0x000040a1. Only a match permits d21x.cpu arp_examine. These are script checks, not newly measured D213 results. The complete captured log supplied for this article belongs to D125 and must not be treated as a D213 test result. Investigate mismatches rather than removing guards.
Both configurations use GDB port 3333 and Telnet port 4444. Run one at a time on the same host, or assign distinct ports. Use the following GDB workflow with an ELF matching the firmware on the D213 board.
Connect with GDB
Use a GDB build compatible with the target RISC-V architecture and an ELF matching the running firmware, including debug information. The executable name below is illustrative; select your SDK's actual RV32-capable GDB.
Keep OpenOCD running and launch a second terminal:
riscv64-unknown-elf-gdb.exe .\firmware.elfAt the GDB prompt:
target extended-remote 127.0.0.1:3333
monitor halt
info registers
x/8i $pc
btOpening the ELF loads host-side symbols; it does not program the target. Attachment and halting affect execution, so put motors and other controlled hardware into a safe state first. Backtraces depend on symbols, compiler optimization and execution state.
For a breakpoint, replace the placeholder with a real firmware function:
hbreak your_function
continuePress Ctrl+C to request an interrupt while running. Hardware breakpoint resources are limited. A breakpoint does not rerun an initialization function that has already completed.
Before finishing, remove breakpoints and explicitly resume if that is the intended target state:
delete breakpoints
monitor resume
detach
quitDo not blindly use load, run or monitor reset halt: this configuration does not establish download, RAM initialization or board-reset support.
General command references: OpenOCD GDB guide and general commands. These references do not validate the D125 wiring or this old driver build.
Frequently asked questions
How do PA10 and PA11 connect to an FT232H?
PA10 is JTAG_MS / TMSC and connects to the shared D1/D2 data node. PA11 is JTAG_CK / TCKC and connects to D0. Select mux function 8 and connect grounds.
Has this ArtInChip D125 cJTAG setup been tested on hardware?
Yes. The project confirms board validation, with logs for IDCODE, DTMCS and RV32 CPU examination. This does not automatically validate other adapters, every GDB operation or Flash programming.
Can this configuration program D125 Flash?
No Flash algorithm is provided. This is a connection and CPU-examination configuration with a separate GDB attach guide, not a Flash programming recipe.
Related guide: ArtInChip D126 Wi-Fi / BLE.
Troubleshooting
| Symptom | Check first |
|---|---|
| FTDI device not found | USB enumeration, VID/PID, driver and other applications; select a serial number for multiple adapters |
| Unknown ftdi_oscan1_mode | OpenOCD fork and build version |
| IDCODE / DTMCS mismatch | PA10/PA11 wiring, ground, IO levels, pinmux, target power and clock speed |
| IR capture error | Preserve logs and assess explicit reads and CPU examination; do not simply disable validation |
| GDB cannot connect | OpenOCD process, port 3333 availability and local address |
| Halt or register access fails | Debug state, link stability, firmware pin multiplexing and old-driver compatibility |
| Wrong symbols or backtrace | Matching ELF and debug information |
