N64 controller interface for the mbed.
main.cpp
- Committer:
- igor_m
- Date:
- 2011-03-14
- Revision:
- 0:b9925eab1c38
File content as of revision 0:b9925eab1c38:
/*
N64 Controller Interface for the mbed.
by Igor Martinovski
March, 2011.
Function Mapping (from www.mixdown.ca/n64dev/)
Bit Function
0 A
1 B
2 Z
3 Start
4 Directional Up
5 Directional Down
6 Directional Left
7 Directional Right
8 unknown (always 0)
9 unknown (always 0)
10 L
11 R
12 C Up
13 C Down
14 C Left
15 C Right
16-23 X value (signed)
23-32 Y value (signed)
Pinout:
Looking at the controller plug, flat side down.
Pin 1 (Left) Ground
Pin 2 (Center) Data**
Pin 3 (Right) +3.3V*
(*)Note: The controller is supplied by 3.6V on the N64, but it seems to work fine on
the 3.3V provided by the mbed.
(**)Warning: The N64 controller must be connected to an open drain pin with a
pull-up resistor. The line must never be driven high by the mbed! If you are not
sure how to connect the controller safely, you may damage the mbed and/or
controller. You have been warned.
*/
#include "mbed.h"
#include "stdint.h"
// Controller Commands
#define GET_STATUS 0x00
#define REQUEST_CONTROLS 0x01
#define READ_MEMPACK 0x02
#define WRITE_MEMPACK 0x03
#define READ_EEPROM 0x04
#define WRITE_EEPROM 0x05
#define RESET_CONTROLLER 0xff
#define T1 24 // Corresponds to 1 us
#define T2 72 // Corresponds to 3 us
DigitalInOut inout(p14); // Connect controller here
// using 220 ohm pull-up
Serial pc(USBTX, USBRX);
uint8_t x, y;
char array[256]; // Temp array for controller data
/* void delay(unsigned int n) is used as a short delay to
time the bit patterns. 1 n is roughly 0.042us on 96MHz CCLK
*/
void delay(unsigned int n) {
unsigned int i;
for (i=0; i<n; i++)
;
}
/* int receive(char *data_array, unsigned char n) is used to
receive a bit stream of bits into an array of n bytes coming
from the controller. This must be called immediately after
sending any kind of request to the controller
*/
int receive(char *data_array, unsigned char n) {
unsigned char sample, previous_sample;
unsigned char bit, byte;
int i;
//inout.input(); // Not sure about this..
sample = inout.read();
for (i=0;i < n ;i++) {
byte = 0;
bit = 0;
while (bit<8) {
previous_sample = sample;
sample = inout.read();
if ((previous_sample ^ sample) & previous_sample) {
delay(60);
sample=inout.read();
if (sample)
byte = byte | (1<<bit);
bit++;
}
data_array[i]= byte;
}
}
return n;
}
/* void send_byte(unsigned char byte) is used to send a single
byte to the controller.
*/
void send_byte(unsigned char byte) {
char i;
//inout.output(); // Not sure about this.
inout.write(1); // Makes sure line is left high
for (i=0; i<8; i++) {
if (byte & 128>>i) {
inout.write(0);
delay(T1);
inout.write(1);
delay(T2);
} else {
inout.write(0);
delay(T2);
inout.write(1);
delay(T1);
}
}
/* Send Stop Bit */
inout.write(0);
delay(T1);
inout.write(1);
delay(T1);
}
int main() {
inout.mode(OpenDrain); // Must use open-drain for N64 Controller!
int i; // Used for the bit-shifting for x and y values
while (1) {
send_byte(1); // Send the request byte
receive(array, 4); // Start receiving bit stream
/* The for loop here is used to reverse the bits for the x and y values retured
by the controller. I am not entirely sure of the format. I'm missing a bit
somewhere.. Values don't range from -127..128. */
x=y=0;
for (i=0;i<=7;i++) {
if (array[2] & (1 << i))
x=x | (1 << (7-i));
if (array[3] & (1 << i))
y=y | (1 << (7-i));
}
pc.printf("%3d %3d %4d %3d \n ", array[0], array[1], (signed char)x, (signed char)y);
}
}