Igor Martinovski / Mbed 2 deprecated N64ControllerInterface

Dependencies:   mbed

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 
00002 /*
00003 N64 Controller Interface for the mbed. 
00004 
00005 by Igor Martinovski 
00006 March, 2011. 
00007 
00008 Function Mapping (from www.mixdown.ca/n64dev/)
00009 
00010 Bit     Function
00011 0       A
00012 1       B
00013 2       Z
00014 3       Start
00015 4       Directional Up
00016 5       Directional Down
00017 6       Directional Left
00018 7       Directional Right
00019 
00020 8       unknown (always 0)
00021 9       unknown (always 0)
00022 10      L
00023 11      R
00024 12      C Up
00025 13      C Down
00026 14      C Left
00027 15      C Right
00028 
00029 16-23   X value (signed)
00030 
00031 23-32   Y value (signed)
00032 
00033 Pinout:
00034 Looking at the controller plug, flat side down.
00035 Pin 1 (Left)    Ground
00036 Pin 2 (Center)  Data**
00037 Pin 3 (Right)   +3.3V*
00038 
00039 (*)Note: The controller is supplied by 3.6V on the N64, but it seems to work fine on
00040 the 3.3V provided by the mbed.
00041 
00042 (**)Warning: The N64 controller must be connected to an open drain pin with a
00043 pull-up resistor. The line must never be driven high by the mbed! If you are not
00044 sure how to connect the controller safely, you may damage the mbed and/or
00045 controller. You have been warned.
00046 */
00047 
00048 #include "mbed.h"
00049 #include "stdint.h"
00050 
00051 // Controller Commands
00052 
00053 #define GET_STATUS          0x00
00054 #define REQUEST_CONTROLS    0x01
00055 #define READ_MEMPACK        0x02
00056 #define WRITE_MEMPACK       0x03
00057 #define READ_EEPROM         0x04
00058 #define WRITE_EEPROM        0x05
00059 #define RESET_CONTROLLER    0xff
00060 
00061 #define T1                  24      // Corresponds to 1 us        
00062 #define T2                  72      // Corresponds to 3 us
00063 
00064 DigitalInOut inout(p14);            // Connect controller here
00065                                     // using 220 ohm pull-up
00066 Serial pc(USBTX, USBRX);
00067 
00068 uint8_t x, y;
00069 char array[256];                    // Temp array for controller data
00070 
00071 /* void delay(unsigned int n) is used as a short delay to
00072    time the bit patterns. 1 n is roughly 0.042us on 96MHz CCLK
00073  */
00074 void delay(unsigned int n) {
00075     unsigned int i;
00076     for (i=0; i<n; i++)
00077         ;
00078 }
00079 
00080 /* int receive(char *data_array, unsigned char n) is used to
00081    receive a bit stream of bits into an array of n bytes coming
00082    from the controller. This must be called immediately after
00083    sending any kind of request to the controller
00084  */
00085 
00086 int receive(char *data_array, unsigned char n) {
00087     unsigned char sample, previous_sample;
00088     unsigned char bit, byte;
00089     int i;
00090 
00091     //inout.input();                // Not sure about this..
00092 
00093     sample = inout.read();
00094     for (i=0;i < n ;i++) {
00095         byte = 0;
00096         bit  = 0;
00097         while (bit<8) {
00098             previous_sample = sample;
00099             sample = inout.read();
00100             if ((previous_sample ^ sample) & previous_sample) {
00101 
00102                 delay(60);
00103                 sample=inout.read();
00104                 if (sample)
00105                     byte = byte  | (1<<bit);
00106                 bit++;
00107             }
00108 
00109             data_array[i]= byte;
00110         }
00111 
00112     }
00113     return n;
00114 }
00115 /* void send_byte(unsigned char byte) is used to send a single
00116    byte to the controller. 
00117  */
00118 void send_byte(unsigned char byte) {
00119     char i;
00120     //inout.output();           // Not sure about this.
00121     inout.write(1);             // Makes sure line is left high
00122   
00123     for (i=0; i<8; i++) {
00124         if (byte & 128>>i) {
00125             inout.write(0);
00126             delay(T1);
00127             inout.write(1);
00128             delay(T2);
00129         } else {
00130             inout.write(0);
00131             delay(T2);
00132             inout.write(1);
00133             delay(T1);
00134         }
00135     }
00136     /* Send Stop Bit */
00137     inout.write(0);
00138     delay(T1);
00139     inout.write(1);
00140     delay(T1);
00141 
00142 }
00143 
00144 int main() {
00145     inout.mode(OpenDrain);           // Must use open-drain for N64 Controller!
00146     
00147     int i;                           // Used for the bit-shifting for x and y values
00148     while (1) {
00149 
00150         send_byte(1); // Send the request byte
00151         receive(array, 4);           // Start receiving bit stream
00152 
00153         /* The for loop here is used to reverse the bits for the x and y values retured
00154            by the controller. I am not entirely sure of the format. I'm missing a bit
00155            somewhere.. Values don't range from -127..128. */
00156         x=y=0;
00157         for (i=0;i<=7;i++) {
00158             if (array[2] & (1 << i))
00159                 x=x | (1 << (7-i));
00160             if (array[3] & (1 << i))
00161                 y=y | (1 << (7-i));
00162         }
00163 
00164         pc.printf("%3d %3d %4d %3d \n ", array[0], array[1], (signed char)x, (signed char)y);
00165 
00166     }
00167 
00168 }