Custom NES Cartridge – Harambe’s Revenge

As far back as I can remember, I’ve been fascinated with computers. This began with the venerable Nintendo Entertainment System – as a child I often dreamt of making my own NES game. This interest lasted well into my teen years, when I would read programming how-to’s from NesDev and other corners of the internet.

Later in life, I met a fellow named Brad Taylor – he was the author of many programming guides for the NES, and just happened to show up at my local hackerspace one fateful day. I had no idea this guy lived in the same country as me, let alone the same city – small world! With Brad’s NES expertise and my PCB design skills, we joined forces to make a USB reprogrammable NES cartridge. This project would be my first foray into PCBA (Printed Circuit Board Assembly), wherein a vendor does all of the component placement and soldering. This was a big deal for me!

The finished product – Raw PCB (left), mounted in cartridge shell (right)

Hardware Design

Initially, Brad and I wanted to make a PCB that could do some very ambitious things, requiring either a very capable processor, or an FPGA device. We began down this path, but soon realized that we were biting off much more than we could chew for something we had never done before. So, we decided to take a step back, and make a smaller project to verify the foundations of our design. Our final design goals were:

  • Be programmable via USB
  • Be able to play NROM format games
  • Feature nonvolatile storage (no battery required)
  • Be as cheap and easy to manufacture as possible

Component Selection

One of our design goals for this project was to make it cheap and easy to manufacture and prototype. That meant excluding BGA packages, which really limited our options. We also opted for a 2 layer PCB to keep manufacturing costs down, which made the layout more challenging than it would be on a 4 layer board.

For the memory, we used whatever was cheap and available from digikey – and could tolerate the NES’s 5V logic buses. We wound up using a SST39SF010 device (one for the PRG memory, and one for the CHR memory).

For the USB interface, I took a misstep in choosing an FTDI FT232H USB interface – I had selected it solely because I had previous experience using this chip. So, we did save some time on having to learn new tools – but at a unit price over $10 at the time, we likely could have found a cheaper option, and simply spent some time learning a new platform. Lesson learned!

One of the challenges of making an NES cartridge is interacting with the console’s lockout functionality. Luckily, the krikzz forums had a firmware load for an Attiny device, so we simply included this same chip in our design, and flashed the provided firmware onto it.

The rest of the components in this design were fairly standard, and included some generic shift registers and regulator circuitry. We used the shift registers to take serially-loaded memory data, and present it to the flash chips as a 48-bit parallel interface.

Fundraising

PCBA can be a costly service, and I didn’t want to go out-of-pocket on the order of $100’s – $1k for a hobby project. To this end, Brad and I opted to fundraise for a production run by following a crowdfunding model. We didn’t want to go as far as a kickstarter, so we solicited local tech groups (as well as friends and family) to see who would be interested in owning one of the cartridges. We received 13 orders and were able to keep the per-unit cost to around 80 dollars, which was a reasonable amount for all involved.

PCB Design, Iterations, Oversights

This design went through a number of hand-soldered prototype revisions before I placed the final order. We never did get a prototype 100% working due to the difficulty of soldering fine-pitched components, but we were reasonably confident that it would work (this later turned out to be partly incorrect).

One oversight was the control circuitry for the “read only” signal to the memory circuitry – we had assumed that the FTDI device would always provide a logic high on a particular signal, and we were using this signal to determine whether or not the device was plugged in to a USB host. This proved wrong, it only held true for a few units. We had to re-work the PCBs with a hardware patch to correct this:

Hardware patches: not as elegant as software patches

This patch takes one of the clock signals, rectifies it, and low-pass filters it to provide our “read only” signal. So instead of detecting if we are plugged in to a USB host, we now detect if we are connected to a powered-on NES. Luckily this patch saved the batch!

