offroad

FTDI library based (non-GPL) bitstream uploader

9 posts in this topic

Hi,

FTDI provides a JTAG library for use with their chips. I implemented a bitstream uploader on top of that (FPGA only, no flash).
Uploading the Pipistrello (LX45) logic analyzer bitstream takes about one second. It's marginally slower than fpgaprog - mainly the library startup; transfer time according to the LED seems about the same.

The project is attached. Note, this is meant as example code, not as a polished tool with command line options etc.
One possible advantage is that the FTDI JTAG library is open-source but not encumbered by a GPL license so it can be linked into a commercial project.
The .bit filename is hardcoded; and the IDCODE response of the FPGA needs to be changed or assertions will fail (here table 5-13).
 

jtagLoader.zip

Share this post


Link to post
Share on other sites

Looks like FTDI's FTCJTAG library is slightly buggy in 64 bit mode... tries to store void* in a DWORD ... size does matter :)

Attached a Visual Studio project that includes
FTCJTAG as source code, fixed for 64 bit and superficial changes - removed WINAPI __declspec(dll?port)
FTD2xx.lib, statically linked

In other words, the resulting .exe file needs no additional DLLs anymore.
 

jtagLoader.zip

Share this post


Link to post
Share on other sites

In BYPASS mode I'm measuring a roundtrip time of ~0.15 ms (the code below needs ~1.5 s). Not too bad...

    printf("Start\n");
    int ix;
    for (ix = 0; ix < 10000; ++ix){
        // === bypass test ===
        WriteDataBuffer[0] = 31; // bypass
        ftStatus = JTAG_Write(ftHandle, true, 6, &WriteDataBuffer, 1, RUN_TEST_IDLE_STATE); assert(ftStatus == FTC_SUCCESS);
        WriteDataBuffer[0] = ix&0x7F; // write any number 0..127
        ftStatus = JTAG_WriteRead(ftHandle, false, 8, &WriteDataBuffer, 1, &ReadDataBuffer, &dwNumBytesReturned, RUN_TEST_IDLE_STATE); assert(ftStatus == FTC_SUCCESS);
        if (ReadDataBuffer[0] != (ix & 0x7F) << 1) // check that output is shifted by 1
            printf("Error\n");
    }
    printf("Stop\n");

Share this post


Link to post
Share on other sites

An additional bugfix to FTDI's FTCJTAG library:

The final data bit in JTAG_WriteRead appears to be broken. The attached library source should fix it.

BTW, if anybody wonders what this is all about: With up to 30 MHz clock rate, we should be able to get data to and from the board much faster than with the usual UARTs, also with sub-ms latency. All that using the JTAG "channel" of the FTDI chip (which is usually idle after configuration), leaving the UART "channel" free for other stuff.
 

jtagLoader.zip

Share this post


Link to post
Share on other sites

follow-up: my example bitstream uploader actually re-started the bitstream from the flash. This was seriously broken.

I've got it working but don't have time to turn it into a standalone example. If anybody needs this, please send me a PM.

BTW, through the JTAG USER1 register I'm getting a sustained data rate > 6MBit/s (using FTDI CLK divider 1), almost 8k independent write transactions per second or 4k independent write-read transactions.
For comparison, a USB virtual COM port (UART) usually manages 1 MBaud (~900 kBit/s) and 1k transactions/second. A parallel FTDI-FPGA interface (Pipistrello) should still be faster, but the feature is rare on off-the-shelf boards.

Share this post


Link to post
Share on other sites
On ‎1‎/‎6‎/‎2017 at 6:37 PM, offroad said:

Hi,

FTDI provides a JTAG library for use with their chips. I implemented a bitstream uploader on top of that (FPGA only, no flash).
Uploading the Pipistrello (LX45) logic analyzer bitstream takes about one second. It's marginally slower than fpgaprog - mainly the library startup; transfer time according to the LED seems about the same.

The project is attached. Note, this is meant as example code, not as a polished tool with command line options etc.
One possible advantage is that the FTDI JTAG library is open-source but not encumbered by a GPL license so it can be linked into a commercial project.
The .bit filename is hardcoded; and the IDCODE response of the FPGA needs to be changed or assertions will fail (here table 5-13).

