element14 Community
element14 Community
    Register Log In
  • Site
  • Search
  • Log In Register
  • Community Hub
    Community Hub
    • What's New on element14
    • Feedback and Support
    • Benefits of Membership
    • Personal Blogs
    • Members Area
    • Achievement Levels
  • Learn
    Learn
    • Ask an Expert
    • eBooks
    • element14 presents
    • Learning Center
    • Tech Spotlight
    • STEM Academy
    • Webinars, Training and Events
    • Learning Groups
  • Technologies
    Technologies
    • 3D Printing
    • FPGA
    • Industrial Automation
    • Internet of Things
    • Power & Energy
    • Sensors
    • Technology Groups
  • Challenges & Projects
    Challenges & Projects
    • Design Challenges
    • element14 presents Projects
    • Project14
    • Arduino Projects
    • Raspberry Pi Projects
    • Project Groups
  • Products
    Products
    • Arduino
    • Avnet & Tria Boards Community
    • Dev Tools
    • Manufacturers
    • Multicomp Pro
    • Product Groups
    • Raspberry Pi
    • RoadTests & Reviews
  • About Us
    About the element14 Community
  • Store
    Store
    • Visit Your Store
    • Choose another store...
      • Europe
      •  Austria (German)
      •  Belgium (Dutch, French)
      •  Bulgaria (Bulgarian)
      •  Czech Republic (Czech)
      •  Denmark (Danish)
      •  Estonia (Estonian)
      •  Finland (Finnish)
      •  France (French)
      •  Germany (German)
      •  Hungary (Hungarian)
      •  Ireland
      •  Israel
      •  Italy (Italian)
      •  Latvia (Latvian)
      •  
      •  Lithuania (Lithuanian)
      •  Netherlands (Dutch)
      •  Norway (Norwegian)
      •  Poland (Polish)
      •  Portugal (Portuguese)
      •  Romania (Romanian)
      •  Russia (Russian)
      •  Slovakia (Slovak)
      •  Slovenia (Slovenian)
      •  Spain (Spanish)
      •  Sweden (Swedish)
      •  Switzerland(German, French)
      •  Turkey (Turkish)
      •  United Kingdom
      • Asia Pacific
      •  Australia
      •  China
      •  Hong Kong
      •  India
      •  Japan
      •  Korea (Korean)
      •  Malaysia
      •  New Zealand
      •  Philippines
      •  Singapore
      •  Taiwan
      •  Thailand (Thai)
      •  Vietnam
      • Americas
      •  Brazil (Portuguese)
      •  Canada
      •  Mexico (Spanish)
      •  United States
      Can't find the country/region you're looking for? Visit our export site or find a local distributor.
  • Translate
  • Profile
  • Settings
BeagleBoard
  • Products
  • Dev Tools
  • Single-Board Computers
  • BeagleBoard
  • More
  • Cancel
BeagleBoard
Blog BBB - USB I/O with FTDI FT2232H
  • Blog
  • Forum
  • Documents
  • Quiz
  • Polls
  • Files
  • Members
  • Mentions
  • Sub-Groups
  • Tags
  • More
  • Cancel
  • New
Join BeagleBoard to participate - click to join for free!
  • Share
  • More
  • Cancel
Group Actions
  • Group RSS
  • More
  • Cancel
Engagement
  • Author Author: shabaz
  • Date Created: 15 Jul 2013 12:16 AM Date Created
  • Views 6058 views
  • Likes 7 likes
  • Comments 16 comments
  • bbb
  • bb_black
  • beagle_bone_black
  • data_acquisition
  • ftdi
  • ti
Related
Recommended

BBB - USB I/O with FTDI FT2232H

shabaz
shabaz
15 Jul 2013

Introduction - why would you want to extend I/O over USB?

The Beaglebone Black's PRU allows very high speed I/O capabilities with guaranteed timing while Linux applications continue to run. As useful as this is, occasionally there may be a need to use FTDI's USB-interfacing UART/FIFO ICs to extend capabilities further. There are a number of benefits to this:

 

* It increases the number of I/O pins available

* It increases the number of serial interfaces

* Provides interfacing to traditional peripherals that require *CS, *RD, *WR signals and an 8-bit data bus

* High speed parallel data transfer (60MHz) in a FIFO mode

* Portability so that applications can run on any device with a USB port

 

In theory the notes here should work just fine for other processor boards too, e.g. RPI, but clearly having a good USB capability (and the processing power to handle high-speed parallel data transfer is important - and the BBB is the ideal platform).

