USBASP, a cheap retro controller adapter?

Intro

Long ago, I stared at my trusty USBASP and asked myself if it was possible to convert it to a USB adapter for a Mega Drive(Genesis) controller. At the time I still did not even know about V-USB or that the USBASP used it. As I write this, I got it working recently, with a SNES controller tough.  In this article I will talk about how I made it work, as well a little about USB. Be warned that this is an article about how I hacked an USBASP ( with software USB) to work as an USB converter for retro controllers. Still, I know is 2017 and native USB is getting popular on many microcontrollers and there are other ways of creating USB adapters.

Because the USBASP has 6 GPIOS easily available, it can be used to connect many old devices, as retro controllers, mice, keyboards, or even custom joypads and controllers (for arcade games or simulators) with help of external chips.

If you are comfortable already with creating USB devices with V-USB, maybe this article can be a bit boring for you. Anyway, feel free to stick around.

USBASP

The usbasp is an open source AVR programmer by Thomas Fischl. I have the popular version showed in the picture below. The schematic for it is easily obtained online.

USBASP programmer
USBASP programmer
USBASP schematic
USBASP schematic

This picture above is from the manual of the programmer I have. It was colorized before, that’s why some wires look grey.

This programmer uses V-USB, by objective development,  a software-only implementation of a low speed USB device for AVR microcontrollers. If you don’t know V-USB, there are some really good tutorials for V-USB in Code and Life for getting started. The USBASP has six GPIOs available at the ICSP header, so there is no need to make any mod to the programmer itself. Also, it can be programmed by the ICSP header, just connect other programmer, short JP2 on the target one and you’re good to go.

I wanted to use a USBASP here because it can be bought for around 1,65USD on eBay. I have some  USB homemade devices here, but they were made with perfboard and lots of wires and solder and probably costed more than 1,65. Unfortunately, I still dont have easy access to a laser printer or CNC mill to make pretty boards.

HID and the SNES Joypad

You can’t compare USB to the simpler protocols used with microcontrollers in general. It is very complex, but thankfully there are people out there willing to make it easier to understand. There is a document called “USB in a Nutshell” by Beyond Logic that helps a lot in this matter.

You probably heard of HID already, it is used by a ton of input devices and it does not need specific drivers. HID uses report descriptors to send data that is interpreted by the computer. HID descriptors are not easy to understand either, but there is a fantastic article on the subject by Eleccelerator.

I chose a SNES controller as I have some fake ones here I could use for testing and spare if I made any mistake. However, this easily works with Genesis, Master System, Atari, NES, PlayStation I guess, and others. The Nintendo 64 and Nintendo Game cube controllers have a serial one wire protocol that is a PIA, They can be adapted to USB, but not easily. The SNES controller has a D-PAD and 8 buttons (X, Y, A, B, L, R, Select and Start).

The SNES joypad only needs three GPIO, and two of them can be shared. I mean n controllers use 2+n GPIOS (If you don’t use external chips, of course). That means the USBASP with 6 GPIOs on the ICSP header can easily have 4 SNES controllers attached to itself.

Poorly drawn front view of the joypad connector
Poorly drawn front view of the joypad connector

Joypad adapter

I made a super simple adapter to connect the SNES controller to the ICSP header. Just wired the SNES joypad buttons to the header on the USBASP. I used two standard male header pins for each controller pin and a 2×5 female header for connecting the board to the ICSP port.

 

That’s it. Some wires,perfboard and a bit of solder.

Code

First, I had to edit usbconfig.h, the configuration file for V-USB. These defines were there already in the HID example, I just edited them to match the schematic above. This is basically it for the configuration file, as I used the one in the HID example. In this file is also possible to change VID and PID or rename the device.

As I said before. A HID device needs a report descriptor, the descriptor is an array of bytes that tell the computer how to read the data the device sends to the computer. I this case, I imagined the data,which must be defined as a report_t struct in main.c, as follows:

You may be imagining why in the earth I need two axes on a SNES controller. Yeah, I thought this at first, as every tutorial I found online used axes for directions.  I read that devices implementing real D-pads are troublesome and sometimes not recognized. I even analyzed the descriptor for a USB controller I have here and it uses axes too. So I went with axis for now.