I am working on getting the MPSSE functionality of the FTDI drivers worked out to enable a bank of 16 GPIO's. This will enable you to have a JTAG, 2 SPI, and an i2c interface simultaneously, if you like. All the features are right there to be had. I am using the Delphi/Pascal lib/headers an Lazarus. I plan to use Lazarus/Freepascal to build the an interface/GUI for the Pipistrello Sump Logic Analyzer also, btw. With the MPSSE and logic analyzer working in tandem some neat possibilities open up. Imagine emulating an STM32 using the GPIO, eliminating the STM32 chip and eliminating the uploading in the "code-compile-upload" process. This way, a chip manufacturer could publish an "emulator" you can code and test against to do non-time critical evaluations. With another FTDI you can do another bank of GPIO's as a "router" to feed the logic analyzer for an automated frontend, for another example. There is a lot of untapped potential with these chips. The FTDI libraries are a goldmine and it's nice since the licensing is included with the hardware purchase, which is nice and simple. 

Good luck with it.

Share this post


Link to post
Share on other sites

Hi Captbill,

check the MPSSE capabilities carefully. As far as I know, the "fast" commands are tied to a few pre-selected pins so you'll have to write and sample the whole 8-bit IO bank. That means, the "programming paradigm" for the FTDI chip is completely different from the regular MPSSE SPI/JTAG/etc libraries, where MPSSE commands operate largely on a single pin.

The clock toggles at twice the data rate so you'd probably have to write
D0[0..7] | CLK_low
D0[0..7] | CLK_high
D1[0..7] | CLK_low
D1[0..7] | CLK_high
D2[0..7] | CLK_low
D2[0..7] | CLK_high
...

Assuming the FTDI chip can't help you with handling the clock on an arbitrary pin, you might end up with 1/3 of the data rate of a "by-the-book" MPSSE implementation.
The slightly-broken FTDI library posted above will run at clock divider 0, so I do achieve the maximum possible 1-bit data rate.

As a word of advice: JTAG isn't rocket science but in implementation it is much harder than it looks due to its flexibility (try to read other peoples' code if you don't believe it).
Most communication standards sacrifice some performance for simplicity (regular framing, layer stacks). This one is flat, and your USB "layer" adds complexity (e.g. max. size of a single FT_Write/FT_Read transaction, formatting the data for MPSSE, ..).

When it comes to "imagining": As an artist, an FPGA inspires and provokes me like a blank sheet of paper because of its infinite potential. As an engineer, blank paper is a no-cost item hauled around with forklifts by the ton :)

PS: Magnus' "FIFO" logic analyzer code might give some examples to 8-bit data handling.

Share this post


Link to post
Share on other sites
6 hours ago, offroad said:

Hi Captbill,

check the MPSSE capabilities carefully. As far as I know, the "fast" commands are tied to a few pre-selected pins so you'll have to write and sample the whole 8-bit IO bank. That means, the "programming paradigm" for the FTDI chip is completely different from the regular MPSSE SPI/JTAG/etc libraries, where MPSSE commands operate largely on a single pin.

 

Yeah, the timing I don't expect to be anywhere near the real hardware but I hope for some consistency. Good enough for some basic emulation, I hope. Doing JTAG, SPI, and I2c simultaneously will be a no go probably. I meant to say individually, one at a time. Most important is if the timing differences are of a consistent nature, for a reasonable emulator.

Thanks for the more detailed breakdown on the timing characteristics. There is very little info on MPSSE out there so this is going in my notes.

Regards

Share this post


Link to post
Share on other sites

Have a look at the FTDI application note: It's actually quite readable.

http://www.ftdichip.com/Support/Documents/AppNotes/AN_135_MPSSE_Basics.pdf
I think MPSSE is geared towards serial IO, with a pre-assigned CLK pin.

BTW, after spending a working day on FTDI's JTAG sample code (and bulldozing over 95 % of lines, and it still works, oh yeah) I've come to the conclusion that JTAG and SPI are things I'd rather deal with in Verilog than in C. It seems a total no-brainer, but only from a safe distance...

 

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now