CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-pyusb

Easy USB access for Python with backend-neutral, cross-platform support

Pending
Overview
Eval results
Files

utilities.mddocs/

Utilities

Helper functions for endpoint handling, interface management, descriptor parsing, and resource cleanup. The util module provides essential utilities for USB device operations and data interpretation.

Capabilities

Endpoint Operations

Parse and interpret endpoint addresses and attributes for proper communication setup.

def endpoint_address(address):
    """
    Return endpoint absolute address.
    
    Parameters:
    - address: int, endpoint address from descriptor
    
    Returns:
    int: absolute endpoint address (0-15)
    """

def endpoint_direction(address):
    """
    Return endpoint transfer direction.
    
    Parameters:
    - address: int, endpoint address from descriptor
    
    Returns:
    int: ENDPOINT_OUT (0) or ENDPOINT_IN (128)
    """

def endpoint_type(bmAttributes):
    """
    Return endpoint type from attributes.
    
    Parameters:
    - bmAttributes: int, endpoint attributes from descriptor
    
    Returns:
    int: endpoint type (ENDPOINT_TYPE_CTRL, ENDPOINT_TYPE_ISO, 
         ENDPOINT_TYPE_BULK, ENDPOINT_TYPE_INTR)
    """

Control Transfer Utilities

Build control transfer parameters and interpret transfer directions.

def ctrl_direction(bmRequestType):
    """
    Return direction of control transfer.
    
    Parameters:
    - bmRequestType: int, request type field
    
    Returns:
    int: CTRL_OUT (0) or CTRL_IN (128)
    """

def build_request_type(direction, type, recipient):
    """
    Build bmRequestType field for control transfer.
    
    Parameters:
    - direction: int, transfer direction (CTRL_OUT or CTRL_IN)
    - type: int, request type (CTRL_TYPE_STANDARD, CTRL_TYPE_CLASS, CTRL_TYPE_VENDOR)
    - recipient: int, recipient (CTRL_RECIPIENT_DEVICE, CTRL_RECIPIENT_INTERFACE, etc.)
    
    Returns:
    int: bmRequestType value
    """

Buffer Management

Create and manage buffers for USB data operations.

def create_buffer(length):
    """
    Create buffer for USB operations.
    
    Parameters:
    - length: int, buffer size in bytes
    
    Returns:
    array.array: buffer suitable for USB operations
    """

Descriptor Search

Find specific descriptors within device configuration hierarchies.

def find_descriptor(desc, find_all=False, custom_match=None, **args):
    """
    Find inner descriptor within a configuration/interface/endpoint hierarchy.
    
    Parameters:
    - desc: descriptor object to search within
    - find_all: bool, return all matches instead of first match
    - custom_match: callable taking descriptor as argument, return True for matches
    - **args: descriptor fields to match
    
    Returns:
    Descriptor object or list of descriptors, None if not found
    """

Interface Management

Claim and release interfaces for exclusive device access.

def claim_interface(device, interface):
    """
    Explicitly claim an interface.
    
    Parameters:
    - device: Device object
    - interface: int or Interface object, interface to claim
    
    Raises:
    - USBError: Interface claim failed
    """

def release_interface(device, interface):
    """
    Explicitly release an interface.
    
    Parameters:
    - device: Device object
    - interface: int or Interface object, interface to release
    
    Raises:
    - USBError: Interface release failed
    """

Resource Management

Clean up device resources and handle proper disposal.

def dispose_resources(device):
    """
    Release internal resources allocated by the device object.
    
    Parameters:
    - device: Device object to clean up
    """

String Descriptors

Retrieve and decode string descriptors with language support.

def get_langids(dev):
    """
    Retrieve list of supported string languages from device.
    
    Parameters:
    - dev: Device object
    
    Returns:
    list: language ID codes supported by device
    
    Raises:
    - USBError: Language ID retrieval failed
    """

def get_string(dev, index, langid=None):
    """
    Retrieve string descriptor from device.
    
    Parameters:
    - dev: Device object
    - index: int, string descriptor index
    - langid: int, language ID (default: first supported language)
    
    Returns:
    str: decoded string descriptor
    
    Raises:
    - USBError: String retrieval failed
    """

USB Constants

Direction and type constants for endpoint and control operations.

# Descriptor types
DESC_TYPE_DEVICE = 0x01
DESC_TYPE_CONFIG = 0x02
DESC_TYPE_STRING = 0x03
DESC_TYPE_INTERFACE = 0x04
DESC_TYPE_ENDPOINT = 0x05

# Endpoint directions
ENDPOINT_IN = 0x80
ENDPOINT_OUT = 0x00

# Endpoint types  
ENDPOINT_TYPE_CTRL = 0x00
ENDPOINT_TYPE_ISO = 0x01
ENDPOINT_TYPE_BULK = 0x02
ENDPOINT_TYPE_INTR = 0x03

# Control transfer directions
CTRL_OUT = 0x00
CTRL_IN = 0x80

# Control transfer types
CTRL_TYPE_STANDARD = 0x00
CTRL_TYPE_CLASS = 0x20
CTRL_TYPE_VENDOR = 0x40
CTRL_TYPE_RESERVED = 0x60

# Control transfer recipients
CTRL_RECIPIENT_DEVICE = 0x00
CTRL_RECIPIENT_INTERFACE = 0x01
CTRL_RECIPIENT_ENDPOINT = 0x02
CTRL_RECIPIENT_OTHER = 0x03

# USB speeds
SPEED_UNKNOWN = 0
SPEED_LOW = 1
SPEED_FULL = 2
SPEED_HIGH = 3
SPEED_SUPER = 4

