usbsid-pico
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-devfor serial port enumeration
Building
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:
When both features are enabled, the driver tries USB first and falls back to serial.
Quick start
use UsbSid;
Examples
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:
# → target/release/libusbsid_pico.{so,dylib,dll}
Generate the C header with cbindgen:
Platform notes
Linux — You may need a udev rule for non-root access:
| \
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.