Source code for romulan.upload_rom

#!/usr/bin/env python3
"""Serial port discovery for the Pico-as-ROM 65C02 firmware.

ROM upload uses the framed v1 Hardware API
(:meth:`romulan.hardware_api.HardwareAPI.upload_rom`). This module only
auto-detects the Pico USB-CDC port for the CLI and client helpers.
"""

from __future__ import annotations

import glob
import sys

try:
    import serial
    import serial.tools.list_ports
except ImportError:
    sys.stderr.write(
        "ERROR: pyserial is required.  Install with:\n"
        "    pip install --user pyserial\n"
    )
    sys.exit(1)


# Raspberry Pi Pico USB VID
RPI_VID = 0x2E8A


[docs] def find_pico_port() -> str: """Auto-detect a Raspberry Pi Pico serial port. Tries USB vendor ID ``0x2E8A`` (Raspberry Pi) first, then falls back to common port name patterns on Linux, macOS, and Windows. Returns: The device path of the detected Pico (e.g. ``/dev/ttyACM0``). Raises: RuntimeError: If zero or more than one matching port is found. """ # First try pyserial's list_ports with VID filter ports = list(serial.tools.list_ports.comports()) pico_ports = [ p.device for p in ports if p.vid == RPI_VID or (p.manufacturer and "Raspberry Pi" in p.manufacturer) ] if len(pico_ports) == 1: return pico_ports[0] if len(pico_ports) > 1: raise RuntimeError( f"Multiple Raspberry Pi Pico devices found: {pico_ports}. " "Please specify one with --port." ) # Fallback: guess by port name patterns patterns = [ "/dev/ttyACM*", "/dev/ttyUSB*", "/dev/cu.usbmodem*", "/dev/tty.usbmodem*", ] candidates = [] for pattern in patterns: candidates.extend(glob.glob(pattern)) # On Windows, COM ports don't glob; list_ports should have caught them. # If we still have nothing, check for COM ports via list_ports. if not candidates and sys.platform == "win32": candidates = [p.device for p in ports] if len(candidates) == 1: return candidates[0] if len(candidates) > 1: raise RuntimeError( f"Multiple serial ports found: {candidates}. " "Please specify one with --port." ) raise RuntimeError( "No Raspberry Pi Pico serial port found.\n" "Please ensure your Pico is connected and running the firmware, " "or specify the port explicitly with --port." )