Friday, June 21, 2013

Year in review

Well, school really caught up with me, and although I've had a few pretty neat projects over the last several months, I haven't had the time to post any of them here.  For one, I finally got around to trying reflow soldering, and created a second revision of my SNES Wii Classic Controller mod which turned out really nicely.  I'm actually working on a third revision now, which may not actually be possible, but if I can manage to get it working, it'll be REALLY nice, so fingers crossed there.


Another project I put a lot of time into was the Altera EMP7064S development board I built for my CST231 class.  A large part of this class was devoted to building a wire-wrap board around the Altera CPLD for the purposes of simultaneously building the board and learning to program it in Verilog.  I chose to put my PCB manufacturing experience to good use and go ahead and build a PCB version of the wire-wrap board we built in class.  Here's the board we built in class (the wiring wasn't *quite* complete in the second photo, but it gives a pretty good indication of how much wire wrapping was involved)




And here's the PCB that I made from the same schematic:



As you can see, I made good use of surface-mount parts for the LED current-limiting resistors, as well as the traffic light LEDs.  I also added a DC power jack and a 7805 regulator so I can just hook up a power plug without the need for a bench power supply.  I also made a nice little clock generator from a dual 555-timer IC that plugs into the 4-pin header directly above the main chip socket, so I don't need a function generator for most stuff either.  I'm pretty happy with this board.  My professor really liked it too, and he bought one of the extra boards from me.


In other news, I'm also still working on the Zelda: Parallel Worlds mapping/walkthrough site.  I finally managed to build my first SNES reproduction cart, of ZPW, of course (I built one of Metroid: Super Zero Mission as well...), and have managed to play through the entire game on the actual console hardware, so yay :)  The one major change coming to the website is that I hope to replace WorldKit with Google Maps API.  I currently have a test page up and running and properly displaying the overworld map, but I'm having a few issues, most of which probably stem from my lack of understanding of the Projection class.  I also have yet to try messing around with markers to see if they'll work for my purposes, but I suspect they'll do fine.  So, be watching for that to roll out site-wide soon (I hope...).


I have a bunch of other small projects I've been working on that aren't really in any shape for a write-up yet, lots of fun with the Super Nintendo and other stuff, but I'll get around to them eventually...

Tuesday, January 8, 2013

Super Nintendo Classic Controller for Wii

Awhile back, Nintendo released an awesome Wii controller as a Club Nintendo Japan exclusive, the Wii Super Famicom Classic Controller.


This thing is beautiful.  The only problem is, not only is it only available through Club Nintendo, it's a Japanese exclusive.  It's been out long enough to have found its way onto Ebay and other resellers, but it typically goes for about $100.  Not cool, Nintendo.  Not cool.  There are 3rd party versions of this controller, but like the cheap Ebay knockoff SNES controllers, they're crap.  So what's a guy to do?  Let's build one!

So, obviously we have to start with an official SNES controller (or, just because I want to, a Super Famicom controller).  I found this project implementing a classic controller adapter in a cheap AVR microcontroller and figured I could improve the hardware design.  The existing design was incredibly simple, and the AVR came in a surface-mount package, so I figured I could shrink the board sufficiently to fit it inside the controller itself.  Actually, there's a ton of room inside the controller, so I could have even fit the DIP version inside if I'd wanted to.  But I wanted to do better.  So I did.  The PCB did shrink down nicely, and here's the result:

With a minimum of external parts, the final
PCB shrunk down quite nicely
The board fits perfectly over the pin header from the original cable

The placement of the PCB avoids all of the spacer posts, meaning no
cutting or other modification to the controller shell is necessary
Voila!


You can find more info, including source and PCB design files, at the project page on my site.

Wednesday, November 7, 2012

Arduino HID Gamepad, Part 2

