Xilinx Platform Cable USB (XPCU) Documentation.
Microprocessor | Cypress EZ-USB FX2LP |
Hardware Accelerated | Yes (Xilinx XC2C256) |
Firmware Stored in Flash | No. Reloaded every power on. |
Firmware State | Proprietary. Mostly reversed. |
Firmware Path |
{Latest ISE path}/ISE_DS/ISE/bin/lin/xusb_emb.hex {Latest ISE path}/ISE_DS/ISE/bin/lin/xusb_xlp.hex |
Latest Firmware Version |
EMB: 1028 (0x0404). XLP: 5381 (0x1705) |
Getting Started
The XPCU controller powers on with no firmware. Loading firmware will cause the device to re-enumerate as a different usb device. Checking lsusb for the idvendor and idproduct will show if the device is programmed.
Default | Programmed | |
idVendor | 0x03FD | 0x03FD |
idProduct | 0x000D | 0x0008 |
Some cables may have different default values. Please report any you find.
Loading the XPCU with firmware can be done with the fxload tool. It can be used manually through the terminal, but the following udev rule will auto load the firmware every time the XPCU is plugged into the host machine.
Interface Selection
The newer XLP firmware for the Platform Cable 1 requires USB interface claiming, and Interface alternate mode selection to work. Using libusb1.0, run libusb_claim_interface(0), then libusb_set_interface_alt_setting(0, 1). Trying to send bulk commands before these steps are done will fail. Devices requiring this step can be identified with the productID of 0x0D.
UDEV Rule for auto firmware loading
Write the following lines to /etc/udev/rules.d/xusbfwu.rules and set the file permission to 644.
SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="03fd", ATTR{idProduct}=="000d", MODE="666", RUN+="/sbin/fxload -v -t fx2 -I '/path/to/xusb_emb.hex' -D $tempnode" SUBSYSTEM=="usb", ACTION=="add", ATTR{idVendor}=="03fd", ATTR{idProduct}=="0008", MODE="666"
When the device is next plugged into USB after a short delay, the led should turn green or red (depending if a JTAG target is detected). If no light turns on, the firmware is not being loaded right. If the light turns on but the device behaves oddly, see the troubleshooting section.
Protocol Specification
The USB specification requires the host to initiate all transfers. Control messages to endpoint 0 control the XPCU. Bulk transfers send jtag data for the command to use (if any).
For all jtag related USB-control messages.bRequest | 0xB0 |
bmRequestType |
OUT(To XPCU): 0x40 IN(To PC): 0xC0 |
wValue | Command number (lower byte) |
wIndex | Parameter to Command |
wLength | Number of bytes to send in control message. |
Bulk OUT Endpoint | EP2 |
Bulk IN Endpoint | EP6 |
Name | Dir | Value | Index | LEN | Description | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Device Disable | O | 0x10 | 0 | 0 | Not required, but you should clean up. | ||||||||||||||
Device Enable | O | 0x18 | 0 | 0 | Required before the device will behave normally. Before running this command, you seem to still be able to read GPIO states, but and transfer commands will do nothing. | ||||||||||||||
Reverse windex | I | 0x20 | low byte to reverse | 1 | Returns the lower 8 bits of the windex value passed into it | ||||||||||||||
Set JTAG Speed | O | 0x28 | Speed | 0 |
Specifies a speed class for the target device and changes the speed of all future JTAG transfers. Often 0x11. Bit 4 should always be set in the speed class. Below is a table of values to send to the controller, and what speed that translates to.
|
||||||||||||||
Write Single JTAG bit | O | 0x30 | pinstates | 0 |
This command will perform writes on either the JTAG target or the internal CPLD. Which one it targets is controlled by command 0x52.
DEFAULT (CPLD UPGRADE MODE OFF)Perform a single GPIF write to the CPLD. Format is not known for now. Full clock cycle appears appears to happen. Only the lower byte of windex is used. WHEN CPLD UPGRADE MODE ONBit bang the internal CPLD's JTAG TDI/TMS/TCK lines. Only up to one transition on each line can be done per request. This means that in order to make one clock cycle for the CPLD's TAP, this message must be sent twice: once to raise TCK and another to lower it again. This makes JTAG operations on the embedded CPLD very very slow. Thus it is only used for upgrading the firmware on the CPLD.
|
||||||||||||||
Read Single JTAG bit and Status | I | 0x38 | 0 | 1 |
This command will operate on the JTAG target or the internal CPLD's TAP. Which one it targets is controlled by command 0x52.
DEFAULT (CPLD UPGRADE MODE OFF)
WHEN CPLD UPGRADE MODE ONRead the state of the TDO pin of the internal CPLD. Will return 0 or 1. No clocking is done, the read is passive. | ||||||||||||||
Return Constant | I | 0x40 | 0 | 2 | Returns 0xB503 | ||||||||||||||
Maybe Read Serial Number? | I | 0x42 | 0 | 0 | Available on the XLP firmware. Returns 8 bytes of data. On XPC1, all data is 0. May be a serial number for devices that support it. | ||||||||||||||
Get Version | I | 0x50 | 0,1,2,3+ | 2 |
Returns information on version numbers of the software running on the device.
|
||||||||||||||
CPLD Upgrade Mode | O | 0x52 | 0: Off 1: On |
0 |
Enabling CPLD UPGRADE MODE is only used for upgrading the internal CPLD. The XPCU controller starts with this mode disabled.
CPLD UPGRADE MODE ON
CPLD UPGRADE MODE OFF
|
||||||||||||||
UNKNOWN | O | 0x68 | Some count | 0 | The lower byte of windex is set to the address lines to the CPLD. The upper byte is written to XGPIFSGLDATLX which triggers a GPIF transaction. |
||||||||||||||
Generate Heat and clock CPLD | I | 0x7X | seems pointless | 0/1 |
This command is very odd. The waveform for talking to the CPLD does nothing except loop waiting for the CPLD to say it is done. windex is set as the data to write to the CPLD but the waveform never asserts data. windex is incremented by one. Processed min is therefore 1. 0xFFFE becomes 0xFFFF, but there is a maximum enforced that keeps 0xFFFF at 0xFFFF (instead of 0x01000000). Commands runs a single GPIF waveworm if the Value is 0x70 to 0x7F (inclusive). CPLD EXTEND pin raised. The value of X determines a few things:
|
||||||||||||||
UNKNOWN | ?? | 6C 88 8A 8c 8E 90 92 94 96 98 9A 9C 9E A2 A4 | UNKNOWN | ??? | Part of a very large block of code with unknown function. No packet captures use these commands. Originally thought to be used for SPI or serial. Unknown function at this time. Appears some of these commands can trigger the same function that 0x7X messages call | ||||||||||||||
Change USB Speed(?) | O | 0xA0 | 0 | 0 | Mostly resets the XPCU, disconnects it from USB, forces full speed USB, then reconnects the XPCU to USB. | ||||||||||||||
Bulk JTAG Transfer | O | 0xa6 | 0xYYZZ See description | 0 | Starts a transfer.
|
||||||||||||||
Bulk: OUT Endpoint: 2 The data to put on the GPIO lines. The data consists of pairs of bytes (two bytes) where each four bit section is a field. Each bit of the fields line up to form key frames. Up to four (4) key frames can be specified per 2 bytes sent. Details on the order the keyframes are executed is below. Two Byte Format: 0xABCD
Please note the following:
Example 1:This example will move the TAP state through TEST_LOGIC_RESET and end in RUN_TEST_IDLE. Red is TMS. Yellow is TCK. Note: For two byte sections where all four state transitions are used, the Platform cable groups those bits and pushes any fractional section off a little while later (likely because of processing delay). Bits: 10 Data: 0x80:00:F0:0F:10:03 xpcu_GPIO_transfer(dh, 9, '\x80\x00\xF0\x0F\x10\x03') Disection (reading each column of the numbers lined up):0x8000 0xf00f 0x1003 TMS: 0x8, 0xf, 0x1 Bin = 1000 1111 0001 TDI: 0x0, 0x0, 0x0 (All 0 means TDI is always low. Ignoring for example.) TDO: 0x0, 0x0, 0x0 (All 0 means read no bits. Ignoring for example.) TXK: 0x0, 0xf, 0x3 Bin = 0000 1111 0011 Reverse each 4 bit section bin(hijk)->bin(kjih):TMS: 1000 1111 0001 -> 0001 1111 1000TXK: 0000 1111 0011 -> 0000 1111 1100 Example 2:Bits: 10 Data: 0xD0:00:F0:0F:10:03 xpcu_GPIO_transfer(dh, 9, '\xD0\x00\xF0\x0F\x10\x03') Example 3:Bits: 10 Data: 0x00:00:F0:0F:10:03 xpcu_GPIO_transfer(dh, 9, '\x00\x00\x00\x0F\x10\x03') Example 4:Bits: 13 Data: 0x80:00:F0:0F:10:0B:00:01 xpcu_GPIO_transfer(dh, 12, '\x80\x00\xF0\x0F\x10\x0B\x00\x01') |
|||||||||||||||||||
Bulk: IN Endpoint: 6 This response message is returned from the Platform Cable after the transfer is completed if any read TDO bits were high in the request message. If no read TDO bits were high, this message is not returned. The return protocol is rather complicated.
Example
This is how the 16 register is shifted, and overflows/transforms into the 32 bit register. In this case we are shifting in the number:
The following will show the states of the return data buffer as data is shifter in. The data being read will be the following 32 bit value:
Here is the state of the return data over time as bits are shifted in.
|
|||||||||||||||||||
Blink Green LED | O | 0x2162 | 0 for Stop 0x00F0 for Start |
0 | Available on the XLP firmware. Causes the Green LED to blink for debug or identification purposes. |
Device Specifications
Troubleshooting
If you want to check the version of firmware you have?
FW_VERSION_STRING=`grep ":0219B900" $PATH_TO_FIRMWARE_FILE`; FW_HEX_VERSION=${FW_VERSION_STRING:9:4}; printf "%d" 0x$FW_HEX_VERSION;
Green light solid after firmware load but device acting weird?
The firmware hex file for this device can be found inside the linux install of ISE. There are several files with the same name at various locations, but ignore them and use the one at {Latest ISE path}/ISE_DS/ISE/bin/lin/xusb_emb.hex. If you use the wrong file, it will either refuse to load, or appear to load but not re-enumerate properly and behave oddly despite the green light on the device lighting up.