avr playstation controller protocol emulator

This is an an AVR (ATmega324p) microcontroller based project which emulates the data protocol of a dual analog playstation controller, and can translate input from other devices so they can also be used as controllers for a ps1 or ps2. The goal is to be able to fully emulate the protocol of an official sony playstation controller so anything that can be connected to or read by the AVR (like other game controllers or custom analog/digital hardware) can then easily function as an input device to the playstation. Also, because all input signals must be digitized and formatted before being sent to the host console, this can also be used to fully customize any connected devices with programmable button configurations, macros, turbo, joystick inversion/sensitivity calibration, or force feedback intensity adjustment.

The prototype board currently has connections for a Wii "nunchuck", a sega saturn controller, two NES controllers, a standard playstation controller, and serial input/output. A 20x2 character LCD displays the current configuration mode, red/green LEDs are used to show communication status with the host device and a blue LED flashes when the host sends a command to actuate the controllers vibration motors. The device works directly with the playstation and playstation2, as well as xbox or pc with a proper adapter like the one shown in the video.

The current source code for the project is linked below and will be updated as new features are added, schematics can also be drawn up if anyone is interested. Ultimately I intend to etch a PCB for the project at which point I will post the board art as well. If anyone has worked or is working on something similar it would be great to hear suggestions and share ideas. Many thanks to everyone who has taken the time to research and post all the controller protocol info at GameSX.com, without it projects like this would not be possible.

At this point the AVR is able to emulate the the full protocol of the classic gray dual analog playstation controller. This controller has 16 digital buttons and two analog sticks with two axis each. It is able to work with all ps1 games, and nearly all ps2 games. When used with a proper adapter it will also work with any other console or pc as well. The project prototype board currently has connections for a ps1/ps2 controller (wired, wireless, analog, or digital), a sega saturn arcade stick, two NES controllers (for the NES advantage), and a nintendo wii "nunchuck". It also featurers a 20x2 character LCD and a few LEDs to show communication status and force feedback command activity. There are also two tact-switches on the board which cycle through configuration modes and toggle whether the AVR identifies itself as an analog or digital controller (functionally the same as the small "analog" button on playstation controllers located below the start and select buttons). I had originally started the project with the 28 pin ATmega168 AVR, but quickly ran out of I/O pins and replaced it with the 40 pin ATmega324p. I eventually ran out of I/O pins on this AVR as well, but that can easily be fixed by adding more shift registers.

There are a few different configuration modes programmed, the most elaborate of which is for the ps2 game Katamari Damacy. This game has a strange configuration by default that requires the player to move both analog sticks together for forward/reverse/lateral movement and in opposite directions to control rotation. The custom "katamari mode" separates this to be like most other 3d games where the left stick controls movement and the right stick controls rotation independent of each other, it also maps some new macros to the unused L2/R2 buttons to make some of the more cumbersome moves in the game much easier to perform. The ps2 controller port on the board is on a separate bus from the connection of the AVR to the host, so all data from the controller must pass through and be formatted by the AVR first. This is what makes it possible to rearrange the control scheme and modify the behavior of the joysticks and vibration motors.

The NES advantage is probably my favorite gaming peripheral of all time, and I wanted to be able to use it with emulated NES games running on an xbox, so I added two NES controller ports so that both the player 1 and player 2 two plugs could be connected simultaneously; this way I could have player 1 operate all the in-game controls like a normal NES controller, and switch to player 2 when I need extra functions for navigating the emulator menu (8 buttons isn't enough for both). I added the saturn port for arcade emulation because I already had a cheap saturn arcade stick (though I have never owned a saturn) and saturn arcade sticks are easy to find at good prices when compared to the more rare playstation ones. The accelerometer based wii nunchuck is fun to play around with in some games, but the only game I have tried where it really works well enough to use over a normal controller is super monkey ball, for which a tilt based controller is a natural fit. Most games designed for joysticks don't seem to play well when they are retrofit with motion controls. The controllers can also be connected and used simultaneously since all of the buttons are logic ORed (that's probably not a word) with each other. When no controllers are connected the AVR defaults the data sent to blank values that a real playstation controller would send when idle, so the playstation will still behave as though a controller were connected.

The biggest limitation of the project so far is that it can not yet fully emulate a ps2 controller, which has an additional mode where 12 of the buttons can be set to return a full byte of pressure data as well as a digital on/off bit. Only a small fraction of games require this mode, and of those games only a small fraction seem to do anything useful with the pressure data. But some games (particularly newer Square-Enix games) require a ps2 controller to be connected and configured in full analog mode. The easy way around this is to fake pressure sensitivity by just sending a 0xFF pressure value for a given button anytime it is pressed. This may have slightly awkward results in games which rely on this sensitivity for something important, but it will at least allow them to be playable without presenting a "dualshock2 controller not connected" error. Implementing this is tricky because there are some additional commands that controllers must respond to when they identify themselves as ps2 controllers to a ps2, which adds complexity to the already chaotic game of chutes and ladders going on in my code at the moment.

  • avr_dsc.c
  • other.h
  • def.h

  • project videos

  • home