Well, I'm finally getting around to moving forward with my Arduino HID Gamepad project (part 1 here).  I finished the wiring on the gamepad shield, and started trying to get the gamepad device report descriptor and event handlers added to the Arduino libraries.  First of all, you need to add the device report descriptor to HID.cpp, located in hardware\arduino\cores\arduino.  Sorry, I can't explain this very well, I barely understand it myself, but this page helped me stumble through.  Add the following to const u8 _hidReportDescriptor[] (near the top of the .cpp file), above the #if RAWHID_ENABLED directive:


    // Gamepad
    0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
    0x09, 0x05,                    // USAGE (Game Pad)
    0xa1, 0x01,                    // COLLECTION (Application)
    0xa1, 0x00,                    //   COLLECTION (Physical)
    0x85, 0x03,                    //     REPORT_ID (3)
    0x05, 0x09,                    //     USAGE_PAGE (Button)
    0x19, 0x01,                    //     USAGE_MINIMUM (Button 1)
    0x29, 0x08,                    //     USAGE_MAXIMUM (Button 8)
    0x15, 0x00,                    //     LOGICAL_MINIMUM (0)
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    0x95, 0x04,                    //     REPORT_COUNT (4)
    0x75, 0x01,                    //     REPORT_SIZE (1)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
    0x09, 0x30,                    //     USAGE (X)
    0x09, 0x31,                    //     USAGE (Y)
    0x15, 0xff,                    //     LOGICAL_MINIMUM (-1)
    0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
    0x95, 0x02,                    //     REPORT_COUNT (2)
    0x75, 0x02,                    //     REPORT_SIZE (2)
    0x81, 0x02,                    //     INPUT (Data,Var,Abs)
    0xc0,                          //   END_COLLECTION
    0xc0                           // END_COLLECTION


This defines a 2-axis, 4-button gamepad.  Next, you need to add the Gamepad class and event handlers to USBAPI.h:


class Gamepad_
{
private:
uint8_t _buttons;
public:
Gamepad_(void);
void begin(void);
void end(void);
void press(uint8_t b);
void release(uint8_t b);
bool isPressed(uint8_t b);
};
extern Gamepad_ Gamepad;


Now you need to put the class definitions in HID.cpp:


//================================================================================
//================================================================================
// Gamepad

Gamepad_::Gamepad_(void) : _buttons(0)
{
}

void Gamepad_::begin(void)
{
}

void Gamepad_::end(void)
{
}

void Gamepad_::press(uint8_t b)
{
_buttons |= b;
HID_SendReport(3,&_buttons,1);
}

void Gamepad_::release(uint8_t b)
{
_buttons &= ~b;
HID_SendReport(3,&_buttons,1);
}

bool Gamepad_::isPressed(uint8_t b)
{
if ((b & _buttons) > 0) 
return true;
return false;
}


Finally, you need to instantiate the Gamepad singleton.  At the top of HID.cpp, add the following line under the Mouse and Keyboard instantiations:

Gamepad_ Gamepad;

Now, you should be able to call Gamepad.begin() in your sketch setup() function, and then call Gamepad.press() and Gamepad.release() to send button press and release reports.  As you can see, Windows now recognizes my new 2-axis, 4-button gamepad :)





Tuesday, October 23, 2012

I have a domain :)

I just finished registering my very own domain :)  This blog can now be found at blog.qwertymodo.com, and my Zelda: Parallel Worlds mapping site can be found at zelda.qwertymodo.com.

Tuesday, October 16, 2012

Non-volatile N64 Controller Pak

Ever since I read this post on the BenHeck forums about modding an N64 Controller Pak to eliminate the need for a battery to maintain the save data.  I decided to take it one step further and build one from scratch.  The first step was to draw up the schematic for the existing Controller Pak, and modify it from there.  For that, I needed a pinout for the card edge.  I found one with a few errors, used it to fill out the schematic, and determined the function of the remaining contacts from there.  Here's the working pinout:

  Pin   Name
--------------
  1     GND
  2     A14
  3     A12
  4     A7
  5     A6
  6     A5
  7     A4
  8     A3
  9     A2
  10    A1
  11    A0
  12    D0
  13    D1
  14    Detect*
  15    3V3
  16    D2

  17    GND
  18    CE1
  19    /CE2
  20    /WE
  21    A13
  22    A8
  23    A9
  24    A11
  25    /OE
  26    A10
  27    D7
  28    D6
  29    D5
  30    D4
  31    3V3
  32    D3

The Detect line is pulled low inside the controller through a pull-down resistor.  The Controller Pak connects Detect to 3V3 to indicate the presence of a cart in the slot (this is true for both the Controller Pak and the Rumble Pak;  the controller determines which type of cart it is by strobing a specific address and reading the response).

