FTDI Linux Misery

1. install ftdi-eeprom and libftdi using apt

chris@chris-MacBookPro:~$ apt list --installed | grep ftdi

ftdi-eeprom/jammy,now 1.5-5build3 amd64 [installed]
libftdi1-2/jammy,now 1.5-5build3 amd64 [installed]
libftdi1-dev/jammy,now 1.5-5build3 amd64 [installed]
libftdi1-doc/jammy,jammy,now 1.5-5build3 all [installed,automatic]

2. Update udev rules

Add a script that will unload the ftdi_sio and usbserial drivers. These drivers conflict with the libftdi driver and prevent ftdi_eeprom from accessing the FTDI chip.

chris@chris-MacBookPro:~$ cat /usr/local/bin/ftdi_sio_unload.sh
#!/bin/bash

# unload the conflicting drivers
rmmod ftdi_sio
rmmod usbserial

Make sure the file is executable:

sudo chmod +x /usr/local/bin/ftdi_sio_unload.sh

Now add a rule that will execute the unload script and set the device file permissions when the FTDI module is inserted.

chris@chris-MacBookPro:~$ cat /etc/udev/rules.d/99-ftdi.rules 
# FTDI rules

SUBSYSTEM=="usb", ATTRS{idVendor}=="0403", ACTION=="add", RUN+="/usr/local/bin/ftdi_sio_unload.sh"

SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", GROUP="dialout", MODE="0777"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6010", GROUP="dialout", MODE="0777"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6011", GROUP="dialout", MODE="0777"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6014", GROUP="dialout", MODE="0777"
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6015", GROUP="dialout", MODE="0777

4. Read from the FTDI chip

Create a configuration file. For a read operation this tells ftdi_eeprom where to save the bin file:

# see /usr/share/doc/ftdi-eeprom for examples

# ftdi_eeprom code can be found at:
# http://developer.intra2net.com/git/?p=libftdi;a=blob;f=src/ftdi.c
# http://developer.intra2net.com/git/?p=libftdi;a=blob;f=src/ftdi.h
# http://developer.intra2net.com/git/?p=libftdi;a=tree;f=ftdi_eeprom
# http://developer.intra2net.com/git/?p=libftdi;a=blob;f=ftdi_eeprom/example.conf
# http://developer.intra2net.com/git/?p=libftdi;a=blob;f=ftdi_eeprom/main.c

filename="ft2232h.bin"   # Filename of the EE file to be generated. Leave empty to skip file writing
#flash_raw=false

# Set the IDs here so you dont have to use the --device option  vendor_id=0x0403
product_id=0x6010

# set these according to the reqs of your programmer SW
manufacturer="ACME Inc"                                 # String: Manufacturer. FT245R factory default FTDI
product="USB Serial Converter"                          # String: Product. FT245R factory default FT245R USB FIFO
serial="08-15"                                          # String: Serial"number". FT245R factory default (sample chip) A9082P2B
use_serial=true                                         # Boolean: Use the serial number string

max_power=500           # Integer: Max. power consumption: value * 2 mA(?). Use 0 if self_powered = true. FT245R factory default 90
self_powered=false      # Boolean: Turn this off for bus powered
remote_wakeup=true      # Boolean: Turn this on for remote wakeup feature

# 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

# Strings to be used in this config file are: 
# "UART", "FIFO", "OPTO", "CPU", "FT1284"
cha_type=UART
chb_type=UART

cha_vcp=true
chb_vcp=true

eeprom_type=0x46        # Integer: Chip Type / EEPROM Type. Corresponds to ftdi_chip_type struct in ftdi.h

## Pin Configuration
#invert_txd                                                # Boolean: Invert TXD signal
#invert_rxd                                                # Boolean: Invert RXD signal
#invert_rts                                                # Boolean: Invert RTS signal
#invert_cts                                                # Boolean: Invert CTS signal
#invert_dtr                                                # Boolean: Invert DTR signal
#invert_dsr                                                # Boolean: Invert DSR signal
#invert_dcd                                                # Boolean: Invert DCD signal
#invert_ri                                             # Boolean: Invert RI signal

