N64 to USB HID interface

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 #include "usbhid.h"
00051 
00052 
00053 USBJoystick joystick;
00054 
00055 
00056 /*
00057 N64 Controller Interface for the mbed.
00058 
00059 by Igor Martinovski
00060 March, 2011.
00061 
00062 Function Mapping (from www.mixdown.ca/n64dev/)
00063 
00064 Bit     Function
00065 0        A
00066 1        B
00067 2        Z
00068 3        Start
00069 4        Directional Up
00070 5        Directional Down
00071 6        Directional Left
00072 7        Directional Right
00073 
00074 8        unknown (always 0)
00075 9        unknown (always 0)
00076 10        L
00077 11        R
00078 12        C Up
00079 13        C Down
00080 14        C Left
00081 15        C Right
00082 
00083 16-23   X value (signed)
00084 
00085 23-32   Y value (signed)
00086 
00087 Pinout:
00088 Looking at the controller plug, flat side down.
00089 Pin 1 (Left)    Ground
00090 Pin 2 (Center)  Data**
00091 Pin 3 (Right)   +3.3V*
00092 
00093 (*)Note: The controller is supplied by 3.6V on the N64, but it seems to work fine on
00094 the 3.3V provided by the mbed.
00095 
00096 (**)Warning: The N64 controller must be connected to an open drain pin with a
00097 pull-up resistor. The line must never be driven high by the mbed! If you are not
00098 sure how to connect the controller safely, you may damage the mbed and/or
00099 controller. You have been warned.
00100 */
00101 
00102 #include "mbed.h"
00103 #include "stdint.h"
00104 
00105 // Controller Commands
00106 
00107 #define GET_STATUS          0x00
00108 #define REQUEST_CONTROLS    0x01
00109 #define READ_MEMPACK        0x02
00110 #define WRITE_MEMPACK       0x03
00111 #define READ_EEPROM         0x04
00112 #define WRITE_EEPROM        0x05
00113 #define RESET_CONTROLLER    0xff
00114 
00115 #define T1                  23      // Corresponds to 1 us        
00116 #define T2                  69      // Corresponds to 3 us
00117 
00118 DigitalInOut inout(p14);            // Connect controller here
00119 // using 220 ohm pull-up
00120 Serial pc(USBTX, USBRX);
00121 
00122 uint8_t x, y;
00123 union controls { /* A definition and a declaration */
00124     uint8_t array[8];
00125     uint32_t result[2];
00126 } controls;
00127 
00128 // Temp array for controller data
00129 
00130 /* void delay(unsigned int n) is used as a short delay to
00131    time the bit patterns. 1 n is roughly 0.042us on 96MHz CCLK
00132  */
00133 void delay(unsigned int n) {
00134     unsigned int i;
00135     for (i=0; i<n; i++)
00136         ;
00137 }
00138 
00139 /* int receive(char *data_array, unsigned char n) is used to
00140    receive a bit stream of bits into an array of n bytes coming
00141    from the controller. This must be called immediately after
00142    sending any kind of request to the controller
00143  */
00144 
00145 int receive(uint8_t *data_array, unsigned char n) {
00146     unsigned char sample, previous_sample;
00147     unsigned char bit, byte;
00148     int i;
00149 
00150 
00151     //inout.input();                // Not sure about this..
00152 
00153     sample = inout.read();
00154     for (i=0; i < n ; i++) {
00155         byte = 0;
00156         bit  = 0;
00157         while (bit<8) {
00158             previous_sample = sample;
00159             sample = inout.read();
00160             if ((previous_sample ^ sample) & previous_sample) {
00161 
00162                 delay(60);
00163                 sample=inout.read();
00164                 if (sample)
00165                     byte = byte  | (128>>bit);
00166                 bit++;
00167             }
00168 
00169             data_array[i]= byte;
00170         }
00171 
00172     }
00173 data_array[2] -= 128;
00174 data_array[3] -= 128;
00175 data_array[4] -= 128;
00176 data_array[5] -= 128;
00177     return n;
00178 }
00179 /* void send_byte(unsigned char byte) is used to send a single
00180    byte to the controller.
00181  */
00182 void send_byte(unsigned char byte) {
00183     char i;
00184     //inout.output();           // Not sure about this.
00185     inout.write(1);             // Makes sure line is left high
00186 
00187     wait_us(500);
00188     for (i=0; i<8; i++) {
00189         if (byte & 128>>i) {
00190             inout.write(0);
00191             delay(T1);
00192             inout.write(1);
00193             delay(T2);
00194         } else {
00195             inout.write(0);
00196             delay(T2);
00197             inout.write(1);
00198             delay(T1);
00199         }
00200     }
00201     /* Send Stop Bit */
00202     inout.write(0);
00203     delay(T1);
00204     inout.write(1);
00205     delay(T1);
00206 }
00207 
00208 /* void send_byte(unsigned char byte) is used to send a single
00209    byte to the controller.
00210  */
00211 void send(uint8_t * cmd, uint8_t n) {
00212     uint8_t i,j,byte;
00213 
00214     inout.write(1);             // Makes sure line is left high
00215     wait_us(500);
00216     for (j=0; j<n; j++) {
00217         byte=cmd[j];
00218         for (i=0; i<8; i++) {
00219             if (byte & 128>>i) {
00220                 inout.write(0);
00221                 delay(T1);
00222                 inout.write(1);
00223                 delay(T2);
00224             } else {
00225                 inout.write(0);
00226                 delay(T2);
00227                 inout.write(1);
00228                 delay(T1);
00229             }
00230         }
00231 
00232     }/* Send Stop Bit */
00233     inout.write(0);
00234     delay(T1);
00235     inout.write(1);
00236     delay(T1);
00237 
00238 }
00239 
00240 
00241 uint8_t cmd[8];
00242 
00243 
00244 int main() {
00245     inout.mode(OpenDrain);           // Must use open-drain for N64 Controller!
00246     uint8_t cmd[8];
00247     int8_t n;
00248     int temp;
00249     uint32_t i, previous_result=0;                           // Used for the bit-shifting for x and y values
00250     while (1) {
00251         wait_ms(10);
00252         n=3;
00253         cmd[0]=2; // Request Controls
00254         cmd[1]=3;
00255         cmd[0]=64;
00256         send(cmd,3);
00257         receive(controls.array, 8);           // Start receiving bit stream
00258         joystick.joystick(controls.array[0], controls.array[1], 
00259                           controls.array[2], controls.array[3],
00260                           controls.array[4], controls.array[5],
00261                           controls.array[6], controls.array[7]
00262                           );  
00263           
00264           
00265                   //pc.printf("%d\t%d\t", (uint8_t)controls.array[0],(uint8_t)controls.array[1]);
00266           //pc.printf("%d\t%d\t%d\t%d\t%d\t%d", (int8_t)(controls.array[2]),(int8_t)controls.array[3],(int8_t)controls.array[4],(int8_t)controls.array[5],controls.array[6],controls.array[7]);
00267         //pc.printf("\n");
00268 
00269         //pc.printf("%3d %3d %d %d\n ", controls.array[0], controls.array[1], (int8_t)controls.array[2], (int8_t)controls.array[3]);
00270 /*
00271         for (n=12; n<8; n++){
00272             if (controls.array[2] & (128 >> n))
00273             pc.printf("1");
00274             else 
00275             pc.printf("0");
00276             }
00277           pc.printf("%d\t%d\t", (uint8_t)controls.array[0],(uint8_t)controls.array[1]);
00278           pc.printf("%d\t%d\t%d\t%d\t%d\t%d", (int8_t)(controls.array[2]),(int8_t)controls.array[3],(int8_t)controls.array[4],(int8_t)controls.array[5],controls.array[6],controls.array[7]);
00279         pc.printf("\n");
00280 
00281         for (n=0; n<16; n++)
00282             pc.printf("%d", (1 & ((uint16_t)controls.result[0] >> n)));
00283         pc.printf(" ");
00284 
00285         for (n=17; n<32; n++)
00286             pc.printf("%d", (1 & ((uint32_t)controls.result[0] >> n)));
00287         pc.printf(" ");
00288         
00289         for (n=0; n<16; n++)
00290             pc.printf("%d", (1 & ((uint16_t)controls.result[1] >> n)));
00291         pc.printf(" ");
00292         
00293         for (n=17; n<32; n++)
00294         pc.printf("%d", (1 & ((uint32_t)controls.result[1] >> n)));
00295         pc.printf("\n");
00296 */
00297     }
00298 
00299     while (1) {
00300         wait_ms(10);
00301         //previous_result=controls.result_32;
00302         send_byte(1);                // Send the request byte
00303         receive(controls.array, 8);           // Start receiving bit stream
00304 
00305         // if (controls.result_32==previous_result) continue;
00306 
00307 
00308         //pc.printf("%3d %3d %d %d\n ", controls.array[0], controls.array[1], (int8_t)controls.array[2], (int8_t)controls.array[3]);
00309         //pc.printf("%d\n",controls.result_32);
00310         //joystick.joystick(controls.array[0],controls.array[1], controls.array[2], controls.array[3]);
00311     }
00312 
00313 }