usbsid-pico 0.1.3

Rust driver for USBSID-Pico – interface MOS SID chips (6581/8580) and hardware emulators over USB
Documentation

usbsid-pico

Crates.io Documentation License

Rust driver for the USBSID-Pico — a Raspberry Pi Pico (RP2040 / RP2350) based board for interfacing one or more MOS SID chips (6581/8580) and hardware SID emulators over USB.

This is a Rust implementation of the original C++ driver by LouDnl. The original driver uses libusb; this crate defaults to serial port communication instead, which avoids platform-specific USB driver setup.

Requirements

  • Rust 1.70+ (2021 edition)
  • A connected USBSID-Pico device
  • On Linux: libudev-dev for serial port enumeration
    sudo apt install libudev-dev   # Debian/Ubuntu
    sudo dnf install systemd-devel # Fedora
    

Building

cargo build --release

The default serial feature uses the OS-provided COM / tty port — no additional drivers or libraries are needed on any platform.

If you want the libusb backend instead (matching the original C++ driver), enable the usb feature. This requires libusb 1.0 headers and on Windows a WinUSB driver via Zadig:

cargo build --features usb

When both features are enabled, the driver tries USB first and falls back to serial.

Quick start

use usbsid_pico::UsbSid;

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let mut sid = UsbSid::new();
    sid.init(/* threaded */ true, /* with_cycles */ true)?;

    // Write to SID register via the ring buffer
    sid.write_ring_cycled(0x01, 0x01, 0xFFFF)?;

    // Read a register
    let val = sid.single_read(0x1B)?;
    println!("OSC3 random: 0x{:02X}", val);

    Ok(())
}

Examples

cargo run --example basic
cargo run --example simple_tone
cargo run --example sid_player -- path/to/tune.sid
cargo run --example sid_player -- path/to/tune.sid --stereo
cargo run --example sid_player -- path/to/tune.sid --sid4 $DE00

The sid_player example includes a 6502 CPU emulator and supports PSID/RSID v1–v4 files with automatic multi-SID detection from the header.

Features

Feature Default Description
serial Yes Serial port backend via serialport. No driver setup needed.
usb No libusb backend via rusb. Matches original C++ driver. Needs libusb headers and on Windows a WinUSB driver.
debug_memory No SID memory tracking.

Architecture

Module Description
device Core UsbSid struct — connection setup, I/O, threading, timing
transport Transport trait with serial and libusb backends
constants Protocol opcodes, USB IDs, clock/timing tables, SID address helpers
ringbuffer Lock-free SPSC ring buffer for the background writer thread
error UsbSidError enum and Result alias
ffi extern "C" functions for C/C++ consumers

Write modes

Mode Function Description
Synchronous single_write / single_read Blocking transfers
Async direct write / write_cycled Non-threaded writes
Async threaded write_ring / write_ring_cycled Background thread drains ring buffer

SID register layout

Each SID occupies 32 registers (0x20 bytes):

SID Registers
SID1 $00–$1F
SID2 $20–$3F
SID3 $40–$5F
SID4 $60–$7F

C FFI

The crate exposes a C-compatible interface. Build as a shared library:

cargo build --release
# → target/release/libusbsid_pico.{so,dylib,dll}

Generate the C header with cbindgen:

cargo install cbindgen
cbindgen --config cbindgen.toml --crate usbsid-pico --output usbsid_pico.h

Platform notes

Linux — You may need a udev rule for non-root access:

echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="cafe", ATTR{idProduct}=="4011", MODE="0666"' | \
  sudo tee /etc/udev/rules.d/99-usbsid.rules
sudo udevadm control --reload-rules

macOS — With the default serial backend no special setup is needed.

Windows — The default serial backend uses the COM port that Windows assigns automatically. If using the usb feature you need to install a WinUSB driver with Zadig.

License

Licensed under either of

at your option.

Acknowledgments

USBSID-Pico hardware and firmware by LouDnl.