PSX Input Interface¶
Reads native PlayStation 1 / PlayStation 2 controllers over the PSX SIO bus. Auto-detects the controller type each poll and decodes every standard PSX peripheral.
Protocol¶
- Bus: PSX SIO -- CLK, ATT, CMD, DAT (open-drain DAT with pull-up)
- Method: RP2040 PIO + DMA, hardware-paced 500 kHz clock with active pull-up on DAT
- Polling: ~250 Hz, paced by the PIO state machine; CPU never bit-bangs
- Location:
src/native/host/psx/
The PSX SIO is a clocked serial bus where the host (us) clocks command bytes out on CMD while the controller clocks reply bytes back on DAT. Each transaction begins by pulling ATT low, sends 0x01 0x42 plus motor bytes, then clocks 17 reply bytes. The first reply byte's high nibble identifies the controller type, the low nibble gives the data-halfword count.
The active pull-up technique briefly drives DAT high (weak 2 mA) at the start of each bit before releasing it back to input. This wins on a released '1' bit against cable capacitance, but loses to the controller's strong pull-down on a '0' bit, so the read stays correct -- and old analog pads (notably Sony SCPH-110) finally read clean at the 500 kHz clock instead of clipping at the 0x00 / 0xFF extremes.
Supported Controllers¶
| Device | Type ID | Notes |
|---|---|---|
| Digital pad | 0x41 | Standard SCPH-1080 |
| DualShock | 0x73 | Analog mode; auto-enabled via config command |
| DualShock 2 | 0x79 | 12-byte per-button pressure (passed to PS3 output mode) |
| neGcon | 0x23 | Namco NPC-101; twist + I/II/L analog buttons |
| Dual Analog flight | 0x53 | SCPH-1110 / Dual Analog "red" mode |
| GunCon | 0x63 | Namco light gun; screen X/Y |
| JogCon | 0xE3 | Namco paddle wheel; experimental recenter FF |
| PlayStation Mouse | 0x12 | SCPH-1090; relative X/Y + 2 buttons |
| Config mode | 0xF3 | Transient response during analog/pressure enable |
Configuration¶
The host sends the standard DualShock unlock sequence (enter config -> set analog mode -> enable rumble -> enable pressure -> exit config). Pads that ignore some of these (digital pad, mouse, GunCon, neGcon) simply stay in their default mode; pads that accept them (DualShock, DS2, JogCon) transition into their richest reporting mode.
Wiring¶
Per-board pin assignments are defined in src/CMakeLists.txt under the psx2usb target. CLK and ATT must remain consecutive GPIOs (the PIO side-set uses both); CMD and DAT can be on any free pins. Both Adafruit variants use the same GPIOs — CLK=GP26, ATT=GP27, CMD=GP28, DAT=GP29 — but they number their A0–A3 pads in opposite directions: the KB2040 is ascending (A0=GP26=CLK … A3=GP29=DAT), while the QT Py RP2040 is descending (A0=GP29=DAT … A3=GP26=CLK). Wire by the per-board pad table in the build guide, not by pad number alone.