I used the HID toll from usb.org and built the following descriptor. Spoiler! It is wrong and the program did not let me fix it. It is missing a END_COLLECTION, that I added later by hand. If you have no idea how to read the descriptor below, you may need to have a read at the link from Eleccelerator I mentioned previously.

The HID tool from usb.org. Unfortunately, I haven’t tried to run it on Linux, but later I read it works fine with wine.

 

Anyway, I tried to plug the thing to the  USB port. Just to see what happened. The device was not recognized, but I ran dmesg and got the following:

Brilliant. The driver even reported the problem. I fixed the report descriptor as follows. The USBASP is reported as “Mouse” because this is the default name for the HID example and I had not changed it at the time.

The report descriptor size must be updated in the usbconfig.h file

So, now I tested and the device was recognized, but I still needed to send the button presses correctly. For this, I just needed to fill a report_t struct with the data from the SNES controller.

The SNES controller has a very well known protocol, it can’t even be called a protocol. Is just a chip that works like a 74hc165 and sends the buttons pressed serially.

Accordingly to a file on Game FAQs

And the button sequence:

Then, it is simple to read the button states.

CLOCK, LATCH and DATA are the pins of PORTB where the SNES controller is connected(these pins are available at the ISCP header).

And, to fill the struct with the button states:

Then the struct is sent whenever the USB interrupt is ready.

The complete code is available on my github.

Conclusions

It works. I tested in both Linux and Windows. As I said before about HID, it does not need custom drivers.

Joypad test on Windows 10
Joypad test on Ubuntu with jstest-gtk

I am happy I could understand USB better, but I still have a lot to study and try. Hope that this post and the links I provide below will be helpful to you.

I may use this with a Raspberry Pi zero in the future to make a emulation machine with genuine SNES or NES controllers.The good thing is I only need a USB port to connect up to four controllers anyway.

How about Digispark? It should be not only cheaper, as smaller. I thought about this, but a Attiny85 only has 6 pins available, and this only if you disable the reset pin, two of these are used for USB, so it cuts down the number of devices that can be connected right to the micro. Also it has a bootloader for Arduino and does not have a ICSP header, so I went with the USBASP for this project.

That is it for now. Thanks for reading!

See ya next post.

Sources

The following articles were very helpful while writing this text:

Code and Life V-USB Tutorials

USB in a Nutshell

HID Report Descriptor Tutorial by Eleccelerator

Super Nintendo Pinouts and Protocol at Game FAQs

USBASP manual

 

 

Robson Couto

I am a Electrical Engineering student. I should be studying motors or transmission lines right now, but instead I am probably reading about computer history, microcontrollers, buses and protocols. My life is basically I having trouble because of this. God help me please.