A more serious oversight existed in the design of the USB micro-B connector footprint. When I tested the assembled units back, they didn’t come up in dmesg… and the USB cable was getting hot to the touch. After some debugging, it turned out that the USB connector’s metal casing was shorting out the extra-long USB pads – I had designed them as such to ease manual soldering, but this was problematic for automated assembly. This was fixed by manually removing each USB connector, applying kapton tape to shield the casing from the PCB traces, and re-soldering it in place (yes, this was very tedious).

Kapton tape and tedious soldering saves the day

Software Design

Flashing Software Design

The flashing software for this design – the logic that shuffled a file from my PC to the cartridge – was simple in concept: use libftdi to connect to the USB interface, and bit-bang the memory data out through the shift register chain. I wrote a number of abstracted layers to produce the bit patterns needed for parallel memory programming, you can see a video of me testing the entire SR output chain below.

Unfortunately, I used up all of the FTDI’s I/O, and couldn’t route back a signal for the “Flash is done writing the current byte” signal. This meant I had to wait the maximum write time delay between every byte to ensure that it wrote successfully. I consider this the single largest oversight in the project, as it meant that programming an NES game (order of kB’s) would take 5 minutes or more. I did not realize just how long this would take until I had implemented and tested it. But, after a ton of testing with Brad’s cartridge reader device, we had a working unit!

The first working game on my hardware – exciting!

Game Software Design

Making and selling a cartridge is all well and good, but I can’t go shipping it with material that I had no right to distribute. To that end, I fulfilled a lifelong dream and created an NES game, Harambe’s Revenge:

I could write an entire series of blog posts on how difficult it was to write this game. And for all of my efforts – it is a very basic game. I wrote it entirely in 6502 assembly, and did the graphics myself via GIMP. I used https://github.com/pinobatch/pently for the audio playback library, and started the project with Damien Yarrick’s Project Template. Brad’s knowledge of NES programming was invaluable during my efforts.

A brief playthrough of the latest version of Harambe’s Revenge
An early version of Harambe’s Revenge running on Hardware

Lessons Learned

At the end of the day, we achieved our goals of learning to design for PCBA, and verified some design assumptions for a future board. We even successfully filled all of the orders. The most important outcomes, in my opinion:

  • Validate footprints for automated PCBA – casings can short out large hand-soldering pads
  • Bit-banging is a poor choice for programming a memory device, and while it kept monetary costs down, I wouldn’t opt for this approach again. If I were to redesign this, I would use an MCU with built-in USB functionality.
  • Start small – had we went for our initial design, there’s a large likelihood we would have not been able to complete it before losing steam. All of the work to make this ‘simple’ board took place over the course of a year!
  • Anticipate failure – we made more PCB’s than were required, as we anticipated that there would be some unit failures, and there certainly were.

Most of all – this project really drove home an important notion: projects don’t succeed on technical merit alone. There will always be difficulties – it’s not about how good your PCB layout is, or how elegant your code is. The success of a complex project comes down to perseverance and teamwork in the face of unpredictable problems. Having said that – thank you for all of your help and hard work, Brad!

Capture-the-Flag PCB: The Long Con 2019

For 2019’s iteration of The Long Con, I volunteered to help wrangle up some brain teasers for their “capture the flag” contest – a tech convention standard wherein attendees compete to solve assorted technical puzzles. As my experience with “cool stuff” mostly lives in the realm of circuit board design, I opted to contribute a circuit-board based puzzle. I think it looks pretty sharp with the silkscreen logo!

Hardware Design

As this is a small local convention, there wasn’t much budget available to go off-the-wall with technical capability – so, my three design goals were: 1. it has to look cool, 2. it has to be cheap, and 3. it has to do something neat. With these design goals in mind, I began my digikey search for an inexpensive but capable microcontroller. I settled on the attiny84a based on it’s capacitive touch capability, as well as an internal temperature sensor. These on-board sensors meant I wouldn’t need to add external sensors, which would increase the unit cost. You can get more info about the attiny84a here.

