How to read and program the EEPROM and configuration of FTDI FT2xx ICs on Linux or Mac OS X

Yes, it is possible, just a little awkward.

For linux, the process is covered nicely in this mozilla sensorweb wiki page, although the explanations here might help to clarify some things. On Mac OS X, there are a few extra steps or changes, especially if you want to install libftdi using homebrew.

When built with the confuse library installed, libftdi also builds a utility called ftdi_eeprom, which can be used to read, flash and erase FT2xx IC’s configuration and EEPROM, much like the FT_PROG GUI utility can on Windows. I tried running FT_PROG in Wine with no success, and so tried installing libftdi. The current homebrew recipe for libftdi installs the library itself, but only one of the example programs and not the FTDI EEPROM utility.

To correct this, first run

brew edit libftdi

then edit the recipe to look something like this:

class Libftdi < Formula
  desc "Library to talk to FTDI chips"
  homepage "https://www.intra2net.com/en/developer/libftdi"
  url "https://www.intra2net.com/en/developer/libftdi/download/libftdi1-1.4.tar.bz2"
  sha256 "ec36fb49080f834690c24008328a5ef42d3cf584ef4060f3a35aa4681cb31b74"

  bottle do
    cellar :any
    rebuild 1
    sha256 "7cc50de6d35d5c7dd6d73a9ff075696dfe82ce57db9464c37b0a35dc0cf8707f" => :mojave
    sha256 "a28c4f481c8174edfb845492c4155511cac868082fd65cce625b55a82f3b54c0" => :high_sierra
    sha256 "ef603f79c7791bac035bf1afe21dcea4b6323372140a246f9aa52031b3631f6b" => :sierra
    sha256 "c023c826c533fd60e664a8f604f54017f84b356e625bbbafb8e5365e4319fa7a" => :el_capitan
    sha256 "7fc5addb888f58fbbd2a2e2e414ead4819a48b7fff4f6b0ebed274b499a38a40" => :yosemite
  end

  depends_on "cmake" => :build
  depends_on "pkg-config" => :build
  depends_on "swig" => :build
  depends_on "libusb"
  depends_on "boost" => :optional
  depends_on "confuse" => :build

  def install
    mkdir "libftdi-build" do
      system "cmake", "..", "-DPYTHON_BINDINGS=OFF", *std_cmake_args
      system "make", "install"
      (libexec/"bin").install "examples/bitbang", "examples/bitbang_ft2232", "examples/find_all", "examples/simple", "examples/bitbang2", "examples/find_all_pp", "examples/stream_test", "examples/baud_test", "examples/bitbang_cbus", "examples/eeprom", "examples/serial_test", "ftdi_eeprom/ftdi_eeprom"
      
      bin.install_symlink libexec/"bin/ftdi_eeprom"
    end
  end

  test do
    system libexec/"bin/find_all"
  end
end

The important changes are making depends_on "confuse" no longer be optional, changing the (libexec/"bin").install line to install the ftdi_eeprom binary and all of the examples (why not, they’re useful), and most importantly, creating a symlink to the ftdi_eeprom binary so that we can run it from anywhere without having to reference the whole path to the libftdi install location.

Having made these changes, install libftdi:

brew install libftdi --build-from-source

You should now be able to run

ftdi_eeprom

and see some nice usage text like this

FTDI eeprom generator v0.1
(c) Intra2net AG and the libftdi developers 
Syntax: ftdi_eeprom [...options...] 
Valid Options:
…
…

Now you’ve successfully installed libftdi and the eeprom utility, you are able to read and program FTDI FT2xx series ICs plugged in to your computer over USB.

Firstly, you need to disable whatever FTDI kernel extension (“driver”) you have installed. You will probably have one or both of the FTDI drivers available installed, and may have to try unloading both of them:

sudo kextunload -b com.apple.driver.AppleUSBFTDI
sudo kextunload -b com.FTDI.driver.FTDIUSBSerialDriver

Make a note of which one successfully unloaded so you can restore the same one once you’ve finished.

The behaviour of the ftdi_eeprom utility is configured mainly from a .conf file, the path to which is provided as the first argument. I couldn’t find any documentation for these configuration files so based mine off this one referenced from the sensorweb repo mentioned above.

The same conf file is used for reading and writing to the FT2xx chip. Here’s my template, with comments explaining how it works (or at least how I think it seems to work…)


# The Vendor ID and Product ID seem to identify a particular chipset
# to target. I used the libftdi utilities and OS X USB Prober app to
# poke around and figure out what numbers to use.

vendor_id=0x403
product_id=0x6001

# The rest of the fields are settings which can be written to the
# FT2xx with the --flash-eeprom option.

# Max. power consumption: value * 2 mA. Use 0 if self_powered = true.
max_power=500

###########
# Strings #
###########
manufacturer="YOUR MANUFACTURER ID HERE"
product="YOUR PRODUCT NAME HERE"
serial="YOUR SERIAL NUMBER HERE"

###########
# Options #
###########
self_powered=false  # Turn this off for bus powered
remote_wakeup=false # Turn this on for remote wakeup feature
use_serial=true     # Use the serial number string

# Normally out don't have to change one of these flags
in_is_isochronous=false     # In Endpoint is Isochronous
out_is_isochronous=false    # Out Endpoint is Isochronous
suspend_pull_downs=false    # Enable suspend pull downs for lower power
change_usb_version=false    # Change USB Version
usb_version=0x0200          # Only used when change_usb_version is enabled

cha_vcp=false
cha_type=FIFO
chb_type=UART

eeprom_type=0x46

########
# Misc #
########

# This is the relative filename that EEPROM contents will either be 
# read from or written to, depending on whether ftdi_eeprom is run
# with the --read-eeprom or --flash-eeprom option.
filename="eeprom.bin"

As mentioned in the comments, first adjust the vendor_id and product_id to match the FT2xx you’re using, then try running

ftdi_eeprom --read-eeprom path/to/your/config_file.conf

You should now find an eeprom.bin file containing the bytes which were stored in the FT chip’s EEPROM. You can now edit that file, as well as changing the settings in the conf file, before running

ftdi_eeprom --flash-eeprom path/to/your/config_file.conf

to write your settings to the chip.

For my use case, writing a custom EEPROM file to the chip was not necessary, so I just left out the filename="eeprom.bin" line, and everything worked fine.

Remember to reload your FTDI kernel extension after making the changes! Probably either

sudo kextload -b com.apple.driver.AppleUSBFTDI

or

sudo kextload -b com.FTDI.driver.FTDIUSBSerialDriver