Skip to content

Instantly share code, notes, and snippets.

@rikka0w0
Last active October 19, 2024 01:18
Show Gist options
  • Save rikka0w0/24b58b54473227502fa0334bbe75c3c1 to your computer and use it in GitHub Desktop.
Save rikka0w0/24b58b54473227502fa0334bbe75c3c1 to your computer and use it in GitHub Desktop.
FT2232 to Digilent JTag for Xilinx FPGAs (ISE/Vivado)

The Digilent JTag uses FT2232, but its configuration EEPROM contains secrete data needed to be recoginzed by Xilinx ISE/Vivado. The following method only works on linux (tested on Ubuntu16.04), but the patched FT2232 doggle also works on Windows. Since WSL1 does not provide USB device access, the following method will not work for WSL1.

DONT use FT_Prog on offical Digilent cable, as it can trash the firmware! The offical eeprom contains secrete data that cannot be handled correctly by FT_Prog.

Here are steps to create a Digilent-like Jtag that can be used in Xilinx ISE and Vivado

  1. Install softwares: sudo apt-get install libftdi1 ftdi-eeprom
  2. Create a file "flash_digilent.conf" with the following content: flash_digilent.conf:
vendor_id=0x0403
product_id=0x6010

flash_raw=true

filename="digilent_jtag_uart.bin"	# Filename, leave empty to skip file writing
  1. Backup the original content of the EEPROM: sudo ftdi_eeprom --read-eeprom flash_digilent.conf, then rename and move the digilent_jtag_uart.bin to a safe storage location.
  2. Generate a firmware for Digilent Jtag with a UART interface:
echo -n -e \\x01\\x08\\x03\\x04\\x10\\x60\\x00\\x07\\x80\\x2f\\x08\\x00\\x00\\x00\\x9a\\x12\\xac\\x34\\xe0\\x1a\\x00\\x00\\x00\\x00\\x56\\x00\\x01\\x00\\xc7\\x92\\x6a\\x35\\x51\\x01\\x80\\x30\\x4a\\x74\\x61\\x67\\x53\\x6d\\x74\\x31\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x44\\x69\\x67\\x69\\x6c\\x65\\x6e\\x74\\x20\\x4a\\x54\\x41\\x47\\x2d\\x53\\x4d\\x54\\x31\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x12\\x03\\x44\\x00\\x69\\x00\\x67\\x00\\x69\\x00\\x6c\\x00\\x65\\x00\\x6e\\x00\\x74\\x00\\x34\\x03\\x44\\x00\\x69\\x00\\x67\\x00\\x69\\x00\\x6c\\x00\\x65\\x00\\x6e\\x00\\x74\\x00\\x20\\x00\\x41\\x00\\x64\\x00\\x65\\x00\\x70\\x00\\x74\\x00\\x20\\x00\\x55\\x00\\x53\\x00\\x42\\x00\\x20\\x00\\x44\\x00\\x65\\x00\\x76\\x00\\x69\\x00\\x63\\x00\\x65\\x00\\x1a\\x03\\x32\\x00\\x31\\x00\\x30\\x00\\x32\\x00\\x30\\x00\\x33\\x00\\x38\\x00\\x35\\x00\\x39\\x00\\x32\\x00\\x38\\x00\\x39\\x00\\x02\\x03\\x00\\x00\\xfb\\x6a > digilent_jtag_uart.bin
  1. Flash the firmware to FT2232's EEPROM: $ sudo ftdi_eeprom --flash-eeprom flash_digilent.conf

End of Tutorial

