Skip to content

Program Lifecycle

Luke Stadem edited this page Jul 1, 2020 · 1 revision

Initialization

Definitions and assembly variables are declared. The PORTB Interrupt-on-change, INT2, and INT1, interrupts are enabled. INT2 is set to a rising edge detection, INT1 to a falling edge detection. INT2 and INT1 are wired together to the same wire to as it needs to listen to both a rising and falling edge case, separate from PORTB. The TRIS registers for each port are initialized based on the schematic.

Main Loop

At the start of the main loop, the controller sets the DATAIO pin to input, and waits 168us. Then it begins an inner loop which waits for the DATAIO pin to become low (checking once every 0.25us). When the pin is low, this means that the console has begun to send a command to the controller.

The inner loop is exited and the program starts to decode the incoming command. Each command is 8 bits long, plus a stop bit. Each bit is 4us long. The program records the state of the pin each microsecond and determines whether the bit is 1 or 0 during the 4th microsecond.

When finished, the 8 bits of data will have been stored in a register, which is then compared against a list of possible commands. The DATAIO pin is also set to output at this point. Because of the strict timing nature of the N64 communication protocol and that the command is always 8 bits long, it's not necessary to listen for the stop bit from the console. However, the program does wait enough time so that the stop bit is complete by the time it gives a response to the console.

Once the command is determined, n-number of bits are transmitted back to the console depending on which command was provided.

Finally, when the response is finished transmitting, the main loop starts again.

Interrupts

There are three different interrupts currently used. They are used to listen for movement in the N64 analog stick. The analog stick sends signals to the controller, whenever there is movement, not continuously. In order to maintain accuracy, the analog stick's movement must always be recorded. Missing even a single instance of movement can cause noticeable effects to the user. More details on how the analog's signal works can be found on the Analog Stick Decoding page.

This microcontroller has 3 independent interrupt pins available, and the first 4 pins of PORTB for another. The three independent interrupts must be set to trigger on either a rising edge (LOW to HIGH) or falling edge (HIGH to LOW). The PORTB interrupt triggers on a change in either direction.

Although the PORTB interrupt could be used for both of the two interrupt signals from the analog stick, the code was significantly more complex to facilitate checking which signal was what caused the interrupt to trigger. Instead, one signal is hooked up to the PORTB interrupt, and the other signal to INT2 and INT1 (with opposing edge detections).

Clone this wiki locally