Designing the circuit board was relatively easy, based on Atmel’s design guides for capacitive sense (this is via their QTouch library). The hardest part was designing the capacitive touch sensor – I opted for the simpler rotary sensor design due to its ease of entry into KiCAD. I tried a few different ways of importing their recommended design, but couldn’t quite get it to work.

Recommended Design
What I wound up using

I had intended to use svg2mod to import the auto-generated footprint, but the polygon approximation didn’t seem to work out to a workable resolution. I didn’t feel like going any further down this rabbit hole, so I opted for the simpler design that Atmel’s documentation suggested.

The rest of the design was reasonably boilerplate MCU work – I stuck to standard components that were available from Digikey, and preferred components that exist in their KiCAD libraries. I have uploaded the KiCAD project to github, check it out!

Schematic diagram for the CTF board

KiCAD/PCBNew view of the circuit board
3D rendering of the PCB

Software Design

The software was very dependent on Atmel’s QTouch library – most of the challenge was actually in configuring their IDE to work correctly. I wrote up my experiences on their forums here. Based on this experience, I have resolved not to use Atmel components for a while… I got the feeling that Atmel Studio is a second class citizen since the Microchip buyout.

The actual software itself is not terribly complicated (or optimized) – Atmel’s QTouch library, for all of its installation issues, was easy to code with. I had wanted to configure the firmware to spend most of it’s time in a low-power sleep state, but after doing some quick calculations, the battery would last the duration of the conference on a coin cell without the low-power modes. And so, I spent no time optimizing this device for power consumption.

You can see the source code for my solution on github here. It is far from the “cleanest” code I’ve written, and was written in a time crunch. But, it did work!

Capacitive touch test

Manufacturing design

For this unit, I opted to use reflow solder techniques. I purchased a Whizoo upgrade kit to modify a toaster oven, but I did not get the parts in time. I ultimately used a thermocouple and manually rode the thermostat on my toaster oven to follow something like a soldering profile. It seemed to work reasonably well!

For flashing the firmware onto the attiny84a, I placed a contact pad that mated with a spring loaded 6-DIP connector on the back of the device. To make for an easy flashing process, I exported a 3d model from kicad and used it to make a 3d-printable jig. I had to manually line up the spring loaded connector and hot glue it in place, which was a little tedious, but worth it in the end.

3d printed programming jig, complete with “Pogo pins”
Demonstrating fit on the jig

Conclusions

The project was an overall success, and people enjoyed the challenge. Unfortunately, out of the 30 that I had tried to manufacture, only 6 worked to their fullest extent! I attribute this to my ambitious use of tiny resistor arrays – it appeared most of the failed units featured poor connections on these components, and my reflow repair skills were simply not up to the task. Luckily(?) only a couple teams got far enough in the CTF to get to the “PCB challenge”, so we were never short on units despite the poor yield.

Another conclusion – try a different MCU vendor next time, Atmel Studio/QTouch installation was a torturous experience!

Puzzle Spoiler

The general intention was for participants to look up the datasheet of the single IC to see what peripherals it had – QTouch and temperature sensing – and work from there.

Puzzle 1 – this conference takes place during the daylight savings time change. Users had to “turn back the clock” by using the capacitive rotory sensor on the clock face. 4 complete rotations would prompt the LEDs to display a byte pattern.

Puzzle 2 – the weather had just begun getting cold in Manitoba (where this conference took place). Users had to get the unit 15 degrees Celsius colder than when they plugged in the battery. This could easily be done by taking the unit outside. This was a fun puzzle to figure out from a software point of view – the calibration on the sensors was not great out of the factory, and I didn’t intend on taking multiple calibration points for each board. So, it simply looks at the temperature delta since the unit turned on instead of comparing against an absolute temperature.

Building a Magic Mirror; Nifty Opto-Isolator Tricks