Some example applications could also be listed, but it's clear the possibilities are vast. Another benefit is that it is possible to easily enable a USB interface on custom hardware, by simply adding a FTDI chip to the project. It's only fair to mention that there are alternative, possibly lower cost methods too. People have successfully shoe-horned small USB stacks into small PIC and AVR microcontrollers that do not possess a native USB interface. Atmel offer ATmega devices that already contain USB capability, at very little cost.

Other manufacturers like Silabs, Exar and Cypress produce devices with similar capabilities to FTDI devices too.

Is it easy?

It turned out to be surprisingly easy - almost no soldering if a pre-built board is used, and very little coding. For creating a custom board (e.g. with your own peripherals on it), FTDI devices don't need a lot of additional circuitry.

There are quite a few similar-sounding part codes, but the FT2232H (PDF datasheet) has been on the interest list for quite a while - working with the BBB provided the opportunity to finally experiment with it. For clarity, it is the FT2232H range, available in a QFP package as part code FT2232HL-R.

 

Connecting up the FT2232H to the BBB

Like most of FTDI's chips, it doesn't take a lot of circuitry to assemble, however in this case I just used a pre-built board available from Seeed Studio for a quick prototyping exercise.

image

Connecting this to a BBB is trivial - just plug in the USB connector and it will power up from the 5V offered by the BBB's USB host port. For experimentation, I tried the so-called bitbang mode, which provides 16 pins of I/O in two banks of 8. Of more interest will be the FIFO modes for high-speed data transfer at up to 60MHz.

 

When plugged in, lsusb reveals the following:

root@beaglebone:~# lsusb
Bus 001 Device 003: ID 0403:6010 Future Technology Devices International, Ltd FT2232C Dual USB-UART/FIFO IC
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
root@beaglebone:~#

 

Note the 0403:6010 - this is the vendor and product ID respectively, in hex (needed later). The board doesn't come with any connector, so SIL headers need to be soldered. The reverse of the board shows the pin naming, and the circuit diagram is here.

image

The bitbang mode is brought out to the ADBUS[7..0] and BDBUS[7..0] pins. For input testing, I just pulled various pins high and low (i.e. to 3.3V and 0V) through a 1k resistor (in case a pin was accidentally still an output) and for output testing a multimeter was used (an LED and resistor would be fine too).

Software introduction

Generally, hi speed I/O may require kernel drivers; in the case of the FT2232H this is no different, but it is already part of Linux images. Some code and libraries are required as part of the application. This is explained in the diagram below.

image

The application software will be the area of interest, where the data is received and transmitted and any processing with the end data is handled. To connect to the kernel driver, a couple of libraries of code need to be linked in to the application code; these are libftdi (open source library for many FTDI ICs) and libusbx which provides a consistent API regardless of if the OS is Linux or Windows.

Building the software

This was quite simple; three downloads are required:

libftdi (download here) - I used version 1-1.0

libconfuse (download here) - version 2.7 - this is used for parsing text files for configuration purposes

libusbx (download link) - version 1.0.16

Create a folder off your home directory (e.g. called 'development') and create a folder called usb inside it.

The three downloads were extracted in the usb folder.

Installing libconfuse 2.7:

./configure
make
make install

(installs in /usr/local/include,lib and share)

 

For libusbx 1.0.16:

./configure --disable-udev
make
make install

(installs in /usr/local/libusb-1.0 and /usr/local/lib)

 

For libftdi 1-1.0, the makefiles are intended to be built with cmake, which I didn't have installed (and is a little unfamiliar to me) - however it is possible to build the code from the command line easily, there are not a lot of commands.

In the folder where libftdi was extracted, traverse to the 'src' folder. Then copy ftdi_versio_i.h.in to ftdi_versio_i.h and replace the variables marked with '@' with a custom value. In other words, modify the following lines so that this is how they appear, and then save the file.

#define FTDI_MAJOR_VERSION 1
#define FTDI_MINOR_VERSION 1
#define FTDI_MICRO_VERSION 0

const char FTDI_VERSION_STRING[] = "1-1.0";
const char FTDI_SNAPSHOT_VERSION[] = "0";

In the same src folder, compile like this:

gcc -c ftdi.c -I/usr/local/include/libusb-1.0
gcc -c ftdi_stream.c -I/usr/local/include/libusb-1.0
ar rs libftdi.a ftdi.o ftdi_stream.o
cp libftdi.a /usr/local/lib/.
cp ftdi.h /usr/local/include/.

Now the code in ftdi_eeprom can be compiled (path is development/usb/libftdi1-1.0/ftdi_eeprom). It requires a file ftdi_eeprom_version.h to be created in a similar manner as before.

#define EEPROM_MAJOR_VERSION 1
#define EEPROM_MINOR_VERSION 1
#define EEPROM_VERSION_STRING "1-1.0"

Type these commands to compile it:

