Zoltan Hudak / UsbHostMAX3421E

Dependents:   UsbHostMAX3421E_Hello

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Wii.h Source File

Wii.h

00001 /* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
00002 
00003  This software may be distributed and modified under the terms of the GNU
00004  General Public License version 2 (GPL2) as published by the Free Software
00005  Foundation and appearing in the file GPL2.TXT included in the packaging of
00006  this file. Please note that GPL2 Section 2[b] requires that all works based
00007  on this software must also be made publicly available under the terms of
00008  the GPL2 ("Copyleft").
00009 
00010  Contact information
00011  -------------------
00012 
00013  Kristian Lauszus, TKJ Electronics
00014  Web      :  http://www.tkjelectronics.com
00015  e-mail   :  kristianl@tkjelectronics.com
00016 
00017  IR camera support added by Allan Glover (adglover9.81@gmail.com) and Kristian Lauszus
00018  */
00019 
00020 #ifndef _wii_h_
00021 #define _wii_h_
00022 
00023 #include "BTD.h"
00024 #include "controllerEnums.h"
00025 
00026 /* Wii event flags */
00027 #define WII_FLAG_MOTION_PLUS_CONNECTED          (1 << 0)
00028 #define WII_FLAG_NUNCHUCK_CONNECTED             (1 << 1)
00029 #define WII_FLAG_CALIBRATE_BALANCE_BOARD        (1 << 2)
00030 
00031 #define wii_check_flag(flag)  (wii_event_flag & (flag))
00032 #define wii_set_flag(flag)  (wii_event_flag |= (flag))
00033 #define wii_clear_flag(flag)  (wii_event_flag &= ~(flag))
00034 
00035 /** Enum used to read the joystick on the Nunchuck. */
00036 enum HatEnum {
00037         /** Read the x-axis on the Nunchuck joystick. */
00038         HatX = 0,
00039         /** Read the y-axis on the Nunchuck joystick. */
00040         HatY = 1,
00041 };
00042 
00043 /** Enum used to read the weight on Wii Balance Board. */
00044 enum BalanceBoardEnum {
00045         TopRight = 0,
00046         BotRight = 1,
00047         TopLeft = 2,
00048         BotLeft = 3,
00049 };
00050 
00051 /**
00052  * This BluetoothService class implements support for the Wiimote including the Nunchuck and Motion Plus extension.
00053  *
00054  * It also support the Wii U Pro Controller.
00055  */
00056 class WII : public BluetoothService {
00057 public:
00058         /**
00059          * Constructor for the WII class.
00060          * @param  p   Pointer to BTD class instance.
00061          * @param  pair   Set this to true in order to pair with the Wiimote. If the argument is omitted then it won't pair with it.
00062          * One can use ::PAIR to set it to true.
00063          */
00064         WII(BTD *p, bool pair = false);
00065 
00066         /** @name BluetoothService implementation */
00067         /** Used this to disconnect any of the controllers. */
00068         void disconnect();
00069         /**@}*/
00070 
00071         /** @name Wii Controller functions */
00072         /**
00073          * getButtonPress(Button b) will return true as long as the button is held down.
00074          *
00075          * While getButtonClick(Button b) will only return it once.
00076          *
00077          * So you instance if you need to increase a variable once you would use getButtonClick(Button b),
00078          * but if you need to drive a robot forward you would use getButtonPress(Button b).
00079          * @param  b          ::ButtonEnum to read.
00080          * @return            getButtonPress(ButtonEnum b) will return a true as long as a button is held down, while getButtonClick(ButtonEnum b) will return true once for each button press.
00081          */
00082         bool getButtonPress(ButtonEnum b);
00083         bool getButtonClick(ButtonEnum b);
00084         /**@}*/
00085 
00086         /** @name Wii Controller functions */
00087 
00088         /** Call this to start the pairing sequence with a controller */
00089         void pair(void) {
00090                 if(pBtd)
00091                         pBtd->pairWithWiimote();
00092         };
00093         /**
00094          * Used to read the joystick of the Nunchuck.
00095          * @param  a Either ::HatX or ::HatY.
00096          * @return   Return the analog value in the range from approximately 25-230.
00097          */
00098         uint8_t getAnalogHat(HatEnum a);
00099         /**
00100          * Used to read the joystick of the Wii U Pro Controller.
00101          * @param  a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY.
00102          * @return   Return the analog value in the range from approximately 800-3200.
00103          */
00104         uint16_t getAnalogHat(AnalogHatEnum a);
00105 
00106         /**
00107          * Pitch calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected.
00108          * @return Pitch in the range from 0-360.
00109          */
00110         float getPitch() {
00111                 if(motionPlusConnected)
00112                         return compPitch;
00113                 return getWiimotePitch();
00114         };
00115 
00116         /**
00117          * Roll calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected.
00118          * @return Roll in the range from 0-360.
00119          */
00120         float getRoll() {
00121                 if(motionPlusConnected)
00122                         return compRoll;
00123                 return getWiimoteRoll();
00124         };
00125 
00126         /**
00127          * This is the yaw calculated by the gyro.
00128          *
00129          * <B>NOTE:</B> This angle will drift a lot and is only available if the Motion Plus extension is connected.
00130          * @return The angle calculated using the gyro.
00131          */
00132         float getYaw() {
00133                 return gyroYaw;
00134         };
00135 
00136         /** Used to set all LEDs and rumble off. */
00137         void setAllOff();
00138         /** Turn off rumble. */
00139         void setRumbleOff();
00140         /** Turn on rumble. */
00141         void setRumbleOn();
00142         /** Toggle rumble. */
00143         void setRumbleToggle();
00144 
00145         /**
00146          * Set LED value without using the ::LEDEnum.
00147          * @param value See: ::LEDEnum.
00148          */
00149         void setLedRaw(uint8_t value);
00150 
00151         /** Turn all LEDs off. */
00152         void setLedOff() {
00153                 setLedRaw(0);
00154         };
00155         /**
00156          * Turn the specific ::LEDEnum off.
00157          * @param a The ::LEDEnum to turn off.
00158          */
00159         void setLedOff(LEDEnum a);
00160         /**
00161          * Turn the specific ::LEDEnum on.
00162          * @param a The ::LEDEnum to turn on.
00163          */
00164         void setLedOn(LEDEnum a);
00165         /**
00166          * Toggle the specific ::LEDEnum.
00167          * @param a The ::LEDEnum to toggle.
00168          */
00169         void setLedToggle(LEDEnum a);
00170         /**
00171          * This will set the LEDs, so the user can see which connections are active.
00172          *
00173          * The first ::LEDEnum indicate that the Wiimote is connected,
00174          * the second ::LEDEnum indicate indicate that a Motion Plus is also connected
00175          * the third ::LEDEnum will indicate that a Nunchuck controller is also connected.
00176          */
00177         void setLedStatus();
00178 
00179         /**
00180          * Return the battery level of the Wiimote.
00181          * @return The battery level in the range 0-255.
00182          */
00183         uint8_t getBatteryLevel();
00184 
00185         /**
00186          * Return the Wiimote state.
00187          * @return See: http://wiibrew.org/wiki/Wiimote#0x20:_Status.
00188          */
00189         uint8_t getWiiState() {
00190                 return wiiState;
00191         };
00192         /**@}*/
00193 
00194         /**@{*/
00195         /** Variable used to indicate if a Wiimote is connected. */
00196         bool wiimoteConnected;
00197         /** Variable used to indicate if a Nunchuck controller is connected. */
00198         bool nunchuckConnected;
00199         /** Variable used to indicate if a Nunchuck controller is connected. */
00200         bool motionPlusConnected;
00201         /** Variable used to indicate if a Wii U Pro controller is connected. */
00202         bool wiiUProControllerConnected;
00203         /** Variable used to indicate if a Wii Balance Board is connected. */
00204         bool wiiBalanceBoardConnected;
00205         /**@}*/
00206 
00207         /* IMU Data, might be usefull if you need to do something more advanced than just calculating the angle */
00208 
00209         /**@{*/
00210 
00211         /** Pitch and roll calculated from the accelerometer inside the Wiimote. */
00212         float getWiimotePitch() {
00213                 return (atan2f(accYwiimote, accZwiimote) + M_PI) * RAD_TO_DEG;
00214         };
00215 
00216         float getWiimoteRoll() {
00217                 return (atan2f(accXwiimote, accZwiimote) + M_PI) * RAD_TO_DEG;
00218         };
00219         /**@}*/
00220 
00221         /**@{*/
00222 
00223         /** Pitch and roll calculated from the accelerometer inside the Nunchuck. */
00224         float getNunchuckPitch() {
00225                 return (atan2f(accYnunchuck, accZnunchuck) + M_PI) * RAD_TO_DEG;
00226         };
00227 
00228         float getNunchuckRoll() {
00229                 return (atan2f(accXnunchuck, accZnunchuck) + M_PI) * RAD_TO_DEG;
00230         };
00231         /**@}*/
00232 
00233         /**@{*/
00234         /** Accelerometer values used to calculate pitch and roll. */
00235         int16_t accXwiimote, accYwiimote, accZwiimote;
00236         int16_t accXnunchuck, accYnunchuck, accZnunchuck;
00237         /**@}*/
00238 
00239         /* Variables for the gyro inside the Motion Plus */
00240         /** This is the pitch calculated by the gyro - use this to tune WII#pitchGyroScale. */
00241         float gyroPitch;
00242         /** This is the roll calculated by the gyro - use this to tune WII#rollGyroScale. */
00243         float gyroRoll;
00244         /** This is the yaw calculated by the gyro - use this to tune WII#yawGyroScale. */
00245         float gyroYaw;
00246 
00247         /**@{*/
00248         /** The speed in deg/s from the gyro. */
00249         float pitchGyroSpeed;
00250         float rollGyroSpeed;
00251         float yawGyroSpeed;
00252         /**@}*/
00253 
00254         /**@{*/
00255         /** You might need to fine-tune these values. */
00256         uint16_t pitchGyroScale;
00257         uint16_t rollGyroScale;
00258         uint16_t yawGyroScale;
00259         /**@}*/
00260 
00261         /**@{*/
00262         /** Raw value read directly from the Motion Plus. */
00263         int16_t gyroYawRaw;
00264         int16_t gyroRollRaw;
00265         int16_t gyroPitchRaw;
00266         /**@}*/
00267 
00268         /**@{*/
00269         /** These values are set when the controller is first initialized. */
00270         int16_t gyroYawZero;
00271         int16_t gyroRollZero;
00272         int16_t gyroPitchZero;
00273         /**@}*/
00274 
00275         /** @name Wii Balance Board functions */
00276 
00277         /**
00278          * Used to get the weight at the specific position on the Wii Balance Board.
00279          * @param  pos ::BalanceBoardEnum to read from.
00280          * @return     Returns the weight in kg.
00281          */
00282         float getWeight(BalanceBoardEnum pos);
00283 
00284         /**
00285          * Used to get total weight on the Wii Balance Board.
00286          * @return Returns the weight in kg.
00287          */
00288         float getTotalWeight();
00289 
00290         /**
00291          * Used to get the raw reading at the specific position on the Wii Balance Board.
00292          * @param  pos ::BalanceBoardEnum to read from.
00293          * @return     Returns the raw reading.
00294          */
00295         uint16_t getWeightRaw(BalanceBoardEnum pos) {
00296                 return wiiBalanceBoardRaw[pos];
00297         };
00298         /**@}*/
00299 
00300 #ifdef WIICAMERA
00301         /** @name Wiimote IR camera functions
00302          * You will have to set ::ENABLE_WII_IR_CAMERA in settings.h to 1 in order use the IR camera.
00303          */
00304         /** Initialises the camera as per the steps from: http://wiibrew.org/wiki/Wiimote#IR_Camera */
00305         void IRinitialize();
00306 
00307         /**
00308          * IR object 1 x-position read from the Wii IR camera.
00309          * @return The x-position of the object in the range 0-1023.
00310          */
00311         uint16_t getIRx1() {
00312                 return IR_object_x1;
00313         };
00314 
00315         /**
00316          * IR object 1 y-position read from the Wii IR camera.
00317          * @return The y-position of the object in the range 0-767.
00318          */
00319         uint16_t getIRy1() {
00320                 return IR_object_y1;
00321         };
00322 
00323         /**
00324          * IR object 1 size read from the Wii IR camera.
00325          * @return The size of the object in the range 0-15.
00326          */
00327         uint8_t getIRs1() {
00328                 return IR_object_s1;
00329         };
00330 
00331         /**
00332          * IR object 2 x-position read from the Wii IR camera.
00333          * @return The x-position of the object in the range 0-1023.
00334          */
00335         uint16_t getIRx2() {
00336                 return IR_object_x2;
00337         };
00338 
00339         /**
00340          * IR object 2 y-position read from the Wii IR camera.
00341          * @return The y-position of the object in the range 0-767.
00342          */
00343         uint16_t getIRy2() {
00344                 return IR_object_y2;
00345         };
00346 
00347         /**
00348          * IR object 2 size read from the Wii IR camera.
00349          * @return The size of the object in the range 0-15.
00350          */
00351         uint8_t getIRs2() {
00352                 return IR_object_s2;
00353         };
00354 
00355         /**
00356          * IR object 3 x-position read from the Wii IR camera.
00357          * @return The x-position of the object in the range 0-1023.
00358          */
00359         uint16_t getIRx3() {
00360                 return IR_object_x3;
00361         };
00362 
00363         /**
00364          * IR object 3 y-position read from the Wii IR camera.
00365          * @return The y-position of the object in the range 0-767.
00366          */
00367         uint16_t getIRy3() {
00368                 return IR_object_y3;
00369         };
00370 
00371         /**
00372          * IR object 3 size read from the Wii IR camera.
00373          * @return The size of the object in the range 0-15.
00374          */
00375         uint8_t getIRs3() {
00376                 return IR_object_s3;
00377         };
00378 
00379         /**
00380          * IR object 4 x-position read from the Wii IR camera.
00381          * @return The x-position of the object in the range 0-1023.
00382          */
00383         uint16_t getIRx4() {
00384                 return IR_object_x4;
00385         };
00386 
00387         /**
00388          * IR object 4 y-position read from the Wii IR camera.
00389          * @return The y-position of the object in the range 0-767.
00390          */
00391         uint16_t getIRy4() {
00392                 return IR_object_y4;
00393         };
00394 
00395         /**
00396          * IR object 4 size read from the Wii IR camera.
00397          * @return The size of the object in the range 0-15.
00398          */
00399         uint8_t getIRs4() {
00400                 return IR_object_s4;
00401         };
00402 
00403         /**
00404          * Use this to check if the camera is enabled or not.
00405          * If not call WII#IRinitialize to initialize the IR camera.
00406          * @return     True if it's enabled, false if not.
00407          */
00408         bool isIRCameraEnabled() {
00409                 return (wiiState & 0x08);
00410         };
00411         /**@}*/
00412 #endif
00413 
00414 protected:
00415         /** @name BluetoothService implementation */
00416         /**
00417          * Used to pass acldata to the services.
00418          * @param ACLData Incoming acldata.
00419          */
00420         void ACLData(uint8_t* ACLData);
00421         /** Used to run part of the state machine. */
00422         void Run();
00423         /** Use this to reset the service. */
00424         void Reset();
00425         /**
00426          * Called when the controller is successfully initialized.
00427          * Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
00428          * This is useful for instance if you want to set the LEDs in a specific way.
00429          */
00430         void onInit();
00431         /**@}*/
00432 
00433 private:
00434 
00435         void L2CAP_task(); // L2CAP state machine
00436 
00437         /* Variables filled from HCI event management */
00438         bool activeConnection; // Used to indicate if it's already has established a connection
00439 
00440         /* Variables used by high level L2CAP task */
00441         uint8_t l2cap_state;
00442         uint8_t wii_event_flag; // Used for Wii flags
00443 
00444         uint32_t ButtonState;
00445         uint32_t OldButtonState;
00446         uint32_t ButtonClickState;
00447         uint16_t hatValues[4];
00448 
00449         uint8_t HIDBuffer[3]; // Used to store HID commands
00450 
00451         uint16_t stateCounter;
00452         bool unknownExtensionConnected;
00453         bool extensionConnected;
00454         bool checkBatteryLevel; // Set to true when getBatteryLevel() is called otherwise if should be false
00455         bool motionPlusInside; // True if it's a new Wiimote with the Motion Plus extension build into it
00456 
00457         /* L2CAP Channels */
00458         uint8_t control_scid[2]; // L2CAP source CID for HID_Control
00459         uint8_t control_dcid[2]; // 0x0060
00460         uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt
00461         uint8_t interrupt_dcid[2]; // 0x0061
00462 
00463         /* HID Commands */
00464         void HID_Command(uint8_t* data, uint8_t nbytes);
00465         void setReportMode(bool continuous, uint8_t mode);
00466 
00467         void writeData(uint32_t offset, uint8_t size, uint8_t* data);
00468         void initExtension1();
00469         void initExtension2();
00470 
00471         void statusRequest(); // Used to update the Wiimote state and battery level
00472 
00473         void readData(uint32_t offset, uint16_t size, bool EEPROM);
00474         void readExtensionType();
00475         void readCalData();
00476         void readWiiBalanceBoardCalibration(); // Used by the library to read the Wii Balance Board calibration values
00477 
00478         void checkMotionPresent(); // Used to see if a Motion Plus is connected to the Wiimote
00479         void initMotionPlus();
00480         void activateMotionPlus();
00481 
00482         uint16_t wiiBalanceBoardRaw[4]; // Wii Balance Board raw values
00483         uint16_t wiiBalanceBoardCal[3][4]; // Wii Balance Board calibration values
00484 
00485         float compPitch; // Fusioned angle using a complimentary filter if the Motion Plus is connected
00486         float compRoll; // Fusioned angle using a complimentary filter if the Motion Plus is connected
00487 
00488         bool activateNunchuck;
00489         bool motionValuesReset; // This bool is true when the gyro values has been reset
00490         uint32_t timer;
00491 
00492         uint8_t wiiState; // Stores the value in l2capinbuf[12] - (0x01: Battery is nearly empty), (0x02:  An Extension Controller is connected), (0x04: Speaker enabled), (0x08: IR enabled), (0x10: LED1, 0x20: LED2, 0x40: LED3, 0x80: LED4)
00493         uint8_t batteryLevel;
00494 
00495 #ifdef WIICAMERA
00496         /* Private function and variables for the readings from the IR Camera */
00497         void enableIRCamera1(); // Sets bit 2 of output report 13
00498         void enableIRCamera2(); // Sets bit 2 of output report 1A
00499         void writeSensitivityBlock1();
00500         void writeSensitivityBlock2();
00501         void write0x08Value();
00502         void setWiiModeNumber(uint8_t mode_number);
00503 
00504         uint16_t IR_object_x1; // IR x position 10 bits
00505         uint16_t IR_object_y1; // IR y position 10 bits
00506         uint8_t IR_object_s1; // IR size value
00507         uint16_t IR_object_x2;
00508         uint16_t IR_object_y2;
00509         uint8_t IR_object_s2;
00510         uint16_t IR_object_x3; // IR x position 10 bits
00511         uint16_t IR_object_y3; // IR y position 10 bits
00512         uint8_t IR_object_s3; // IR size value
00513         uint16_t IR_object_x4;
00514         uint16_t IR_object_y4;
00515         uint8_t IR_object_s4;
00516 #endif
00517 };
00518 #endif