Igor Martinovski
/
USBJoystick
N64 to USB HID interface
Diff: main.cpp
- 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