Generalized adaptation of the WiiChuk_compat library.

Fork of WiiChuk_compat by Greg Brush

WiiChuck.cpp

Committer:
d34d
Date:
2014-12-22
Revision:
5:be9ce129de7c
Parent:
3:fcc2f24d0644

File content as of revision 5:be9ce129de7c:

#include "WiiChuck.h"

WiiChuck::WiiChuck(PinName data, PinName clk, uint32_t i2cFrequency):_i2c(data, clk),
        _callback(NULL), _initialized(false) {
    _i2c.frequency(i2cFrequency);

    // initialize Wii extension (nunchuk) based on "new way" initialization
    // http://wiibrew.org/wiki/Wiimote#The_New_Way
    // also disables need for decryption
    
    char cmd[] = {0xF0, 0x55};
    if (_i2c.write(NUNCHUCK_ADDR, (const char*)cmd, sizeof(cmd)) == I2C_ACK) {
        _initialized = true;
    }
    
    cmd[0] = 0xfb; cmd[1]= 0x00;
    _i2c.write(NUNCHUCK_ADDR, (const char*)cmd, sizeof(cmd));
}

bool WiiChuck::read(nunchuck_data_t* data) {
    char readBuf[NUNCHUCK_READLEN];
    
    if (!_initialized) {
        return false;
    }
    
    const char cmd[] = {0x00};
    if (_i2c.write(NUNCHUCK_ADDR, (const char*)cmd, sizeof(cmd)) == I2C_ACK) {
        wait(I2C_READ_DELAY);
        if (_i2c.read(NUNCHUCK_ADDR, readBuf, sizeof(readBuf)) == I2C_ACK) {      
            data->joyX = readBuf[JOY_X_IDX];
            data->joyY = readBuf[JOY_Y_IDX];
            data->accX = (uint16_t) readBuf[ACC_X_IDX] << 2 + ((readBuf[BUTTON_IDX] >> 2) & 0x03);
            data->accY = (uint16_t) readBuf[ACC_Y_IDX] << 2 + ((readBuf[BUTTON_IDX] >> 4) & 0x03);
            data->accZ = (uint16_t) readBuf[ACC_Z_IDX] << 2 + ((readBuf[BUTTON_IDX] >> 6) & 0x03);

            data->buttonZ = !(readBuf[BUTTON_IDX] & 0x01);
            data->buttonC = !(readBuf[BUTTON_IDX] & 0x02);
            return true;
        }
    }

    return false;
}

void WiiChuck::attach(pt2Func function, float t) {
    _callback = function;
    _getValues.attach(this, &WiiChuck::getValues, t);
}

void WiiChuck::detach() {
     _getValues.detach();
     _callback = NULL;
}

bool WiiChuck::calibrateJoystickNeutralPosition(uint8_t* centerX, uint8_t* centerY) {
    if (!_initialized) return false;
    
    nunchuck_data_t data;
    uint16_t tempX = 0, tempY = 0;
    
    for (size_t i = 0; i < 8; i++) {
        if (!this->read(&data)) return false;
        
        tempX += data.joyX;
        tempY += data.joyY;
    }
    
    // take the average of the readings ( >> 3 == / 8)
    *centerX = tempX >> 3;
    *centerY = tempY >> 3;
    return true;
}

void WiiChuck::getValues() {
    bool hasData = read(&_data);
  
    if(hasData && _callback != NULL) {
        _callback(&_data);
    }
}