### Run bit_server example Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt Execute the bit_server example from the command line to test bitbang functionality. ```python python -m pylibftdi.examples.bit_server ``` -------------------------------- ### Install pylibftdi and libftdi Source: https://context7.com/codedstructure/pylibftdi/llms.txt Install libftdi using platform-specific package managers, then install pylibftdi using pip. Test the installation by listing connected devices. ```bash # Install libftdi first (platform-specific) # macOS: brew install libftdi # Debian/Ubuntu: sudo apt-get install libftdi1-2 # Arch Linux: sudo pacman -S libftdi # Then install pylibftdi pip install pylibftdi # Test installation by listing connected devices python3 -m pylibftdi.examples.list_devices ``` -------------------------------- ### Run info example Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt To display additional information about the environment pylibftdi is running in, execute the info example using the command line. ```python python -m pylibftdi.examples.info ``` -------------------------------- ### Install pylibftdi Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/quickstart.md Install the pylibftdi library using pip. Refer to the installation guide for detailed requirements. ```bash python3 -m pip install pylibftdi ``` -------------------------------- ### Running LED Flash Example Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt This command demonstrates how to run an example script for pulsing an LED connected to D0 using the pylibftdi library. ```bash python -m pylibftdi.examples.led_flash ``` -------------------------------- ### List Devices Example (Python 3) Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt This example demonstrates how to list available FTDI devices using Python 3. It was fixed to work correctly in Python 3 following version 0.18.0. ```python from pylibftdi import Driver driver = Driver() devices = driver.list_devices() if devices: print("Found devices:") for device in devices: print(f" - {device}") else: print("No devices found.") ``` -------------------------------- ### Example System Information Output Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/troubleshooting.md This is an example of the output you can expect when running the pylibftdi system information script. It details versions of various libraries and system components. ```text pylibftdi version : 0.18.0 libftdi version : libftdi_version(major=1, minor=4, micro=0, version_str='1.4', snapshot_str='unknown') libftdi library name : libftdi1.so.2 libusb version : libusb_version(major=1, minor=0, micro=22, nano=11312, rc='', describe='http://libusb.info') libusb library name : libusb-1.0.so.0 Python version : 3.7.3 OS platform : Linux-5.0.0-32-generic-x86_64-with-Ubuntu-19.04-disco ``` -------------------------------- ### BitBangDevice Example Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/index.md Example of using BitBangDevice to control GPIO pins. Ensure the device ID is correct. ```python >>> from pylibftdi import BitBangDevice >>> with BitBangDevice('FT0123') as dev: ... dev.port |= 1 ``` -------------------------------- ### Install pylibftdi using pip Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/installation.md Use this command to install the pylibftdi package. Ensure you have libftdi installed on your system. ```bash pip install pylibftdi ``` -------------------------------- ### Install libftdi on Arch Linux Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/installation.md Install the libftdi library on Arch Linux using the pacman package manager. This is a prerequisite for pylibftdi. ```bash sudo pacman -S libftdi ``` -------------------------------- ### Install libftdi runtime on Debian/Ubuntu Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/installation.md Install the libftdi1 runtime library on Debian-based systems like Ubuntu and Raspberry Pi OS. This provides the necessary components for pylibftdi. ```bash sudo apt-get install libftdi1-2 ``` -------------------------------- ### Install libftdi on macOS using Homebrew Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/installation.md Install the libftdi library on macOS using the Homebrew package manager. This is a prerequisite for pylibftdi. ```bash brew install libftdi ``` -------------------------------- ### Serial Device MIDI Example Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/index.md Example of using the Device class to send a MIDI 'note on' message. Sets baudrate to 31250, common for MIDI. ```python >>> # Send a MIDI 'note on' message >>> from pylibftdi import Device >>> with Device() as dev: ... dev.baudrate = 31250 ... dev.write('\x90\x64\x64') ``` -------------------------------- ### Custom MidiDevice Subclass Example Source: https://context7.com/codedstructure/pylibftdi/llms.txt Demonstrates creating a custom Device subclass for MIDI communication, setting a specific baudrate and implementing MIDI message methods. ```python from pylibftdi import Device import time class MidiDevice(Device): """FTDI device configured for MIDI protocol (31250 baud, 8-N-1)""" def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.baudrate = 31250 def note_on(self, channel, note, velocity): """Send MIDI note on message""" self.write(bytes([0x90 | (channel & 0x0F), note & 0x7F, velocity & 0x7F])) def note_off(self, channel, note): """Send MIDI note off message""" self.write(bytes([0x80 | (channel & 0x0F), note & 0x7F, 0])) def control_change(self, channel, controller, value): """Send MIDI control change message""" self.write(bytes([0xB0 | (channel & 0x0F), controller & 0x7F, value & 0x7F])) # Play a scale with MidiDevice() as midi: notes = [60, 62, 64, 65, 67, 69, 71, 72] # C major scale for note in notes: midi.note_on(0, note, 100) time.sleep(0.25) midi.note_off(0, note) time.sleep(0.05) # Send raw MIDI data with MidiDevice() as midi: # Note on: channel 1, note 64 (E4), velocity 100 midi.write(b'\x90\x40\x64') time.sleep(1) # Note off midi.write(b'\x80\x40\x00') ``` -------------------------------- ### Error Handling Examples Source: https://context7.com/codedstructure/pylibftdi/llms.txt Illustrates how to handle various exceptions like FtdiError for device issues, LibraryMissingError for missing libftdi, and permissions errors on Linux. ```python from pylibftdi import Device, Driver, FtdiError, LibraryMissingError # Handle device not found try: with Device(device_id='NONEXISTENT') as dev: dev.write(b'test') except FtdiError as e: print(f"Device error: {e}") # Suggests running: python3 -m pylibftdi.examples.list_devices # Handle library not installed try: driver = Driver() devices = driver.list_devices() except LibraryMissingError as e: print(f"libftdi not found: {e}") print("Install libftdi: brew install libftdi (macOS)") # Handle permissions error (Linux) try: with Device() as dev: dev.write(b'test') except FtdiError as e: if '-4' in str(e) or '-8' in str(e): print("Permissions error - try setting up udev rules") print("Or run with: sudo python3 script.py") # Check if device is open dev = Device(lazy_open=True) if dev.closed: print("Device not yet opened") dev.open() if not dev.closed: print("Device is now open") dev.close() # Get error details from driver with Device() as dev: try: dev.ftdi_fn.ftdi_set_baudrate(999999999) # Invalid baudrate except Exception: error_msg = dev.get_error_string() print(f"FTDI error: {error_msg}") ``` -------------------------------- ### BitBangDevice read-modify-write example Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt Demonstrates how BitBangDevice now reads the device pin state on startup, ensuring read-modify-write operations across process runs behave as expected. ```python >>> from pylibftdi import BitBangDevice >>> d = BitBangDevice() >>> d.port = 1 >>> ^D # restart interpreter ``` -------------------------------- ### Serial Transfer Example Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt This example checks that pseudo-random data sent over a serial connection is correctly transferred. It demonstrates basic serial communication. ```python import time import random from pylibftdi import SerialDevice def serial_transfer(): try: # Use a specific PID/VID if known, otherwise it will list devices # dev = SerialDevice(pid=0x6015, vid=0x0403) dev = SerialDevice() except Exception as e: print(f"Error opening device: {e}") return print(f"Using device: {dev.device_id}") # Configure serial port (example settings) dev.baudrate = 9600 dev.bytesize = 8 dev.parity = 'N' dev.stopbits = 1 dev.flowcontrol = None # Generate pseudo-random data data_to_send = bytes([random.randint(0, 255) for _ in range(100)]) print(f"Sending {len(data_to_send)} bytes...") dev.write(data_to_send) time.sleep(0.1) # Give time for data to be sent/received # Read data back # Note: Reading back might require a specific setup on the other end # or sending a command to echo data. This example assumes echo or similar. # For a true test, you'd need two devices or a loopback connection. received_data = dev.read(len(data_to_send)) print(f"Received {len(received_data)} bytes.") if data_to_send == received_data: print("Data transfer successful!") else: print("Data transfer failed or data mismatch.") # print(f"Sent: {data_to_send}") # print(f"Received: {received_data}") dev.close() if __name__ == "__main__": serial_transfer() ``` -------------------------------- ### Synchronize Dependencies with uv Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/developing.md Use uv to synchronize project dependencies and install pylibftdi in editable mode. This command creates a .venv virtual environment and installs development dependencies. ```bash .../pylibftdi$ uv sync .../pylibftdi$ uv run pytest .../pylibftdi$ uv run ruff check src tests ``` -------------------------------- ### Test LED Flash Output Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/quickstart.md Execute this example to test the output functionality by flashing an LED connected to a bit-bang capable FTDI device. Ensure the LED is connected correctly with a resistor. ```bash python3 -m pylibftdi.examples.led_flash ``` -------------------------------- ### Interact with FTDI Devices from REPL Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/quickstart.md Use this command to start an interactive Python REPL session with pylibftdi imported. This allows for quick interaction with FTDI devices. ```python python3 -im pylibftdi >>> d = Device() >>> d.write('Hello World') >>> ``` -------------------------------- ### BitBangDevice Parallel IO with pylibftdi Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/introduction.md Shows how to use BitBangDevice for parallel IO operations. This example configures direction and manipulates specific bits. ```python >>> from pylibftdi import BitBangDevice >>> >>> with BitBangDevice('FTE00P4L') as bb: ... bb.direction = 0x0F # four LSB are output(1), four MSB are input(0) ... bb.port |= 2 # set bit 1 ... bb.port &= 0xFE # clear bit 0 ``` -------------------------------- ### Clone pylibftdi Repository Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/developing.md Clone the pylibftdi repository from GitHub to start development. This is the initial step for any local development work. ```bash $ git clone https://github.com/codedstructure/pylibftdi $ cd pylibftdi ``` -------------------------------- ### BitBangDevice Port vs. Latch Example Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/how_to.md Demonstrates a read-modify-write operation using BitBangDevice. Using `dev.latch` instead of `dev.port` in read-modify-write scenarios prevents input states from interfering with the operation. ```python >>> dev = BitBangDevice() # 1 >>> dev.direction = 0x81 # 2 # set bits 0 and 7 are output >>> dev.port = 0 # 3 >>> for _ in range(255): # 4 >>> dev.port += 1 # 5 # read-modify-write operation ``` -------------------------------- ### Serial Device Access with pylibftdi Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/introduction.md Demonstrates basic serial communication with an FTDI device in text mode. Ensure libftdi is installed. ```python >>> from pylibftdi import Device >>> >>> with Device(mode='t') as dev: ... dev.baudrate = 115200 ... dev.write('Hello World') ``` -------------------------------- ### BitBangDevice Port Manipulation Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt Demonstrates how to manipulate the port of a BitBangDevice. This example shows setting a specific bit high while preserving other bits. ```python from pylibftdi import BitBangDevice d = BitBangDevice() d.port |= 2 ``` -------------------------------- ### Accessing libftdi functions via ftdi_fn Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/advanced_usage.md Demonstrates opening a device, switching to bit-bang mode, writing data, switching back to serial mode, and writing a string. This example requires prior knowledge of libftdi and ctypes. ```python from pylibftdi import Device with Device() as dev: dev.ftdi_fn.ftdi_set_bitmode(1, 0x01) dev.write('\x00\x01\x00') dev.ftdi_fn.ftdi_set_bitmode(0, 0x00) dev.write('Hello World!!!') ``` -------------------------------- ### Direct ftdi_fn Access Example Source: https://context7.com/codedstructure/pylibftdi/llms.txt Accesses functions not directly wrapped by pylibftdi, requiring manual context passing. ```python from ctypes import byref from pylibftdi import Device with Device() as dev: # Direct library access (need to pass context manually) result = dev.fdll.ftdi_set_baudrate(byref(dev.ctx), 115200) if result != 0: print(f"Error: {dev.get_error_string()}") ``` -------------------------------- ### Device Opening with Interface Number Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt Example of opening a specific FTDI device when multiple devices are connected, by specifying the interface number. ```python Device(interface=1) ``` -------------------------------- ### Get libftdi and libusb versions Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/advanced_usage.md Shows how to retrieve the major, minor, and micro versions of the loaded libftdi and libusb libraries. This is useful for compatibility checks. ```python from pylibftdi import Driver Driver().libftdi_version() ``` ```python Driver("ftdi1").libftdi_version() ``` ```python Driver("ftdi").libftdi_version() ``` -------------------------------- ### BitBangDriver Interface Properties Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt This example shows the change in the BitBangDriver interface, where direction and port are now properties instead of overriding read/write functions. ```python BitBangDriver.direction = ... BitBangDriver.port = ... ``` -------------------------------- ### Define Bitfields for LCD Control with Bus Class Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/bitbang.md Illustrates how to use the Bus class to define and manage bitfields for controlling an LCD display. This setup maps specific IO lines to data, register select, and enable signals. ```python class LCD(object): """ The UM232R/245R is wired to the LCD as follows: DB0..3 to LCD D4..D7 (pin 11..pin 14) DB6 to LCD 'RS' (pin 4) DB7 to LCD 'E' (pin 6) """ data = Bus(0, 4) rs = Bus(6) e = Bus(7) ``` -------------------------------- ### Get libftdi version Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt The `libftdi_version()` method can be used to determine the version of the libftdi driver in use. This is useful for compatibility checks or debugging. ```python >>> from pylibftdi import Driver >>> Driver().libftdi_version() (1, 0, 0, '1.0', 'v1.0-6-gafb9082') >>> Driver('ftdi').libftdi_version() (0, 99, 0, '0.99', 'v0.17-305-g50d77f8') ``` -------------------------------- ### Rotate Bits on IO Lines Continuously Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/bitbang.md Shows a continuous bit rotation on the IO lines using BitBangDevice. This example assumes a default device connection and runs indefinitely. ```python >>> with BitBangDevice() as bb: ... bb.port = 1 ... while True: ... # Rotate the value in bb.port ... bb.port = ((bb.port << 1) | ((bb.port >> 8) & 1)) & 0xFF ... time.sleep(1) ``` -------------------------------- ### Bus Descriptor - LCD Interface Simulation Source: https://context7.com/codedstructure/pylibftdi/llms.txt Illustrates using the Bus descriptor to create a Pythonic interface for controlling an LCD display. This example defines named bit fields for data, RS, and E pins, simplifying low-level bit manipulation for LCD commands and data. ```python from pylibftdi import BitBangDevice, Bus import time # Define an LCD interface with named bit fields class LCD: """ HD44780 LCD wiring: D0-D3 -> LCD D4-D7 (4-bit data) D6 -> LCD RS (Register Select) D7 -> LCD E (Enable/Clock) """ data = Bus(0, 4) # 4-bit bus starting at bit 0 rs = Bus(6) # Single bit at position 6 e = Bus(7) # Single bit at position 7 def __init__(self, device): self.device = device def write_nibble(self, rs_val, nibble): self.rs = rs_val self.data = nibble self.e = 1 # Clock high self.e = 0 # Clock low (latch data) def write_byte(self, rs_val, byte): self.write_nibble(rs_val, byte >> 4) # High nibble self.write_nibble(rs_val, byte & 0x0F) # Low nibble def write_cmd(self, cmd): self.write_byte(0, cmd) # RS=0 for command def write_char(self, char): self.write_byte(1, ord(char)) # RS=1 for data # Use the LCD class with BitBangDevice() as bb: bb.baudrate = 60 # Slow baudrate for LCD timing lcd = LCD(bb) # Initialize 4-bit mode lcd.data = 3 for _ in range(3): lcd.e = 1 lcd.e = 0 lcd.data = 2 lcd.e = 1 lcd.e = 0 # Configure display lcd.write_cmd(0x20) # Function set lcd.write_cmd(0x01) # Clear display lcd.write_cmd(0x06) # Entry mode lcd.write_cmd(0x0C) # Display on # Write text for char in "Hello!": lcd.write_char(char) ``` -------------------------------- ### Enumerate FTDI Devices with Driver.list_devices Source: https://context7.com/codedstructure/pylibftdi/llms.txt Use Driver.list_devices() to get a list of connected FTDI devices, including their manufacturer, description, and serial number. You can also retrieve libftdi and libusb version information. ```python from pylibftdi import Driver # Create a driver instance and list all connected devices driver = Driver() devices = driver.list_devices() # Each device is a tuple: (manufacturer, description, serial_number) for manufacturer, description, serial in devices: print(f"Found: {manufacturer} - {description} (Serial: {serial})") # Example output: # Found: FTDI - UM232R USB <-> Serial (Serial: FTE4FFVQ) # Found: FTDI - UB232R (Serial: FTAS1UN5) # Get library version information version = driver.libftdi_version() print(f"libftdi version: {version.major}.{version.minor}.{version.micro}") # Output: libftdi version: 1.5.0 # Get libusb version usb_version = driver.libusb_version() print(f"libusb version: {usb_version.major}.{usb_version.minor}.{usb_version.micro}") ``` -------------------------------- ### Open Device with PID/VID Selection Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt Use pid and vid selection when opening a new Device. This is useful when multiple devices are present and specific selection is needed. ```python from pylibftdi import Device dev = Device(pid=0x6015, vid=0x0403) ``` -------------------------------- ### Open Device with Custom Vendor and Product IDs Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/how_to.md If your FTDI device has a VID/PID not in the default list, you can specify them using the `vid` and `pid` keyword arguments when creating a `Device` instance. ```python >>> from pylibftdi import Device >>> dev = Device(vid=0x1234, pid=0x5678) ``` -------------------------------- ### Build Distribution Artifacts Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/developing.md Build the source distribution and wheel artifacts for the release using uv build. These artifacts are necessary for publishing to PyPI. ```bash .../pylibftdi$ uv build ``` -------------------------------- ### Publish to PyPI Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/developing.md Publish the built distribution artifacts to PyPI using uv publish. Requires a PyPI API token, which can be provided via an environment variable or directly. ```bash .../pylibftdi$ uv publish --token pypi-... # or via environment variable .../pylibftdi$ UV_PUBLISH_TOKEN=pypi-... uv publish ``` -------------------------------- ### Prepare for PyPI Release Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/developing.md Update version numbers, sync dependencies, and commit changes before creating a release. This ensures all necessary files are updated and tracked. ```bash .../pylibftdi$ vim pyproject.toml CHANGES.txt # update with new version .../pylibftdi$ uv sync --upgrade .../pylibftdi$ make # ensure everything works .../pylibftdi$ git add pyproject.toml uv.lock CHANGES.txt .../pylibftdi$ git commit -m "Release 0.x.0" ``` -------------------------------- ### Specify libftdi driver search path Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt When initializing the Driver, you can provide a string or tuple of strings to specify the driver search path. This allows you to prioritize specific libftdi versions or drivers. ```python >>> d = Driver() >>> # equivalent to... >>> d = Driver(('ftdi1', 'libftdi1', 'ftdi', 'libftdi')) >>> # and if we wanted to use ftdi 0.x on Linux: >>> d = Driver('ftdi') ``` -------------------------------- ### Activate Virtual Environment and Run Tests Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/developing.md Activate the virtual environment created by uv and then run tests using pytest. This is an alternative to using `uv run`. ```bash .../pylibftdi$ uv sync .../pylibftdi$ source .venv/bin/activate (pylibftdi) .../pylibftdi$ pytest ``` -------------------------------- ### Device Indexing Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt Use the 'index' parameter in the Device() constructor to select a specific device from the list returned by Driver.list_devices(). This is useful when PIDs/VIDs are the same but you need to access a particular device by its position. ```python from pylibftdi import Driver, Device driver = Driver() # Assuming driver.list_devices() returns ['dev1', 'dev2', 'dev3'] # To get the second device: dev = Device(index=1) ``` -------------------------------- ### Unload FTDI Driver on macOS Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/troubleshooting.md Use this command to unload the FTDI VCP driver on macOS when it conflicts with libftdi access. This is often necessary on macOS versions prior to Monterey or if the driver was installed by other software. ```bash sudo kextunload -bundle-id com.FTDI.driver.FTDIUSBSerialDriver ``` -------------------------------- ### Run Tests with unittest Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/developing.md Discover and run tests using Python's built-in unittest module. This provides an alternative testing method. ```bash (pylibftdi) .../pylibftdi$ python3 -m unittest discover ``` -------------------------------- ### List Supported USB Vendor and Product IDs Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/how_to.md Run this code to see the default USB Vendor and Product IDs that pylibftdi checks for. If your device is not listed, you may need to specify its IDs manually. ```python >>> from pylibftdi import USB_VID_LIST, USB_PID_LIST >>> print(', '.join(hex(pid) for pid in USB_VID_LIST)) 0x403 >>> print(', '.join(hex(pid) for pid in USB_PID_LIST)) 0x6001, 0x6010, 0x6011, 0x6014, 0x6015 ``` -------------------------------- ### Open Multiple Device Interfaces with pylibftdi Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/how_to.md Use the `interface_select` parameter in the Device constructor to specify which interface of a multi-interface device to connect to. Symbolic constants like INTERFACE_A, INTERFACE_B, etc., are available in the pylibftdi namespace. ```python from pylibftdi import Device, INTERFACE_A dev = Device(interface_select=INTERFACE_A) ``` -------------------------------- ### Run pylibftdi System Info Script Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/troubleshooting.md Execute this command to gather information about your system's pylibftdi, libftdi, libusb, Python, and OS versions. This is helpful for diagnosing issues. ```bash python3 -m pylibftdi.examples.info ``` -------------------------------- ### Device Opening with Device ID Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt Illustrates opening an FTDI device using a device ID, which can be a serial number or device description. If multiple devices match, an arbitrary one is selected. ```python Device(device_id='') # or Device('') ``` -------------------------------- ### Create a MIDI Device Subclass Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/serial.md Subclass the Device class to configure it for MIDI communication, setting the baudrate to 31250. Ensure the superclass __init__ is called first. ```python class MidiDevice(Device): """subclass of pylibftdi.Device configured for MIDI""" def __init__(self, *o, **k): Device.__init__(self, *o, **k) self.baudrate = 31250 ``` -------------------------------- ### Serial IO with Device Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/basic_usage.md Use the Device class for serial communication. Set the baudrate and write data. Ensure to use a 'with' statement for proper resource management. ```python from pylibftdi import Device with Device(mode='t') as dev: dev.baudrate = 115200 dev.write('Hello World') ``` -------------------------------- ### Driver and Library Version Information Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt The `Driver.libusb_version()` and `libftdi_version()` methods now return strings instead of bytestrings for textual version information, improving usability. ```python from pylibftdi import Driver driver = Driver() libusb_ver = driver.libusb_version() ftdi_ver = driver.libftdi_version() print(f"libusb version: {libusb_ver}") print(f"libftdi version: {ftdi_ver}") ``` -------------------------------- ### Enumerate FTDI Devices Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/quickstart.md Run this command to list all connected FTDI devices. It displays the manufacturer, model, and serial number for each device. ```bash python3 -m pylibftdi.examples.list_devices ``` -------------------------------- ### Use MidiDevice for MIDI Communication Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/serial.md Instantiate and use the MidiDevice class for sending MIDI data. It provides a file-based API for read and write operations. ```python >>> m = MidiDevice() >>> m.write('\x90\x80\x80') >>> time.sleep(1) >>> m.write('\x80\x00') ``` -------------------------------- ### Device Write Operation With Chunking Enabled Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/how_to.md Shows how to set the `chunk_size` parameter to manage I/O operations in smaller chunks, allowing for more responsive interrupt handling (e.g., Ctrl-C) during writes. ```python >>> dev = Device() >>> dev.baudrate = 120 >>> dev.chunk_size = 10 >>> dev.write('helloworld' * 1000) ``` -------------------------------- ### List Connected FTDI Devices Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/installation.md Run this command to verify that pylibftdi can detect and list connected FTDI devices. If no output is shown, check for potential permission problems, especially on Linux. ```default $ python3 -m pylibftdi.examples.list_devices ``` -------------------------------- ### Keyword-Only Arguments for Device and Driver Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt Device() and Driver() arguments are now keyword-only. This change protects against typos or incorrect arguments. If you were passing libftdi_search as a positional argument, create a driver instance separately and pass it using the 'driver' keyword-only parameter. ```python from pylibftdi import Driver, Device driver = Driver(libftdi_search='/path/to/libftdi.so') dev = Device(driver=driver) ``` -------------------------------- ### Publish to TestPyPI (Dry Run) Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/developing.md Publish to TestPyPI for a dry run before releasing to the main PyPI. This allows verification of the release process without affecting the live index. ```bash .../pylibftdi$ uv publish --publish-url https://test.pypi.org/legacy/ --token pypi-... ``` -------------------------------- ### List USB Devices on Linux Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/troubleshooting.md Use the `lsusb` command to list all connected USB devices on a Linux system. This helps in identifying the FTDI device by its Vendor and Product ID. ```bash ben@ben-laptop:~$ lsusb ``` -------------------------------- ### Test FTDI Device Communication with LED Flash Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/installation.md Execute this command to test basic communication with an FTDI device, even without an LED connected. Errors may indicate permission issues or device detection failures. Quit with Ctrl-C. ```default $ python3 -m pylibftdi.examples.led_flash ``` -------------------------------- ### Driver.list_devices - Enumerate Connected FTDI Devices Source: https://context7.com/codedstructure/pylibftdi/llms.txt Lists all connected FTDI devices and retrieves libftdi and libusb version information. ```APIDOC ## Driver.list_devices - Enumerate Connected FTDI Devices ### Description This method enumerates all connected FTDI devices, returning a list of tuples containing manufacturer, description, and serial number for each device. It also provides access to the libftdi and libusb library versions. ### Method ``` Driver.list_devices() Driver.libftdi_version() Driver.libusb_version() ``` ### Parameters None for `list_devices`, `libftdi_version`, `libusb_version`. ### Request Example ```python from pylibftdi import Driver driver = Driver() devices = driver.list_devices() for manufacturer, description, serial in devices: print(f"Found: {manufacturer} - {description} (Serial: {serial})") version = driver.libftdi_version() print(f"libftdi version: {version.major}.{version.minor}.{version.micro}") usb_version = driver.libusb_version() print(f"libusb version: {usb_version.major}.{usb_version.minor}.{usb_version.micro}") ``` ### Response #### Success Response (200) - **devices**: list of tuples `(manufacturer: str, description: str, serial_number: str)` - **version**: object with `major`, `minor`, `micro` attributes (int) - **usb_version**: object with `major`, `minor`, `micro` attributes (int) #### Response Example ```json { "devices": [ ["FTDI", "UM232R USB <-> Serial", "FTE4FFVQ"], ["FTDI", "UB232R", "FTAS1UN5"] ], "version": {"major": 1, "minor": 5, "micro": 0}, "usb_version": {"major": 1, "minor": 0, "micro": 18} } ``` ``` -------------------------------- ### Test Pin Read Input Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/quickstart.md Run this command to test input functionality by reading and printing the status of input pins on the FTDI device. Remove any existing connections to port lines before running. ```bash python3 -m pylibftdi.examples.pin_read ``` -------------------------------- ### Run Tests with Activated Virtualenv Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/developing.md Run project tests using pytest after activating the virtual environment. This is a common workflow for testing changes. ```bash (pylibftdi) .../pylibftdi$ pytest ``` -------------------------------- ### Push Tags to Origin Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/developing.md Push all local tags, including the newly created release tag, to the remote repository. This makes the release tag available to others. ```bash .../pylibftdi$ git push origin main --tags ``` -------------------------------- ### Fix for ftdi_get_library_version on M1 Macs Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt Addresses an issue where `ftdi_get_library_version` failed on M1 Macs. This ensures the library version can be correctly retrieved on Apple Silicon hardware. ```python from pylibftdi import ftdi_get_library_version try: version = ftdi_get_library_version() print(f"libftdi version: {version}") except Exception as e: print(f"Error getting library version: {e}") ``` -------------------------------- ### Configure udev rules for FTDI device access (Vendor ID only) Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/installation.md An alternative udev rule that matches only the FTDI vendor ID, providing broader access to FTDI devices. Use this if specific product IDs are not recognized. ```udev SUBSYSTEMS=="usb", ATTRS{idVendor}=="0403", GROUP="dialout", MODE="0660" ``` -------------------------------- ### Run Tests with uv Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/developing.md Execute all project tests using pytest via the uv run command. This ensures the project's integrity after changes. ```bash .../pylibftdi$ uv run pytest ``` -------------------------------- ### BitBangDevice - Read-Modify-Write Operations Source: https://context7.com/codedstructure/pylibftdi/llms.txt Demonstrates read-modify-write operations on output pins using the latch property for atomic updates. Ensure the device is configured for bit-bang mode. ```python with BitBangDevice() as bb: bb.direction = 0xFF # All outputs bb.latch = 0x55 # Set initial pattern bb.latch += 1 # Increment works correctly with latch ``` -------------------------------- ### Flushing Input Buffer Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt Shows how to clear the input buffer of an FTDI device, similar to the flush_input operation in pySerial. ```python d.flush_input() ``` -------------------------------- ### Flushing Output Buffer Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt Demonstrates clearing the output buffer of an FTDI device, analogous to the flush_output operation in pySerial. ```python d.flush_output() ``` -------------------------------- ### Parallel IO with BitBangDevice Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/basic_usage.md Utilize BitBangDevice for parallel IO. Configure port direction and manipulate individual bits. The device ID can be specified to open a particular device. ```python from pylibftdi import BitBangDevice with BitBangDevice('FTE00P4L') as bb: bb.direction = 0x0F # four LSB are output(1), four MSB are input(0) bb.port |= 2 # set bit 1 bb.port &= 0xFE # clear bit 0 ``` -------------------------------- ### Add Custom Product ID to Supported List Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/how_to.md Alternatively, you can append a custom Product ID to the `USB_PID_LIST` after import. The `Device` constructor will then recognize devices with this ID. ```python >>> from pylibftdi import USB_PID_LIST, USB_VID_LIST, Device >>> USB_PID_LIST.append(0x1234) >>> >>> dev = Device() # will now recognise a device with PID 0x1234. ``` -------------------------------- ### ftdi_fn - Direct libftdi Function Access Source: https://context7.com/codedstructure/pylibftdi/llms.txt Provides direct access to low-level libftdi functions through the `ftdi_fn` attribute. This allows fine-grained control over device parameters like line properties, bit mode, flow control, and latency. Requires careful handling of ctypes and device context. ```python from pylibftdi import Device from ctypes import byref, c_ubyte # Access low-level libftdi functions with Device() as dev: # Set line parameters: 8 data bits, 2 stop bits, no parity # ftdi_set_line_property(context, bits, stopbits, parity) dev.ftdi_fn.ftdi_set_line_property(8, 2, 0) # Switch to bitbang mode temporarily # ftdi_set_bitmode(context, bitmask, mode) dev.ftdi_fn.ftdi_set_bitmode(0xFF, 0x01) # All outputs, bitbang mode dev.write(b'\x00\x01\x00') # Toggle pin dev.ftdi_fn.ftdi_set_bitmode(0, 0x00) # Back to serial mode dev.write(b'Hello World!') # Set flow control # 0=none, 1=RTS/CTS, 2=DTR/DSR, 3=XON/XOFF dev.ftdi_fn.ftdi_setflowctrl(1) # Enable RTS/CTS # Set latency timer (1-255 ms) dev.ftdi_fn.ftdi_set_latency_timer(1) # 1ms for low latency # Read pins directly in bitbang mode pin_state = c_ubyte() dev.ftdi_fn.ftdi_read_pins(byref(pin_state)) print(f"Pin state: {pin_state.value:08b}") # Purge buffers dev.ftdi_fn.ftdi_tcioflush() # Flush both RX and TX ``` -------------------------------- ### Device Write Operation Without Chunking Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/how_to.md Illustrates a potentially long-running write operation to an FTDI device at a low baud rate. During this operation, Ctrl-C interruptions may be ignored. ```python >>> dev = Device() >>> dev.baudrate = 120 # nice and slow! >>> dev.write('helloworld' * 1000) ``` -------------------------------- ### Serial Communication with Device Class Source: https://context7.com/codedstructure/pylibftdi/llms.txt Utilize the Device class for serial communication, supporting both binary and text modes. Configure baud rate, read/write data, and manage device connections using context managers or manual open/close. ```python from pylibftdi import Device # Basic usage with context manager (auto open/close) with Device(mode='t') as dev: dev.baudrate = 115200 dev.write('Hello World') response = dev.read(100) # Read up to 100 characters # Open a specific device by serial number with Device(device_id='FTE4FFVQ', mode='b') as dev: dev.baudrate = 9600 dev.write(b'\x01\x02\x03') # Write binary data data = dev.read(10) # Returns bytes in binary mode # Multiple identical devices - select by index with Device(device_id='UM232R', device_index=1) as dev: dev.write(b'Data to second matching device') # Text mode with custom encoding with Device(mode='t', encoding='utf-8') as dev: dev.baudrate = 57600 dev.write('Unicode text: äöü') text = dev.readline() # Read until newline # Manual open/close with lazy_open dev = Device(lazy_open=True) dev.open() dev.baudrate = 19200 dev.write(b'Hello') dev.flush() # Flush both input and output buffers dev.close() # Select specific interface on multi-interface devices (FT2232, FT4232) with Device(interface_select=1) as dev: # INTERFACE_A = 1 dev.write(b'Data to interface A') # Chunked I/O for interruptible operations with Device(chunk_size=64) as dev: dev.write(b'x' * 1000) # Written in 64-byte chunks ``` -------------------------------- ### SerialDevice - RS232 Control Lines and Data Transfer Source: https://context7.com/codedstructure/pylibftdi/llms.txt Shows how to use SerialDevice for RS232 communication, including setting baudrate, controlling modem signals (DTR, RTS), reading status (CTS, DSR, RI), and performing basic data read/write operations. Hardware flow control can be enabled. ```python from pylibftdi import SerialDevice import time # Basic serial with hardware flow control signals with SerialDevice() as dev: dev.baudrate = 9600 # Set output control lines dev.dtr = 1 # Assert DTR (Data Terminal Ready) dev.rts = 1 # Assert RTS (Request To Send) # Read input control lines print(f"CTS (Clear To Send): {dev.cts}") print(f"DSR (Data Set Ready): {dev.dsr}") print(f"RI (Ring Indicator): {dev.ri}") # Get full modem status (2-byte bitfield) status = dev.modem_status print(f"Modem status: {status:016b}") # Send data dev.write(b'AT\r\n') time.sleep(0.1) response = dev.read(100) print(f"Response: {response}") ``` ```python # Loopback test with RTS connected to CTS with SerialDevice() as dev: dev.rts = 0 assert dev.cts == 0, "CTS should follow RTS in loopback" dev.rts = 1 assert dev.cts == 1, "CTS should follow RTS in loopback" print("RTS-CTS loopback test passed") ``` -------------------------------- ### Flush Operation with libftdi >= 1.5 Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt The `flush()` method now uses `ftdi_tc[io]flush` functions from libftdi version 1.5 and later, replacing the deprecated `ftdi_usb_purge_*` functions. ```python from pylibftdi import Device try: dev = Device() # Perform some read/write operations dev.flush() # Uses ftdi_tc[io]flush if libftdi >= 1.5 dev.close() except Exception as e: print(f"Error: {e}") ``` -------------------------------- ### FT230 Device Support (PID 0x6015) Source: https://github.com/codedstructure/pylibftdi/blob/main/CHANGES.txt Added support for FT230 devices by including the USB PID 0x6015 in the default PID list. ```python from pylibftdi import Device # Devices with PID 0x6015 (FT230) can now be opened by default try: dev = Device(pid=0x6015, vid=0x0403) # Example for FT230 print(f"Successfully opened FT230 device: {dev.device_id}") dev.close() except Exception as e: print(f"Could not open FT230 device: {e}") ``` -------------------------------- ### Diagnose USB Devices on Mac OS X Source: https://github.com/codedstructure/pylibftdi/blob/main/docs/troubleshooting.md This command lists USB devices and filters the output to show details about FTDI devices. It's helpful for identifying device information like Product ID, Vendor ID, and Serial Number. ```bash ben$ system_profiler SPUSBDataType | grep -C 7 FTDI ```