After seeing a critical mass of Magic Mirror builds online, I caved and built one as a Christmas gift for my girlfriend – I made a few innovations on top of the other builds I’ve seen, so I’ve documented them here.  I drew much of the inspiration from Dylan Pierce in particular, so be sure to check out his build log as well!  Here’s the finished product, before wall-mounting:

 

mirror2

Build Process:

As I did not have the patience to spec out my own LCD panel, I decided to purchase a used victim TV, and worked from there.  The first step was to pop the bezel off and take a few measurements:

 

20161221_002223

 

With measurements of the LCD panel itself, I was able to mount the LCD panel in a basic 2×4 frame:

20161222_203728

The LCD Panel did not have any usable mounting holes that could mate with the 2×4, so I held it in place with some small angle brackets.

20161222_210831
After installing the brackets, I realized the single-screw mounting hole would be prone to rotation – some flank screws made for a quick fix.  Also pictured: speed holes

 

20161222_211047
I eventually added small metal mending plates to sandwich the LCD bezel in the frame (not pictured)

The TV I had cannibalised did not support HDMI/CEC control via the raspi, so I patched in to the power button with an opto-isolator (Sharp PC817).  By using an opto-isolator, the raspi only “sees” an LED as the load, allowing for safe coupling between the raspi and the TV circuitry.  The pin spacing on the PC817 was conducive to patching in directly to the tactile switches.  I also replaced the TV’s “off” LED with an opto-isolator connected in the opposite direction – this lets the raspi know if the TV is on or not.  This is important, because the power button is of the on/off toggle type; the raspi wouldn’t be able to know if it was turning it “on” or “off” otherwise, it would only know that it is changing the state.

 

20161222_213606

 

Originally, I was going to power the TV on and off via cron job, until a coworker suggested putting a sensor in to turn the mirror on when someone is in front of it.  I just happened to have a spare ultrasonic sensor around, so I mounted it into the frame and wired it up via GPIO pins on the rpi:

20161224_172106

With all the electronics connected + working, I glued the fancy mirror-glass in place (Actually, it’s acrylic), and added a nice aesthetic touch with some faux-oak molding and iron-on veneer (ran out of veneer, so the bottom got the thin piece).  I measured the mirror piece to have a 0.5″ margin beyond the viewable LCD portion so that I could affix it to the LCD bezel for a tight fit.  Mirror glass was the same used by Dylan Pierce available at TAP Plastics:

20161224_231110
The notch is in place to accommodate a power cable while wall-mounted.  Also pictured: speed holes

 

The ultrasonic sensors were a bit tricky; I drilled holes in the moulding and adjusted them with a dremel.  They are by no means perfect…

20161224_231134

 

And here’s a view of the rear/electronics – the intention is that this will be wall-mounted, so I didn’t bother with a protective cover.  Zip ties were applied liberally.

20161224_231116

 

Schematic

mirror_schem
Note: The optoisolator / ultrasonic sensor circuitry was soldered onto a piece of perfboard that mated with the RPi’s GPIO header

Software

The base software installation uses raspbian jessie and MagicMirror², and raspbian packages python-gpiozero and wiringpi (i.e. install via sudo apt-get install _____).  All GPIO control code is below.

Note: all .sh and .py files live in /home/pi, the .service files live in /etc/systemd/system/, enable via:

  • cd /etc/systemd/system
  • sudo systemctl enable detect_person.service
  • sudo systemctl enable tv.service

This allows for control via, e.g. sudo service tv [start|stop].  The tv.service serves to turn on the tv during the boot process (as well as for general debugging), while the detect_person service performs the ongoing operation for person detection.   Note that the particulars in detect_person.py need to be tuned to the environment that the mirror is installed in!

I also had to play with some settings /boot/config.txt to get the right screen orientation, see the comments in that file for details.

 

 

 

Hacking Dollar-Store Bluetooth Devices (The Kindness of Strangers) part 2

This is a continuation of “Hacking Dollar-Store Bluetooth Devices (The Kindness of Strangers) part 1”

