Igor Martinovski
/
N64ControllerInterface
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); } }