Crate pscontroller_rs[−][src]
Playstation Controller driver for Rust's Embedded Hardware Abstraction Layer
The original PlayStation and most of its peripherals are 20+ years old at this point, but they're easy to interface with for fun projects and wireless variants are easy to come by while being pretty cheap ($28 Canadian for two as of this writing).
The current state of this library is such that it's pretty naïve to which controller is plugged in, and it will make a guess based on the response to a poll request. The response is broken into a header with an identification byte and an acknowledge byte and we use the whole identification byte and just assume the data its sending is correct.
If you own something particularly interesting for the PS1 or PS2 that plugs into the controller port and isn't supported here, feel free to reach out by creating an issue and we can work out some creative way to get the device working with this library.
Efficiencies can be made here, and things will likely improve, but the darn thing is useful now so let's start using it! If you find things to fix, please make an issue.
Hardware
Because the PlayStation can have up to four devices sharing the same SPI bus (two controllers and two memory cards), they made the data out (MISO) pin open drain. That means that it can only pull the line low and you'll need to add your own resistor connected from that pin to +5v. In my testing with a voltage divider on a PlayStation 2, the value is between 220 and 500 ohms.
Development and testing is recommended to by done on a Raspberry Pi as it has a reliable SPI bus. Early testing on both a Next Thing Co. C.H.I.P. and an Odroid C1+ didn't go very well. The C.H.I.P. added unexpected clock changes, and the C1+ had voltage pull up/down problems with the data lines.
The controller itself is a 3.3v logic device and any force feedback is meant to be driven by the 7.5v cd-rom voltage. Testing using the 5v line on of the Raspberry Pi technically works, but the result is much weaker than the original console.
Bibliography
Here is the list of the great bits of documentation that helped get this project started and continue to provide a good cross-reference to double check the work done here.
- psxpad.html - Wiring, testing and bootstrapping game pad on Linux with SPI
- ps_eng.txt - Controller / Memory Card Protocols (pre-DualShock)
- Playstation 2 (Dual Shock) controller protocol notes - Command protocols
- psxpblib - Interfacing PlayStation controllers via the parallel port
- Simulated PS2 Controller for Autonomously playing Guitar Hero - SPI protocol captures
Modules
baton |
G.A E., Inc. GEA001 Controller |
classic |
Sony's Original PlayStation Controller |
dualshock |
Sony's DualShock Controllers |
guitarhero |
RedOctane's Guitar Hero Controller |
guncon |
Namco's GunGon Controller |
jogcon |
Namco's JogCon Controller |
negcon |
Namco's NeGcon Controller |
Structs
ControllerConfiguration |
Holds information about the controller's configuration and constants |
PlayStationPort |
The main event! Create a port using an SPI bus and start commanding controllers! |
Enums
Device |
Possible devices that can be returned by the poll command to the controller. Currently, we're relying both on the device type (high nybble) and the number of 16bit words its returning (low nybble) to guess the device type. |
Error |
Errors that can arrise from trying to communicate with the controller |
MultitapPort |
The active port to set on the Multitap |
Traits
HasStandardButtons |
Many controllers have the same set of buttons (Square, Circle, L3, R1, etc). The devices that do have these buttons implement this trait. Depite the original Controller not having L3 and R3, they are brought out regardless and just considered unpressable. |
PollCommand |
Commands to send off with a poll request. |
Unions
ControllerData |
The poll command returns a series of bytes. This union allows us to interact with those bytes with some functions. It's nice sugar that allows us to use the data in an obvious way without needing to copy the bytes around |