USB Host Shield 2.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
Wii.h
Go to the documentation of this file.
1 /* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
2 
3  This software may be distributed and modified under the terms of the GNU
4  General Public License version 2 (GPL2) as published by the Free Software
5  Foundation and appearing in the file GPL2.TXT included in the packaging of
6  this file. Please note that GPL2 Section 2[b] requires that all works based
7  on this software must also be made publicly available under the terms of
8  the GPL2 ("Copyleft").
9 
10  Contact information
11  -------------------
12 
13  Kristian Lauszus, TKJ Electronics
14  Web : http://www.tkjelectronics.com
15  e-mail : kristianl@tkjelectronics.com
16 
17  IR camera support added by Allan Glover (adglover9.81@gmail.com) and Kristian Lauszus
18  */
19 
20 #ifndef _wii_h_
21 #define _wii_h_
22 
23 #include "BTD.h"
24 #include "controllerEnums.h"
25 
27 #define WIICAMERA
28 
29 /* Bluetooth L2CAP states for L2CAP_task() */
30 #define L2CAP_WAIT 0
31 
32 // These states are used if the Wiimote is the host
33 #define L2CAP_CONTROL_SUCCESS 1
34 #define L2CAP_INTERRUPT_SETUP 2
35 
36 // These states are used if the Arduino is the host
37 #define L2CAP_CONTROL_CONNECT_REQUEST 3
38 #define L2CAP_CONTROL_CONFIG_REQUEST 4
39 #define L2CAP_INTERRUPT_CONNECT_REQUEST 5
40 
41 #define L2CAP_INTERRUPT_CONFIG_REQUEST 6
42 
43 #define L2CAP_CHECK_MOTION_PLUS_STATE 7
44 #define L2CAP_CHECK_EXTENSION_STATE 8
45 #define L2CAP_INIT_MOTION_PLUS_STATE 9
46 #define L2CAP_LED_STATE 10
47 #define L2CAP_DONE 11
48 
49 #define L2CAP_INTERRUPT_DISCONNECT 12
50 #define L2CAP_CONTROL_DISCONNECT 13
51 
52 /* L2CAP event flags */
53 #define L2CAP_FLAG_CONTROL_CONNECTED 0x001
54 #define L2CAP_FLAG_INTERRUPT_CONNECTED 0x002
55 #define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS 0x004
56 #define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS 0x008
57 #define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE 0x040
58 #define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE 0x080
59 #define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST 0x100
60 #define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST 0x200
61 
62 /* Macros for L2CAP event flag tests */
63 #define l2cap_connected_control_flag (l2cap_event_flag & L2CAP_FLAG_CONTROL_CONNECTED)
64 #define l2cap_connected_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_INTERRUPT_CONNECTED)
65 #define l2cap_config_success_control_flag (l2cap_event_flag & L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)
66 #define l2cap_config_success_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS)
67 #define l2cap_disconnect_response_control_flag (l2cap_event_flag & L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE)
68 #define l2cap_disconnect_response_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE)
69 #define l2cap_connection_request_control_flag (l2cap_event_flag & L2CAP_FLAG_CONNECTION_CONTROL_REQUEST)
70 #define l2cap_connection_request_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST)
71 
72 /* Wii event flags */
73 #define WII_FLAG_MOTION_PLUS_CONNECTED 0x400
74 #define WII_FLAG_NUNCHUCK_CONNECTED 0x800
75 
76 #define motion_plus_connected_flag (l2cap_event_flag & WII_FLAG_MOTION_PLUS_CONNECTED)
77 #define nunchuck_connected_flag (l2cap_event_flag & WII_FLAG_NUNCHUCK_CONNECTED)
78 
79 #define PAIR 1
80 
82 enum Hat {
84  HatX = 0,
86  HatY = 1,
87 };
88 
94 class WII : public BluetoothService {
95 public:
102  WII(BTD *p, bool pair = false);
103 
109  virtual void ACLData(uint8_t* ACLData);
111  virtual void Run();
113  virtual void Reset();
115  virtual void disconnect();
127  bool getButtonPress(Button b);
128  bool getButtonClick(Button b);
133  void pair(void) {
134  if(pBtd)
135  pBtd->pairWithWiimote();
136  }
142  uint8_t getAnalogHat(Hat a);
148  uint16_t getAnalogHat(AnalogHat a);
149 
154  double getPitch() {
155  return pitch;
156  };
157 
162  double getRoll() {
163  return roll;
164  };
165 
172  double getYaw() {
173  return gyroYaw;
174  };
175 
177  void setAllOff();
179  void setRumbleOff();
181  void setRumbleOn();
183  void setRumbleToggle();
184 
189  void setLedRaw(uint8_t value);
194  void setLedOff(LED a);
199  void setLedOn(LED a);
204  void setLedToggle(LED a);
214  void setLedStatus();
215 
220  uint8_t getBatteryLevel();
225  uint8_t getWiiState() {
226  return wiiState;
227  };
228 
233  void attachOnInit(void (*funcOnInit)(void)) {
234  pFuncOnInit = funcOnInit;
235  };
240  bool wiimoteConnected;
249  /* IMU Data, might be usefull if you need to do something more advanced than just calculating the angle */
250 
253  double wiimotePitch;
254  double wiimoteRoll;
260  double nunchuckRoll;
265  int16_t accX;
266  int16_t accY;
267  int16_t accZ;
270  /* Variables for the gyro inside the Motion Plus */
272  double gyroPitch;
274  double gyroRoll;
276  double gyroYaw;
277 
282  double yawGyroSpeed;
287  uint16_t pitchGyroScale;
288  uint16_t rollGyroScale;
289  uint16_t yawGyroScale;
294  int16_t gyroYawRaw;
295  int16_t gyroRollRaw;
296  int16_t gyroPitchRaw;
301  int16_t gyroYawZero;
302  int16_t gyroRollZero;
303  int16_t gyroPitchZero;
306 #ifdef WIICAMERA
307 
311  void IRinitialize();
312 
317  uint16_t getIRx1() {
318  return IR_object_x1;
319  };
320 
325  uint16_t getIRy1() {
326  return IR_object_y1;
327  };
328 
333  uint8_t getIRs1() {
334  return IR_object_s1;
335  };
336 
341  uint16_t getIRx2() {
342  return IR_object_x2;
343  };
344 
349  uint16_t getIRy2() {
350  return IR_object_y2;
351  };
352 
357  uint8_t getIRs2() {
358  return IR_object_s2;
359  };
360 
365  uint16_t getIRx3() {
366  return IR_object_x3;
367  };
368 
373  uint16_t getIRy3() {
374  return IR_object_y3;
375  };
376 
381  uint8_t getIRs3() {
382  return IR_object_s3;
383  };
384 
389  uint16_t getIRx4() {
390  return IR_object_x4;
391  };
392 
397  uint16_t getIRy4() {
398  return IR_object_y4;
399  };
400 
405  uint8_t getIRs4() {
406  return IR_object_s4;
407  };
408 
415  return(wiiState & 0x08);
416  };
418 #endif
419 
420 private:
421  BTD *pBtd; // Pointer to BTD instance
422 
428  void onInit();
429  void (*pFuncOnInit)(void); // Pointer to function called in onInit()
430 
431  void L2CAP_task(); // L2CAP state machine
432 
433  /* Variables filled from HCI event management */
434  uint16_t hci_handle;
435  bool activeConnection; // Used to indicate if it's already has established a connection
436 
437  /* Variables used by high level L2CAP task */
438  uint8_t l2cap_state;
439  uint16_t l2cap_event_flag; // l2cap flags of received Bluetooth events
440 
441  uint32_t ButtonState;
442  uint32_t OldButtonState;
443  uint32_t ButtonClickState;
444  uint16_t hatValues[4];
445 
446  uint8_t HIDBuffer[3]; // Used to store HID commands
447 
448  uint16_t stateCounter;
449  bool unknownExtensionConnected;
450  bool extensionConnected;
451  bool checkExtension; // Set to false when getBatteryLevel() is called otherwise if should be true
452  bool motionPlusInside; // True if it's a new Wiimote with the Motion Plus extension build into it
453 
454  /* L2CAP Channels */
455  uint8_t control_scid[2]; // L2CAP source CID for HID_Control
456  uint8_t control_dcid[2]; // 0x0060
457  uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt
458  uint8_t interrupt_dcid[2]; // 0x0061
459  uint8_t identifier; // Identifier for connection
460 
461  /* HID Commands */
462  void HID_Command(uint8_t* data, uint8_t nbytes);
463  void setReportMode(bool continuous, uint8_t mode);
464 
465  void writeData(uint32_t offset, uint8_t size, uint8_t* data);
466  void initExtension1();
467  void initExtension2();
468 
469  void statusRequest(); // Used to update the Wiimote state and battery level
470 
471  void readData(uint32_t offset, uint16_t size, bool EEPROM);
472  void readExtensionType();
473  void readCalData();
474 
475  void checkMotionPresent(); // Used to see if a Motion Plus is connected to the Wiimote
476  void initMotionPlus();
477  void activateMotionPlus();
478 
479  double pitch; // Fusioned angle using a complimentary filter if the Motion Plus is connected
480  double roll; // Fusioned angle using a complimentary filter if the Motion Plus is connected
481 
482  bool activateNunchuck;
483  bool motionValuesReset; // This bool is true when the gyro values has been reset
484  unsigned long timer;
485 
486  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)
487  uint8_t batteryLevel;
488 
489 #ifdef WIICAMERA
490  /* Private function and variables for the readings from the IR Camera */
491  void enableIRCamera1(); // Sets bit 2 of output report 13
492  void enableIRCamera2(); // Sets bit 2 of output report 1A
493  void writeSensitivityBlock1();
494  void writeSensitivityBlock2();
495  void write0x08Value();
496  void setWiiModeNumber(uint8_t mode_number);
497 
498  uint16_t IR_object_x1; // IR x position 10 bits
499  uint16_t IR_object_y1; // IR y position 10 bits
500  uint8_t IR_object_s1; // IR size value
501  uint16_t IR_object_x2;
502  uint16_t IR_object_y2;
503  uint8_t IR_object_s2;
504  uint16_t IR_object_x3; // IR x position 10 bits
505  uint16_t IR_object_y3; // IR y position 10 bits
506  uint8_t IR_object_s3; // IR size value
507  uint16_t IR_object_x4;
508  uint16_t IR_object_y4;
509  uint8_t IR_object_s4;
510 #endif
511 };
512 #endif