gcc main.c -I/usr/local/include/libusb-1.0  -I/usr/local/include -I. -L/usr/local/lib -lftdi -lusb-1.0 -lconfuse -o ftdi_eeprom
cp ftdi_eeprom /usr/bin

Then example code files can be compiled as shown here for instance (path is development/usb/libftdi1-1.0/examples):

gcc simple.c -I/usr/local/include/libusb-1.0  -I/usr/local/include -L/usr/local/lib -lftdi -lusb-1.0 -o ftdi_simple
cp ftdi_simple /usr/bin

There is an another example program in the same folder, called bitbang_ft2232.c but it needs a small change; replace where it says 0x6001 (product ID) with 0x6010 in two places, and then compile:

gcc bitbang_ft2232.c -I/usr/local/include/libusb-1.0  -I/usr/local/include -L/usr/local/lib -lftdi -lusb-1.0 -o bitbang

When the bitbang program is run, it will just slowly toggle some pins (bits 0 and 1) on the two ports.

As an experiment, the code was modified to toggle pins with no delay for thousands of times; a speed of about 20,000 writes per second is possible, allowing for 10kHz square-waves (this was not measured on a scope, so it is just a guideline). Bitbanging in this manner will not have real-time accuracy like the PRU. (The FIFO mode that the FT2232H is capable of will be far better than bitbanging too, but needs to still be tested. However, bitbanging is still suitable for some purposes). Note: See comments section below. Accuracy is extremely poor with the bitbang way; an alternative method using buffers is available on the FTDI and that method should be investigated.

