Modulus Prawn Wireless Remote Car
Project by Alan Lee, James Shuster, and Neil Semidin

N64 Controller Design

Custom Clock
Polling Device
Signal Capture
Interrupt Handler and Software


Since the N64 controller required frequent polling and complicated waveform interpretation, it was determined it would be easier to implement the polling and signal capture in hardware. This also allowed the hardware to only generate interrupts when the controller state had changed; eliminating the overhead for servicing meaningless interrupts. This required the implementation of a custom-made clock (simple divider), polling device, and a capture device.

Custom Clock

Since the custom clock used the system bus clock as its input (10Mhz), it required a 10:1 divider to produce a 1us periodic clock signal. The generation of a 1us clock was important as the controller data was serial and each button was read as a 4us chunk.

Polling Device

To avoid unnecessary interrupts, an automatic polling device was created to ensure the controller would be read every 1-1000ms (user customizable value). In order to prevent the controller from being overly sensitive, the value was set at 100ms. The polling device produced a “poll-in-progress” signal that ensured that the bi-directional line would never be driven by both the controller and the hardware.

Signal Capture

The most straightforward method to capture controller feedback was to trigger on a falling edge of the data. At this point, an event register would be driven high and a counter would evaluate how long the data remained low. This process was activated immediately following a polling operation and collected all 32 bits of feedback. In addition, the module was able to compare the current data versus previous data and throw an interrupt if the two differed. This allowed for all generated interrupts to be of high importance. Since the polling operation was self governed, the interrupt was also able to reset itself without core intervention.

Interrupt Handler and Software

The interrupt handler was set to trigger on a rising edge since the signal was self-resetting. When an interrupt was triggered, the handler loaded an address that decoded into a request for the current controller data held in the signal capture registers. At this point, a C-function was called on the 32 bit value. The software was then able to read and characterize which buttons changed as of the last interrupt. As changes were detected, a 32 bit global register was filled with 8 bit encoded instructions pertaining to the car actions and behavior. When the 32 bit register was full (or the C-function was finishing) the serial transmission function was invoked. This reliably and accurately passed the instruction to the MPC555.