Xilinx Platform Cable USB on Windows¶
This note covers the xilinxPlatformCableUsb_alt backend on portable Windows
builds.
Expected USB states¶
Before firmware load, some SP605/Xilinx embedded Platform Cable devices appear as:
03fd:000d
After xusb_emb.hex is loaded, the same device can re-enumerate as:
03fd:0008
Both states must be accessible to libusb. On Windows, use Zadig and bind the Xilinx device/interface to WinUSB or libusbK. If only the boot state is bound, firmware upload can succeed but JTAG transfers can fail after reload.
The public xilinx-xusb mirror documents udev entries for Xilinx PIDs such as
0007, 0008, 0009, 000d, 000f, 0013, and 0015.
Runtime firmware lookup¶
The portable package should contain:
install/share/openFPGALoader/xusb_emb.hex
Runtime lookup order is:
1. --probe-firmware <path>
2. OPENFPGALOADER_XUSB_FIRMWARE
3. share/openFPGALoader/xusb_emb.hex beside the portable install
4. legacy Vivado/ISE paths
Endpoint and alternate-setting debug¶
Some Windows/libusbK installations expose the post-firmware interface but reject
libusb_set_interface_alt_setting(0, 1) with LIBUSB_ERROR_IO. If control
transfers work but JTAG bulk transfers fail with:
FX2 write error: LIBUSB_ERROR_NOT_FOUND
JTAG init failed with: TDO is stuck at 0
then the bulk endpoint pair is not available in the currently selected alternate setting.
This fork scans the USB descriptors and tries to select the alternate setting that contains one bulk OUT endpoint and one bulk IN endpoint. It still defaults to the classic Xilinx endpoints:
OUT 0x02
IN 0x86
For manual testing, these environment variables are available:
$env:OPENFPGALOADER_XPCU_OUT_EP = "0x02"
$env:OPENFPGALOADER_XPCU_IN_EP = "0x86"
To skip alternate-setting selection entirely:
$env:OPENFPGALOADER_XPCU_SKIP_ALT_SETTING = "1"
Clear them again with:
Remove-Item Env:\OPENFPGALOADER_XPCU_OUT_EP -ErrorAction SilentlyContinue
Remove-Item Env:\OPENFPGALOADER_XPCU_IN_EP -ErrorAction SilentlyContinue
Remove-Item Env:\OPENFPGALOADER_XPCU_SKIP_ALT_SETTING -ErrorAction SilentlyContinue
Normal test command:
.\openFPGALoader.exe -c xilinxPlatformCableUsb_alt --freq 700000 --detect
Control-transfer timeout after reload¶
Some SP605 / Xilinx Platform Cable USB combinations enumerate correctly after FX2 firmware load, and descriptor endpoint discovery can succeed, but the first vendor control read may still time out:
XPCU bulk endpoints: OUT=0x02 IN=0x86
Unable to read control request: LIBUSB_ERROR_TIMEOUT
JTAG init failed with: Unable to read constant.
The Windows backend now retries early XPCU control transfers and uses a longer FX2 control timeout by default.
Useful debug overrides:
$env:OPENFPGALOADER_FX2_CTRL_TIMEOUT_MS = "2000"
$env:OPENFPGALOADER_XPCU_CTRL_RETRIES = "60"
$env:OPENFPGALOADER_XPCU_CTRL_RETRY_DELAY_MS = "100"
.\openFPGALoader.exe -c xilinxPlatformCableUsb_alt --freq 700000 --detect
Use normal .\openFPGALoader.exe in the command above; the escaped marker is
only to avoid accidental formatting in some markdown renderers.
Accelerated-transfer timeout¶
If version, status, and speed commands succeed but the first JTAG operation
fails on the GPIO transfer command with LIBUSB_ERROR_TIMEOUT, the cable or
its Windows USB driver is rejecting the accelerated 0xA6 transfer trigger.
An IDCODE printed after that failure is invalid scan data and must not be added
to the FPGA database.
The backend now falls back automatically to the older control-transfer JTAG protocol. To avoid waiting for the initial accelerated-transfer timeout, force that mode before running the command:
$env:OPENFPGALOADER_XPCU_CONTROL_BITBANG = "1"
.\openFPGALoader.exe -c xilinxPlatformCableUsb_alt --freq 700000 --detect
This mode performs two USB control writes per JTAG clock and a status read for each captured TDO bit, so detection and programming are considerably slower. Clear the override to retry accelerated transfers:
Remove-Item Env:\OPENFPGALOADER_XPCU_CONTROL_BITBANG -ErrorAction SilentlyContinue