A quick program was created to test inputs in bitbanging mode too, and it reads input values at a similar speed. The program is attached (very untidy for now - it's late in the evening! but it works). The program reads the AD[7..0] pins repeatedly, and displays the 8-bit value in hex on the screen. Run it, and it will display lots of 0xff on the screen (the inputs appear to float high) and pulling low (1k resistor to 0V) on any of the input pins will make the text change.

To compile the code:

gcc bbtest.c -I/usr/local/include/libusb-1.0  -I/usr/local/include -L/usr/local/lib -lftdi -lusb-1.0 -o bbtest

 

Summary / Next Steps

To a large extent the PRU capability has rendered this almost redundant, but it's good to know that it is easy to interface high-speed data in several ways with the BBB now. The FTDI device is easy to use because a ready-built board is available, but equally it is easy to include the IC on a PCB where a USB interface is not currently available. Experimenting with the FIFO modes will be interesting.

 

Part 2: FIFO mode

A "synchronous FIFO" mode is available on the FT2232H, which is supposed to allow far higher rate I/O. In order to enable this, an EEPROM needs to be programmed. There is a ftdi_eeprom program that was compiled earlier (see above), however it did not work. The alternative is to just download a Windows executable called FT_PROG and use that.

Download FT_PROG from here  (PDF help file is here).

Run FT_PROG, click on the magnifying glass icon ("scan and parse") to read the board EEPROM. It will display as lots of FFFF, since it is a blank part.

image

On the left side device tree, expand to FT EEPROM->Hardware Specific->Port A->Hardware, and change the property from RS232 UART to 245 FIFO, which is needed for the FIFO modes to function. Repeat for Port B.

Then, go to File->Save as Template (e.g. my245fifotemplate.xml).

Select the Device:0 on the device tree, right click, and select 'Program device'. It should be virtually instantaneous, and the Device Output will show some new values instead of FFFF.

You could confirm all is well by restarting the FT_PROG application and clicking the scan icon again, and viewing the EEPROM contents.

 

Once this is done, unplug the FT2232H from the Windows maching and plug it back into the BBB. There is code in the examples folder called stream_test.c, and it is compiled in a similar manner as the other examples:

gcc stream_test.c -I/usr/local/include/libusb-1.0  -I/usr/local/include -L/usr/local/lib -lftdi -lusb-1.0 -o ftdi_stream_test
cp ftdi_stream_test /usr/bin

The program can be run by typing:

ftdi_stream_test -n dump.bin

It will capture data at a very high speed and dump to a file (unformatted raw bytes), whenever the *WR pin (pin 27 on the FT2232H-R chip, or P3_17 (ACBUS3) on the ready-built board is pulled low.

The '-n' suppresses error messages when bytes are skipped.

It appears that bytes are guaranteed to skip, and I'm guessing this is because there is a delay writing to the filesystem. With a very short *WR pulse (of the order of tens of nsec) the number of bytes written to file appear to be close to the expected value (assuming that the FT2232H is trying to capture at 60MHz). At any longer pulse, bytes are skipped. For further investigation!

Attachments:
bbtest.c.txt.zip
  • Sign in to reply

Top Comments

  • Former Member
    Former Member over 12 years ago +3
    A couple of observations as I'm just delving into libftdi for a second time... Lots of the libftdi code has hard coded device id's that dont cover all of the available ftdi devices. For example the ftdi_usb_find_…
  • Former Member
    Former Member over 12 years ago +2
    I forgot to say, your diagram shows libftdi & libusbx sitting on top of a driver. That's slightly misleading. While there will be a driver of some sort for the USB host port that will be there regardless…
  • Former Member
    Former Member over 12 years ago in reply to shabaz +2
    shabaz wrote: The white box being the Linux standard USB driver or Windows, etc. That's sort of my point.. plug a FTDI chip into a windows machine and you get the D2XX and/or Standard COM port drivers…
  • shabaz
    shabaz over 12 years ago in reply to Former Member

    Ah, got it - I understand. I've had to do the same too, on my Windows machine before I could try out libftdi for Serial-to-USB. I had to go through the pain of searching in .inf files (or try to change the VID/PID and have the risk to mis-configure the eeprom! Which I did).

    I'll update the diag, and change the white box to say "Standard USB driver (any FTDI vendor driver must be uninstalled)".

    Thanks for the clarification.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Former Member
    Former Member over 12 years ago in reply to shabaz

    shabaz wrote:

    The white box being the Linux standard USB driver or Windows, etc.

    That's sort of my point.. plug a FTDI chip into a windows machine and you get the D2XX and/or Standard COM port drivers loaded for you, but to use libusbx/libftdi you have to remove those and replace them with something else before libusb can talk to the device. (Just been through all this since my device in the photo will eventually be used on a windows machine)

    Similarly on linux, you'll get ftdi_sio loaded by udev, but as that claims the device you need to remove it before libftdi can control the same functions.

     

    In contrast, my usb scanner doesn't have a kernel driver at all, instead xsane finds it using libusb.

     

    So ignore everything in the Application software box, below that you have a box labelled 'Driver'. What driver is that ?  Keeping in mind that there's a specific kernel driver called ftdi_sio that gets loaded for all compatible FTDI devices.  When someone sees a diagram like that, first thought will usually be that it's the driver for the FTDI device.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • shabaz
    shabaz over 12 years ago in reply to Former Member

    Hi Selsinork,

     

    Thanks for the information. I concur, the FTDI part is expensive for what it is. I'll bear the FT232H in mind for projects.

    Interesting comments on using read_data and write_data for enabling the buffer and have better flow, and how the baud rate setting (I was wondering what that was for in some of the example code!) can be used to control the input/output rate! I suppose they repurpose the UART clock present in the silicon for bitbang mode!

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • shabaz
    shabaz over 12 years ago in reply to Former Member

    Hi Selsinork,

     

    My understanding was that libusbx provided a consistent northbound API so that portable software can be written without having to worry if the underlying kernel and (standard USB) driver belonged to Linux or Windows, and that libftdi made use of that API. Both libusbx and libftdi running in the user application space. The white box being the Linux standard USB driver or Windows, etc.

    Did you mean the diagram makes it look like libftdi could be a driver? Or is my understanding above incorrect? I suppose the diagram above is a bit vague - It is drawn like a protocol stack, although in this case it is APIs. Let me know, and I'll get it changed.

    • Cancel
    • Vote Up 0 Vote Down
    • Sign in to reply
    • More
    • Cancel
  • Former Member
    Former Member over 12 years ago

    I forgot to say, your diagram shows libftdi & libusbx sitting on top of a driver.  That's slightly misleading. While there will be a driver of some sort for the USB host port that will be there regardless if you want to be able to talk to the usb bus.

     

    The diagram could give the impression that you need the ftdi_sio driver installed and libusbx then talks to that, but a big part of the point of libusbx is that you can talk to the device without requiring a driver at all and can therefore write your driver as a userspace application.

    • Cancel
    • Vote Up +2 Vote Down
    • Sign in to reply
    • More
    • Cancel
<>
element14 Community

element14 is the first online community specifically for engineers. Connect with your peers and get expert answers to your questions.

  • Members
  • Learn
  • Technologies
  • Challenges & Projects
  • Products
  • Store
  • About Us
  • Feedback & Support
  • FAQs
  • Terms of Use
  • Privacy Policy
  • Legal and Copyright Notices
  • Sitemap
  • Cookies

An Avnet Company © 2026 Premier Farnell Limited. All Rights Reserved.

Premier Farnell Ltd, registered in England and Wales (no 00876412), registered office: Farnell House, Forge Lane, Leeds LS12 2NE.

ICP 备案号 10220084.

Follow element14

  • X
  • Facebook
  • linkedin
  • YouTube