Dependencies:   mbed

Committer:
alfredog83
Date:
Sat Feb 12 18:01:06 2011 +0000
Revision:
0:4e399a907c98

        

Who changed what in which revision?

UserRevisionLine numberNew contents of line
alfredog83 0:4e399a907c98 1 /*
alfredog83 0:4e399a907c98 2 * WiiClassicControllerReader. A program allowing the output of one or two
alfredog83 0:4e399a907c98 3 * Wii Classic Controllers to be read via I2C and decoded for use, using the mbed
alfredog83 0:4e399a907c98 4 * microcontroller and its associated libraries.
alfredog83 0:4e399a907c98 5 *
alfredog83 0:4e399a907c98 6 * Written by Alfredo Guerrero <alfredog83@gmail.com> for the mbedGC open-source
alfredog83 0:4e399a907c98 7 * game console <http://www.mbedgc.com>. Based on the original code for
alfredog83 0:4e399a907c98 8 * the WiiNunchuckReader written by Petras Saduikis <petras@petras.co.uk>.
alfredog83 0:4e399a907c98 9 *
alfredog83 0:4e399a907c98 10 * This file is part of WiiClassicControllerReader.
alfredog83 0:4e399a907c98 11 *
alfredog83 0:4e399a907c98 12 * WiiClassicControllerReader is free software: you can redistribute it and/or modify
alfredog83 0:4e399a907c98 13 * it under the terms of the GNU General Public License as published by
alfredog83 0:4e399a907c98 14 * the Free Software Foundation, either version 3 of the License, or
alfredog83 0:4e399a907c98 15 * (at your option) any later version.
alfredog83 0:4e399a907c98 16 *
alfredog83 0:4e399a907c98 17 * WiiClassicControllerReader is distributed in the hope that it will be useful,
alfredog83 0:4e399a907c98 18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
alfredog83 0:4e399a907c98 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
alfredog83 0:4e399a907c98 20 * GNU General Public License for more details.
alfredog83 0:4e399a907c98 21 *
alfredog83 0:4e399a907c98 22 * You can find a copy of the GNU General Public License at <http://www.gnu.org/licenses/>.
alfredog83 0:4e399a907c98 23 */
alfredog83 0:4e399a907c98 24
alfredog83 0:4e399a907c98 25 #include "WiiClassicControllerReader.h"
alfredog83 0:4e399a907c98 26
alfredog83 0:4e399a907c98 27 // constructor
alfredog83 0:4e399a907c98 28 WiiClassicControllerReader::WiiClassicControllerReader(PinName sda, PinName scl) :
alfredog83 0:4e399a907c98 29 controllerPort(sda, scl),
alfredog83 0:4e399a907c98 30 ljoyX(0), ljoyY(0), rjoyX(0), rjoyY(0), buttonX(0), buttonY(0), buttonA(0),
alfredog83 0:4e399a907c98 31 buttonB(0), buttonZL(0), buttonZR(0), buttonLT(0), buttonRT(0), buttonLC(0),
alfredog83 0:4e399a907c98 32 buttonRC(0), buttonHOME(0), buttonSELECT(0), buttonSTART(0), buttonDU(0),
alfredog83 0:4e399a907c98 33 buttonDD(0), buttonDL(0), buttonDR(0), controllerInit(false)
alfredog83 0:4e399a907c98 34 {
alfredog83 0:4e399a907c98 35 }
alfredog83 0:4e399a907c98 36
alfredog83 0:4e399a907c98 37 void WiiClassicControllerReader::RequestRead()
alfredog83 0:4e399a907c98 38 {
alfredog83 0:4e399a907c98 39 // don't expect client to remember to send an init to the nunchuck
alfredog83 0:4e399a907c98 40 // so do it for them here
alfredog83 0:4e399a907c98 41 if (!controllerInit)
alfredog83 0:4e399a907c98 42 {
alfredog83 0:4e399a907c98 43 controllerInit = ControllerInit();
alfredog83 0:4e399a907c98 44 }
alfredog83 0:4e399a907c98 45
alfredog83 0:4e399a907c98 46 if (controllerInit) // don't start reading if init failed
alfredog83 0:4e399a907c98 47 {
alfredog83 0:4e399a907c98 48 if (ControllerRead())
alfredog83 0:4e399a907c98 49 {
alfredog83 0:4e399a907c98 50 // only decode successful reads
alfredog83 0:4e399a907c98 51 ControllerDecode();
alfredog83 0:4e399a907c98 52 }
alfredog83 0:4e399a907c98 53 }
alfredog83 0:4e399a907c98 54 }
alfredog83 0:4e399a907c98 55
alfredog83 0:4e399a907c98 56 bool WiiClassicControllerReader::ControllerInit()
alfredog83 0:4e399a907c98 57 {
alfredog83 0:4e399a907c98 58 bool success = false;
alfredog83 0:4e399a907c98 59
alfredog83 0:4e399a907c98 60 const BYTE cmd[] = {CONTROLLER_REGADDR, 0x00};
alfredog83 0:4e399a907c98 61 if (I2C_OK == controllerPort.write(CONTROLLER_ADDR, (const char*)cmd, sizeof(cmd))) success = true;
alfredog83 0:4e399a907c98 62
alfredog83 0:4e399a907c98 63 return success;
alfredog83 0:4e399a907c98 64 }
alfredog83 0:4e399a907c98 65
alfredog83 0:4e399a907c98 66 bool WiiClassicControllerReader::ControllerRead()
alfredog83 0:4e399a907c98 67 {
alfredog83 0:4e399a907c98 68 bool success = false;
alfredog83 0:4e399a907c98 69
alfredog83 0:4e399a907c98 70 // write the address we want to read from
alfredog83 0:4e399a907c98 71 const BYTE cmd[] = {0x00};
alfredog83 0:4e399a907c98 72 if (I2C_OK == controllerPort.write(CONTROLLER_ADDR, (const char*)cmd, sizeof(cmd)))
alfredog83 0:4e399a907c98 73 {
alfredog83 0:4e399a907c98 74 // the Wii Classic Controller is non-standard I2C
alfredog83 0:4e399a907c98 75 // and can't manage setting the read address and immediately supplying the data
alfredog83 0:4e399a907c98 76 // so wait a bit
alfredog83 0:4e399a907c98 77 wait(I2C_READ_DELAY);
alfredog83 0:4e399a907c98 78
alfredog83 0:4e399a907c98 79 if (I2C_OK == controllerPort.read(CONTROLLER_ADDR, readBuf, sizeof(readBuf))) success = true;
alfredog83 0:4e399a907c98 80 }
alfredog83 0:4e399a907c98 81
alfredog83 0:4e399a907c98 82 return success;
alfredog83 0:4e399a907c98 83 }
alfredog83 0:4e399a907c98 84
alfredog83 0:4e399a907c98 85 void WiiClassicControllerReader::ControllerDecode()
alfredog83 0:4e399a907c98 86 {
alfredog83 0:4e399a907c98 87 ljoyX = (int)readBuf[0] & MASK_LX;
alfredog83 0:4e399a907c98 88 ljoyY = (int)readBuf[1] & MASK_LY;
alfredog83 0:4e399a907c98 89 rjoyY = (int)readBuf[2] & MASK_RY;
alfredog83 0:4e399a907c98 90 buttonRT = (int)readBuf[3] & MASK_RT;
alfredog83 0:4e399a907c98 91 buttonRC = (int)readBuf[4] & MASK_RC_DL;
alfredog83 0:4e399a907c98 92 buttonSTART = (int)readBuf[4] & MASK_BSTART_ZR;
alfredog83 0:4e399a907c98 93 buttonHOME = (int)readBuf[4] & MASK_BHOME_X;
alfredog83 0:4e399a907c98 94 buttonSELECT = (int)readBuf[4] & MASK_BSELECT_A;
alfredog83 0:4e399a907c98 95 buttonLC = (int)readBuf[4] & MASK_LC_Y;
alfredog83 0:4e399a907c98 96 buttonDD = (int)readBuf[4] & MASK_BDD_B;
alfredog83 0:4e399a907c98 97 buttonDR = (int)readBuf[4] & MASK_BDR_ZL;
alfredog83 0:4e399a907c98 98 buttonDU = (int)readBuf[5] & MASK_BDU;
alfredog83 0:4e399a907c98 99 buttonDL = (int)readBuf[5] & MASK_RC_DL;
alfredog83 0:4e399a907c98 100 buttonZR = (int)readBuf[5] & MASK_BSTART_ZR;
alfredog83 0:4e399a907c98 101 buttonX = (int)readBuf[5] & MASK_BHOME_X;
alfredog83 0:4e399a907c98 102 buttonA = (int)readBuf[5] & MASK_BSELECT_A;
alfredog83 0:4e399a907c98 103 buttonY = (int)readBuf[5] & MASK_LC_Y;
alfredog83 0:4e399a907c98 104 buttonB = (int)readBuf[5] & MASK_BDD_B;
alfredog83 0:4e399a907c98 105 buttonZL = (int)readBuf[5] & MASK_BDR_ZL;
alfredog83 0:4e399a907c98 106
alfredog83 0:4e399a907c98 107 // the RjoyX axis and LT values are really 5 bit values
alfredog83 0:4e399a907c98 108 // so shift the 2 bit values read from the controller
alfredog83 0:4e399a907c98 109 // 3 bits to the right
alfredog83 0:4e399a907c98 110 rjoyX = ( (int)readBuf[0] & MASK_RX34 ) << 3;
alfredog83 0:4e399a907c98 111 buttonLT = ( (int)readBuf[2] & MASK_LT34 ) << 3;
alfredog83 0:4e399a907c98 112
alfredog83 0:4e399a907c98 113 // and for each value add bit 2, bit 1, and bit 0
alfredog83 0:4e399a907c98 114 // as required
alfredog83 0:4e399a907c98 115 if (readBuf[2] & MASK_BDR_ZL) rjoyX += 1;
alfredog83 0:4e399a907c98 116 if (readBuf[1] & MASK_BDD_B) rjoyX += 2;
alfredog83 0:4e399a907c98 117 if (readBuf[1] & MASK_BDR_ZL) rjoyX += 4;
alfredog83 0:4e399a907c98 118 if (readBuf[3] & MASK_LC_Y) buttonLT += 1;
alfredog83 0:4e399a907c98 119 if (readBuf[3] & MASK_BDD_B) buttonLT += 2;
alfredog83 0:4e399a907c98 120 if (readBuf[3] & MASK_BDR_ZL) buttonLT += 4;
alfredog83 0:4e399a907c98 121
alfredog83 0:4e399a907c98 122 }