Quantcast
Channel: nesdev.org
Viewing all articles
Browse latest Browse all 746

Hacking the Wii U Gamepad

$
0
0
This is a bit of an old project of mine. I've first made attempts in 2016, but I was not very successful at the time.

The basic idea is to run custom code on the Wii U gamepad. People managed to connect the gamepad to a PC and feed their own video feed into it, but this is one step further. The gamepad runs off an ARM9 CPU, so it is technically possible to have it run as a standalone device, not connected to a Wii U or a PC or anything. I've always thought that doing so would be nifty.

The tricky part is actually getting code onto the gamepad. The "normal" way would be to send code over wifi, like the Wii U does. But that will only work if the gamepad is already running a functional firmware, so that excludes any sort of testing and reverse-engineering work.

The gamepad firmware is stored in a 32MB SPI Flash memory. On this picture of the gamepad motherboard, the Flash is marked in orange.
wiiugamepadmobo2.jpg
On the other side of the motherboard, we find a bunch of test points. I marked those that relate to the SPI bus.
wiiugamepadmobo.jpg
CS0 is the chipselect line for the Flash. I also added UIC CS, which is the chipselect line for the UIC (auxiliary microcontroller that is also connected to the SPI bus).

The RESET line isn't very interesting. It is a simple reset circuit just for the Flash chip, and isn't controlled by the other hardware.

My original attempts at using these test points for some sort of in-situ access to the Flash chip were unsuccessful. You have to remove the Flash chip from the motherboard to access it, which isn't terribly convenient, especially as the Flash sits under the motherboard when it is installed in the gamepad. I made other attempts with breakout connectors that allowed me to unplug the Flash and reprogram it separately, but they weren't super reliable.

It also didn't help that I was largely blind at the time. Not being able to turn on the screen, all I could use as output was the rumble GPIO. So I couldn't really debug stuff.


This year, I wanted to give it a try again, but with better equipment.
fpga0.jpg
fpga1.jpg
I'm using a FPGA board to emulate the Flash. Makes it a lot easier to upload code to the gamepad.

This project was based off spispy, but I ended up building my own from the ground up. I ran into several issues with spispy, one of them being the speed of the gamepad's SPI bus. The first stage bootloader runs it at 16MHz, but past that it goes up to 48MHz, and spispy can't keep up with that.

I'm not yet able to run the stock firmware off the Flash emulator, I don't know why -- I know the second stage bootloader is reading the firmware header correctly, so I know that my design is able to keep up with the 48MHz clock. There might be a stupid bug somewhere...

But so far it has proven reliable enough to run custom code by replacing the second stage bootloader. And as soon as I was able to get working SPI code on the gamepad, it proved very useful to debugging -- I added a special log command to the FPGA design that just forwards data to my computer, and thus I was able to have a far better output than just toggling the rumble GPIO.

Next step was actually managing to display something on the gamepad's screen. The gamepad is nothing like, say, the DS, where the video hardware "just works" and you can display stuff after some very basic initialization. Here, displaying something is a whole ordeal. You have to talk to the LCD over I2C to initialize it, then set up the video hardware correctly for it to actually output something, and talk to the UIC over SPI to turn on the backlight. So far, I was stuck on the first step...

But with the FPGA debug line, I was able to finally get I2C comm working.
Copie d'écran_20240917_234047.png
That's the LCD ID -- my gamepad has a JDI LCD (08922201). There's another possible ID in the firmware code for a Panasonic LCD (00000002).

Getting the video setup right proved challenging, but eventually I got there too.
checkerboard.jpg
Finally.

My next goal from there is to figure out how to sync to VBlank. Then try figuring out more of the hardware. Since we have UIC comm working, input should be a mostly solved problem. The rest will require more work.

I'd like to get wifi working -- then I could have a simple bootloader that would support loading custom binaries over wifi.

I'd also like to dump the first stage bootloader, but it seems to be protected in some way -- I tried reading at 0xFFFF0000 and it's just zero.

Statistics: Posted by Arisotura — Fri Sep 20, 2024 3:14 am — Replies 10 — Views 459



Viewing all articles
Browse latest Browse all 746

Trending Articles