Pure Python FTDI device driver for USB-to-serial/GPIO/SPI/I2C/JTAG bridge devices
—
FTDI device EEPROM access for reading configuration, modifying device parameters, and managing device identity information. Enables customization of USB descriptors, device behavior, and hardware configuration.
Open and manage EEPROM access on FTDI devices.
class FtdiEeprom:
def open(self, device):
"""
Open EEPROM access on FTDI device.
Parameters:
- device: FTDI device URL, UsbDevice, or device descriptor
Raises:
- FtdiEepromError: EEPROM access failed
- FtdiError: Device connection error
"""
def close(self):
"""Close EEPROM access and release device."""
def is_empty(self) -> bool:
"""Check if EEPROM is empty (all 0xFF)."""Read EEPROM content and configuration data.
def read_eeprom(self) -> bytes:
"""
Read entire EEPROM content.
Returns:
bytes: Complete EEPROM data
Raises:
- FtdiEepromError: Read operation failed
"""
def dump_config(self, file=None) -> str:
"""
Dump current EEPROM configuration in human-readable format.
Parameters:
- file: Optional file object to write output
Returns:
str: Configuration dump
"""
def size(self) -> int:
"""
Get EEPROM size in bytes.
Returns:
int: EEPROM size
"""
def data_width(self) -> int:
"""
Get EEPROM data width.
Returns:
int: Data width in bits (typically 16)
"""Write and modify EEPROM content with validation.
def write_eeprom(self):
"""
Write modified configuration to EEPROM.
Raises:
- FtdiEepromError: Write operation failed
"""
def erase_eeprom(self):
"""
Erase entire EEPROM (set all bytes to 0xFF).
Raises:
- FtdiEepromError: Erase operation failed
"""
def sync(self):
"""
Synchronize configuration changes to EEPROM.
Raises:
- FtdiEepromError: Synchronization failed
"""
def reset_device(self):
"""Reset device to apply EEPROM changes."""Modify USB device descriptors and identification strings.
def set_manufacturer_name(self, name: str):
"""
Set USB manufacturer string.
Parameters:
- name: Manufacturer name (max 255 characters)
Raises:
- FtdiEepromError: String too long or invalid
"""
def set_product_name(self, name: str):
"""
Set USB product string.
Parameters:
- name: Product name (max 255 characters)
"""
def set_serial_number(self, serial: str):
"""
Set USB serial number string.
Parameters:
- serial: Serial number (max 255 characters)
"""
def get_manufacturer_name(self) -> str:
"""Get current manufacturer string."""
def get_product_name(self) -> str:
"""Get current product string."""
def get_serial_number(self) -> str:
"""Get current serial number string."""Configure FTDI device hardware behavior and capabilities.
def set_property(self, name: str, value):
"""
Set EEPROM configuration property.
Parameters:
- name: Property name
- value: Property value
Common properties:
- 'vendor_id': USB vendor ID (16-bit)
- 'product_id': USB product ID (16-bit)
- 'type': Device type code
- 'self_powered': Self-powered flag (bool)
- 'remote_wakeup': Remote wakeup capability (bool)
- 'max_power': Maximum power consumption (mA)
"""
def get_property(self, name: str):
"""
Get EEPROM configuration property.
Parameters:
- name: Property name
Returns:
Property value
"""
def has_property(self, name: str) -> bool:
"""Check if property exists in configuration."""Configure individual FTDI channels for multi-port devices.
def set_channel_config(self, channel: int, config: dict):
"""
Configure specific channel properties.
Parameters:
- channel: Channel number (0-based)
- config: Configuration dictionary
Configuration options:
- 'type': Channel type ('uart', 'fifo', 'cpu_fifo', etc.)
- 'driver': Driver type ('vcp', 'd2xx')
- 'invert': Signal inversion flags
"""
def get_channel_config(self, channel: int) -> dict:
"""Get configuration for specific channel."""Configure CBUS pins for devices that support them.
def set_cbus_function(self, cbus: int, function: str):
"""
Set CBUS pin function.
Parameters:
- cbus: CBUS pin number (0-3 or 0-9 depending on device)
- function: Pin function ('tristate', 'txled', 'rxled', 'txrxled',
'pwren', 'sleep', 'drive0', 'drive1', 'iomode', 'bitbang_wr',
'bitbang_rd', 'timestamp', 'awake')
"""
def get_cbus_function(self, cbus: int) -> str:
"""Get current CBUS pin function."""
def get_cbus_pins(self) -> int:
"""Get number of available CBUS pins."""Helper classes for EEPROM data representation.
class Hex2Int(int):
"""2-digit hexadecimal integer representation."""
class Hex4Int(int):
"""4-digit hexadecimal integer representation."""EEPROM sizes by FTDI device:
Standard FTDI device configuration includes:
from pyftdi.eeprom import FtdiEeprom
# Open EEPROM
eeprom = FtdiEeprom()
eeprom.open('ftdi:///1')
# Read current configuration
config_dump = eeprom.dump_config()
print(config_dump)
# Read raw EEPROM data
raw_data = eeprom.read_eeprom()
print(f"EEPROM size: {len(raw_data)} bytes")
print(f"Raw data: {raw_data.hex()}")
eeprom.close()from pyftdi.eeprom import FtdiEeprom
eeprom = FtdiEeprom()
eeprom.open('ftdi:///1')
# Change device identity
eeprom.set_manufacturer_name("My Company")
eeprom.set_product_name("Custom FTDI Device")
eeprom.set_serial_number("CUST001")
# Write changes to EEPROM
eeprom.sync()
# Reset device to apply changes
eeprom.reset_device()
eeprom.close()from pyftdi.eeprom import FtdiEeprom
eeprom = FtdiEeprom()
eeprom.open('ftdi:///1')
# Set custom USB configuration
eeprom.set_property('vendor_id', 0x1234) # Custom vendor ID
eeprom.set_property('product_id', 0x5678) # Custom product ID
eeprom.set_property('max_power', 500) # 500mA max power
eeprom.set_property('self_powered', False) # Bus powered
eeprom.set_property('remote_wakeup', True) # Enable remote wakeup
# Apply changes
eeprom.sync()
eeprom.close()from pyftdi.eeprom import FtdiEeprom
eeprom = FtdiEeprom()
eeprom.open('ftdi:///1') # FT232R with CBUS pins
# Configure CBUS pins
eeprom.set_cbus_function(0, 'txled') # CBUS0 = TX LED
eeprom.set_cbus_function(1, 'rxled') # CBUS1 = RX LED
eeprom.set_cbus_function(2, 'sleep') # CBUS2 = Sleep indicator
eeprom.set_cbus_function(3, 'drive1') # CBUS3 = Always high
# Check configuration
for i in range(4):
func = eeprom.get_cbus_function(i)
print(f"CBUS{i}: {func}")
eeprom.sync()
eeprom.close()from pyftdi.eeprom import FtdiEeprom
eeprom = FtdiEeprom()
eeprom.open('ftdi:///1') # FT2232H dual channel device
# Configure channel A
channel_a_config = {
'type': 'uart',
'driver': 'vcp',
'invert': 0x00
}
eeprom.set_channel_config(0, channel_a_config)
# Configure channel B
channel_b_config = {
'type': 'fifo',
'driver': 'd2xx',
'invert': 0x00
}
eeprom.set_channel_config(1, channel_b_config)
eeprom.sync()
eeprom.close()from pyftdi.eeprom import FtdiEeprom
def backup_eeprom(device_url, filename):
"""Backup EEPROM to file."""
eeprom = FtdiEeprom()
eeprom.open(device_url)
data = eeprom.read_eeprom()
with open(filename, 'wb') as f:
f.write(data)
eeprom.close()
print(f"EEPROM backed up to {filename}")
def restore_eeprom(device_url, filename):
"""Restore EEPROM from file."""
with open(filename, 'rb') as f:
data = f.read()
eeprom = FtdiEeprom()
eeprom.open(device_url)
# This is a simplified example - actual restore would need
# to parse and validate the EEPROM structure
print("Warning: Direct restore not implemented for safety")
eeprom.close()
# Usage
backup_eeprom('ftdi:///1', 'eeprom_backup.bin')from pyftdi.eeprom import FtdiEeprom
def factory_reset(device_url):
"""Reset EEPROM to factory defaults."""
eeprom = FtdiEeprom()
eeprom.open(device_url)
# Erase EEPROM
eeprom.erase_eeprom()
# Set basic configuration
eeprom.set_manufacturer_name("FTDI")
eeprom.set_product_name("FT232R USB UART") # Device specific
eeprom.set_property('vendor_id', 0x0403)
eeprom.set_property('product_id', 0x6001) # Device specific
# Apply changes
eeprom.sync()
eeprom.reset_device()
eeprom.close()
print("Device reset to factory defaults")
# Use with caution!
# factory_reset('ftdi:///1')from pyftdi.eeprom import FtdiEeprom, FtdiEepromError
from pyftdi.ftdi import FtdiError
try:
eeprom = FtdiEeprom()
eeprom.open('ftdi:///1')
eeprom.set_manufacturer_name("Test Company")
eeprom.sync()
except FtdiEepromError as e:
print(f"EEPROM operation error: {e}")
except FtdiError as e:
print(f"FTDI device error: {e}")
finally:
if 'eeprom' in locals():
eeprom.close()# Exception types
class FtdiEepromError(FtdiError):
"""EEPROM access error"""
# CBUS function constants
CBUS_FUNCTIONS = {
'tristate': 0,
'rxled': 1,
'txled': 2,
'txrxled': 3,
'pwren': 4,
'sleep': 5,
'drive0': 6,
'drive1': 7,
'iomode': 8,
'bitbang_wr': 9,
'bitbang_rd': 10
}
# Channel type constants
CHANNEL_TYPES = {
'uart': 0,
'fifo': 1,
'cpu_fifo': 2,
'opto': 3,
'fpi': 4
}Install with Tessl CLI
npx tessl i tessl/pypi-pyftdi