API for interfacing with a game cube controller

Dependencies:   mbed

Gamecube Controller Interface

This is a library to interface the Gamecube Controller to the mbed. The goal of this project is to read input data from the controller.

Introduction

This library lets you read data from a Gamecube Controller. It allows you to use two pins to get 6+ buttons, a D-pad (up/down/left/right), two variable triggers, and two joysticks. The controller was stripped of its connector and this wiki shows the subsequent steps to wire the controller to the mbed and code needed to read data through a serial connection. Assembly was used because the timing for the controller needs to have microsecond accuracy. The shortest wait found using wait_us(...) was 1.5us.

Pinout

ColorFunction
Yellow5V power supply (rumble)
RedData: bi-directional / 3.3V
GreenGround
WhiteGround
Blue3.3V power supply

*Note this pinout is for the latest Gamecube controller /media/uploads/christopherjwang/6.jpg

Wiring

The Gamecube controller was cut to expose the wires. Seperate them and solder other wires on to them for stability and consistency.

/media/uploads/christopherjwang/2.jpg

Color (Gamecube)mbed Pin
YellowVOUT
Redp9 and p10
GreenGround
WhiteGround
BlueVU

/media/uploads/christopherjwang/bro.png

Gamecube Controller Protocol

The Gamecube controller uses 3.3V logic (bidirectional), 3.3V to power the controller, and 5V for the rumble motor.

The 5V power used by the rumble motor is always on, and the motor is controlled by a command sent to the controller.

The controller uses one bi-directional data line to communicate with the console. This is an active high 3.3V logic signal, using a 10K pull-up resistor to 3.3V to hold the line high. Communication is initiated by the console sending a 24-bit string to the controller, after which the controller responds with 64-bits of button state and joystick data.

The transfer speed is fast at around 4 microseconds per bit. .A low bit is signaled by a 3us low followed by 1us high, and a high bit is signaled by 1us low followed by 3us high.

Here is a 0 followed by a 1

/media/uploads/christopherjwang/bro2.png

The last bit of the command is the 'rumble' control. Setting this bit to one enables the rumble motor, and clearing it disables the motor.

Polling for Data

When the Gamecube or the controller sends a string of bits, it terminates it with a single (high) stop bit. Therefore, in order to send the string 00000000, the Gamecube would send 000000001.

There is a typical interval of about 6ms between successive updates. The real time update time would depend on the game being played or the video frame update rate. The sequence starts with a 24-bit command from the console:

0100 0000 0000 0011 0000 000 (0*) *rumble

After the 24-bit command, the controller responds with a string of bits that contain the state of all the buttons along with joystick position data. The sequence of the returned data is shown in the table below. The buttons are listed in transmission order, from left to right.

Byte 0000StartYXBA
Byte 11LRZD-UpD-DownD-RightD-Left
Byte 2Joystick X Value (8 bit)
Byte 3Joystick Y Value (8 bit)
Byte 4C-Stick X Value (8 bit)
Byte 5C-Stick Y Value (8 bit)
Byte 6Left Button Value (8 bit)
Byte 7Right Button Value (8 bit)

Example Code

Basic program to use with library

//
#include "mbed.h"
#include "Gamecube.h"
 
Serial pc1(USBTX, USBRX); // tx, rx
DigitalOut myled(LED1);
int main() {
    Gamecube g(p9); // gamecube controller connected to pin 9
    int device_id = g.get_device_id();
    if (device_id != NINTENDO_DEVICE_GC_WIRED) { // device id for controller is 0x0900
        pc1.printf("this device is not a nintendo gamecube wired controller!, it returned an ID of %d\n", device_id);    
    }
    while(1) {
        g.update();
        pc1.printf("A: %d \n\rB: %d \n\rX: %d \n\rY: %d \n\rL: %d \n\rR: %d \n\rZ: %d \n\rSTART: %d \n\rD_UP: %d \n\rD_LEFT: %d \n\rD_DOWN: %d \n\rD_RIGHT: %d \n\rJOYSTICK_X: %d \n\rJOYSTICK_Y: %d \n\rC_STICK_X: %d \n\rC_STICK_Y: %d \n\rLEFT_TRIGGER: %d \n\rRIGHT_TRIGGER: %d \n\r", g.A, g.B, g.X, g.Y, g.L, g.R, g.Z, g.START, g.D_UP, g.D_LEFT, g.D_DOWN, g.D_RIGHT, g.JOYSTICK_X, g.JOYSTICK_Y, g.C_STICK_X, g.C_STICK_Y, g.LEFT_TRIGGER, g.RIGHT_TRIGGER);
        wait(1);
        
        g.rumble(true); // rumble working
        myled = 1;
        wait(1);
        myled = 0;
        g.rumble(false);
        wait(.2);
    }
}