Now run the read command:

chris@chris-MacBookPro:~$ ftdi_eeprom --verbose --device i:0x0403:0x6010  --read-eeprom ft2232.conf

FTDI eeprom generator v0.17
(c) Intra2net AG and the libftdi developers <opensource@intra2net.com>
FTDI read eeprom: 0
EEPROM size: 256
VID:     0x0403
PID:     0x6010
Release: 0x0700
Bus Powered: 100 mA USB Remote Wake Up
Manufacturer: FTDI
Product:      USB <-> Serial Converter
Serial:       FT4X8O38
Checksum      : c71a
Attached EEPROM: 93x56
Pull IO pins low during suspend
Enable Remote Wake Up
PNP: 1
Channel A has Mode UART VCP
Channel B has Mode UART VCP
AL has 4 mA drive
AH has 4 mA drive
BL has 4 mA drive
BH has 4 mA drive
Warning: Not writing eeprom, you must supply a valid filename
FTDI close: 0

The file is now found in the current dir:

Its a good idea to backup this file now, in case of accidents later!

5. Build a new eeprom bin

Using the existing conf file we can rebuild the eeprom bin to contain different settings. Notice that our conf file had different manufacturer/produc/serial settings from the values that were read from the chip. Lets rebuild the eeprom bin using those new settings:

chris@chris-MacBookPro:~$ ftdi_eeprom --build-eeprom ft2232.conf 

FTDI eeprom generator v0.17
(c) Intra2net AG and the libftdi developers <opensource@intra2net.com>
FTDI read eeprom: 0
EEPROM size: 256
Used eeprom space: 236 bytes
Writing to file: ft2232h.bin
FTDI close: 0

Note if you add to many characters to these conf settings you will exceed the eeprom max size and get an error from ftdi_eeprom

Lets have a look at our new eeprom binary:

6. Write the new bin image to the chip eeprom

Use the flash command to write the new image to the chip eeprom. Again, the conf file is only used to tell ftdi_eeprom where to find the bin file.

chris@chris-MacBookPro:~$ ftdi_eeprom --flash-eeprom ft2232.conf 

FTDI eeprom generator v0.17
(c) Intra2net AG and the libftdi developers <opensource@intra2net.com>
FTDI read eeprom: 0
EEPROM size: 256
Used eeprom space: 236 bytes
FTDI write eeprom: 0
Writing to file: ft2232h.bin
FTDI close: -1

Note sure why we get a -1 on the close operation. It doesn’t seem to matter.

Now lets unplug the FTDI module and see what we get when its plugged in again:

chris@chris-MacBookPro:~$ ftdi_eeprom --verbose --read-eeprom ft2232.conf

FTDI eeprom generator v0.17
(c) Intra2net AG and the libftdi developers <opensource@intra2net.com>
FTDI read eeprom: 0
EEPROM size: 256
VID:     0x0403
PID:     0x6010
Release: 0x0700
Bus Powered: 500 mA USB Remote Wake Up
Manufacturer: ACME Inc
Product:      USB Serial Converter
Serial:       08-15
Checksum      : c7bc
Attached EEPROM: 93x46
Enable Remote Wake Up
PNP: 1
Channel A has Mode FIFO
Channel B has Mode UART VCP
AL has 4 mA drive
AH has 4 mA drive
BL has 4 mA drive
BH has 4 mA drive
FTDI close: 0

7. Resources

  • config file example is installed to here: /usr/share/doc/ftdi-eeprom

  • ftdi_eeprom code can be found at: http://developer.intra2net.com/git

  • udev tips: https://www.bitshiftmyrobot.com/2024/10/09/udev-tips/

Leave a Reply

Your email address will not be published. Required fields are marked *