Usage Examples

Endpoint Analysis

import usb.core
import usb.util

device = usb.core.find(idVendor=0x1234, idProduct=0x5678)
device.set_configuration()

config = device.get_active_configuration()
interface = config.interfaces()[0]

for endpoint in interface.endpoints():
    addr = endpoint.bEndpointAddress
    attrs = endpoint.bmAttributes
    
    print(f"Endpoint address: 0x{addr:02x}")
    print(f"  Absolute address: {usb.util.endpoint_address(addr)}")
    
    direction = usb.util.endpoint_direction(addr)
    if direction == usb.util.ENDPOINT_IN:
        print("  Direction: IN")
    else:
        print("  Direction: OUT")
    
    ep_type = usb.util.endpoint_type(attrs)
    type_names = {
        usb.util.ENDPOINT_TYPE_CTRL: "Control",
        usb.util.ENDPOINT_TYPE_ISO: "Isochronous", 
        usb.util.ENDPOINT_TYPE_BULK: "Bulk",
        usb.util.ENDPOINT_TYPE_INTR: "Interrupt"
    }
    print(f"  Type: {type_names[ep_type]}")
    print(f"  Max packet size: {endpoint.wMaxPacketSize}")

Interface Management

import usb.core
import usb.util

device = usb.core.find(idVendor=0x1234, idProduct=0x5678)
device.set_configuration()

interface_num = 0

try:
    # Claim interface for exclusive access
    usb.util.claim_interface(device, interface_num)
    print(f"Interface {interface_num} claimed")
    
    # Perform device operations...
    
finally:
    # Always release interface when done
    usb.util.release_interface(device, interface_num)
    print(f"Interface {interface_num} released")

String Descriptor Access

import usb.core
import usb.util

device = usb.core.find(idVendor=0x1234, idProduct=0x5678)

try:
    # Get supported languages
    langids = usb.util.get_langids(device)
    print(f"Supported languages: {[hex(lid) for lid in langids]}")
    
    # Get device strings in first supported language
    if langids and device.iManufacturer:
        manufacturer = usb.util.get_string(device, device.iManufacturer, langids[0])
        print(f"Manufacturer: {manufacturer}")
    
    if langids and device.iProduct:
        product = usb.util.get_string(device, device.iProduct, langids[0])
        print(f"Product: {product}")
        
    if langids and device.iSerialNumber:
        serial = usb.util.get_string(device, device.iSerialNumber, langids[0])
        print(f"Serial number: {serial}")
        
except usb.core.USBError as e:
    print(f"String access failed: {e}")

Descriptor Search

import usb.core
import usb.util

device = usb.core.find(idVendor=0x1234, idProduct=0x5678)
device.set_configuration()

config = device.get_active_configuration()

# Find all bulk endpoints
bulk_endpoints = usb.util.find_descriptor(
    config,
    find_all=True,
    custom_match=lambda e: usb.util.endpoint_type(e.bmAttributes) == usb.util.ENDPOINT_TYPE_BULK
)

print(f"Found {len(bulk_endpoints)} bulk endpoints:")
for ep in bulk_endpoints:
    direction = "IN" if usb.util.endpoint_direction(ep.bEndpointAddress) == usb.util.ENDPOINT_IN else "OUT"
    print(f"  Endpoint 0x{ep.bEndpointAddress:02x} ({direction})")

# Find specific interface by class
hid_interface = usb.util.find_descriptor(
    config,
    bInterfaceClass=3  # HID class
)

if hid_interface:
    print(f"Found HID interface: {hid_interface.bInterfaceNumber}")

Control Transfer Setup

import usb.core
import usb.util

device = usb.core.find(idVendor=0x1234, idProduct=0x5678)

# Build request type for vendor-specific IN request to device
request_type = usb.util.build_request_type(
    usb.util.CTRL_IN,
    usb.util.CTRL_TYPE_VENDOR,
    usb.util.CTRL_RECIPIENT_DEVICE
)

print(f"Request type: 0x{request_type:02x}")

# Perform control transfer
try:
    result = device.ctrl_transfer(
        request_type,
        0x01,  # Vendor-specific request
        0x0000,  # wValue
        0x0000,  # wIndex
        64  # Read 64 bytes
    )
    print(f"Control transfer result: {result}")
    
except usb.core.USBError as e:
    print(f"Control transfer failed: {e}")

Buffer Management

import usb.core
import usb.util

device = usb.core.find(idVendor=0x1234, idProduct=0x5678)
device.set_configuration()

# Create buffer for reading data
buffer = usb.util.create_buffer(1024)
print(f"Created buffer of size {len(buffer)}")

# Use buffer with read operation
endpoint_addr = 0x81  # IN endpoint
try:
    bytes_read = device.read(endpoint_addr, buffer, timeout=1000)
    print(f"Read {bytes_read} bytes into buffer")
    print(f"Data: {buffer[:bytes_read]}")
    
except usb.core.USBTimeoutError:
    print("Read operation timed out")

Resource Cleanup

import usb.core
import usb.util

device = usb.core.find(idVendor=0x1234, idProduct=0x5678)

try:
    # Perform device operations
    device.set_configuration()
    # ... communication ...
    
finally:
    # Clean up device resources
    usb.util.dispose_resources(device)
    print("Device resources disposed")

Install with Tessl CLI

npx tessl i tessl/pypi-pyusb

docs

backends.md

control-requests.md

device-communication.md

device-discovery.md

index.md

legacy-api.md

utilities.md

tile.json