From this, it's fairly trivial to connect an FRAM chip in place of the original SRAM.  I chose to use the Ramtron FM28V020, though the any of the FM18*08 chips should work as well.  If we don't really care about the dual CE lines, we can ignore CE1 and connect /CE2 directly to the RAM.  After that, all that is needed is a pull-up resistor on the /CE line (10Kohm is a good value) and a smoothing cap between 3V3 and GND (100nF is good).

I'll be working on a 4x version soon, using a 1Mbit FRAM chip (Ramtron FM28V100).  The basic wiring for this is the same as above, but add pull-up resistors on the A15 and A16 lines, then connect those lines to a 4-position switch that connects to GND.  Use diodes to isolate the connections between the address lines and the switch, since one position on the switch will pull both lines to GND, but you don't want *every* position to do that.

If you'd like to buy a pre-assembled, nonvolatile N64 Controller Pak (1x or 4x), shoot me an email.  I have a lot of extras sitting around...

Wednesday, August 29, 2012

Progress on Parallel Worlds

Well, in case you haven't seen it (or haven't seen it recently), head over to http://parallelworldsmaps.appspot.com to check out the new visual overhaul I've finally given to my mapping project for the game Legend of Zelda: Parallel Worlds.  For those of you who don't know, Parallel Worlds is a ROM hack of Legend of Zelda: A Link to the Past, resulting in a completely new game, with all an all-new story, fully redone dungeons and maps, and some minor graphical changes to go with all that.  The game is HARD.  Like, Contra hard.  And what's worse is, because the map and dungeons are all new, there aren't any maps to show you where everything is when you inevitably get lost.  I have found a single walkthrough floating around on the internet that has maps, but other than that, you're s.o.l.  So, I took it upon myself to map the entire game, in full, lossless resolution.  After completing the Light World Overworld map (well, I still have some touch-up work to do...), I discovered an awesome piece of software called Worldkit which would allow me to turn my shiny new really-big-picture into a fully interactive map with zoom and pan, as well as geotag annotations for tagging items and important landmarks.  So I got it all loaded up and decided to host it on Google's App Engine framework (which is kind of a weird use of the App Engine framework, but there are plenty of other people hosting static websites on GAE, so whatever...).  As of yet, I can't seem to get annotations working on the web (they work great on the local dev server that comes with the GAE SDK... frustrating), but I have finally gotten around to giving the page itself a facelift from the previous blank-page-with-embedded-flash-object-slapped-into-the-corner.  It is now a presentable web page, with a nice template that will allow me to easily deploy new pages as I finish the maps.  Also, speaking of finishing maps, I managed to map all of Din's Catacombs, which is a pretty nice achievement (if I do say so myself) in that the entire dungeon is normally pitch-black, making mapping via screenshot extremely tedious at best and nearly impossible at worst.  The walkthrough I mentioned earlier with screenshots of all of the dungeons actually doesn't have one for Din's Catacombs.  So I may be the first to have mapped it.  Go me :)  Anyway, the Din's Catacombs page is a bit of a mess right now, I was trying out a different template which really isn't working so well, but I'll fix it up soon.  I've also started work on the Icy World Overworld map, which I currently have about 20% complete, so hopefully that will be online soon as well.

Friday, August 17, 2012

New Zelda: Parallel Worlds Interactive Map

I have discovered a means to make my Zelda Parallel Worlds mapping project much more interesting and useful by creating a fully interactive map with navigation and annotation features using an awesome piece of software called WorldKit.  I am hosting the project using Google's App Engine framework, and have uploaded my current Light World overworld map to test the software and deployment functionality.  I have not yet added any annotations (and I probably won't until I have the Icy World map done), but you can test the zoom and pan features.  Unfortunately, the zoomify software I'm using to generate the zoom tiles only works with JPEG images, so it does get lossy at full zoom, but I suppose that's really the best route to go anyway, then I can offer the full-resolution, lossless PNG for download from a separate link.  I'm still brushing up on my HTML so I can actually have a nice page rather than the current blank page with the embedded map viewer.  It's a work in progress, but check it out at http://parallelworldsmaps.appspot.com/