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.

Dependencies:   mbed

Files at this revision

API Documentation at this revision

Comitter:
alfredog83
Date:
Sat Feb 12 18:01:06 2011 +0000
Commit message:

Changed in this revision

I2CConfig.h Show annotated file Show diff for this revision Revisions of this file
WiiClassicControllerDefs.h Show annotated file Show diff for this revision Revisions of this file
WiiClassicControllerReader.cpp Show annotated file Show diff for this revision Revisions of this file
WiiClassicControllerReader.h Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
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