N64 to USB HID interface

Dependencies:   mbed

Revision:
0:547c5459faa6
Child:
1:38815edb0ecb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Sun Sep 25 03:44:08 2011 +0000
@@ -0,0 +1,237 @@
+
+/*
+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"
+#include "usbhid.h"
+
+
+USBJoystick joystick;
+
+
+/*
+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;
+union controls { /* A definition and a declaration */
+    uint8_t array[4];
+    uint32_t result_32;
+} controls;
+
+// 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(uint8_t *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;
+        }
+
+    }
+     /* 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 (controls.array[2] & (1 << i))
+                x=x | (1 << (7-i));
+            if (controls.array[3] & (1 << i))
+                y=y | (1 << (7-i));
+        }
+        data_array[2]=x;
+        data_array[3]=y;
+    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
+
+    wait_us(500);
+    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!
+
+    uint32_t i, previous_result=0;                           // Used for the bit-shifting for x and y values
+    send_byte(RESET_CONTROLLER);
+              wait_ms(10);
+    while (1) {
+        wait_ms(10);
+        previous_result=controls.result_32;
+        send_byte(1);                // Send the request byte
+        receive(controls.array, 4);           // Start receiving bit stream
+        
+        if (controls.result_32==previous_result) continue;
+        
+        
+        pc.printf("%3d %3d %d %d\n ", controls.array[0], controls.array[1], (int8_t)controls.array[2], (int8_t)controls.array[3]);
+        //pc.printf("%d\n",controls.result_32);
+//joystick.joystick(controls.array[0],controls.array[1], controls.array[2], controls.array[3]);
+    }
+
+}
\ No newline at end of file