# Super Nintendo USB Controller

## Overview

![](https://cdn-learn.adafruit.com/assets/assets/000/124/738/medium800/hacks_IMG_8943.png?1695927330)

Many of us have fond memories growing up playing Super Nintendo. The controller is iconic and a true gaming classic. Rather than relegating these old controllers to the dust bin, they can be given new life.

In this guide, we'll show you how to easily convert any original Super Nintendo compatible controller into a fully functional modern USB gamepad that can be used just about anywhere.

**We will be tack-soldering onto the PCB inside the controller but there's no cutting or component removal so it's super easy to convert it back to SNES-plug-compatibility if you decide to go back to your retro roots!**

## Features

- Fully re-programmable Super Nintendo USB controller
- Windows/MacOS/Linux Compatible USB HID Gamepad
- 100% reversible modification

## Materials & Tools

- **Super Nintendo Console Controller**
- An Adafruit KB2040 microcontroller
- About 2ft of jumper wire (Thin 30 AWG wire wrap recommended)
- A soldering iron and solder
- Hot glue gun with glue stick
- Flush angled cutter pliers
- A multimeter (optional)
- Phillips screwdriver
- USB-A cable

## Parts
### Adafruit KB2040 - RP2040 Kee Boar Driver

[Adafruit KB2040 - RP2040 Kee Boar Driver](https://www.adafruit.com/product/5302)
A wild Kee Boar appears! It’s a shiny **KB2040**! An Arduino Pro Micro-shaped board for Keebs with RP2040. (#keeblife 4 evah) A lot of folks like using Adafruit parts for their Keeb builds – but with the ItsyBitsy not being pin-compatible with the Pro Micro pinout, it...

In Stock
[Buy Now](https://www.adafruit.com/product/5302)
[Related Guides to the Product](https://learn.adafruit.com/products/5302/guides)
![Angled shot of short black microcontroller.](https://cdn-shop.adafruit.com/640x480/5302-07.jpg)

### Rainbow "Wire Wrap" Thin 30 AWG Prototyping & Repair Wire

[Rainbow "Wire Wrap" Thin 30 AWG Prototyping & Repair Wire](https://www.adafruit.com/product/4730)
This stuff is called "wire-wrap wire" because it used to be used for wire-wrapping high-speed digital circuits on a special kind of contact board. It's pretty rare to see wire-wrapping in these days of low-cost PCB fabrication, but the wire is still really handy for prototyping...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4730)
[Related Guides to the Product](https://learn.adafruit.com/products/4730/guides)
![Large spool of Rainbow Wire Wrap Thin Prototyping & Repair Wire](https://cdn-shop.adafruit.com/640x480/4730-00.jpg)

### USB A/Micro Cable - 2m

[USB A/Micro Cable - 2m](https://www.adafruit.com/product/2185)
This is your standard USB A-Plug&nbsp;to Micro-USB cable. It's 2 meters long so you'll have plenty of cord to work with for those longer extensions.

In Stock
[Buy Now](https://www.adafruit.com/product/2185)
[Related Guides to the Product](https://learn.adafruit.com/products/2185/guides)
![USB Cable with Type A and Micro B ends](https://cdn-shop.adafruit.com/640x480/2185-00.jpg)

If needed/desired:

### Flush diagonal cutters

[Flush diagonal cutters](https://www.adafruit.com/product/152)
These are the best diagonal cutters, large super-comfortable grip to use and have strong nippers for perfect trimming of wires and leads. I've used my pair every day for years.

In Stock
[Buy Now](https://www.adafruit.com/product/152)
[Related Guides to the Product](https://learn.adafruit.com/products/152/guides)
![Red and black diagonal flush cutters](https://cdn-shop.adafruit.com/640x480/152-02.jpg)

### Digital Multimeter - Model 9205B+

[Digital Multimeter - Model 9205B+](https://www.adafruit.com/product/2034)
This massive multimeter has everything but the kitchen sink included. It's a great addition to any workbench or toolbox. &nbsp;It's low cost, simple to use, and has a big clear display with all the measurements you need and more!

The multimeter includes:

- AC/DC Voltage...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2034)
[Related Guides to the Product](https://learn.adafruit.com/products/2034/guides)
![Angled shot of a Digital Multimeter - Model 9205B+. ](https://cdn-shop.adafruit.com/640x480/2034-01.jpg)

# Super Nintendo USB Controller

## How it Works

The Super Nintendo controller has a relatively simple protocol. It uses two 8-bit shift registers in parallel, totaling 16-bits. 12 button state bits followed by 4 device ID bits.

The shift registers can be read by signaling a latch pulse to start the read cycle, followed by 16 clock pulses for each of the 16 data bits to be read in.

A latch pulse tells the controller that the console is about to send clock pulses and read in the button data. Each time the clock signal goes low the next button data bit is read in.

![](https://cdn-learn.adafruit.com/assets/assets/000/124/835/medium800/hacks_SCOPE.gif?1696452670)

For example, the first bit is `B`, second bit is `Y`, third is `Select` and so on. In the image above you can see what it looks like when `Y` and `Start` buttons are held and released together, over and over.

# Super Nintendo USB Controller

## Mod the Controller

### Disassemble

Start by removing the five Phillips head screws on the rear of the controller.

&nbsp;

Carefully remove the PCB from the shell and disconnect the cable.

![hacks_IMG_8949.png](https://cdn-learn.adafruit.com/assets/assets/000/124/740/medium640/hacks_IMG_8949.png?1695930436)

![hacks_IMG_8950.png](https://cdn-learn.adafruit.com/assets/assets/000/124/741/medium640/hacks_IMG_8950.png?1695930499)

Your circuit board may have one or two chips, but both variants will have the same five output pins on the cable connector.

![hacks_IMG_8951.png](https://cdn-learn.adafruit.com/assets/assets/000/124/745/medium640/hacks_IMG_8951.png?1695931047)

### Clean (optional)

With these controllers being over three decades old and likely never been cleaned, this is a good opportunity to clean it up.

&nbsp;

The rubber pads and plastic parts can all be cleaned with a simple mixture of dish soap, water, and a bit of gentle scrubbing.

![hacks_IMG_8956.png](https://cdn-learn.adafruit.com/assets/assets/000/124/743/medium640/hacks_IMG_8956.png?1695930907)

![hacks_IMG_8957.png](https://cdn-learn.adafruit.com/assets/assets/000/124/744/medium640/hacks_IMG_8957.png?1695930994)

### Solder USB Cable

Next we will need to prepare and solder a USB-A cable directly to the KB2040 microcontroller board. Any old spare USB-A cable will work for this project.

&nbsp;

Start by cutting off the unused end of the cable opposite of the USB-A connector. Then trim back the outer insulation to reveal the 4 USB wires. (Power, Ground, D+ and D-)

![hacks_IMG_8963.png](https://cdn-learn.adafruit.com/assets/assets/000/124/749/medium640/hacks_IMG_8963.png?1695931583)

![hacks_IMG_8964.png](https://cdn-learn.adafruit.com/assets/assets/000/124/750/medium640/hacks_IMG_8964.png?1695931772)

![](https://cdn-learn.adafruit.com/assets/assets/000/125/069/medium800/hacks_SNES.png?1697035590)

Info: 

The wire colors are common but may not always match. Verify with a volt meter.

- Black: Ground
- Green: D+
- White: D-
- Red: Power

Following the diagram below, solder the four wires to the KB2040. (and the shielding wire to ground if present)

![hacks_IMG_8965.png](https://cdn-learn.adafruit.com/assets/assets/000/124/751/medium640/hacks_IMG_8965.png?1695931794)

![](https://cdn-learn.adafruit.com/assets/assets/000/124/784/medium800/hacks_USBA-TO-KB2040.png?1696034700)

### Solder Wires to Controller

Cut 5 jumper wires about 4 inches long (10cm). Then strip a small bit of insulation off of the wire tips.

![hacks_IMG_8952.png](https://cdn-learn.adafruit.com/assets/assets/000/124/746/medium640/hacks_IMG_8952.png?1695931360)

On the front side of the controller PCB, solder a wire to each of the five controller cable pins.

![hacks_IMG_8953.png](https://cdn-learn.adafruit.com/assets/assets/000/124/747/medium640/hacks_IMG_8953.png?1695931405)

![hacks_IMG_8955.png](https://cdn-learn.adafruit.com/assets/assets/000/124/748/medium640/hacks_IMG_8955.png?1695931427)

Keeping track of the pin number wire order, carefully flip over the board and place it within the front half of the controller shell.

![hacks_IMG_8960.png](https://cdn-learn.adafruit.com/assets/assets/000/124/752/medium640/hacks_IMG_8960.png?1695931950)

![hacks_IMG_8961.png](https://cdn-learn.adafruit.com/assets/assets/000/124/753/medium640/hacks_IMG_8961.png?1695931965)

### Mount KB2040

Using a healthy dab of hot glue, the KB2040 can be mounted directly to the controller PCB.&nbsp;

![hacks_IMG_8966.png](https://cdn-learn.adafruit.com/assets/assets/000/124/754/medium640/hacks_IMG_8966.png?1695932137)

## Solder Wires to KB2040

The SNES controller shift registers are capable of operating at 3.3V, the safe operating range of the KB2040's GPIO. So we'll connect the SNES power to the KB2040's 3.3V pin.

![](https://cdn-learn.adafruit.com/assets/assets/000/124/785/medium800/hacks_SNES-TO-KB2040.png?1696034738)

Solder the remaining wires to the KB2040. Ground to ground. Then clock, latch, and data pins to D5, D6, and D7.

&nbsp;

**SNES → KB2040**  
1: Ground&nbsp; → GND  
2: Data&nbsp; &nbsp; &nbsp;→ D7&nbsp; &nbsp;  
3: Latch&nbsp; &nbsp; → D6&nbsp; &nbsp;  
4: Clock&nbsp; &nbsp; → D5&nbsp; &nbsp;  
5: Power&nbsp; → 3.3V

![hacks_IMG_8967.png](https://cdn-learn.adafruit.com/assets/assets/000/124/755/medium640/hacks_IMG_8967.png?1695932627)

![hacks_IMG_8969.png](https://cdn-learn.adafruit.com/assets/assets/000/124/756/medium640/hacks_IMG_8969.png?1695932678)

### Program the KB2040

Before reassembling the controller, put the KB2040 in boot mode.

Holding the boot button while connecting the USB cable to a computer will mount a storage device called **RPI-RP2**.

![hacks_IMG_8968.png](https://cdn-learn.adafruit.com/assets/assets/000/124/757/medium640/hacks_IMG_8968.png?1695933103)

# Super Nintendo USB Controller

## Installing CircuitPython

[CircuitPython](https://github.com/adafruit/circuitpython) is a derivative of [MicroPython](https://micropython.org) designed to simplify experimentation and education on low-cost microcontrollers. It makes it easier than ever to get prototyping by requiring no upfront desktop software downloads. Simply copy and edit files on the **CIRCUITPY** drive to iterate.

## CircuitPython Quickstart

Follow this step-by-step to quickly get CircuitPython running on your board.

[Download the latest version of CircuitPython for this board via circuitpython.org](https://circuitpython.org/board/adafruit_kb2040/)
 **Click the link above to download the latest CircuitPython UF2 file.**

Save it wherever is convenient for you.

![install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/655/medium640/install_circuitpython_on_rp2040_RP2040_UF2_downloaded.jpg?1618943202)

![](https://cdn-learn.adafruit.com/assets/assets/000/108/852/medium800/adafruit_products_KeeBoar_boot_reset.jpg?1644515196)

To enter the bootloader, hold down the **BOOT/**** BOOTSEL button**(highlighted in red above), and while continuing to hold it (don't let go!), press and release the**reset button**(highlighted in red or blue above).&nbsp;**Continue to hold the BOOT/BOOTSEL button until the RPI-RP2 drive appears!**

If the drive does not appear, release all the buttons, and then repeat the process above.

You can also start with your board unplugged from USB, press and hold the BOOTSEL button (highlighted in red above), continue to hold it while plugging it into USB, and wait for the drive to appear before releasing the button.

A lot of people end up using charge-only USB cables and it is very frustrating! **Make sure you have a USB cable you know is good for data sync.**

You will see a new disk drive appear called **RPI-RP2**.

&nbsp;

Drag the **adafruit\_circuitpython\_etc.uf2** file to **RPI-RP2.**

![install_circuitpython_on_rp2040_RP2040_bootloader_drive.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/656/medium640/install_circuitpython_on_rp2040_RP2040_bootloader_drive.jpg?1618943666)

![install_circuitpython_on_rp2040_RP2040_drag_UF2.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/657/medium640/install_circuitpython_on_rp2040_RP2040_drag_UF2.jpg?1618943674)

The **RPI-RP2** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

That's it, you're done! :)

![install_circuitpython_on_rp2040_RP2040_CIRCUITPY.jpg](https://cdn-learn.adafruit.com/assets/assets/000/101/658/medium640/install_circuitpython_on_rp2040_RP2040_CIRCUITPY.jpg?1618943864)

## Safe Mode

You want to edit your **code.py** or modify the files on your **CIRCUITPY** drive, but find that you can't. Perhaps your board has gotten into a state where **CIRCUITPY** is read-only. You may have turned off the **CIRCUITPY** drive altogether. Whatever the reason, safe mode can help.

Safe mode in CircuitPython does not run any user code on startup, and disables auto-reload. This means a few things. First, safe mode _bypasses any code in_ **boot.py** (where you can set **CIRCUITPY** read-only or turn it off completely). Second, _it does not run the code in_ **code.py**. And finally, _it does not automatically soft-reload when data is written to the_ **CIRCUITPY** _drive_.

Therefore, whatever you may have done to put your board in a non-interactive state, safe mode gives you the opportunity to correct it without losing all of the data on the **CIRCUITPY** drive.

### Entering Safe Mode
To enter safe mode when using CircuitPython, plug in your board or hit reset (highlighted in red above). Immediately after the board starts up or resets, it waits 1000ms. On some boards, the onboard status LED (highlighted in green above) will blink yellow during that time. If you press reset during that 1000ms, the board will start up in safe mode. It can be difficult to react to the yellow LED, so you may want to think of it simply as a slow double click of the reset button. (Remember, a fast double click of reset enters the bootloader.)

### In Safe Mode

If you successfully enter safe mode on CircuitPython, the LED will intermittently blink yellow three times.

If you connect to the serial console, you'll find the following message.

```terminal
Auto-reload is off.
Running in safe mode! Not running saved code.

CircuitPython is in safe mode because you pressed the reset button during boot. Press again to exit safe mode.

Press any key to enter the REPL. Use CTRL-D to reload.
```

You can now edit the contents of the **CIRCUITPY** drive. Remember, _your code will not run until you press the reset button, or unplug and plug in your board, to get out of safe mode._

## Flash Resetting UF2

If your board ever gets into a really _weird_ state and CIRCUITPY doesn't show up as a disk drive after installing CircuitPython, try loading this 'nuke' UF2 to RPI-RP2. which will do a 'deep clean' on your Flash Memory. **You will lose all the files on the board** , but at least you'll be able to revive it! After loading this UF2, follow the steps above to re-install CircuitPython.

[Download flash erasing "nuke" UF2](https://cdn-learn.adafruit.com/assets/assets/000/101/659/original/flash_nuke.uf2?1618945856)
# Super Nintendo USB Controller

## Code the Controller

## Text Editor

Adafruit recommends using the&nbsp; **Mu** &nbsp;editor for editing your CircuitPython code. You can get more info in&nbsp;[this guide](https://learn.adafruit.com/welcome-to-circuitpython/installing-mu-editor).

Alternatively, you can use any text editor that saves simple text files.

## Download the Project Bundle

Your project will use a specific set of CircuitPython libraries, and the&nbsp; **code.py** &nbsp;file. To get everything you need, click on the&nbsp; **Download Project Bundle** &nbsp;link below, and uncompress the .zip file.

Drag the contents of the uncompressed bundle directory onto your board's&nbsp; **CIRCUITPY** &nbsp;drive, replacing any existing files or directories with the same names, and adding any new ones that are necessary. The&nbsp; **CIRCUITPY** drive appears when you plug the KB2040 into the computer via USB.

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Super_Nintendo_USB_Controller/boot.py

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/Super_Nintendo_USB_Controller/code.py

![circuitpy](https://adafruit.github.io/Adafruit_Learning_System_Guides/Super_Nintendo_USB_Controller.png )

## How It Works

The code uses the `digitalio`&nbsp;library to send the SNES console latch/clock signals and to read the controller button data wire. Then the `usb_hid`&nbsp;library is used to send standard USB HID Gamepad reports when buttons are pressed or released.

### USB HID Gamepad Descriptor

First, the **boot.py** file is needed to predefine the USB descriptor to appear to the computer as gamepad at boot time. Within this file the `usb_hid` library is imported and a custom USB HID gamepad descriptor is defined. This descriptor follows a [common pattern](https://github.com/OpenStickCommunity/GP2040-CE/blob/main/headers/gamepad/descriptors/HIDDescriptors.h#L156 "GP2040-CE HID GAMEPAD DESCRIPTOR") of DirectInput compatible USB controllers, making it easily compatible with Windows, Mac, and Linux operating systems.

The USB Gamepad descriptor defined has a size of 19 bytes.

- 1st and 2nd bytes contain the 14 button bits. (1 = pressed, 0 = released)
- 3rd byte contains a 4-bit hat switch value (d-pad)
- 4th-7th bytes are the 8-bit analog axis values X, Y, Z, Rz (left/right analog stick)
- The remaining bytes contain compatibility feature flags and vendor specific values.

### Libraries

The meat of our program lives within the **code.py** file. It starts with the importing the necessary libraries.

```python
import time
import board
import digitalio
import usb_hid
```

### Digital In Out

Next, to define the controller's Latch, Clock, and Data GPIO pin numbers. Then to create an instance of the `DigitalInOut` class for each pin and set the pin directions.

Pulsing the Latch wire output high will signal to the controller the start of the next read cycle. Then the controller will wait for a sequence of Clock output pulses. Upon each clock high/low, the controller will respond with the next button bit that we will read from the data input. (0 = pressed, 1 = released)

```python
LATCH_PIN = board.D6
CLOCK_PIN = board.D5
DATA_PIN = board.D7

# Set up pins for SNES Controller
latch = digitalio.DigitalInOut(LATCH_PIN)
latch.direction = digitalio.Direction.OUTPUT

clock = digitalio.DigitalInOut(CLOCK_PIN)
clock.direction = digitalio.Direction.OUTPUT

data = digitalio.DigitalInOut(DATA_PIN)
data.direction = digitalio.Direction.INPUT
data.pull = digitalio.Pull.UP  # pull-up as a default
```

### SNES to USB Mapping

Next, to define the `buttonmap` object that will be used to translate from the SNES controller button data read in to the USB HID report output byte and bit positions.

The buttons are defined in the order they are read in from the SNES controller. For example, SNES bit 0 is "B", bit 1 is "Y", bit 2 is "Select", etc.

`"ButtonName": (SNES bit index, HID byte index, HID bit index)`

```python
# SNES to USB button mapping
buttonmap = {
    "B": (0, 0, 0x2),       # Button 1
    "Y": (1, 0, 0x1),       # Button 3
    "Select": (2, 1, 0x01), # Button 9
    "Start": (3, 1, 0x02),  # Button 10
    "Up": (4, 0, 0),        # D-pad North
    "Down": (5, 0, 0),      # D-pad South
    "Left": (6, 0, 0),      # D-pad East
    "Right": (7, 0, 0),     # D-pad West
    "A": (8, 0, 0x4),       # Button 2
    "X": (9, 0, 0x8),       # Button 4
    "L": (10, 0, 0x10),     # Button 5
    "R": (11, 0, 0x20)      # Button 6
}
```

### D-pad to Hat-switch State

Standard USB HID gamepads use a hat-switch value for directional pad button inputs. We will use the `dpad_state` object to store the current d-pad directions. Then the `hat_map` is used to convert that state directly to the corresponding hat-switch directional value.

```python
# D-pad buttons to hat-switch value
dpad_state = {
    "Up": 0,
    "Down": 0,
    "Left": 0,
    "Right": 0,
}

hat_map = {
    (0, 0, 0, 0): 0x08,  # Released
    (1, 0, 0, 0): 0x00,  # N
    (1, 1, 0, 0): 0x01,  # NE
    (0, 1, 0, 0): 0x02,  # E
    (0, 1, 0, 1): 0x03,  # SE
    (0, 0, 0, 1): 0x04,  # S
    (0, 0, 1, 1): 0x05,  # SW
    (0, 0, 1, 0): 0x06,  # W
    (1, 0, 1, 0): 0x07,  # NW
}
```

### SNES Controller Reading

Next, we'll define the&nbsp;`read_snes_controller()` function that will be used to poll the controller by pulsing the latch and clock outputs while reading the data input.

The function will read and return 16-bits from the controller. The first 12-bits each represent a button, while the remaining 4-bits are the controller ID (all high).

```python
def read_snes_controller():
    data_bits = []
    latch.value = True
    time.sleep(0.000012)  # 12µs
    latch.value = False

    for _ in range(16):
        time.sleep(0.000006)  # Wait 6µs
        data_bits.append(data.value)

        clock.value = True
        time.sleep(0.000006)  # 6µs
        clock.value = False
        time.sleep(0.000006)  # 6µs

    return data_bits
```

### USB HID Gamepad Device

Next, we'll define `gamepad_device` with the usb\_hid device predefined at boot within the **boot.py** file.

```python
# Find the gamepad device in the usb_hid devices
gamepad_device = None
for device in usb_hid.devices:
    if device.usage_page == 0x01 and device.usage == 0x05:
        gamepad_device = device
        break
```

### USB HID Output Report

Finally, we'll need to create an array of 19 bytes called `report`. Set the hat-switch byte to its default value of `0x08`. Also set the unused analog values to the default center position of `127`.

Then create a `prev_report` array for keeping track of when the output report needs to be updated.

```python
report = bytearray(19)
report[2] = 0x08  # default released hat switch value
report[3] = 127  # default x center value
report[4] = 127  # default y center value
report[5] = 127  # default z center value
report[6] = 127  # default rz center value

prev_report = bytearray(report)
```

### Main Loop

The main loop first reads in the SNES controller `button_state`. Then each possible button state bit is checked and the corresponding USB HID output report bits are toggled depending on whether it is pressed or released. (`report[0] or report[1]`)

Once the buttons have been processed, the `dpad_state` will be [SOCD](https://www.hitboxarcade.com/blogs/support/what-is-socd "What is SOCD?") cleaned. Meaning we will clean up opposing button direction presses to avoid them being output.

Then the `dpad_state` is translated to the hat-switch value and set to the third report byte. (`report[2]`)

Finally whenever the report data has changed, send the USB HID output report data with the `send_report(report)` function.

```python
while True:
    button_state = read_snes_controller()
    all_buttons = list(buttonmap.keys())

    for idx, button in enumerate(all_buttons):
        index, byte_index, button_value = buttonmap[button]
        is_pressed = not button_state   [index]  # True if button is pressed

        if button in dpad_state:  # If it's a direction button
            dpad_state[button] = 1 if is_pressed else 0
        else:
            if is_pressed:
                report[byte_index] |= button_value
            else: # not pressed, reset button state
                report[byte_index] &= ~button_value

    # SOCD (up priority and neutral horizontal)
    if (dpad_state["Up"] and dpad_state["Down"]):
        dpad_state["Down"] = 0
    if (dpad_state["Left"] and dpad_state["Right"]):
        dpad_state["Left"] = 0
        dpad_state["Right"] = 0

    # Extract the dpad_state to a tuple and get the corresponding hat value
    dpad_tuple = (dpad_state["Up"], dpad_state["Right"], dpad_state["Left"], dpad_state["Down"])
    report[2] = hat_map[dpad_tuple]  # Assuming report[2] is the byte for the hat switch

    if prev_report != report:
        gamepad_device.send_report(report)
        prev_report[:] = report

    time.sleep(0.1)
```

# Super Nintendo USB Controller

## Use the Controller

## Testing

To quickly check your work, the website [Gamepad-Tester.com](https://gamepad-tester.com) is an easy way to test USB controllers on any computer with a browser.

After pressing a button the website will detect the controller and start showing button presses.

For compatibility, this project used a full gamepad USB HID descriptor with 14-buttons, d-pad, and two analog sticks. So only the D-pad and 8 buttons programmed will register button presses.

## Reassemble

Congratulations! If the button presses are being detected, then you have successfully completed the Super Nintendo controller USB mod.

Lastly, put the shell back together and screw-in the five screws to the back shell.

![](https://cdn-learn.adafruit.com/assets/assets/000/124/758/medium800/hacks_IMG_8972.png?1695933192)

## Play and Tinker

Now you are ready to start gaming on Windows, Mac, or Linux operating systems.

For fun, the code can be easily modified to remap buttons or even to map the d-pad presses to analog stick outputs.

# Super Nintendo USB Controller

## Bonus (GP2040-CE)

But wait.. there's more!

The great part about the KB2040 boards is the RP2040 chip and its ability to run the GP2040-CE firmware.

## What is GP2040-CE?

GP2040-CE is a multiplatform, open source gamepad firmware that is compatible with PC, PS3 and PS4, Nintendo Switch, Steam Deck, MiSTer and Android.

Also a SNES Input add-on was recently added to GP2040-CE. So if you followed the KB2040 pinout in this guide, then you can use this pre-compiled build of GP2040-CE with the SNES Input add-on automatically enabled.

[Download GP2040-CE Firmware with SNES Input Addon](https://github.com/RobertDaleSmith/snes2usb/releases/download/v0.1/SNES2USB_GP2040-CE_0.7.1_KB2040.uf2)
## Installing GP2040-CE

To flash this firmware to the KB2040, simply hold the boot button while connecting the USB cable to a computer like was done with the CircuitPython install.

Then drag-n-drop this file onto the **RPI-RP2** storage device that mounts.

### Gamepad Testing

Using [Gamepad-Tester.com](https://gamepad-tester.com/) again, you can verify GP2040-CE is working. By default the controller will be in X-input mode and should display as an Xbox 360 controller.

![hacks_TEST_START.gif](https://cdn-learn.adafruit.com/assets/assets/000/124/946/medium640thumb/hacks_TEST_START.jpg?1696615690)

## Input Modes

While connecting the controller's USB cable, you can hold A, B, X, or Y to switch the controllers [input mode](https://gp2040-ce.info/#/usage?id=input-modes "GP2040-CE Input Modes"). For example, holding&nbsp; **B** button will make the controller compatible with Nintendo Switch.

## Web Config

GP2040-CE even includes a built-in [web configurator](https://gp2040-ce.info/#/web-configurator "GP2040-CE Web Config") with a slew of advanced options. Simply hold the&nbsp; **Start** button while connecting the controller to put it in config mode. Then open a web browser and navigate to **http://192.168.7.1/**.

## Fun Time

That's it! Now go play some games and have fun with your new Super Nintendo USB controller.


## Featured Products

### SNES Controller

[SNES Controller](https://www.adafruit.com/product/131)
A third-party SNES (Super Nintendo/Famicom) controller. Works great with Fuzeboxen as well!

No Longer Stocked
[Buy Now](https://www.adafruit.com/product/131)
[Related Guides to the Product](https://learn.adafruit.com/products/131/guides)
### Adafruit KB2040 - RP2040 Kee Boar Driver

[Adafruit KB2040 - RP2040 Kee Boar Driver](https://www.adafruit.com/product/5302)
A wild Kee Boar appears! It’s a shiny **KB2040**! An Arduino Pro Micro-shaped board for Keebs with RP2040. (#keeblife 4 evah) A lot of folks like using Adafruit parts for their Keeb builds – but with the ItsyBitsy not being pin-compatible with the Pro Micro pinout, it...

In Stock
[Buy Now](https://www.adafruit.com/product/5302)
[Related Guides to the Product](https://learn.adafruit.com/products/5302/guides)
### Rainbow "Wire Wrap" Thin 30 AWG Prototyping & Repair Wire

[Rainbow "Wire Wrap" Thin 30 AWG Prototyping & Repair Wire](https://www.adafruit.com/product/4730)
This stuff is called "wire-wrap wire" because it used to be used for wire-wrapping high-speed digital circuits on a special kind of contact board. It's pretty rare to see wire-wrapping in these days of low-cost PCB fabrication, but the wire is still really handy for prototyping...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4730)
[Related Guides to the Product](https://learn.adafruit.com/products/4730/guides)
### USB A/Micro Cable - 2m

[USB A/Micro Cable - 2m](https://www.adafruit.com/product/2185)
This is your standard USB A-Plug&nbsp;to Micro-USB cable. It's 2 meters long so you'll have plenty of cord to work with for those longer extensions.

In Stock
[Buy Now](https://www.adafruit.com/product/2185)
[Related Guides to the Product](https://learn.adafruit.com/products/2185/guides)
### Flush diagonal cutters

[Flush diagonal cutters](https://www.adafruit.com/product/152)
These are the best diagonal cutters, large super-comfortable grip to use and have strong nippers for perfect trimming of wires and leads. I've used my pair every day for years.

In Stock
[Buy Now](https://www.adafruit.com/product/152)
[Related Guides to the Product](https://learn.adafruit.com/products/152/guides)
### Digital Multimeter - Model 9205B+

[Digital Multimeter - Model 9205B+](https://www.adafruit.com/product/2034)
This massive multimeter has everything but the kitchen sink included. It's a great addition to any workbench or toolbox. &nbsp;It's low cost, simple to use, and has a big clear display with all the measurements you need and more!

The multimeter includes:

- AC/DC Voltage...

Out of Stock
[Buy Now](https://www.adafruit.com/product/2034)
[Related Guides to the Product](https://learn.adafruit.com/products/2034/guides)

## Related Guides

- [Adafruit KB2040](https://learn.adafruit.com/adafruit-kb2040.md)
- [Commodore Keyboard to USB HID with CircuitPython](https://learn.adafruit.com/commodore-keyboard-to-usb-hid-with-circuitpython.md)
- [DOOM Keeb](https://learn.adafruit.com/doom-keeb.md)
- [Big Key Switches Macro Pad](https://learn.adafruit.com/big-key-switch.md)
- [4x12 Ortho Mechanical Keyboard](https://learn.adafruit.com/4x12-ortho-mechanical-keyboard.md)
- [See N Say Brain Transplant](https://learn.adafruit.com/see-n-say-brain-transplant.md)
- [Fisher-Price USB Foot Pedal](https://learn.adafruit.com/fisher-price-usb-foot-pedal.md)
- [PB Gherkin 30% keyboard with KMK, CircuitPython, & KB2040](https://learn.adafruit.com/pb-gherkhin-30-keyboard-with-kmk-circuitpython-kb2040.md)
- [Fisher-Price USB Controller](https://learn.adafruit.com/fisher-price-usb-controller.md)
- [May Pad Macropad with the KB2040, KMK, and CircuitPython](https://learn.adafruit.com/maypad-macropad-with-the-kb2040-kmk-and-circuitpython.md)
- [Planetary Gear Dreidels](https://learn.adafruit.com/planetary-gear-dreidels.md)
- [How to Choose a Microcontroller](https://learn.adafruit.com/how-to-choose-a-microcontroller.md)
- [16-Step Drum Sequencer](https://learn.adafruit.com/16-step-drum-sequencer.md)
- [Navi10 MacroPad with KB2040 and KMK CircuitPython keyboard firmware](https://learn.adafruit.com/navi10-macropad-with-kb2040-and-kmk-circuitpython-keyboard-firmware.md)
- [Stepper Motor Turntable](https://learn.adafruit.com/stepper-motor-turntable.md)
