My attempt at a SNES Bot, couple of questions

Discussion in 'Modding and Hacking - Consoles and Electronics' started by Sonny_Jim, Sep 21, 2013.

  1. Sonny_Jim

    Sonny_Jim Enthusiastic Member

    Joined:
    Apr 29, 2012
    Messages:
    525
    Likes Received:
    31
    Got bored today so I'd thought I'd have a go at making something interesting, which was using my Raspberry Pi's GPIO pins to interface with the SNES controller port. Because I'm skint I'm using whatever I have lying around, which is the Retropie GPIO adapter. Normally, these are used to connect a SNES controller to a Raspberry Pi but I'm thinking it should work just as well the other way round. The ultimate aim is to have something I can playback TAS runs onto real hardware, but for now I'm just going to see if I can get the start button to work ;-)

    One issue that popped up quickly was the speed at which I'd need to poll the GPIO pins, which according to this helpful document is ~12us, according to what I've read here the library I'm using (wiringPi) should be ok (83Khz vs ~7Mhz).

    Couple of questions:

    Q1.
    I read here that the controllers are happy with anything from 3V-7V, does anyone know if the console itself will function with 3.3v inputs on the data line? I'm guessing a quick read of the schematics and relevant datasheet will help me here. I only ask this as it appears the RetroPie GPIO adapter only outputs 3.3v and I'm wondering if that's going to be a show stopper.

    Q2.
    Am I insane? Wouldn't it be a lot easier to use a microcontroller and interface the Pi to that?


    p.s Some shoddy source code is up here,
    https://github.com/SonnyJim/snesbot
     
  2. Sonny_Jim

    Sonny_Jim Enthusiastic Member

    Joined:
    Apr 29, 2012
    Messages:
    525
    Likes Received:
    31
    Getting there slowly. I'm pretty sure that the SNES is happy with 3.3v inputs on the data line as I can get it to just about work, I believe the issues I am having are down to timing at the moment. Also I've found out that some games poll the controllers differently, some need to have the last 4 bits of the 16 bits of data to be high for example.

    Anyway, here's a pic of my setup, hopefully I'll be able to show something a bit more impressive like a video rather than just a picture of a pile of wires ;-)

    snesbot.jpg
     
  3. xmog123x

    xmog123x Peppy Member

    Joined:
    May 7, 2010
    Messages:
    382
    Likes Received:
    14
    why not just use spi?
     
  4. The Last Bandit

    The Last Bandit Member

    Joined:
    Mar 14, 2012
    Messages:
    11
    Likes Received:
    0
    Looks like something you could do with an Arduino fairly quickly. The SNES controller protocol is well documented at this stage, any examples I seen do suggest the last 4 bits are always set high.
     
  5. Sonny_Jim

    Sonny_Jim Enthusiastic Member

    Joined:
    Apr 29, 2012
    Messages:
    525
    Likes Received:
    31
    It looks like I'm going to have to try doing it that way, for some reason or another (scheduling?) what I have at the moment is far too random, even though I'm 90% it should work. I can get the SNES controller test program to recognise that a controller is plugged in and that a button is pressed, but it's very glitchy. When I try it in games I get multiple button presses when I should only have the start button being pressed.

    I did try using a 74HCT244N as a level converter to get the data line output up to 5V but I didn't see any improvement. One thing I am wondering if it's creating a delay as it passes through it, but then the datasheet says that it's in the range of 12 - 15ns so it shouldn't be.


    Yes, all the other projects I've seen use an Arduino, but I had a Pi sitting around so I'd thought I'd have a go using that instead.

    One thing that I'm not sure about is whether I should be looping round in the for loop 15 or 16 times. Different docs say slightly different things, but most of them are about reading the controllers and not interfacing with the SNES itself.

    Oh well, back to the shed.

    Ninja EDIT:

    I don't know much about SPI, but I'm pretty sure in this situation I'd need the Pi to act as a slave, which isn't possible at the moment:
     
    Last edited: Sep 23, 2013
  6. The Last Bandit

    The Last Bandit Member

    Joined:
    Mar 14, 2012
    Messages:
    11
    Likes Received:
    0
    [​IMG]

    You need to clock out 16 bits of data so depends on when you start counting in your loop. SPI isn't really necessary here, you can bit-bang the data out if you can meet the timing requirements.
     
  7. Sonny_Jim

    Sonny_Jim Enthusiastic Member

    Joined:
    Apr 29, 2012
    Messages:
    525
    Likes Received:
    31
    Cool, thanks for the diagram, it's certainly easier to read than the ASCII version I was using.

    It looks like at the moment I won't be able to get the precision I need with the code I have. I'm going to try switching it to be interrupt driven which hopefully should make it more stable.
     
  8. Sonny_Jim

    Sonny_Jim Enthusiastic Member

    Joined:
    Apr 29, 2012
    Messages:
    525
    Likes Received:
    31
    Well, I had a crack at using interrupts and got some very strange results. I setup a very simple program with counters that incremented on the clock and latch interrupts. What I expected to see was a latch every 16.67ms (60Hz) and 16 clocks for each latch (as per the protocol).

    What I actually saw was a latch every 20ms (50Hz) and between 3-4 clocks per latch.
    Now the 50/60Hz thing I'm pretty sure is down to me having a PAL console (which is SuperCIC'd), but I tried it in both modes and with both PAL and NTSC carts and still came to the same result.

    The other thing that is totally baffling me is that I was only seeing 2/3 clocks per latch, the only thing I can think causing that would be that I'm not doing something to the data line that the SNES expects, causing it to send out another latch signal in the hopes of making the 'controller' work.

    I'm trying a different approach now, with 2 8bit shift registers loaded up by the Pi which is then read out to the SNES, rather than trying to bitbang my way through it.

    Certainly learning a lot but it's getting a tad bit confusing!

    EDIT: And here's something interesting

    Most if not all games (SuperFX1/2, SA-1, 1st party and 3rd party etc) all put out 50Hz latches, but the Nintendo Controller test cart and the SuperGameboy put out 100Hz latches. I'm guessing they have cycles to spare so read the controllers faster.
     
    Last edited: Sep 25, 2013
  9. The Last Bandit

    The Last Bandit Member

    Joined:
    Mar 14, 2012
    Messages:
    11
    Likes Received:
    0
    Try declaring "clocked" and "latched" as volatile
     
  10. Sonny_Jim

    Sonny_Jim Enthusiastic Member

    Joined:
    Apr 29, 2012
    Messages:
    525
    Likes Received:
    31
    After chatting to a few guys in #messdev, it's apparently normal for a PAL SNES to output latches at 50Hz. I thought the SuperCIC would change that as I tried in all 3 modes but no difference. I've had other weird issues with the mod, so my theory is that one of the wires has come off and it's stuck in 50Hz mode.

    Also after a bit more investigating it appears that I am blowing bubbles in my cornflakes (aka dreaming) if I think I'll be able to clock out the data fast enough using the GPIO interrupts on the Pi, so current plan is to do it the really, really easy way.

    Take a cheapo knockoff SNES controller, wire up 14 GPIOs to the buttons and parallel load from the Pi when it sees a latch and let the dual 4021's in the controller do the clocking out.

    EDIT: If you are thinking of doing this, make sure you tie the grounds of the Pi and the SNES together but only feed the controllers 3.3v (ie from the Pi, not 5V from the SNES). The 4021's will operate fine at 3.3v but the Pi GPIO pins don't like 5V at all.
     
    Last edited: Sep 26, 2013
  11. Sonny_Jim

    Sonny_Jim Enthusiastic Member

    Joined:
    Apr 29, 2012
    Messages:
    525
    Likes Received:
    31
    Quick update: It works! Kinda....

    I tried using soldering onto a knockoff SNES controller but either my iron was too hot/my soldering sucks/the pcbs are sh*t (pick one) I ended up lifting a couple of tracks, so that approach didn't work. It's probably the easiest way to go, as you'll probably end up buying one anyway to use the connector that comes with it.

    So I went off and bought a pair of 4021's (which is all that's in a SNES controller anyway) and I'm glad to say it works! Huzzah! The controller is detected successfully and I can toggle the GPIO pins to press buttons on the SNES. I even had a crappy game of Super Mario Brothers using a USB keyboard, slightly let down by my coding so I couldn't press more than one button at a time.

    But I'm pretty happy, all that's left is to write some software to use the interface. A couple of ideas I've had:

    Special moves/cheats set as macros, so I can press a button and it automatically performs the button combinations me
    Record and playback games (subject to RNG issues)
    Netplay
    TAS videos
    etc etc
     
  12. Sonny_Jim

    Sonny_Jim Enthusiastic Member

    Joined:
    Apr 29, 2012
    Messages:
    525
    Likes Received:
    31
    Update time, sorry about the crap video but as I've discovered, it's hard to film a CRT with a camera phone! It's a short video of the mess that is my workbench and of the Pi completing the Nintendo Controller Test:
    [video=youtube_share;qKzb42Lm0YE]http://youtu.be/qKzb42Lm0YE[/video]



    I've managed to get live joystick input working, it's connected like this:

    Playstation 2 controller -> PS2 to USB converter -> Raspberry Pi -> GPIO -> 2 x 4021 shift registers -> SNES controller port

    It actually works pretty darn well! I was able to pull off some 32 hit combos on Killer Instinct so I'm classing that as tested and working!

    I've started on recording and playback support which just about works as long as I don't press the buttons too fast. After trying to optimise my code by using memory buffers instead of reading/writing from files directly I've had a bit of a eureka moment and figured out where the problem with my code is.

    (warning: boring bit)

    Right now I am basically dumping the evdev data from the Linux kernel (/dev/input/js0 and /dev/input/event0 for the keyboard), along with the current latch pulse and then replaying the data back out through the GPIO pins on the Pi. I was seeing drifts on the latch pulse, so the Pi was up to 8 latches behind. I couldn't figure out why as live input seemed to work just fine and I'm sure that the Pi should be fast enough to respond but then I noticed this bit of code:
    https://github.com/SonnyJim/snesbot/blob/master/snesbot.c#L344

    The program flow is:
    Read evdev data into some variables, one button press at a time
    Wait for the correct latch
    Write data to GPIO pins
    Go back to reading in the evdev data

    The problem occurs when two buttons are pressed on *exactly* the same latch, my code currently doesn't account for this so it can take a while for it to catch up again, meanwhile the SNES latch and program latch are now out of sync and crapness ensues. I'm not sure how to fix it yet, I may have to take a different approach where the evdev data is preprocessed before playing back. Getting very close to it playback working now though :)
     
  13. Sonny_Jim

    Sonny_Jim Enthusiastic Member

    Joined:
    Apr 29, 2012
    Messages:
    525
    Likes Received:
    31
    Another update and I'm pleased to say I got the b*stard working! Huzzah! I was an idiot and was trying to run the 4021's with 3.3V, whereas they need 5V to operate reliably. I can't tell you how pleased I was to see Orchid wallop a 42 Hit combo, then playback perfectly again, and again, and again :)

    I'm in the process of tidying up the code and making a few decent videos to show it off, but for now I'll post a pic of the schematic I came up with:
    SNESBot_schem.png
     
  14. Sonny_Jim

    Sonny_Jim Enthusiastic Member

    Joined:
    Apr 29, 2012
    Messages:
    525
    Likes Received:
    31
    Here's a (crappy) video of it in action:
     
    Last edited by a moderator: May 25, 2015
  15. Sonny_Jim

    Sonny_Jim Enthusiastic Member

    Joined:
    Apr 29, 2012
    Messages:
    525
    Likes Received:
    31
    Another crappy short video of it doing a tool assisted speedrun from TASVideos.org

     
    Last edited by a moderator: May 25, 2015
sonicdude10
Draft saved Draft deleted
Insert every image as a...
  1.  0%

Share This Page