A program that enables communication between one or two Wii Classic Controllers and the mbed via I2C. Includes a test program that utilizes the PIC Serial Analyzer.
Revision 0:4e399a907c98, committed 2011-02-12
- Comitter:
- alfredog83
- Date:
- Sat Feb 12 18:01:06 2011 +0000
- Commit message:
Changed in this revision
diff -r 000000000000 -r 4e399a907c98 I2CConfig.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/I2CConfig.h Sat Feb 12 18:01:06 2011 +0000 @@ -0,0 +1,51 @@ +/* +* WiiClassicControllerReader. A program allowing the output of one or two +* Wii Classic Controllers to be read via I2C and decoded for use, using the mbed +* microcontroller and its associated libraries. +* +* Written by Alfredo Guerrero <alfredog83@gmail.com> for the mbedGC open-source +* game console <http://www.mbedgc.com>. Based on the original code for +* the WiiNunchuckReader written by Petras Saduikis <petras@petras.co.uk>. +* +* This file is part of WiiClassicControllerReader. +* +* WiiClassicControllerReader is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* WiiClassicControllerReader is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You can find a copy of the GNU General Public License at <http://www.gnu.org/licenses/>. +*/ + +#ifndef ALFREDOG83_I2CCONFIG_H +#define ALFREDOG83_I2CCONFIG_H + +#include <mbed.h> + +class I2CPort_A +{ +public: + static const PinName SDA; + static const PinName SCL; +}; + + +class I2CPort_B +{ +public: + static const PinName SDA; + static const PinName SCL; +}; + +const PinName I2CPort_A::SDA = p9; +const PinName I2CPort_A::SCL = p10; + +const PinName I2CPort_B::SDA = p28; +const PinName I2CPort_B::SCL = p27; + +#endif \ No newline at end of file
diff -r 000000000000 -r 4e399a907c98 WiiClassicControllerDefs.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WiiClassicControllerDefs.h Sat Feb 12 18:01:06 2011 +0000 @@ -0,0 +1,61 @@ +/* +* WiiClassicControllerReader. A program allowing the output of one or two +* Wii Classic Controllers to be read via I2C and decoded for use, using the mbed +* microcontroller and its associated libraries. +* +* Written by Alfredo Guerrero <alfredog83@gmail.com> for the mbedGC open-source +* game console <http://www.mbedgc.com>. Based on the original code for +* the WiiNunchuckReader written by Petras Saduikis <petras@petras.co.uk>. +* +* This file is part of WiiClassicControllerReader. +* +* WiiClassicControllerReader is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* WiiClassicControllerReader is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You can find a copy of the GNU General Public License at <http://www.gnu.org/licenses/>. +*/ + +#ifndef ALFREDOG83_WIICLASSICCONTROLLERDEFS_H +#define ALFREDOG83_WIICLASSICCONTROLLERDEFS_H + +// I2C +#define CONTROLLER_ADDR 0xA4 // I2C library doesn't right shift the address, so provided shifted +#define CONTROLLER_REGADDR 0x40 // relevant register address +#define CONTROLLER_READLEN 0x06 // always read this many bytes back + +// bitmasks for individual buttons +// LX, LY: left analog stick X, Y (0-63) +// RX, RY: right analog stick X, Y (0-31) [RX separated among bytes 0-2] +// RT, LT: right, left trigger (0-31) [LT separated among bytes 2-3] +// B{ZR,ZL,A,B,X,Y,START,HOME,SELECT}: discrete buttons +// BD{L,R,U,D}: D-pad direction buttons +// LC,RC: digital button click of LT, RT when pressed down all the way +#define MASK_LX 0x3F // LX<5:0> +#define MASK_RX34 0xC0 // RX<4:3> +#define MASK_LY 0x3F // LY<5:0> +#define MASK_RY 0x1F // RY<4:0> +#define MASK_LT34 0x60 // LT<4:3> +#define MASK_RT 0x1F // RT<4:0> +#define MASK_BDU 0x01 // DU +#define MASK_RC_DL 0x02 // DL, RC +#define MASK_BSTART_ZR 0x04 // ZR, START +#define MASK_BHOME_X 0x08 // X, HOME +#define MASK_BSELECT_A 0x10 // A, SELECT +#define MASK_LC_Y 0x20 // LC, Y, LT<0> +#define MASK_BDD_B 0x40 // B, DD, LT<1>, RX<1> +#define MASK_BDR_ZL 0x80 // ZL, DR, LT<2>, RX<0>, RX<2> + +// timing +#define I2C_READ_DELAY 0.01 + +// I2C status +#define I2C_OK 0 // zero on success (ACK), non-zero on fail (NACK) for read or write + +#endif \ No newline at end of file
diff -r 000000000000 -r 4e399a907c98 WiiClassicControllerReader.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WiiClassicControllerReader.cpp Sat Feb 12 18:01:06 2011 +0000 @@ -0,0 +1,122 @@ +/* +* WiiClassicControllerReader. A program allowing the output of one or two +* Wii Classic Controllers to be read via I2C and decoded for use, using the mbed +* microcontroller and its associated libraries. +* +* Written by Alfredo Guerrero <alfredog83@gmail.com> for the mbedGC open-source +* game console <http://www.mbedgc.com>. Based on the original code for +* the WiiNunchuckReader written by Petras Saduikis <petras@petras.co.uk>. +* +* This file is part of WiiClassicControllerReader. +* +* WiiClassicControllerReader is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* WiiClassicControllerReader is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You can find a copy of the GNU General Public License at <http://www.gnu.org/licenses/>. +*/ + +#include "WiiClassicControllerReader.h" + +// constructor +WiiClassicControllerReader::WiiClassicControllerReader(PinName sda, PinName scl) : + controllerPort(sda, scl), + ljoyX(0), ljoyY(0), rjoyX(0), rjoyY(0), buttonX(0), buttonY(0), buttonA(0), + buttonB(0), buttonZL(0), buttonZR(0), buttonLT(0), buttonRT(0), buttonLC(0), + buttonRC(0), buttonHOME(0), buttonSELECT(0), buttonSTART(0), buttonDU(0), + buttonDD(0), buttonDL(0), buttonDR(0), controllerInit(false) +{ +} + +void WiiClassicControllerReader::RequestRead() +{ + // don't expect client to remember to send an init to the nunchuck + // so do it for them here + if (!controllerInit) + { + controllerInit = ControllerInit(); + } + + if (controllerInit) // don't start reading if init failed + { + if (ControllerRead()) + { + // only decode successful reads + ControllerDecode(); + } + } +} + +bool WiiClassicControllerReader::ControllerInit() +{ + bool success = false; + + const BYTE cmd[] = {CONTROLLER_REGADDR, 0x00}; + if (I2C_OK == controllerPort.write(CONTROLLER_ADDR, (const char*)cmd, sizeof(cmd))) success = true; + + return success; +} + +bool WiiClassicControllerReader::ControllerRead() +{ + bool success = false; + + // write the address we want to read from + const BYTE cmd[] = {0x00}; + if (I2C_OK == controllerPort.write(CONTROLLER_ADDR, (const char*)cmd, sizeof(cmd))) + { + // 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(I2C_READ_DELAY); + + if (I2C_OK == controllerPort.read(CONTROLLER_ADDR, readBuf, sizeof(readBuf))) success = true; + } + + return success; +} + +void WiiClassicControllerReader::ControllerDecode() +{ + ljoyX = (int)readBuf[0] & MASK_LX; + ljoyY = (int)readBuf[1] & MASK_LY; + rjoyY = (int)readBuf[2] & MASK_RY; + buttonRT = (int)readBuf[3] & MASK_RT; + buttonRC = (int)readBuf[4] & MASK_RC_DL; + buttonSTART = (int)readBuf[4] & MASK_BSTART_ZR; + buttonHOME = (int)readBuf[4] & MASK_BHOME_X; + buttonSELECT = (int)readBuf[4] & MASK_BSELECT_A; + buttonLC = (int)readBuf[4] & MASK_LC_Y; + buttonDD = (int)readBuf[4] & MASK_BDD_B; + buttonDR = (int)readBuf[4] & MASK_BDR_ZL; + buttonDU = (int)readBuf[5] & MASK_BDU; + buttonDL = (int)readBuf[5] & MASK_RC_DL; + buttonZR = (int)readBuf[5] & MASK_BSTART_ZR; + buttonX = (int)readBuf[5] & MASK_BHOME_X; + buttonA = (int)readBuf[5] & MASK_BSELECT_A; + buttonY = (int)readBuf[5] & MASK_LC_Y; + buttonB = (int)readBuf[5] & MASK_BDD_B; + buttonZL = (int)readBuf[5] & MASK_BDR_ZL; + + // the RjoyX axis and LT values are really 5 bit values + // so shift the 2 bit values read from the controller + // 3 bits to the right + rjoyX = ( (int)readBuf[0] & MASK_RX34 ) << 3; + buttonLT = ( (int)readBuf[2] & MASK_LT34 ) << 3; + + // and for each value add bit 2, bit 1, and bit 0 + // as required + if (readBuf[2] & MASK_BDR_ZL) rjoyX += 1; + if (readBuf[1] & MASK_BDD_B) rjoyX += 2; + if (readBuf[1] & MASK_BDR_ZL) rjoyX += 4; + if (readBuf[3] & MASK_LC_Y) buttonLT += 1; + if (readBuf[3] & MASK_BDD_B) buttonLT += 2; + if (readBuf[3] & MASK_BDR_ZL) buttonLT += 4; + +} \ No newline at end of file
diff -r 000000000000 -r 4e399a907c98 WiiClassicControllerReader.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/WiiClassicControllerReader.h Sat Feb 12 18:01:06 2011 +0000 @@ -0,0 +1,106 @@ +/* +* WiiClassicControllerReader. A program allowing the output of one or two +* Wii Classic Controllers to be read via I2C and decoded for use, using the mbed +* microcontroller and its associated libraries. +* +* Written by Alfredo Guerrero <alfredog83@gmail.com> for the mbedGC open-source +* game console <http://www.mbedgc.com>. Based on the original code for +* the WiiNunchuckReader written by Petras Saduikis <petras@petras.co.uk>. +* +* This file is part of WiiClassicControllerReader. +* +* WiiClassicControllerReader is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* WiiClassicControllerReader is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You can find a copy of the GNU General Public License at <http://www.gnu.org/licenses/>. +*/ + +#ifndef ALFREDOG83_WIICLASSICCONTROLLERREADER_H +#define ALFREDOG83_WIICLASSICCONTROLLERREADER_H + +#include <mbed.h> +#include "WiiClassicControllerDefs.h" + +typedef unsigned char BYTE; + +class WiiClassicControllerReader +{ +public: + // constructors + WiiClassicControllerReader(PinName sda, PinName scl); + + // functions + void RequestRead(); + + // accessors + int getLJoyX() const { return ljoyX; } + int getLJoyY() const { return ljoyY; } + int getRJoyX() const { return rjoyX; } + int getRJoyY() const { return rjoyY; } + int getButtonX() const { return buttonX; } + int getButtonY() const { return buttonY; } + int getButtonA() const { return buttonA; } + int getButtonB() const { return buttonB; } + int getButtonLT() const { return buttonLT; } + int getButtonRT() const { return buttonRT; } + int getButtonLC() const { return buttonLC; } + int getButtonRC() const { return buttonRC; } + int getButtonZL() const { return buttonZL; } + int getButtonZR() const { return buttonZR; } + int getButtonSELECT() const { return buttonSELECT; } + int getButtonHOME() const { return buttonHOME; } + int getButtonSTART() const { return buttonSTART; } + int getButtonDU() const { return buttonDU; } + int getButtonDD() const { return buttonDD; } + int getButtonDL() const { return buttonDL; } + int getButtonDR() const { return buttonDR; } + int getBufferSize() const { return sizeof(readBuf); } + char* getReadBuf() { return readBuf; } + +private: + // classic controls states + int ljoyX; + int ljoyY; + int rjoyX; + int rjoyY; + int buttonY; + int buttonX; + int buttonB; + int buttonA; + int buttonLT; + int buttonRT; + int buttonLC; + int buttonRC; + int buttonZL; + int buttonZR; + int buttonSELECT; + int buttonHOME; + int buttonSTART; + int buttonDU; + int buttonDD; + int buttonDL; + int buttonDR; + + // classic init state + bool controllerInit; + + // classic I2C port + I2C controllerPort; + + // read data + char readBuf[CONTROLLER_READLEN]; + + // functions + bool ControllerInit(); + bool ControllerRead(); + void ControllerDecode(); +}; + +#endif \ No newline at end of file
diff -r 000000000000 -r 4e399a907c98 main.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sat Feb 12 18:01:06 2011 +0000 @@ -0,0 +1,95 @@ +/* +* WiiClassicControllerReader. A program allowing the output of one or two +* Wii Classic Controllers to be read via I2C and decoded for use, using the mbed +* microcontroller and its associated libraries. +* +* Written by Alfredo Guerrero <alfredog83@gmail.com> for the mbedGC open-source +* game console <http://www.mbedgc.com>. Based on the original code for +* the WiiNunchuckReader written by Petras Saduikis <petras@petras.co.uk>. +* +* This file is part of WiiClassicControllerReader. +* +* WiiClassicControllerReader is free software: you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* WiiClassicControllerReader is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You can find a copy of the GNU General Public License at <http://www.gnu.org/licenses/>. +*/ + +#include "I2CConfig.h" +#include "WiiClassicControllerReader.h" + +#define LOOP_DELAY 1 // seconds + +// global declarations +Serial serial(USBTX, USBRX); + +void ReadAndReport(WiiClassicControllerReader* const ctrlr, const char* const portname) +{ + int bufSize = 0; + char* bufPtr = NULL; + bool debug = true; + + ctrlr->RequestRead(); + serial.printf("%s: ", portname); + + if (debug) + { + bufSize = ctrlr->getBufferSize(); + bufPtr = ctrlr->getReadBuf(); + if (bufPtr != NULL) + { + for (int i = 0; i < bufSize; i++) + { + serial.printf("%x ", bufPtr[i]); + } + serial.printf("\r\n"); + } + } + serial.printf("\r\nA\tB\tX\tY\tZL\tZR\tDU\tDD\tDL\tDR\tH\r\n"); + serial.printf("%d\t", ctrlr->getButtonA()); + serial.printf("%d\t", ctrlr->getButtonB()); + serial.printf("%d\t", ctrlr->getButtonX()); + serial.printf("%d\t", ctrlr->getButtonY()); + serial.printf("%d\t", ctrlr->getButtonZL()); + serial.printf("%d\t", ctrlr->getButtonZR()); + serial.printf("%d\t", ctrlr->getButtonDU()); + serial.printf("%d\t", ctrlr->getButtonDD()); + serial.printf("%d\t", ctrlr->getButtonDL()); + serial.printf("%d\t", ctrlr->getButtonDR()); + serial.printf("%d\t", ctrlr->getButtonHOME()); + serial.printf("\r\nSEL\tSTART\tLT\tLC\tRT\tRC\tLX\tLY\tRX\tRY\r\n"); + serial.printf("%d\t", ctrlr->getButtonSELECT()); + serial.printf("%d\t", ctrlr->getButtonSTART()); + serial.printf("%d\t", ctrlr->getButtonLT()); + serial.printf("%d\t", ctrlr->getButtonLC()); + serial.printf("%d\t", ctrlr->getButtonRT()); + serial.printf("%d\t", ctrlr->getButtonRC()); + serial.printf("%d\t", ctrlr->getLJoyX()); + serial.printf("%d\t", ctrlr->getLJoyY()); + serial.printf("%d\t", ctrlr->getRJoyX()); + serial.printf("%d\t", ctrlr->getRJoyY()); + serial.printf("\r\n\n\n"); +} + +int main() +{ + WiiClassicControllerReader ctrlrA(I2CPort_A::SDA, I2CPort_A::SCL); +// WiiClassicControllerReader ctrlrB(I2CPort_B::SDA, I2CPort_B::SCL); + + while (true) + { + ReadAndReport(&ctrlrA, "PORT A"); +// ReadAndReport(&ctrlrB, "PORT B"); + + wait(LOOP_DELAY); + } + + return EXIT_SUCCESS; +} \ No newline at end of file
diff -r 000000000000 -r 4e399a907c98 mbed.bld --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Sat Feb 12 18:01:06 2011 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/9a9732ce53a1