After putting the EEPROM programming document (rda5871_progguide) through google translate, I was able to discern the format of this mysterious binary dump I had created – I created a simple program to parse the Saleae log file (saleae_log) into one contiguous binary image (binary_image – extension is just to get around wordpress, it’s binary) and parse the info header as well as  some of the configuration data (hopefully).

However, the data I got back was pretty trivial:

Parsing info header…
**************
Chip ID: 0x5873
Version: 6.4
PSKey Length: 532
Data Length: 6912
PSKey: SYS_CONFIG_ID_NULL
Length: 0
Data: {}

This at least provided a sanity check against the info header format – the Chip ID matches what is laid out in the guide.  But, none of the datasheet’s “PSKey” information located at 0x88 seems to be used – just 532 bytes of “SYS_CONFIG_ID_NULL” and zero-length data blocks.  As well, the ISR code regions described seem to reside well out of the memory range of the binary dump – e.g. 0x80006880 – so it appears I am no further along in the binary image, pending further ingenuity…

 

But then I noticed some clearly labelled serial connections!

20160911_115417
I was able to squeeze in a tiny terminal header to break out the TX/RX solder pads

20160911_120627
Pro tip – you can pop the Atmel IC out of an arduino board, and you have a simple USB <-> TTL RS232 bridge

20160911_125657

 

I was able to discern from my ‘scope that the data was transmitting at a line discipline of 115200 Baud 8N1 – however, the data that it spat back at me was indecipherable.  Consistent, but gibberish.  I had some hopes that it was unicode / chinese characters, but this was quickly ruled out (unless this serial prompt also uses arabic…).  If I had to guess, this is some binary debug and/or manufacturing automation output.  Oh well.

I also noticed that the device would pair to my PC as a USB keyboard – it ends up sending a “Volume up” keystroke and a “Enter” keystroke between the two buttons.  I was hopeful that the EEPROM image would contain the keycodes for these, allowing us to change it’s behaviour, but I was unable to find such.

My next step will be to selectively write some of the EEPROM data & (hopefully) change the device’s name – stay tuned!

Hacking Dollar-Store Bluetooth Devices (The Kindness of Strangers) part 1

Ah, the dollar store – risky condoms, something labelled as mustard, and every permutation of pastey-looking, thin-plastic discharge courtesy of third-world prisons factories all line the utilitarian wire-shelves; How do our capitalist overlords tolerate such thrift?  Just how much nausea-ketchup must one purchase to turn a profit at $1/bottle?  I don’t even care to know, because I’m too busy ogling the most modern dollar store trinket yet(?); this Bluetooth camera shutter!

 

2iw7srr

 

This things works right out of the box – but that’s boring, because that’s what we expected it to do (actually, I didn’t even expect it to do that.)  I decided to take this thing to SkullSpace (my local hackerspace) to see what makes this zany device tick –  this three-dollar chunk of plastic that wirelessly talks to my cell phone!?

20160904_183253See those two lines coming from the large chip to the small chip?  Yup, thats an I2C bus!  Googling the part number (RDA5871 ) reveals that the larger chip is a bluetooth IC with an integrated ARM core, and the smaller one is ostensibly a configuration ROM.  After connecting our handy logic analyser and twiddling with the I2C settings, I was able to get a log of all the data being read from the smaller chip:

 

saleae_log (text file, output from Saelae logic)

 

Lo and behold, searching through the text file for the Bluetooth name – “AB Shutter”, we find it:

 

[…]

1.363279600000000,7,’161′,’0′,Read,ACK
1.363303200000000,7,’161′,’0′,Read,ACK
1.363327400000000,7,’161′,A,Read,ACK
1.363351000000000,7,’161′,B,Read,ACK
1.363374400000000,7,’161′,’ ‘,Read,ACK
1.363398600000000,7,’161’,S,Read,ACK
1.363422200000000,7,’161′,h,Read,ACK
1.363445800000000,7,’161′,u,Read,ACK
1.363470000000000,7,’161′,t,Read,ACK
1.363493400000000,7,’161′,t,Read,ACK
1.363517000000000,7,’161′,e,Read,ACK
1.363541200000000,7,’161′,r,Read,ACK
1.363564800000000,7,’161′,’ ‘,Read,ACK

