N64 to USB HID interface
main.cpp
- Committer:
- igor_m
- Date:
- 2014-12-10
- Revision:
- 5:eb93a4f91396
- Parent:
- 4:fee2d61ad6bc
File content as of revision 5:eb93a4f91396:
/*
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 23 // Corresponds to 1 us
#define T2 69 // 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[8];
uint32_t result[2];
} 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 | (128>>bit);
bit++;
}
data_array[i]= byte;
}
}
data_array[2] -= 128;
data_array[3] -= 128;
data_array[4] -= 128;
data_array[5] -= 128;
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);
}
/* void send_byte(unsigned char byte) is used to send a single
byte to the controller.
*/
void send(uint8_t * cmd, uint8_t n) {
uint8_t i,j,byte;
inout.write(1); // Makes sure line is left high
wait_us(500);
for (j=0; j<n; j++) {
byte=cmd[j];
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);
}
uint8_t cmd[8];
int main() {
inout.mode(OpenDrain); // Must use open-drain for N64 Controller!
uint8_t cmd[8];
int8_t n;
int temp;
uint32_t i, previous_result=0; // Used for the bit-shifting for x and y values
while (1) {
wait_ms(10);
n=3;
cmd[0]=2; // Request Controls
cmd[1]=3;
cmd[0]=64;
send(cmd,3);
receive(controls.array, 8); // Start receiving bit stream
joystick.joystick(controls.array[0], controls.array[1],
controls.array[2], controls.array[3],
controls.array[4], controls.array[5],
controls.array[6], controls.array[7]
);
//pc.printf("%d\t%d\t", (uint8_t)controls.array[0],(uint8_t)controls.array[1]);
//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]);
//pc.printf("\n");
//pc.printf("%3d %3d %d %d\n ", controls.array[0], controls.array[1], (int8_t)controls.array[2], (int8_t)controls.array[3]);
/*
for (n=12; n<8; n++){
if (controls.array[2] & (128 >> n))
pc.printf("1");
else
pc.printf("0");
}
pc.printf("%d\t%d\t", (uint8_t)controls.array[0],(uint8_t)controls.array[1]);
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]);
pc.printf("\n");
for (n=0; n<16; n++)
pc.printf("%d", (1 & ((uint16_t)controls.result[0] >> n)));
pc.printf(" ");
for (n=17; n<32; n++)
pc.printf("%d", (1 & ((uint32_t)controls.result[0] >> n)));
pc.printf(" ");
for (n=0; n<16; n++)
pc.printf("%d", (1 & ((uint16_t)controls.result[1] >> n)));
pc.printf(" ");
for (n=17; n<32; n++)
pc.printf("%d", (1 & ((uint32_t)controls.result[1] >> n)));
pc.printf("\n");
*/
}
while (1) {
wait_ms(10);
//previous_result=controls.result_32;
send_byte(1); // Send the request byte
receive(controls.array, 8); // 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]);
}
}