Library for communicating with a Wii classic controller using the I2C bus.

Dependents:   WiiClassicControllerTest

Note that you will also need the CommonTypes library to use this.

Get it here:http://mbed.org/users/RichardE/code/CommonTypes/

WiiClassicController.cpp

Committer:
RichardE
Date:
2013-06-29
Revision:
0:242100dadee8
Child:
3:ecae3d286a99

File content as of revision 0:242100dadee8:

/*
 * SOURCE FILE : WiiClassicController.cpp
 *
 * Definition of class WiiClassicController.
 * Allows use of a Wii classic controller using an I2C bus.
 *
 */

#include "WiiClassicController.h"

// REMOVE THIS!
extern Serial pc;

/** Constructor.
 * @param sda pin to use for SDA.
 * @param scl pin to use for SCL.
 */
WiiClassicController::WiiClassicController( PinName sda, PinName scl ) :
    controllerPort( sda, scl ),
    initialised( false )
{
}

/** Destructor.
 */
WiiClassicController::~WiiClassicController() {
}

/** Read from the controller.
 * @returns true on success, false on failure.
 */
bool WiiClassicController::Read( void ) {
    // Don't expect client to remember to send an init to the nunchuck
    // so do it for them here.
    if( ! initialised ) {
        initialised = ControllerInit();
    }
    // Don't start reading if init failed
    return initialised && ControllerRead();
}

/** Initialise the controller.
 * @returns true on success, false on failure.
 */
bool WiiClassicController::ControllerInit( void ) {
    const UInt8 cmd[] = { CONTROLLER_REGADDR, 0x00 };
    bool ok = ( controllerPort.write( CONTROLLER_ADDR, (const char*)cmd, sizeof(cmd) ) == 0 );
    pc.printf( "ControllerInit returned %d\r\n", (int)ok );
    return ok;
}

/** Read from the controller, assuming it has been initialised.
 * @returns true on success, false on failure.
 */
bool WiiClassicController::ControllerRead() {
    // write the address we want to read from
    const UInt8 cmd[] = { 0x00 };
    if( controllerPort.write( CONTROLLER_ADDR, (const char*)cmd, sizeof(cmd) ) == 0 ) {
        // The Wii Classic Controller is non-standard I2C
        // and can't manage setting the read address and immediately supplying the data
        // so wait a bit.
        wait( 0.01 );
        if( controllerPort.read( CONTROLLER_ADDR, (char*)readBuf, sizeof(readBuf) ) == 0 ) {
            for( int i = 0; i < CONTROLLER_READLEN; ++i ) {
                readBuf[ i ] = Decode( readBuf[ i ] );
            }
            return true;
        }
        else {
            return false;
        }
    }
    else {
        return false;
    }
}