Generalized adaptation of the WiiChuk_compat library.

Fork of WiiChuk_compat by Greg Brush

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers WiiChuck.cpp Source File

WiiChuck.cpp

00001 #include "WiiChuck.h"
00002 
00003 WiiChuck::WiiChuck (PinName data, PinName clk, uint32_t i2cFrequency):_i2c(data, clk),
00004         _callback(NULL), _initialized(false) {
00005     _i2c.frequency(i2cFrequency);
00006 
00007     // initialize Wii extension (nunchuk) based on "new way" initialization
00008     // http://wiibrew.org/wiki/Wiimote#The_New_Way
00009     // also disables need for decryption
00010     
00011     char cmd[] = {0xF0, 0x55};
00012     if (_i2c.write(NUNCHUCK_ADDR, (const char*)cmd, sizeof(cmd)) == I2C_ACK) {
00013         _initialized = true;
00014     }
00015     
00016     cmd[0] = 0xfb; cmd[1]= 0x00;
00017     _i2c.write(NUNCHUCK_ADDR, (const char*)cmd, sizeof(cmd));
00018 }
00019 
00020 bool WiiChuck::read(nunchuck_data_t* data) {
00021     char readBuf[NUNCHUCK_READLEN];
00022     
00023     if (!_initialized) {
00024         return false;
00025     }
00026     
00027     const char cmd[] = {0x00};
00028     if (_i2c.write(NUNCHUCK_ADDR, (const char*)cmd, sizeof(cmd)) == I2C_ACK) {
00029         wait(I2C_READ_DELAY);
00030         if (_i2c.read(NUNCHUCK_ADDR, readBuf, sizeof(readBuf)) == I2C_ACK) {      
00031             data->joyX = readBuf[JOY_X_IDX];
00032             data->joyY = readBuf[JOY_Y_IDX];
00033             data->accX = (uint16_t) readBuf[ACC_X_IDX] << 2 + ((readBuf[BUTTON_IDX] >> 2) & 0x03);
00034             data->accY = (uint16_t) readBuf[ACC_Y_IDX] << 2 + ((readBuf[BUTTON_IDX] >> 4) & 0x03);
00035             data->accZ = (uint16_t) readBuf[ACC_Z_IDX] << 2 + ((readBuf[BUTTON_IDX] >> 6) & 0x03);
00036 
00037             data->buttonZ = !(readBuf[BUTTON_IDX] & 0x01);
00038             data->buttonC = !(readBuf[BUTTON_IDX] & 0x02);
00039             return true;
00040         }
00041     }
00042 
00043     return false;
00044 }
00045 
00046 void WiiChuck::attach(pt2Func function, float t) {
00047     _callback = function;
00048     _getValues.attach(this, &WiiChuck::getValues, t);
00049 }
00050 
00051 void WiiChuck::detach() {
00052      _getValues.detach();
00053      _callback = NULL;
00054 }
00055 
00056 bool WiiChuck::calibrateJoystickNeutralPosition(uint8_t* centerX, uint8_t* centerY) {
00057     if (!_initialized) return false;
00058     
00059     nunchuck_data_t data;
00060     uint16_t tempX = 0, tempY = 0;
00061     
00062     for (size_t i = 0; i < 8; i++) {
00063         if (!this->read(&data)) return false;
00064         
00065         tempX += data.joyX;
00066         tempY += data.joyY;
00067     }
00068     
00069     // take the average of the readings ( >> 3 == / 8)
00070     *centerX = tempX >> 3;
00071     *centerY = tempY >> 3;
00072     return true;
00073 }
00074 
00075 void WiiChuck::getValues() {
00076     bool hasData = read(&_data);
00077   
00078     if(hasData && _callback != NULL) {
00079         _callback(&_data);
00080     }
00081 }