[…]

Looks like we are reading the chip correctly!  I noticed the above block is one giant read (about 6.8kB) starting from ROM address 0x0228 – We see two writes to address 160, the data of which is 0x0228.  This is a typical I2C EEPROM “Start reading data from here” command.   The device then spits out consecutive bytes, starting from the supplied address, on every read.   I carved out the relevant 6.8k read manually, and used awk to extract the “read” column.  Then, I used this simple python script to convert the decimal “read data” output into a binary file (note – I had to change the csv data from ASCII to decimal in Saleae Logic):

test_out (Arbitrary extension, just binary data)

But what is this file?  Is it an ARM binary? I have no idea!  I was hopeful that the device was reading a full firmware image directly from the I2C ROM, but I cannot find any indication of such (yet).  I have tried looking at earlier reads in the I2C transactions to discern any kind of header information, but nothing was obvious – I’ve tried pointing the file command at it to determine it’s type via magic bytes, and I’ve also tried running it through various ARM dissemblers with no luck.

I did manage to find this defunct google code page regarding the RDA5871, and I am happy to report that the previous maintainer has replied to my random emails with some documentation on how to configure the device via ROM!  I am hopeful to get this pointed at the mystery file dump that I have.   The only hurdle is that the document is primarily in chinese, so stay tuned for when I wrangle together a translation –  for any of you willing to take a gander, here it is: rda5871_progguide

 

 

 

Halloween 2014 – a functioning gameboy

For Halloween this year, I decided to step up my costume game and make a fully functioning gameboy costume:

Video:

A ton of people who saw the costume wouldn’t believe it worked until they pushed a button….. but the reaction was always priceless

 

Click ‘Continue Reading’ to see how the magic works!

Read more “Halloween 2014 – a functioning gameboy”

Tube amp repair

A few years ago I picked up this little gem of an amp at a gun show for a paltry 25 bucks.  Not a bad snag!

20140513_215846
vintage!

It worked great, except the volume knob didn’t seem to do much… it always sounded like it was on full blast.  So, I brought it down to Skullspace to tinker with it.

Aside from the potentiometer not really changing the volume, it was also quite scratchy when changing volumes.  This is usually a sign of a worn-out potentiometer, so I ripped out the old one and temporary wired up a replacement off ebay.

Doing a test run with alligator clips

I carefully tested the amplifier (you really dont want to touch the high-voltage tube supply wires in there when it’s powered…) and it sounded way better than before!  I deemed it a success and installed the new potentiometer, still with test connections:

20140513_220655
Dry fit before everything gets soldered

Everything seemed to work alright, so I soldered everything in place:

20140513_230304
hand-wired goodness

The only issue I faced was that the old wires did not really wick up the solder so well.  I suspect there are some poor connections because of this, but for now it works… maybe some proper flux paste would work better than rosin-core solder?

 

Stay tuned for an audio clip!

Gameduino2 test game

Hello internet, I recently received my Gameduino2 via kickstarter and dreamt up a quick demo – tilting the screen moves the ball around (with realistic-ish physics), and keeping it on the “path” longer earns more points:

This demo doesn’t even touch the Gameduino2’s capabilities – just a fun proof of concept.  Maybe someone can build off of it?

Anyways, code is available at https://github.com/trdenton/gameduino2-ballgame, including a pre-compiled .elf file for the arduino Uno.  I am using the Eclipse Arduino plugin from http://baeyens.it/eclipse, and have included the project files.  It should still work in the arduino IDE if you remove the eclipse project files – Enjoy!