15 thoughts to “USBASP, a cheap retro controller adapter?”

  1. Hi,

    Thanks to sharing it with us :)
    A question : you said “That means the USBASP with 6 GPIOs on the ICSP header can easily have 4 SNES controllers attached to itself.”. So I presume it is possible to create 4 HID too ?
    I would like to use my USBASP for 2 gamepad in a first time, do you have some advices ?

    Thank you :)

    1. Hello Shcmurtz.
      Sorry for the late reply, wordpress isn’t notifying my email correctly.
      To use 2 gamepads, you basically have to expand the code to two collections and report descriptors. Ufortunately I did not implement it, but it is explained on the Eleccelerator website.
      http://eleccelerator.com/tutorial-about-usb-hid-report-descriptors/
      You have to program the next GPIO to read the other controller as well.
      Any trouble you can leave another comment here.

      Robson

      1. Thanks for your reply ! I will try but it’s not easy for me (I’m not really a developper ;) ).

        By the way, I take a look to this project below, it’s not based on usbasp but on a Atmega8. I’m pretty sure that we can adapt the code for USBasp. The code is harder but I will take a look too because this code has many interesting functionalities.

        http://www.raphnet.net/electronique/snes_nes_usb/index_en.php
        http://www.raphnet.net/electronique/4nes4snes/index_en.php

        Do you think it’s possible to adapt it to usbasp ? (basically it’s just necessary to change GPIO numbers, isn’t it ?)

        1. Hi Schmurtz
          Raphaels adaptors are great! I actually built the 4 joypads one in the link you sent me. You can see a picture of it here: https://dragaosemchama.com/2015/11/snes-controller-to-pc-adapter-with-arduino-micro/
          I believe it may be possible to adapt them to a usbasp, but I have to have a look at his code first.
          You see, I am not a developer as well haha

          Edit: I am getting it to work. The computer recognizes the usbasp as Rapahel’s 4snes, but I need to fix some things

          1. Thanks Robson !
            By my side I already made a kind of gamepad adapter before : the “USB RetroPad Adapter” :
            http://www.brunofreitas.com/node/41
            Not really hard to make (it’s basically an arduino too), the most harder part was to compile the firmware with some modifications (I use it on an old original xbox !).

            I was thinking that I will be able to modify Rapahel’s 4snes code to USBasp easily but his code is more complex than I was thinking :p
            I really like this idea because there’s almost nothing to solder on usbasp to get it works and it’s really cheap :)

            Awesome if you already has the usbasp recognized ! I tried few days ago without success (ahah it seems that you still more a developer than me :p ).
            I’ll be happy to help you or make tests if you need.
            Looking forward to your investigations :)

        2. Hi Schmurtz
          I left a long comment here yesterday but the website asked me to log again and I lost it.
          Anyway. Awesome adapter. This guy has some cool stuff on his website. I should check them out.
          So far I still have not gotten it to work. There seems to be some bug when reading the controller, I will try to hook up a logic analyser to the usbasp to check the signals this wekeend.
          I took this as a challenge to myself haha.
          Stick around!

  2. Hi Robson,
    Ahah great challenge, I totally understand this kind of obstinacy because I work in the same way ;)
    I would love to know how to use a logic analyser ! What kind do you use ?

    By the way, about your bad experience with “re-authentification” : I recommend you to try the extension “Lazarus”, I use it on firefox (but it seems to exist for chrome too), it allow to recover the content of a web form you were writing just before something bad happen. Not useful every day but you will love it when shit happens :p

    I keep in touch :)

    1. Hi Schmurtz

      I got it to work! I will tweak the code a little more and then post the source at the end of the post :)

      About the logic analyzer, I use a dirty cheap one from ebay. I guess it cost around five dolars. Also got some test clips from ebay to hook up to the pins or legs in the circuit.
      If you have seen a oscilloscope, it is about the some, but only for digital levels(0 to 5V) and usually eight or more inputs. You can see digital signals vary in time with one. With mine, I could see that the clock pin on the controller was not being driven, there should be a square wave in this pin and there was nothing. I used pin 1 on PORTD for clock, if you see the usbasp schematic online(http://www.fischl.de/usbasp/bilder/usbasp_circuit.png) there is a 270 ohm resistor between the microcontroller and the programming header.
      1- Anyway, the serial pins are not used by the official firmware.
      2- Mine had a 1K resistor instead, I guess that a 270 ohm resistor would not kill the signal. But 1K definitely is too much. China tools, you get what you paid for haha.
      I bypassed the 1K ohm resistor and the controller was working fine. I tested with one controller only, but switching between the 4 input pins and they all worked fine.
      I guess the resistor can be removed, bypassed with a wire or swapped for a lower value one.

      Thanks for the tip about the extension. I will check it out!
      I saw this video on hackaday early. It is about cheap logic probes and sigrok I guess. I have the blue one.
      https://www.youtube.com/watch?v=dobU-b0_L1I
      (It is an hour long, but hopefully you can cut through it to the interesting bits ;p or you can find another short one. These tools are very easy to understand )

      Robson

  3. Awesome Robson ! You did it !
    Good analyze, removing a resistor stay a very acceptable mod to make a 4 snes adapter !
    Looking forward your code to make a try and I’m very curious to compare your modifications with the original one. It will help me to understand the code and PIN affectation.

    Thanks for the video about the logic analyser, I’m about to watch this video and buy one :)

    1. Hello Schmurtz

      The code is available at:
      https://github.com/robsoncouto/usbasp4snes/
      As you guessed, it is mostly renaming GPIOs. But you can peek at every changes made in the commits tab (https://github.com/robsoncouto/usbasp4snes/commits/master). I warn you tough, there are some false positives as git saw some changes where there were none. This is possibly a bug with line breaks between different systems.
      GreatScott is a very talented youtuber. His videos are very packed with useful info :)
      I also find him very creative to come up with these many videos so quickly haha

      If you have trouble with this project or any other, just leave a comment here.
      Robson

Leave a Reply

Your email address will not be published. Required fields are marked *