Pure Python FTDI device driver for USB-to-serial/GPIO/SPI/I2C/JTAG bridge devices
npx @tessl/cli install tessl/pypi-pyftdi@0.57.0A pure Python library providing user-space drivers for FTDI USB-to-serial/GPIO/SPI/I2C/JTAG bridge devices. PyFtdi enables direct hardware communication without requiring kernel drivers, supporting a wide range of FTDI chips for various communication protocols and GPIO operations.
pip install pyftdipyusb>=1.0.0,!=1.2.0, pyserial>=3.0import pyftdi
from pyftdi.ftdi import FtdiProtocol-specific imports:
from pyftdi.spi import SpiController
from pyftdi.i2c import I2cController
from pyftdi.gpio import GpioAsyncController, GpioSyncController, GpioMpsseController
from pyftdi.jtag import JtagController
from pyftdi.eeprom import FtdiEeprom
from pyftdi.usbtools import UsbTools
from pyftdi.serialext import serial_for_urlfrom pyftdi.spi import SpiController
# Configure SPI controller with FTDI device
spi = SpiController()
spi.configure('ftdi:///1') # Use first available FTDI device, interface 1
# Get SPI port for chip select 0
spi_port = spi.get_port(cs=0, freq=6E6, mode=0)
# Perform SPI transaction
response = spi_port.exchange([0x9F], 3) # Read device ID
print([hex(x) for x in response])
# Clean up
spi.terminate()PyFtdi provides layered access to FTDI devices:
ftdi): Low-level FTDI device communication and configurationThis design enables both simple protocol-specific usage and advanced multi-protocol applications where one FTDI device handles multiple communication types simultaneously.
PyFtdi uses URL-based device specification for consistent device addressing:
ftdi://[vendor[:product[:index|:serial]]]/interfaceftdi:///1 - Any FTDI device, interface 1ftdi://0x403:0x6014:0/1 - Specific FT232H device, interface 1ftdi://0x403:0x6014:12345678/1 - Device with serial number 12345678Single Port Devices (UART + GPIO):
Multi-Protocol Devices (UART + GPIO + SPI + I2C + JTAG):
Low-level FTDI device access, configuration, and direct communication for custom protocols or advanced usage scenarios.
class Ftdi:
def open(self, device, interface, direction=None, **kwargs): ...
def close(self): ...
def read_data(self, size): ...
def write_data(self, data): ...
def set_baudrate(self, baudrate): ...
def reset(self): ...SPI master controller with support for multiple chip selects, simultaneous GPIO access, variable clock speeds up to 30MHz, and non-byte-aligned transfers.
class SpiController:
def configure(self, url, **kwargs): ...
def terminate(self): ...
def get_port(self, cs, freq=6000000, mode=0): ...
def get_gpio(self): ...
class SpiPort:
def exchange(self, out, readlen=0, start=True, stop=True, duplex=False): ...
def read(self, readlen, start=True, stop=True): ...
def write(self, out, start=True, stop=True): ...I2C master controller with support for device addressing, register access, bus scanning, simultaneous GPIO access, and clock stretching handling.
class I2cController:
def configure(self, url, **kwargs): ...
def terminate(self): ...
def get_port(self, address): ...
def get_gpio(self): ...
class I2cPort:
def read(self, readlen, relax=True): ...
def write(self, out, relax=True): ...
def read_from(self, regaddr, readlen, relax=True): ...
def write_to(self, regaddr, out, relax=True): ...
def exchange(self, out, readlen, relax=True): ...Multiple GPIO controller types supporting different operating modes: asynchronous bitbang, synchronous clocked operation, and high-performance MPSSE mode.
class GpioAsyncController:
def set_direction(self, pins, direction): ...
def read(self, with_output=False): ...
def write(self, value): ...
class GpioSyncController:
def set_direction(self, pins, direction): ...
def read(self, with_output=False): ...
def write(self, value): ...
class GpioMpsseController:
def set_direction(self, pins, direction): ...
def read(self, with_output=False): ...
def write(self, value): ...JTAG controller supporting TAP state machine management, instruction and data register access, chain discovery, and basic debugging operations.
class JtagController:
def configure(self, url, **kwargs): ...
def close(self): ...
def reset(self): ...
def write_ir(self, instruction): ...
def write_dr(self, data): ...
def read_dr(self, length): ...
def shift_register(self, out, length): ...FTDI device EEPROM access for reading configuration, modifying device parameters, and managing device identity information.
class FtdiEeprom:
def open(self, device): ...
def close(self): ...
def read_eeprom(self): ...
def write_eeprom(self): ...
def erase_eeprom(self): ...
def set_manufacturer_name(self, name): ...
def set_product_name(self, name): ...
def set_serial_number(self, serial): ...
def sync(self): ...USB device enumeration, FTDI device detection, URL parsing, and device capability identification.
class UsbTools:
@staticmethod
def find_all(vps, nb=0): ...
@staticmethod
def get_device(vendor, product, index=0, serial=None, path=None): ...
@staticmethod
def show_devices(vendor, product, serial=None): ...
@staticmethod
def parse_url(url, scheme): ...PySerial-compatible interface for UART communication using FTDI devices, enabling drop-in replacement for standard serial ports.
from pyftdi.serialext import serial_for_url
def serial_for_url(url, **kwargs):
"""Create serial connection from FTDI URL"""# Exception types
class FtdiError(IOError): ...
class FtdiFeatureError(FtdiError): ...
class FtdiMpsseError(FtdiFeatureError): ...
class FtdiEepromError(FtdiError): ...
class SpiIOError(FtdiError): ...
class I2cIOError(IOError): ...
class I2cNackError(I2cIOError): ...
class I2cTimeoutError(TimeoutError): ...
class GpioException(FtdiError): ...
class JtagError(Exception): ...
class UsbToolsError(Exception): ...
# Logging utilities
class FtdiLogger:
log: Logger
@classmethod
def set_formatter(cls, formatter): ...
@classmethod
def get_level(cls): ...
@classmethod
def set_level(cls, level): ...