hexdump of digilent_eeprom.raw (Original version of Digilent's Jtag, no UART):

digilent_eeprom.raw is a binary file!

rikka@rikka-virtual-machine:~$ hexdump -C digilent_eeprom.raw 
00000000  01 01 03 04 10 60 00 07  80 2f 08 00 00 00 9a 12  |.....`.../......|
00000010  ac 34 e0 1a 00 00 00 00  56 00 01 00 c7 92 6a 35  |.4......V.....j5|
00000020  51 01 80 30 4a 74 61 67  53 6d 74 31 00 00 00 00  |Q..0JtagSmt1....|
00000030  00 00 00 00 00 44 69 67  69 6c 65 6e 74 20 4a 54  |.....Digilent JT|
00000040  41 47 2d 53 4d 54 31 00  00 00 00 00 00 00 00 00  |AG-SMT1.........|
00000050  00 00 01 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00000060  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
00000090  00 00 00 00 00 00 00 00  00 00 12 03 44 00 69 00  |............D.i.|
000000a0  67 00 69 00 6c 00 65 00  6e 00 74 00 34 03 44 00  |g.i.l.e.n.t.4.D.|
000000b0  69 00 67 00 69 00 6c 00  65 00 6e 00 74 00 20 00  |i.g.i.l.e.n.t. .|
000000c0  41 00 64 00 65 00 70 00  74 00 20 00 55 00 53 00  |A.d.e.p.t. .U.S.|
000000d0  42 00 20 00 44 00 65 00  76 00 69 00 63 00 65 00  |B. .D.e.v.i.c.e.|
000000e0  1a 03 32 00 31 00 30 00  32 00 30 00 33 00 38 00  |..2.1.0.2.0.3.8.|
000000f0  35 00 39 00 32 00 38 00  39 00 02 03 00 00 7b 6e  |5.9.2.8.9.....{n|
00000100

How did I patch the second interface to make it a UART

Compile (gcc xxx.c -o xxx) the following code and run it. It will patch the EEPROM file (digilent_eeprom.raw) and recalculate the checksum. After patching, follow mentioned procedure to flash the patched EEPROM. Now interface A is JTag (Digilent & Xilinx compatible) and interface B is UART which can be used for debug purposes.

Changes: byte0x01: 0x01 -> 0x08, byte0xFE: 0x7B->0xFB, byte0xFF: 0x6E->0x6A

#include <stdio.h>
#include <stdint.h>

int main()
{
    uint8_t buf[256];
    int size = sizeof(buf);
    unsigned short checksum, value;
    FILE * pFile;
    pFile = fopen("digilent_eeprom.raw", "rw+b");
    fread(buf, 1, 256, pFile);
    
    buf[1] = 0x08;

    // calculate checksum
    checksum = 0xAAAA;

    for (int i = 0; i < size/2-1; i++)
    {
        value = buf[i*2];
        value += buf[(i*2)+1] << 8;

        checksum = value^checksum;
        checksum = (checksum << 1) | (checksum >> 15);
    }

    printf("%02x, %02x\n", buf[size-2], buf[size-1]);

    buf[size-2] = checksum & 0xFF;
    buf[size-1] = (checksum >> 8 ) & 0xFF;

    fseek(pFile, 0, SEEK_SET);
    fwrite(buf, 1, 256, pFile);

    fclose(pFile);
    return 0;
}

TI's DSP Emulator This command gives the original FT2232 firmware of the TI's XDS100v2 Jtag emulator (With SCI/UART):

echo -n -e \\x00\\x08\\x03\\x04\\xd0\\xa6\\x00\\x07\\x80\\xc8\\x0c\\x00\\xcc\\x0c\\x9a\\x06\\xa0\\x4a\\xea\\x10\\x00\\x00\\x00\\x00\\x56\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x06\\x03\\x54\\x00\\x49\\x00\\x4a\\x03\\x54\\x00\\x65\\x00\\x78\\x00\\x61\\x00\\x73\\x00\\x20\\x00\\x49\\x00\\x6e\\x00\\x73\\x00\\x74\\x00\\x72\\x00\\x75\\x00\\x6d\\x00\\x65\\x00\\x6e\\x00\\x74\\x00\\x73\\x00\\x20\\x00\\x49\\x00\\x6e\\x00\\x63\\x00\\x2e\\x00\\x58\\x00\\x44\\x00\\x53\\x00\\x31\\x00\\x30\\x00\\x30\\x00\\x20\\x00\\x56\\x00\\x65\\x00\\x72\\x00\\x20\\x00\\x32\\x00\\x2e\\x00\\x30\\x00\\x10\\x03\\x46\\x00\\x32\\x00\\x38\\x00\\x4d\\x00\\x33\\x00\\x36\\x00\\x58\\x00\\x00\\x00\\x00\\x00\\x98\\x54 > ti_jtag_sci.bin

flash_ti.conf:

vendor_id=0x0403
product_id=0xa6d0

flash_raw=true

filename="ti_jtag_sci.bin"	# Filename, leave empty to skip file writing

References:

http://jumpstartengineering.com/embedded_systems/jtag/changing-ft2232h-based-device-parameters/

https://github.com/sprhawk/libftdi/blob/3e078e16d4909044b00de1c610e7904e40a614d9/src/ftdi.c#L3076

@taronhov
Copy link

taronhov commented Apr 14, 2023

Bytes in the same dump (256 bytes):

01 00 03 04 14 60 00 09 80 32 08 00 00 00 A0 0E AE 20 CE 0C 00 00 00 00 00 00 00 00 00 00 56 00 02 00 4A 58 58 69 6C 69 6E 78 00 48 57 2D 46 54 44 49 2D 54 45 53 54 20 46 54 32 33 32 48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0E 03 58 00 69 00 6C 00 69 00 6E 00 78 00 20 03 5A 00 43 00 55 00 31 00 30 00 36 00 20 00 45 00 76 00 61 00 6C 00 20 00 4B 00 69 00 74 00 0C 03 30 00 33 00 37 00 33 00 31 00 02 03 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 D7 90

Convert to Binary format and save in a file (e.g. by copying this into the HxD (Hex Editor) program).
Or use "xxd" command in Linux (xxd -r -p <Text file with above content (.txt)> <Binary output file (.bin)>).

@Livius90
Copy link

Livius90 commented Apr 14, 2023

Vivado Design Suite User Guide: Programming and Debugging (UG908)

Programming FTDI Devices for Vivado Hardware Manager Support
For FTDI devices to be recognized as a USB-to-JTAG interface in Xilinx® JTAG software tools such as XSDB or the Vivado® Hardware Manger the EEPROM on the FTDI device must be programmed. Programming the FTDI is accomplished by using the program_ftdi utility included in the Vivado install. Once programmed, the FTDI device will be recognized as a valid programming cable in Vivado.

The program_ftdi utility supports the following FTDI devices:

  • FT232H
  • FT2232H
  • FT4232H

Has anyone tried to program the FTDI ICs according to this UG908 description, does this procedure work? Is it mean we can make a "home-made" FTDI USB-to-JTAG devices in any time in free?

@thanh7921
Copy link

Has anyone tried to program the FTDI ICs according to this UG908 description, does this procedure work? Is it mean we can make a "home-made" FTDI USB-to-JTAG devices in any time in free?

I have tried to use the program_ftdi provided in Vivado 2023.1, writing into my FT4232H breakout board. After encountering segfault (Xilinx!), I tried to steps outlined in this post, which led to inexplicable success program_ftdi segfaults without error message.

The command used (after all the steps in the post and invoking settings64.sh)

valgrind --trace-children=yes \
    program_ftdi -write -ftdi FT4232H \
        -serial FFFFFF -vendor "Yours truly" \
        -board "Chinese FT4232H breakout board" \
        -desc "FT4232 with Xilinx secret sauce"

I tried various serial, vendor, board and desc value. Some of them worked, some just failed. Anyone looking to try this method will have to experiment to find the right values.

The generate binary content in the EEPROM

00000000: 8088 0304 1160 0008 8032 0800 0000 9a0e  .....`...2......
00000010: a840 e80e 0000 0000 5600 0400 4a58 596f  [email protected]
00000020: 7572 7320 7472 756c 7900 4368 696e 6573  urs truly.Chines
00000030: 6520 4654 3432 3332 4820 6272 6561 6b6f  e FT4232H breako
00000040: 7574 2062 6f61 7264 0000 0000 0000 0000  ut board........
00000050: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000060: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000070: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000080: 0000 0000 0000 0000 0000 0000 0000 0000  ................
00000090: 0000 0000 0000 0000 0000 0e03 5800 6900  ............X.i.
000000a0: 6c00 6900 6e00 7800 4003 4600 5400 3400  [email protected].
000000b0: 3200 3300 3200 2000 7700 6900 7400 6800  2.3.2. .w.i.t.h.
000000c0: 2000 5800 6900 6c00 6900 6e00 7800 2000   .X.i.l.i.n.x. .
000000d0: 7300 6500 6300 7200 6500 7400 2000 7300  s.e.c.r.e.t. .s.
000000e0: 6100 7500 6300 6500 0e03 4600 4600 4600  a.u.c.e...F.F.F.
000000f0: 4600 4600 4600 0203 0000 0000 0000 3acd  F.F.F.........:.

I have not test the board yet. But if it doesn't work, then I will post more update.

@alghasi
Copy link

alghasi commented Feb 17, 2024

i use FT2232H-56Q and program eeprom same following document. but not work correctly
eeprom read with FT_Prog:
Device: 0 [Loc ID:0x1D1]

Word MSB
0000: 0101 0403 6010 0700 2F80 0008 0000 129A ....`.../.......

0008: 34AC 1AE0 0000 0000 0056 0001 92C7 356A 4........V....5j

0010: 0150 3070 744A 6761 7348 0031 0000 0000 .P0ptJgasH.1....

0018: 0000 0000 4400 6769 6C69 6E65 2074 544A ....D.giline tTJ

0020: 4741 482D 3153 0000 0000 0000 0000 0000 GAH-1S..........

0028: 0000 0011 0000 0000 0000 0000 0000 0000 ................

0030: 0000 0000 0000 0000 0000 0000 0000 0000 ................

0038: 0000 0000 0000 0000 0000 0000 0000 0000 ................

0040: 0101 0403 6010 0700 2F80 0008 0000 129A ....`.../.......

0048: 34AC 1AE0 0000 0000 0056 0001 92C7 356A 4........V....5j

0050: 0150 3070 744A 6761 7348 0031 0000 0000 .P0ptJgasH.1....

0058: 0000 0000 4400 6769 6C69 6E65 2074 544A ....D.giline tTJ

0060: 4741 482D 3153 0000 0000 0000 0000 0000 GAH-1S..........

0068: 0000 0011 0000 0000 0000 0000 0000 0000 ................

0070: 0000 0000 0000 0000 0000 0000 0000 0000 ................

0078: 0000 0000 0000 0000 0000 0000 0000 0000 ................

when i use ft2232 its work correctly

@emeb
Copy link

emeb commented Mar 30, 2024

Just a warning - some FT2232H boards being sold on AliExpress these days (March 2024) are being delivered with 128-byte EEPROMs (type 93C46) that won't hold the full 256-byte configuration required to emulate the Digilent Adept JTAG cable.

@sud234
Copy link

sud234 commented Apr 23, 2024

Hi,

How do I modify the contents of EEPROM to make both ports A and B work as Xilinx JTAG. I am able to make only port A work as JTAG using inbuilt Xilinx Vivado ftdi_write command. I have seen the FTDI dumps repo. I am willing to understand more but I do not understand how to use the dumps. I am using FT4232 with already working port A JTAG.

@fatihakalan
Copy link

Hi,

I have a custom board for FT232, 2232, and 4232. I want to program the Kria KV26 via my custom board. I used your repo to customize my custom board. I read the Digilent HS2 EEPROM data and stored it in a safe location, then I programmed my custom board with this binary file on Ubuntu 16.04. When I plugged both cards into a Windows machine, I checked the data with the FT_PROG application. All the data is the same on both boards. However, when I try with the HS2, the Vivado Hardware Manager detects it, but when I try with my custom board, it does not see the Kria; it just sees the FTDI bus(detects TCK). I share with you EEPROM data in FT_PROG in the below. (Pic1: HS2 Pic2:My custom board)

Pic1:
image

Pic2:
image
@rikka0w0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment