FTDI FT232RL: Bit Bang Mode (Linux) [Part 1]
I want to discuss the topic of easily controlling GPIO pins from a computer via a wired interface. This is particularly useful when working with a development board that I need to reset physically or put into DFU (Device Firmware Upgrade) mode. Typically, this process requires pressing the physical Reset or DFU button on the board itself. However, I aim to automate this process, allowing me to perform these actions directly from the computer using a single python
script. Additionally, having this capability would enable me to continue development even when I'm not at home, eliminating the need to be physically present with the hardware.
The first idea that comes to mind is to use an Arduino or ESP board, as they usually have a USB port and available GPIO pins, which could be configured accordingly through a serial COM port. However, this approach requires writing firmware for the MCU, implementing the serial protocol, and developing the computer-side software. It sounds like a project that I don't really have time for, so I searched for other solutions and recalled that cheap $1 USB-to-UART adapters can have a special mode that allows controlling the pins directly from the computer. So let's focus on this.
This mode is called graceful bit-bang
, and its main feature is to drive the GPIO pins from the computer while the software emulates serial protocols like SPI and I2C, providing more control over them. Although there are really rare cases when this level of control is truly needed, we use this feature for our purpose of just controlling several GPIO pins.
Choosing the Right USB to UART Converter
There are currently numerous vendors of USB to UART converters, but the most popular are:
- Silicon Labs (CP2102)
- FTDI (FT232RL)
- WCH (CH340)
- Prolific (PL2303)
Among them, FTDI
stands out as the leader in bit-bang support. Therefore, let's focus on the FTDI FT232RL
as the most affordable and popular option on the market.
Installing the D2XX Driver on Linux
Im using the Ubuntu 22.04 so lets oversee the driver documentation we wold need:
- Proprietary FTDI Driver D2XX for Linux
- D2XX Programmer's Guide
- AN_232R-01 - Bit Bang Mode Availability for the FT232R and FT245R
- FT232R datasheet
First, let's download the D2XX Linux version and install the driver. It's actually not a driver in the classical definition; instead, it's the static and dynamic compiled libraries that can be used by custom applications.
To install these libraries, follow the Readme.txt
in the D2XX driver folder:
-
Copy the libraries to the cental location
sudo cp libftd2xx.* /usr/local/lib
-
Set Permissions to allow non-root access to the shared object.
sudo chmod 0755 /usr/local/lib/libftd2xx.so.1.4.27
-
Create a Symbolic Link to the specific version of the shared object.
sudo ln -sf /usr/local/lib/libftd2xx.so.1.4.27 /usr/local/lib/libftd2xx.so
-
Copy Header Files to a Central Location.
cd .. cp ftd2xx.h /usr/local/include cp WinTypes.h /usr/local/include
-
Update the Linker Cache.
sudo ldconfig -v
On most distributions, the linux kernel will have either a built-in or optional
module called "ftdi_sio". This will detect an FTDI device and automatically
invoke the "usbserial" module and create devices such as "/dev/ttyUSB0".
When the ftdi_sio module is controlling an FTDI device it is not available to
libftd2xx. If the library attempts to access the device it will receive a
message "FT_Open failed".
To Unbind the device, first First identify the device identifier to remove.
ls /sys/bus/usb/drivers/ftdi_sio
This will show a list of ports on USB devices that are linked to the
ftdi_sio driver.
These are in the form 1-2:1.0 (bus number 1 - port number, 2 : device, 1 . interface 0) for Port A, and 1-2:1.1 would be Port B on the same device.
The /dev/ttyUSBx node can be mapped to the device identifier using:
lsusb -t
Then unbind it with the command:
echo -n 1-2:1.1 | sudo tee /sys/bus/usb/drivers/ftdi_sio/unbind
The unbind command should be executed once every time the FTDI is connected and you want to start working with D2XX driver.
The last thing to make is ensure your FTDI USB device is accessible without requiring elevated privileges, create a custom udev rule:
sudo nano /etc/udev/rules.d/99-ftdi.rules
And add the content to it:
ATTRS{idVendor}=="0403", ATTRS{idProduct}=="6001", MODE="0666"
reload the udev rules:
sudo udevadm control --reload-rules
sudo udevadm trigger
That's pretty much it for this article. In the next article, we’ll create a Python script to control our GPIO's.