Functions

Functions

    // constructor
    Gamecube(PinName _data_line); 

    // gets the device id
    int get_device_id();

    // call this to update public variables in header file
    void update(void);

Library

Import programgamecube_controller

API for interfacing with a game cube controller

Demo

Files at this revision

API Documentation at this revision

Comitter:
christopherjwang
Date:
Sun Dec 06 19:16:05 2015 +0000
Parent:
0:7434770d9fc9
Commit message:
MVP, hard coded at p9 and p10

Changed in this revision

Nintendo.cpp Show diff for this revision Revisions of this file
Nintendo.h Show diff for this revision Revisions of this file
diff -r 7434770d9fc9 -r a93f71ee6778 Nintendo.cpp
--- a/Nintendo.cpp	Sun Dec 06 19:15:28 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,504 +0,0 @@
-///*
-//Copyright (c) 2014-2015 NicoHood
-//See the readme for credit to other people.
-//
-//Permission is hereby granted, free of charge, to any person obtaining a copy
-//of this software and associated documentation files (the "Software"), to deal
-//in the Software without restriction, including without limitation the rights
-//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//copies of the Software, and to permit persons to whom the Software is
-//furnished to do so, subject to the following conditions:
-//
-//The above copyright notice and this permission notice shall be included in
-//all copies or substantial portions of the Software.
-//
-//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-//THE SOFTWARE.
-//*/
-//
-//#include "Nintendo.h"
-//
-////================================================================================
-//// Gamecube
-////================================================================================
-//
-//// it has this fucking global variable...
-////Gamecube_ Gamecube;
-////
-////Gamecube_::Gamecube_(void) {
-////    
-////}
-//
-//Gamecube_::Gamecube_(PinName _data_line)
-//    :data_line(_data_line)
-//{
-//    
-//}
-//
-//bool Gamecube_::begin(const uint8_t pin)
-//{
-//    // discard the information
-//    Gamecube_Status_t status;
-//    return begin(pin, status);
-//}
-//
-//bool Gamecube_::begin(const uint8_t pin, Gamecube_Status_t &status) {
-////    // get the port mask and the pointers to the in/out/mode registers
-////    uint8_t bitMask = digitalPinToBitMask(pin);
-////    uint8_t port = digitalPinToPort(pin);
-////    volatile uint8_t* modePort = portModeRegister(port);
-////    volatile uint8_t* outPort = portOutputRegister(port);
-////    volatile uint8_t* inPort = portInputRegister(port);
-////
-////    // Initialize the gamecube controller by sending it a null byte.
-////    // This is unnecessary for a standard controller, but is required for the
-////    // Wavebird.
-////    uint8_t command[] = { 0x00 };
-////
-////    // don't want interrupts getting in the way
-////    uint8_t oldSREG = SREG;
-////    cli();
-////
-////    // send the command
-////    gc_send(command, sizeof(command), modePort, outPort, bitMask);
-////
-////    // read in data
-////    uint8_t receivedBytes = gc_get((uint8_t*)&status, sizeof(status), modePort, outPort, inPort, bitMask);
-////
-////    // end of time sensitive code
-////    SREG = oldSREG;
-////
-////    // return status information for optional use
-////    bool newinput;
-////    if (receivedBytes == sizeof(status)){
-////        // switch the first two bytes to compare it easy with the documentation
-////        uint8_t temp = status.whole8[0];
-////        status.whole8[0] = status.whole8[1];
-////        status.whole8[1] = temp;
-////
-////        newinput = true;
-////    }
-////    else
-////        newinput = false;
-////    return newinput;
-//}
-////
-////
-////bool Gamecube_::end(const uint8_t pin){
-////    // Turns off rumble by sending a normal reading request
-////    // and discards the information
-////    Gamecube_Data_t report;
-////    return read(pin, report, false);
-////}
-////
-////
-////bool Gamecube_::read(const uint8_t pin, Gamecube_Data_t &report, const bool rumble)
-////{
-////    // get the port mask and the pointers to the in/out/mode registers
-////    uint8_t bitMask = digitalPinToBitMask(pin);
-////    uint8_t port = digitalPinToPort(pin);
-////    volatile uint8_t* modePort = portModeRegister(port);
-////    volatile uint8_t* outPort = portOutputRegister(port);
-////    volatile uint8_t* inPort = portInputRegister(port);
-////
-////    // command to send to the gamecube, LSB is rumble
-////    uint8_t command[] = { 0x40, 0x03, rumble & 0x01 };
-////
-////    // don't want interrupts getting in the way
-////    uint8_t oldSREG = SREG;
-////    cli();
-////
-////    // send the command
-////    gc_send(command, sizeof(command), modePort, outPort, bitMask);
-////
-////    // read in new data
-////    uint8_t receivedBytes = gc_get((uint8_t*)&report, sizeof(report), modePort, outPort, inPort, bitMask);
-////
-////    // end of time sensitive code
-////    SREG = oldSREG;
-////
-////    // return status information for optional use
-////    bool newinput;
-////    if (receivedBytes == sizeof(report))
-////        newinput = true;
-////    else
-////        newinput = false;
-////    return newinput;
-////}
-////
-////
-//////================================================================================
-////// Gamecube/N64 i/o functions
-//////================================================================================
-////
-////// nop definitions, placed here so the header/user
-////// doesnt see/use this because it is %[nop] specific
-/////*
-////Serial.begin(115200);
-////for (int n = 0; n < 100; n++) {
-////Serial.print("#define nopn");
-////Serial.print(n);
-////Serial.print(" nopn");
-////Serial.println(n % 3);
-////}
-////*/
-////
-////#define nopManual(n) nopn ## n
-////#define nopn0 // (0 % 3)
-////#define nopn1 "nop\n" // (1 % 3)
-////#define nopn2 "nop\nnop\n" // (2 % 3)
-////#define nopn3 nopn0 // (3 % 3)
-////#define nopn4 nopn1 //..
-////#define nopn5 nopn2
-////#define nopn6 nopn0
-////#define nopn7 nopn1
-////#define nopn8 nopn2
-////#define nopn9 nopn0
-////#define nopn10 nopn1
-////#define nopn11 nopn2
-////#define nopn12 nopn0
-////#define nopn13 nopn1
-////#define nopn14 nopn2
-////#define nopn15 nopn0
-////#define nopn16 nopn1
-////#define nopn17 nopn2
-////#define nopn18 nopn0
-////#define nopn19 nopn1
-////#define nopn20 nopn2
-////#define nopn21 nopn0
-////#define nopn22 nopn1
-////#define nopn23 nopn2
-////#define nopn24 nopn0
-////#define nopn25 nopn1
-////#define nopn26 nopn2
-////#define nopn27 nopn0
-////#define nopn28 nopn1
-////#define nopn29 nopn2
-////#define nopn30 nopn0
-////#define nopn31 nopn1
-////#define nopn32 nopn2
-////#define nopn33 nopn0
-////#define nopn34 nopn1
-////#define nopn35 nopn2
-////#define nopn36 nopn0
-////#define nopn37 nopn1
-////#define nopn38 nopn2
-////#define nopn39 nopn0
-////#define nopn40 nopn1
-////#define nopn41 nopn2
-////#define nopn42 nopn0
-////#define nopn43 nopn1
-////#define nopn44 nopn2
-////#define nopn45 nopn0
-////#define nopn46 nopn1
-////#define nopn47 nopn2
-////#define nopn48 nopn0
-////#define nopn49 nopn1
-////#define nopn50 nopn2
-////#define nopn51 nopn0
-////#define nopn52 nopn1
-////#define nopn53 nopn2
-////#define nopn54 nopn0
-////#define nopn55 nopn1
-////#define nopn56 nopn2
-////#define nopn57 nopn0
-////#define nopn58 nopn1
-////#define nopn59 nopn2
-////#define nopn60 nopn0
-////#define nopn61 nopn1
-////#define nopn62 nopn2
-////#define nopn63 nopn0
-////#define nopn64 nopn1
-////#define nopn65 nopn2
-////#define nopn66 nopn0
-////#define nopn67 nopn1
-////#define nopn68 nopn2
-////#define nopn69 nopn0
-////#define nopn70 nopn1
-////#define nopn71 nopn2
-////#define nopn72 nopn0
-////#define nopn73 nopn1
-////#define nopn74 nopn2
-////#define nopn75 nopn0
-////#define nopn76 nopn1
-////#define nopn77 nopn2
-////#define nopn78 nopn0
-////#define nopn79 nopn1
-////#define nopn80 nopn2
-////#define nopn81 nopn0
-////#define nopn82 nopn1
-////#define nopn83 nopn2
-////#define nopn84 nopn0
-////#define nopn85 nopn1
-////#define nopn86 nopn2
-////#define nopn87 nopn0
-////#define nopn88 nopn1
-////#define nopn89 nopn2
-////#define nopn90 nopn0
-////#define nopn91 nopn1
-////#define nopn92 nopn2
-////#define nopn93 nopn0
-////#define nopn94 nopn1
-////#define nopn95 nopn2
-////#define nopn96 nopn0
-////#define nopn97 nopn1
-////#define nopn98 nopn2
-////#define nopn99 nopn0
-////
-////#define nop_reg "%[nop]" // in this sketch we named the register like this
-////#define nop_block(id, N) /* nops have to be >=3 in order to work*/ \
-////"ldi " nop_reg ", (" #N "/3)\n" /* (1) ldi, start */ \
-////".L%=_nop_loop" #id ":\n" /* + ((N-1) * (1) dec + (2) brne), (N-1) loops */ \
-////"dec " nop_reg "\n" /* + (1) dec + (1) brne, last loop */ \
-////"brne .L%=_nop_loop" #id "\n" /* --> (N * 3) nops */ \
-////nopManual(N) /* N % 3 manual nops */
-//
-//void Gamecube_::gc_send(uint8_t* buff, uint8_t len) {
-//    __disable_irq();
-//    uint8_t i;
-//    data_line.output();
-//    for (i=0; i < len; i++) {
-//        data_line.write(buff[i]);
-//        wait_us(1);
-//    }
-//    __enable_irq();
-//}
-/////**
-//// * This sends the given byte sequence to the controller
-//// * length must be at least 1
-//// */
-////void gc_send(uint8_t* buff, uint8_t len,
-////    volatile uint8_t* modePort, volatile uint8_t* outPort, uint8_t bitMask)
-////{
-////    // set pin to output, default high
-////    *outPort |= bitMask;
-////    *modePort |= bitMask;
-////
-////    // temporary register values used as "clobbers"
-////    register uint8_t bitCount;
-////    register uint8_t data;
-////    register uint8_t nop;
-////
-////    asm volatile (
-////        "; Start of gc_send assembly\n"
-////
-////        // passed in to this block are:
-////        // the %a[buff] register is the buffer pointer
-////        // %[len] is the register holding the length of the buffer in bytes
-////
-////        // Instruction cycles are noted in parentheses
-////        // branch instructions have two values, one if the branch isn't
-////        // taken and one if it is
-////
-////        // %[data] will be the current buffer byte loaded from memory
-////        // %[bitCount] will be the bit counter for the current byte. when this
-////        // reaches 0, we need to decrement the length counter, load
-////        // the next buffer byte, and loop. (if the length counter becomes
-////        // 0, that's our exit condition)
-////
-////        // This label starts the outer loop, which sends a single byte
-////        ".L%=_byte_loop:\n"
-////        "ld %[data], %a[buff]+\n" // (2) load the next byte and increment byte pointer
-////        "ldi %[bitCount],0x08\n" // (1) set bitcount to 8 bits
-////
-////        // This label starts the inner loop, which sends a single bit
-////        ".L%=_bit_loop:\n"
-////        "st %a[outPort],%[low]\n" // (2) pull the line low
-////
-////        // line needs to stay low for 1�s for a 1 bit, 3�s for a 0 bit
-////        // this block figures out if the next bit is a 0 or a 1
-////        // the strategy here is to shift the register left, then test and
-////        // branch on the carry flag
-////        "lsl %[data]\n" // (1) shift left. MSB goes into carry bit of status reg
-////        "brcc .L%=_zero_bit\n" // (1/2) branch if carry is cleared
-////
-////
-////        // this block is the timing for a 1 bit (1�s low, 3�s high)
-////        // Stay low for 2uS: 16 - 2 (above lsl,brcc) - 2 (below st) = 12 cycles
-////        nop_block(1, 12) // nop block 1, 12 cycles
-////
-////        "st %a[outPort],%[high]\n" // (2) set the line high again
-////        // Now stay high for 2�s of the 3�s to sync up with the branch below
-////        // 2*16 - 2 (for the rjmp) = 30 cycles
-////        nop_block(2, 30) // nop block 2, 30 cycles
-////        "rjmp .L%=_finish_bit\n" // (2)
-////
-////
-////        // this block is the timing for a 0 bit (3�s low, 1�s high)
-////        // Need to go high in 3*16 - 3 (above lsl,brcc) - 2 (below st) = 43 cycles
-////        ".L%=_zero_bit:\n"
-////        nop_block(3, 43) // nop block 3, 43 cycles
-////        "st %a[outPort],%[high]\n" // (2) set the line high again
-////
-////
-////        // The two branches meet up here.
-////        // We are now *exactly* 3�s into the sending of a bit, and the line
-////        // is high again. We have 1�s to do the looping and iteration
-////        // logic.
-////        ".L%=_finish_bit:\n"
-////        "dec %[bitCount]\n" // (1) subtract 1 from our bit counter
-////        "breq .L%=_load_next_byte\n" // (1/2) branch if we've sent all the bits of this byte
-////
-////        // At this point, we have more bits to send in this byte, but the
-////        // line must remain high for another 1�s (minus the above
-////        // instructions and the jump below and the st instruction at the
-////        // top of the loop)
-////        // 16 - 2(above) - 2 (rjmp below) - 2 (st after jump) = 10
-////        nop_block(4, 10) // nop block 4, 10 cycles
-////        "rjmp .L%=_bit_loop\n" // (2)
-////
-////
-////        // This block starts 3 cycles into the last 1�s of the line being high
-////        // We need to decrement the byte counter. If it's 0, that's our exit condition.
-////        // If not we need to load the next byte and go to the top of the byte loop
-////        ".L%=_load_next_byte:\n"
-////        "dec %[len]\n" // (1) len--
-////        "breq .L%=_loop_exit\n" // (1/2) if the byte counter is 0, exit
-////        // delay block:
-////        // needs to go high after 1�s or 16 cycles
-////        // 16 - 5 (above) - 2 (the jump itself) - 5 (after jump) = 4
-////        nop_block(5, 4) // nop block 5, 4 cycles
-////        "rjmp .L%=_byte_loop\n" // (2)
-////
-////
-////        // Loop exit
-////        ".L%=_loop_exit:\n"
-////
-////        // final task: send the stop bit, which is a 1 (1�s low 3�s high)
-////        // the line goes low in:
-////        // 16 - 6 (above since line went high) - 2 (st instruction below) = 8 cycles
-////        nop_block(6, 8) // nop block 6, 8 cycles
-////        "st %a[outPort],%[low]\n" // (2) pull the line low
-////        // stay low for 1�s
-////        // 16 - 2 (below st) = 14
-////        nop_block(7, 14) // nop block 7, 14 cycles
-////        "st %a[outPort],%[high]\n" // (2) set the line high again
-////        // just stay high. no need to wait 3�s before returning
-////
-////        // ----------
-////        // outputs:
-////        : [buff] "+e" (buff), // (read and write)
-////        [outPort] "+e" (outPort), // (read and write)
-////        [bitCount] "=&d" (bitCount), // (output only, ldi needs the upper registers)
-////        [data] "=&r" (data), // (output only)
-////        [nop] "=&d" (nop) // (output only, ldi needs the upper registers)
-////
-////        // inputs:
-////        : [len] "r" (len),
-////        [high] "r" (*outPort | bitMask), // precalculate new pin states
-////        [low] "r" (*outPort & ~bitMask) // this works because we turn interrupts off
-////
-////        // no clobbers
-////        ); // end of asm volatile
-////}
-////
-////
-/////**
-////* Read bytes from the gamecube controller
-////* listen for the expected bytes of data back from the controller and
-////* and pack it into the buff
-////*/
-////uint8_t gc_get(uint8_t* buff, uint8_t len,
-////    volatile uint8_t* modePort, volatile uint8_t* outPort, volatile uint8_t * inPort, uint8_t bitMask)
-////{
-////    // prepare pin for input with pullup
-////    *modePort &= ~bitMask;
-////    *outPort |= bitMask;
-////
-////    // temporary register values used as "clobbers"
-////    register uint8_t timeoutCount; // counts down the timeout
-////    register uint8_t bitCount; // counts down 8 bits for each byte
-////    register uint8_t inputVal; // temporary variable to save the pin states
-////    register uint8_t data; // keeps the temporary received data byte
-////    register uint8_t receivedBytes; // the return value of the function
-////
-////    asm volatile (
-////        "; Start of gc_get assembly\n"
-////
-////        // [bitCount] is our bit counter. We read %[len] bytes
-////        // and increment the byte pointer and receivedBytes every 8 bits
-////        "ldi %[bitCount],0x08\n" // (1) set bitcount to 8 bits
-////        "ldi %[receivedBytes],0x00\n" // (1) default exit value is 0 bytes received
-////
-////        // This first spinloop waits for the line to go low.
-////        // It loops 64 times before it gives up and returns
-////        ".L%=_wait_for_low:\n"
-////        "ldi %[timeoutCount],%[timeout]\n" // (1) set the timeout
-////        ".L%=_wait_for_low_loop:\n" // 7 cycles if loop fails
-////        "ld %[inputVal], %a[inPort]\n" // (2) read the pin (happens before the 2 cycles)
-////        "and %[inputVal], %[bitMask]\n" // (1) compare pinstate with bitmask
-////        "breq .L%=_wait_for_measure\n" // (1/2) jump to the measure part if pin is low
-////        // the following happens if the line is still high
-////        "dec %[timeoutCount]\n" // (1) decrease timeout by 1
-////        "brne .L%=_wait_for_low_loop\n" // (1/2) loop if the counter isn't 0
-////        "rjmp .L%=_exit\n" // (2) timeout, jump to the end
-////
-////
-////        // Next block. The line has just gone low. Wait approx 2�s
-////        // each cycle is 1/16 �s on a 16Mhz processor
-////        // best case: 32 - 5 (above) - 1 (below) = 26 nops
-////        // worst case: 32 - 5 (above) - 6 (above, worst case) - 1 (below) = 20 nops
-////        // --> 23 nops
-////        ".L%=_wait_for_measure:\n"
-////        // nop block, 23 cycles, use inputVal as temporary reg since we dont need it right now
-////        "ldi %[inputVal], (23/3)\n" /* (1) ldi, start */
-////        ".L%=_nop_loop1:\n" /* + ((N-1) * (1) dec + (2) brne), (N-1) loops */
-////        "dec %[inputVal]\n" /* + (1) dec + (1) brne, last loop */
-////        "brne .L%=_nop_loop1\n" /* --> (N * 3) nops */
-////        nopManual(2) /* 23 % 3 manual nops */
-////        // save the data
-////        "lsl %[data]\n" // (1) left shift the current byte in %[data]
-////        "ld %[inputVal], %a[inPort]\n" // (2) read the pin (happens before the 2 cycles)
-////        "and %[inputVal], %[bitMask]\n" // (1) compare pinstate with bitmask
-////        "breq .L%=_check_bit_count\n" // (1/2) skip setting data to 1 if pin is low
-////        "sbr %[data],0x01\n" // set bit 1 in %[data] if pin is high
-////        ".L%=_check_bit_count:\n"
-////        "dec %[bitCount]\n" // (1) decrement 1 from our bit counter
-////        "brne .L%=_wait_for_high\n" // (1/2) branch if we've not received the whole byte
-////
-////        // we received a full byte
-////        "st %a[buff]+,%[data]\n" // (2) save %[data] back to memory and increment byte pointer
-////        "inc %[receivedBytes]\n" // (1) increase byte count
-////        "ldi %[bitCount],0x08\n" // (1) set bitcount to 8 bits again
-////        "cp %[len],%[receivedBytes]\n" // (1) %[len] == %[receivedBytes] ?
-////        "breq .L%=_exit\n" // (1/2) jump to exit if we received all bytes
-////        // dont wait for line to go high again
-////
-////
-////        // This next block waits for the line to go high again.
-////        // again, it sets a timeout counter of 64 iterations
-////        ".L%=_wait_for_high:\n"
-////        "ldi %[timeoutCount],%[timeout]\n" // (1) set the timeout
-////        ".L%=_wait_for_high_loop:\n" // 7 cycles if loop fails
-////        "ld %[inputVal], %a[inPort]\n" // (2) read the pin (happens before the 2 cycles)
-////        "and %[inputVal], %[bitMask]\n" // (1) compare pinstate with bitmask
-////        "brne .L%=_wait_for_low\n" // (1/2) line is high. ready for next loop
-////        // the following happens if the line is still low
-////        "dec %[timeoutCount]\n" // (1) decrease timeout by 1
-////        "brne .L%=_wait_for_high_loop\n" // (1/2) loop if the counter isn't 0
-////        // timeout, exit now
-////        ".L%=_exit:\n"
-////
-////        // ----------
-////        // outputs:
-////        : [receivedBytes] "=&d" (receivedBytes), // (ldi needs the upper registers)
-////        [buff] "+e" (buff), // (read and write)
-////        [bitCount] "=&d" (bitCount), // (output only, ldi needs the upper registers)
-////        [timeoutCount] "=&r" (timeoutCount), // (output only)
-////        [inputVal] "=&r" (inputVal), // (output only)
-////        [data] "=&r" (data) // (output only)
-////
-////        // inputs
-////        : [len] "r" (len),
-////        [inPort] "e" (inPort),
-////        [bitMask] "r" (bitMask),
-////        [timeout] "M" (NINTENDO_GAMECUBE_N64_TIMEOUT) // constant
-////        ); // end of asm volatile
-////
-////    return receivedBytes;
-////}
\ No newline at end of file
diff -r 7434770d9fc9 -r a93f71ee6778 Nintendo.h
--- a/Nintendo.h	Sun Dec 06 19:15:28 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,160 +0,0 @@
-///*
-//Copyright (c) 2014-2015 NicoHood
-//See the readme for credit to other people.
-//
-//Permission is hereby granted, free of charge, to any person obtaining a copy
-//of this software and associated documentation files (the "Software"), to deal
-//in the Software without restriction, including without limitation the rights
-//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-//copies of the Software, and to permit persons to whom the Software is
-//furnished to do so, subject to the following conditions:
-//
-//The above copyright notice and this permission notice shall be included in
-//all copies or substantial portions of the Software.
-//
-//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-//THE SOFTWARE.
-//*/
-//
-//#ifndef NINTENDO_H
-//#define NINTENDO_H
-//
-//#include <stdint.h>
-//#include <mbed.h>
-////#include <Arduino.h>
-//
-////================================================================================
-//// Settings
-////================================================================================
-//
-//// timeout for the reading function for the pin to go low/high
-//#define NINTENDO_GAMECUBE_N64_TIMEOUT NINTENDO_GAMECUBE_N64_TIMEOUT_US(28)
-//
-////================================================================================
-//// Definitions
-////================================================================================
-//
-////#if (F_CPU != 16000000)
-////#error This library only supports 16MHz AVRs
-////#endif
-//
-//// timeout for the reading function for the pin to go low/high
-//#define NINTENDO_GAMECUBE_N64_TIMEOUT_US(uS) (uS * F_CPU / (1000000 * 7))
-//
-////================================================================================
-//// Gamecube
-////================================================================================
-//
-//// gamecube controller device status ids
-//#define NINTENDO_DEVICE_GC_WIRED 0x0900
-//
-//// dpad directions
-//#define NINTENDO_GAMECUBE_DPAD_CENTERED 0
-//#define NINTENDO_GAMECUBE_DPAD_UP (1 << 3)
-//#define NINTENDO_GAMECUBE_DPAD_UP_RIGHT (NINTENDO_GAMECUBE_DPAD_UP | NINTENDO_GAMECUBE_DPAD_RIGHT)
-//#define NINTENDO_GAMECUBE_DPAD_RIGHT (1 << 1)
-//#define NINTENDO_GAMECUBE_DPAD_DOWN_RIGHT (NINTENDO_GAMECUBE_DPAD_DOWN | NINTENDO_GAMECUBE_DPAD_RIGHT)
-//#define NINTENDO_GAMECUBE_DPAD_DOWN (1 << 2)
-//#define NINTENDO_GAMECUBE_DPAD_DOWN_LEFT (NINTENDO_GAMECUBE_DPAD_DOWN | NINTENDO_GAMECUBE_DPAD_LEFT)
-//#define NINTENDO_GAMECUBE_DPAD_LEFT (1 << 0)
-//#define NINTENDO_GAMECUBE_DPAD_UP_LEFT (NINTENDO_GAMECUBE_DPAD_UP | NINTENDO_GAMECUBE_DPAD_LEFT)
-//
-//typedef union{
-//    // 8 bytes of datareport that we get from the controller
-//    uint8_t whole8[];
-//    uint16_t whole16[];
-//    uint32_t whole32[];
-//
-//    struct{
-//        uint8_t buttons0;
-//        union{
-//            uint8_t buttons1;
-//            uint8_t dpad : 4;
-//        };
-//    };
-//
-//    struct {
-//        // first data byte (bitfields are sorted in LSB order)
-//        uint8_t a : 1;
-//        uint8_t b : 1;
-//        uint8_t x : 1;
-//        uint8_t y : 1;
-//        uint8_t start : 1;
-//        uint8_t high0 : 1;
-//        uint8_t errlatch : 1;
-//        uint8_t errstat : 1;
-//
-//        // second data byte
-//        uint8_t dleft : 1;
-//        uint8_t dright : 1;
-//        uint8_t ddown : 1;
-//        uint8_t dup : 1;
-//        uint8_t z : 1;
-//        uint8_t r : 1;
-//        uint8_t l : 1;
-//        uint8_t high1 : 1;
-//
-//        // 3rd-8th data byte
-//        uint8_t xAxis;
-//        uint8_t yAxis;
-//        uint8_t cxAxis;
-//        uint8_t cyAxis;
-//        uint8_t left;
-//        uint8_t right;
-//    };
-//} Gamecube_Data_t;
-//
-//typedef union{
-//    // 3 bytes of statusreport that we get from the controller
-//    uint8_t whole8[];
-//    uint16_t whole16[];
-//    struct {
-//        // device information
-//        uint16_t device;
-//
-//        // controller status (only rumble is known)
-//        uint8_t status0 : 3;
-//        uint8_t rumble : 1;
-//        uint8_t status1 : 4;
-//    };
-//} Gamecube_Status_t;
-//
-//class Gamecube_{
-//public:
-//    Gamecube_(void);
-//    Gamecube_(PinName _data_line);
-//
-//    bool begin(const uint8_t pin, Gamecube_Status_t &status);
-//    bool begin(const uint8_t pin);
-////    bool end(const uint8_t pin);
-////    bool read(const uint8_t pin, Gamecube_Data_t &report, const bool rumble = false); // default no rumble
-////    inline void write(void){} // TODO
-//    void gc_send(uint8_t* buff, uint8_t len);
-//
-//private:
-//    DigitalInOut data_line;
-//};
-//
-//extern Gamecube_ Gamecube;
-////
-//////================================================================================
-////// Function prototypes
-//////================================================================================
-////
-//
-//// functions to communicate with the gc/n64 controller
-//void gc_send(uint8_t* buff, uint8_t len);
-//
-////void gc_send(uint8_t* buff, uint8_t len,
-////    volatile uint8_t* modePort, volatile uint8_t* outPort, uint8_t bitMask);
-////
-////uint8_t gc_get(uint8_t* buff, uint8_t len,
-////    volatile uint8_t* modePort, volatile uint8_t* outPort, volatile uint8_t * inPort, uint8_t bitMask);
-////
-////
-//#endif // include guard
\ No newline at end of file