Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

USB Transport

WCH-Link uses USB bulk transfers. There is no kernel driver in the loop on Linux/macOS: wlink opens the device with nusb, claims interface 0, and reads and writes bulk endpoints directly. On 32-bit Windows an optional native WCHLinkDLL.dll (CH375) backend is available, falling back to nusb.

Source: src/probe.rs (constants), src/usb_device.rs (backend implementations).

USB identifiers

ModeVIDPIDNotes
RV (RISC-V debug/flash)0x1a860x8010The mode wlink operates in
DAP (ARM SWD)0x1a860x8012wlink refuses to flash in this mode

The same physical probe appears under one PID or the other depending on its mode. wlink mode-switch flips between them.

Endpoints

EndpointDirectionPurpose
0x01OUTCommand frames (81 CMD LEN PAYLOAD)
0x81INCommand responses (82 … / 81 …)
0x02OUTData endpoint: flash algorithm blob, firmware chunks
0x82INData endpoint: memory dump, per-chunk write acknowledgement
0x02OUT (DAP mode only)Raw mode-switch frame

Command reads use a 64-byte buffer; a single bulk read is treated as one response frame. Data-endpoint transfers are streams, not frames: wlink loops over 64-byte bulk reads until the requested byte count is reached, and pads the final written chunk with 0xff to the family’s data packet size.

The nusb backend stores a 5-second default in NusbDevice::timeout; the current bulk read/write calls do not apply it and rely on nusb’s own blocking behaviour.

Selecting a probe

With several probes attached, enumeration order is not stable. wlink accepts either an index or a USB serial number:

wlink list
# <WCH-Link#0 nusb device> ID 1a86:8010 Serial F93D8F067E10 (USB-FS 12 Mbps) (RV mode)
# <WCH-Link#1 nusb device> ID 1a86:8010 Serial D7708F065C7F (USB-FS 12 Mbps) (RV mode)

wlink -d 1a86:8010:D7708F065C7F status   # probe-rs style VID:PID:SERIAL
wlink -d D7708F065C7F status             # serial alone
wlink -d 1 status                        # legacy index

Serial matching is case-insensitive and works in either RV or DAP mode; the VID/PID in the selector are validated but not used for matching.

Mode switching

Switching from RV to DAP mode sends a command frame on the normal command endpoint:

DirectionRaw bytesMeaning
RV → DAP81 ff 01 41RawCommand<0xff> with payload 0x41
DAP → RV81 ff 01 52written raw to endpoint 0x02 while in DAP mode

Both operations are experimental; the CH549-based first-generation probe can only switch modes by reflashing its firmware. Support is reported by WchLinkVariant::support_switch_mode in src/probe.rs.

Variants

CodeVariantHardwareCapabilities
0x01WchLinkVariant::Ch549WCH-Link (CH549)No CH32V00X, no mode switch, no power/SDI functions
0x02 / 0x12WchLinkVariant::ECh32v305WCH-LinkE (CH32V305)Full support, including SDI print
0x03WchLinkVariant::SCh32v203WCH-LinkS (CH32V203)Full chip support
0x05 / 0x85WchLinkVariant::WCh32v208WCH-LinkW (CH32V208)Wireless variant; no CH56X/CH57X/CH582/CH59X
other——Error::UnknownLinkVariant

See Probe Info and Firmware Version for how the variant byte is returned and how firmware versions are decoded.