User Tools

Site Tools


fpgapad

FPGApad

The FPGApad is Arisotura's modified WiiU gamepad, which serves for reverse-engineering and development purposes. This page is intended to document the FPGApad and provide a blueprint for anyone wanting to attempt a similar mod.

Reason

On a stock gamepad, the firmware can only be updated over wifi. Since the firmware runs on the bare metal, you need a functional firmware to do anything, including uploading new code to the gamepad. This excludes any sort of reverse-engineering work because it would be way too easy to brick the gamepad.

Going around this limitation requires directly accessing the Flash memory, where the firmware is stored. However, my attempts at in-situ programming the Flash memory were unsuccessful. Removing the Flash chip and adding connectors (so it could be disconnected and connected to a separate programmer) showed some success, although it wasn't completely reliable and was rather finicky.

A problem I ran into when trying to run code on the gamepad was that I was pretty much working blindly. My only output was the rumble motor GPIO. Getting the LCD to display something requires some amount of initialization, and I wasn't really able to debug my faulty init code.

Eventually, I had the idea of doing away with the Flash chip entirely, and instead emulating it. I found spispy, a FPGA-based Flash memory emulator. With this, I set to work. I ordered a FPGA board and modified a gamepad motherboard, removing the Flash memory and adding a SPI breakout connector.

spispy wasn't suitable for this project – it can't keep up with the 48MHz SPI clock the gamepad uses – but it gave me the inspiration I needed. I built my own SPI Flash emulator design. In some ways, it is more limited than spispy, since it's intended for a specific purpose, but I was able to make it work with a 48MHz SPI clock.

Thus, the FPGApad was born.

It proved to be a very convenient way to upload code to the gamepad: I can do so from my computer over USB, and I don't have to worry about Flash write cycles, since the FPGA uses SDRAM. It also proved invaluable as a debug output: I could simply send data over the SPI bus and have the FPGA forward it to my computer. This finally allowed me to get my LCD init sequence working, and even more.

FPGA

Since spispy was built on the Radiona ULX3S, I went with that board too. I went with the 85K version to be safe, but smaller versions should be able to support the Flash emulator too. They may need some adaptations, like moving the SPI clock input to a different pin.

It may even be possible to port the Flash emulator to other FPGA boards. They would need to have SDRAM that supports atleast 133MHz of clock speed, and ideally 32MB or more.

Flash emulator

Flash emulator codebase

The codebase is a bit of a mess.

(TODO: add the rest)

FPGA/computer interface

The FPGA communicates with the computer over USB (on the US1 port of the ULX3S). The FPGA exposes a serial interface running at 3 megabauds, 8 bits, no parity, 1 stop bit.

The communication protocol is binary: send one command byte, send required address/length bytes if any, then send or receive data bytes.

The following commands are supported:

Command Description
0x30 Get version
0x31 Read memory
0x32 Write memory

Command 0x30

Returns the current protocol version (0x01).

Command 0x31

Reads data from SDRAM.

This command takes 4 parameter bytes: 3 for the address (MSb's first), 1 for the length to read. Address and length are expressed in 8-byte chunks.

After the parameter bytes are sent, data from the requested memory address is returned.

Command 0x32

Write data to SDRAM.

This command takes 4 parameter bytes: 3 for the address (MSb's first), 1 for the length to write. Address and length are expressed in 8-byte chunks.

After the parameter bytes are sent, data bytes should be sent to be written to memory. A 0x01 byte is returned when the write has completed.

Debug output

When the gamepad runs, the FPGA also sends the following data to the computer:

  • SPI command bytes, and address bytes for commands that take addresses
  • All SPI bytes received after SPI command 0xF2
  • Byte 0xE2 when gamepad Vcc drops to zero, to indicate a reset

FPGA/gamepad interface

The FPGA connects to the gamepad's SPI bus, where it emulates Flash memory.

The following SPI commands are currently supported:

Command Description
0x02 Page program
0x03 Read
0x04 Write disable
0x05 Read status (basic status bits supported)
0x06 Write enable
0x20 Subsector erase
0x9E/0x9F Read chip ID (fixed 20,BA,19,00,00,…)
0xB7 Enter 4-byte address mode
0xD8 Sector erase
0xE9 Leave 4-byte address mode
0xF2 Debug

Command 0xF2 is an addition to the normal Flash command set. It allows to abuse the SPI bus as a debug output.

When receiving command 0xF2, the FPGA simply forwards all subsequent bytes to the computer until the SPI chipselect line goes high.

The data sent via command 0xF2 follows a simple format: a simple 16-bit header is sent MSB-first after the command byte to indicate how the subsequent data should be parsed.

Bits Description
0-13 Data length in bytes
14-15 Data handling; 0=hexdump, 1=file, 2=string, 3=string

Data handling value 1 means the data should be dumped to a binary file. Other values mean it should be displayed in the terminal, as a hex dump or directly as a string.

fpgapad.txt · Last modified: 2025/03/19 22:59 by arisotura

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki