diff options
Diffstat (limited to 'lib/usbhost/USB_Host_Shield_2.0/Wii.h')
-rw-r--r-- | lib/usbhost/USB_Host_Shield_2.0/Wii.h | 518 |
1 files changed, 518 insertions, 0 deletions
diff --git a/lib/usbhost/USB_Host_Shield_2.0/Wii.h b/lib/usbhost/USB_Host_Shield_2.0/Wii.h new file mode 100644 index 000000000..960f2273d --- /dev/null +++ b/lib/usbhost/USB_Host_Shield_2.0/Wii.h | |||
@@ -0,0 +1,518 @@ | |||
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 | |||
26 | /* Wii event flags */ | ||
27 | #define WII_FLAG_MOTION_PLUS_CONNECTED (1 << 0) | ||
28 | #define WII_FLAG_NUNCHUCK_CONNECTED (1 << 1) | ||
29 | #define WII_FLAG_CALIBRATE_BALANCE_BOARD (1 << 2) | ||
30 | |||
31 | #define wii_check_flag(flag) (wii_event_flag & (flag)) | ||
32 | #define wii_set_flag(flag) (wii_event_flag |= (flag)) | ||
33 | #define wii_clear_flag(flag) (wii_event_flag &= ~(flag)) | ||
34 | |||
35 | /** Enum used to read the joystick on the Nunchuck. */ | ||
36 | enum HatEnum { | ||
37 | /** Read the x-axis on the Nunchuck joystick. */ | ||
38 | HatX = 0, | ||
39 | /** Read the y-axis on the Nunchuck joystick. */ | ||
40 | HatY = 1, | ||
41 | }; | ||
42 | |||
43 | /** Enum used to read the weight on Wii Balance Board. */ | ||
44 | enum BalanceBoardEnum { | ||
45 | TopRight = 0, | ||
46 | BotRight = 1, | ||
47 | TopLeft = 2, | ||
48 | BotLeft = 3, | ||
49 | }; | ||
50 | |||
51 | /** | ||
52 | * This BluetoothService class implements support for the Wiimote including the Nunchuck and Motion Plus extension. | ||
53 | * | ||
54 | * It also support the Wii U Pro Controller. | ||
55 | */ | ||
56 | class WII : public BluetoothService { | ||
57 | public: | ||
58 | /** | ||
59 | * Constructor for the WII class. | ||
60 | * @param p Pointer to BTD class instance. | ||
61 | * @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. | ||
62 | * One can use ::PAIR to set it to true. | ||
63 | */ | ||
64 | WII(BTD *p, bool pair = false); | ||
65 | |||
66 | /** @name BluetoothService implementation */ | ||
67 | /** Used this to disconnect any of the controllers. */ | ||
68 | void disconnect(); | ||
69 | /**@}*/ | ||
70 | |||
71 | /** @name Wii Controller functions */ | ||
72 | /** | ||
73 | * getButtonPress(Button b) will return true as long as the button is held down. | ||
74 | * | ||
75 | * While getButtonClick(Button b) will only return it once. | ||
76 | * | ||
77 | * So you instance if you need to increase a variable once you would use getButtonClick(Button b), | ||
78 | * but if you need to drive a robot forward you would use getButtonPress(Button b). | ||
79 | * @param b ::ButtonEnum to read. | ||
80 | * @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. | ||
81 | */ | ||
82 | bool getButtonPress(ButtonEnum b); | ||
83 | bool getButtonClick(ButtonEnum b); | ||
84 | /**@}*/ | ||
85 | |||
86 | /** @name Wii Controller functions */ | ||
87 | |||
88 | /** Call this to start the paring sequence with a controller */ | ||
89 | void pair(void) { | ||
90 | if(pBtd) | ||
91 | pBtd->pairWithWiimote(); | ||
92 | }; | ||
93 | /** | ||
94 | * Used to read the joystick of the Nunchuck. | ||
95 | * @param a Either ::HatX or ::HatY. | ||
96 | * @return Return the analog value in the range from approximately 25-230. | ||
97 | */ | ||
98 | uint8_t getAnalogHat(HatEnum a); | ||
99 | /** | ||
100 | * Used to read the joystick of the Wii U Pro Controller. | ||
101 | * @param a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY. | ||
102 | * @return Return the analog value in the range from approximately 800-3200. | ||
103 | */ | ||
104 | uint16_t getAnalogHat(AnalogHatEnum a); | ||
105 | |||
106 | /** | ||
107 | * Pitch calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected. | ||
108 | * @return Pitch in the range from 0-360. | ||
109 | */ | ||
110 | double getPitch() { | ||
111 | if(motionPlusConnected) | ||
112 | return compPitch; | ||
113 | return getWiimotePitch(); | ||
114 | }; | ||
115 | |||
116 | /** | ||
117 | * Roll calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected. | ||
118 | * @return Roll in the range from 0-360. | ||
119 | */ | ||
120 | double getRoll() { | ||
121 | if(motionPlusConnected) | ||
122 | return compRoll; | ||
123 | return getWiimoteRoll(); | ||
124 | }; | ||
125 | |||
126 | /** | ||
127 | * This is the yaw calculated by the gyro. | ||
128 | * | ||
129 | * <B>NOTE:</B> This angle will drift a lot and is only available if the Motion Plus extension is connected. | ||
130 | * @return The angle calculated using the gyro. | ||
131 | */ | ||
132 | double getYaw() { | ||
133 | return gyroYaw; | ||
134 | }; | ||
135 | |||
136 | /** Used to set all LEDs and rumble off. */ | ||
137 | void setAllOff(); | ||
138 | /** Turn off rumble. */ | ||
139 | void setRumbleOff(); | ||
140 | /** Turn on rumble. */ | ||
141 | void setRumbleOn(); | ||
142 | /** Toggle rumble. */ | ||
143 | void setRumbleToggle(); | ||
144 | |||
145 | /** | ||
146 | * Set LED value without using the ::LEDEnum. | ||
147 | * @param value See: ::LEDEnum. | ||
148 | */ | ||
149 | void setLedRaw(uint8_t value); | ||
150 | |||
151 | /** Turn all LEDs off. */ | ||
152 | void setLedOff() { | ||
153 | setLedRaw(0); | ||
154 | }; | ||
155 | /** | ||
156 | * Turn the specific ::LEDEnum off. | ||
157 | * @param a The ::LEDEnum to turn off. | ||
158 | */ | ||
159 | void setLedOff(LEDEnum a); | ||
160 | /** | ||
161 | * Turn the specific ::LEDEnum on. | ||
162 | * @param a The ::LEDEnum to turn on. | ||
163 | */ | ||
164 | void setLedOn(LEDEnum a); | ||
165 | /** | ||
166 | * Toggle the specific ::LEDEnum. | ||
167 | * @param a The ::LEDEnum to toggle. | ||
168 | */ | ||
169 | void setLedToggle(LEDEnum a); | ||
170 | /** | ||
171 | * This will set the LEDs, so the user can see which connections are active. | ||
172 | * | ||
173 | * The first ::LEDEnum indicate that the Wiimote is connected, | ||
174 | * the second ::LEDEnum indicate indicate that a Motion Plus is also connected | ||
175 | * the third ::LEDEnum will indicate that a Nunchuck controller is also connected. | ||
176 | */ | ||
177 | void setLedStatus(); | ||
178 | |||
179 | /** | ||
180 | * Return the battery level of the Wiimote. | ||
181 | * @return The battery level in the range 0-255. | ||
182 | */ | ||
183 | uint8_t getBatteryLevel(); | ||
184 | |||
185 | /** | ||
186 | * Return the Wiimote state. | ||
187 | * @return See: http://wiibrew.org/wiki/Wiimote#0x20:_Status. | ||
188 | */ | ||
189 | uint8_t getWiiState() { | ||
190 | return wiiState; | ||
191 | }; | ||
192 | /**@}*/ | ||
193 | |||
194 | /**@{*/ | ||
195 | /** Variable used to indicate if a Wiimote is connected. */ | ||
196 | bool wiimoteConnected; | ||
197 | /** Variable used to indicate if a Nunchuck controller is connected. */ | ||
198 | bool nunchuckConnected; | ||
199 | /** Variable used to indicate if a Nunchuck controller is connected. */ | ||
200 | bool motionPlusConnected; | ||
201 | /** Variable used to indicate if a Wii U Pro controller is connected. */ | ||
202 | bool wiiUProControllerConnected; | ||
203 | /** Variable used to indicate if a Wii Balance Board is connected. */ | ||
204 | bool wiiBalanceBoardConnected; | ||
205 | /**@}*/ | ||
206 | |||
207 | /* IMU Data, might be usefull if you need to do something more advanced than just calculating the angle */ | ||
208 | |||
209 | /**@{*/ | ||
210 | |||
211 | /** Pitch and roll calculated from the accelerometer inside the Wiimote. */ | ||
212 | double getWiimotePitch() { | ||
213 | return (atan2(accYwiimote, accZwiimote) + PI) * RAD_TO_DEG; | ||
214 | }; | ||
215 | |||
216 | double getWiimoteRoll() { | ||
217 | return (atan2(accXwiimote, accZwiimote) + PI) * RAD_TO_DEG; | ||
218 | }; | ||
219 | /**@}*/ | ||
220 | |||
221 | /**@{*/ | ||
222 | |||
223 | /** Pitch and roll calculated from the accelerometer inside the Nunchuck. */ | ||
224 | double getNunchuckPitch() { | ||
225 | return (atan2(accYnunchuck, accZnunchuck) + PI) * RAD_TO_DEG; | ||
226 | }; | ||
227 | |||
228 | double getNunchuckRoll() { | ||
229 | return (atan2(accXnunchuck, accZnunchuck) + PI) * RAD_TO_DEG; | ||
230 | }; | ||
231 | /**@}*/ | ||
232 | |||
233 | /**@{*/ | ||
234 | /** Accelerometer values used to calculate pitch and roll. */ | ||
235 | int16_t accXwiimote, accYwiimote, accZwiimote; | ||
236 | int16_t accXnunchuck, accYnunchuck, accZnunchuck; | ||
237 | /**@}*/ | ||
238 | |||
239 | /* Variables for the gyro inside the Motion Plus */ | ||
240 | /** This is the pitch calculated by the gyro - use this to tune WII#pitchGyroScale. */ | ||
241 | double gyroPitch; | ||
242 | /** This is the roll calculated by the gyro - use this to tune WII#rollGyroScale. */ | ||
243 | double gyroRoll; | ||
244 | /** This is the yaw calculated by the gyro - use this to tune WII#yawGyroScale. */ | ||
245 | double gyroYaw; | ||
246 | |||
247 | /**@{*/ | ||
248 | /** The speed in deg/s from the gyro. */ | ||
249 | double pitchGyroSpeed; | ||
250 | double rollGyroSpeed; | ||
251 | double yawGyroSpeed; | ||
252 | /**@}*/ | ||
253 | |||
254 | /**@{*/ | ||
255 | /** You might need to fine-tune these values. */ | ||
256 | uint16_t pitchGyroScale; | ||
257 | uint16_t rollGyroScale; | ||
258 | uint16_t yawGyroScale; | ||
259 | /**@}*/ | ||
260 | |||
261 | /**@{*/ | ||
262 | /** Raw value read directly from the Motion Plus. */ | ||
263 | int16_t gyroYawRaw; | ||
264 | int16_t gyroRollRaw; | ||
265 | int16_t gyroPitchRaw; | ||
266 | /**@}*/ | ||
267 | |||
268 | /**@{*/ | ||
269 | /** These values are set when the controller is first initialized. */ | ||
270 | int16_t gyroYawZero; | ||
271 | int16_t gyroRollZero; | ||
272 | int16_t gyroPitchZero; | ||
273 | /**@}*/ | ||
274 | |||
275 | /** @name Wii Balance Board functions */ | ||
276 | |||
277 | /** | ||
278 | * Used to get the weight at the specific position on the Wii Balance Board. | ||
279 | * @param ::BalanceBoardEnum to read from. | ||
280 | * @return Returns the weight in kg. | ||
281 | */ | ||
282 | float getWeight(BalanceBoardEnum pos); | ||
283 | |||
284 | /** | ||
285 | * Used to get total weight on the Wii Balance Board. | ||
286 | * @returnReturns the weight in kg. | ||
287 | */ | ||
288 | float getTotalWeight(); | ||
289 | |||
290 | /** | ||
291 | * Used to get the raw reading at the specific position on the Wii Balance Board. | ||
292 | * @param ::BalanceBoardEnum to read from. | ||
293 | * @return Returns the raw reading. | ||
294 | */ | ||
295 | uint16_t getWeightRaw(BalanceBoardEnum pos) { | ||
296 | return wiiBalanceBoardRaw[pos]; | ||
297 | }; | ||
298 | /**@}*/ | ||
299 | |||
300 | #ifdef WIICAMERA | ||
301 | /** @name Wiimote IR camera functions | ||
302 | * You will have to set ::ENABLE_WII_IR_CAMERA in settings.h to 1 in order use the IR camera. | ||
303 | */ | ||
304 | /** Initialises the camera as per the steps from: http://wiibrew.org/wiki/Wiimote#IR_Camera */ | ||
305 | void IRinitialize(); | ||
306 | |||
307 | /** | ||
308 | * IR object 1 x-position read from the Wii IR camera. | ||
309 | * @return The x-position of the object in the range 0-1023. | ||
310 | */ | ||
311 | uint16_t getIRx1() { | ||
312 | return IR_object_x1; | ||
313 | }; | ||
314 | |||
315 | /** | ||
316 | * IR object 1 y-position read from the Wii IR camera. | ||
317 | * @return The y-position of the object in the range 0-767. | ||
318 | */ | ||
319 | uint16_t getIRy1() { | ||
320 | return IR_object_y1; | ||
321 | }; | ||
322 | |||
323 | /** | ||
324 | * IR object 1 size read from the Wii IR camera. | ||
325 | * @return The size of the object in the range 0-15. | ||
326 | */ | ||
327 | uint8_t getIRs1() { | ||
328 | return IR_object_s1; | ||
329 | }; | ||
330 | |||
331 | /** | ||
332 | * IR object 2 x-position read from the Wii IR camera. | ||
333 | * @return The x-position of the object in the range 0-1023. | ||
334 | */ | ||
335 | uint16_t getIRx2() { | ||
336 | return IR_object_x2; | ||
337 | }; | ||
338 | |||
339 | /** | ||
340 | * IR object 2 y-position read from the Wii IR camera. | ||
341 | * @return The y-position of the object in the range 0-767. | ||
342 | */ | ||
343 | uint16_t getIRy2() { | ||
344 | return IR_object_y2; | ||
345 | }; | ||
346 | |||
347 | /** | ||
348 | * IR object 2 size read from the Wii IR camera. | ||
349 | * @return The size of the object in the range 0-15. | ||
350 | */ | ||
351 | uint8_t getIRs2() { | ||
352 | return IR_object_s2; | ||
353 | }; | ||
354 | |||
355 | /** | ||
356 | * IR object 3 x-position read from the Wii IR camera. | ||
357 | * @return The x-position of the object in the range 0-1023. | ||
358 | */ | ||
359 | uint16_t getIRx3() { | ||
360 | return IR_object_x3; | ||
361 | }; | ||
362 | |||
363 | /** | ||
364 | * IR object 3 y-position read from the Wii IR camera. | ||
365 | * @return The y-position of the object in the range 0-767. | ||
366 | */ | ||
367 | uint16_t getIRy3() { | ||
368 | return IR_object_y3; | ||
369 | }; | ||
370 | |||
371 | /** | ||
372 | * IR object 3 size read from the Wii IR camera. | ||
373 | * @return The size of the object in the range 0-15. | ||
374 | */ | ||
375 | uint8_t getIRs3() { | ||
376 | return IR_object_s3; | ||
377 | }; | ||
378 | |||
379 | /** | ||
380 | * IR object 4 x-position read from the Wii IR camera. | ||
381 | * @return The x-position of the object in the range 0-1023. | ||
382 | */ | ||
383 | uint16_t getIRx4() { | ||
384 | return IR_object_x4; | ||
385 | }; | ||
386 | |||
387 | /** | ||
388 | * IR object 4 y-position read from the Wii IR camera. | ||
389 | * @return The y-position of the object in the range 0-767. | ||
390 | */ | ||
391 | uint16_t getIRy4() { | ||
392 | return IR_object_y4; | ||
393 | }; | ||
394 | |||
395 | /** | ||
396 | * IR object 4 size read from the Wii IR camera. | ||
397 | * @return The size of the object in the range 0-15. | ||
398 | */ | ||
399 | uint8_t getIRs4() { | ||
400 | return IR_object_s4; | ||
401 | }; | ||
402 | |||
403 | /** | ||
404 | * Use this to check if the camera is enabled or not. | ||
405 | * If not call WII#IRinitialize to initialize the IR camera. | ||
406 | * @return True if it's enabled, false if not. | ||
407 | */ | ||
408 | bool isIRCameraEnabled() { | ||
409 | return (wiiState & 0x08); | ||
410 | }; | ||
411 | /**@}*/ | ||
412 | #endif | ||
413 | |||
414 | protected: | ||
415 | /** @name BluetoothService implementation */ | ||
416 | /** | ||
417 | * Used to pass acldata to the services. | ||
418 | * @param ACLData Incoming acldata. | ||
419 | */ | ||
420 | void ACLData(uint8_t* ACLData); | ||
421 | /** Used to run part of the state machine. */ | ||
422 | void Run(); | ||
423 | /** Use this to reset the service. */ | ||
424 | void Reset(); | ||
425 | /** | ||
426 | * Called when the controller is successfully initialized. | ||
427 | * Use attachOnInit(void (*funcOnInit)(void)) to call your own function. | ||
428 | * This is useful for instance if you want to set the LEDs in a specific way. | ||
429 | */ | ||
430 | void onInit(); | ||
431 | /**@}*/ | ||
432 | |||
433 | private: | ||
434 | |||
435 | void L2CAP_task(); // L2CAP state machine | ||
436 | |||
437 | /* Variables filled from HCI event management */ | ||
438 | bool activeConnection; // Used to indicate if it's already has established a connection | ||
439 | |||
440 | /* Variables used by high level L2CAP task */ | ||
441 | uint8_t l2cap_state; | ||
442 | uint8_t wii_event_flag; // Used for Wii flags | ||
443 | |||
444 | uint32_t ButtonState; | ||
445 | uint32_t OldButtonState; | ||
446 | uint32_t ButtonClickState; | ||
447 | uint16_t hatValues[4]; | ||
448 | |||
449 | uint8_t HIDBuffer[3]; // Used to store HID commands | ||
450 | |||
451 | uint16_t stateCounter; | ||
452 | bool unknownExtensionConnected; | ||
453 | bool extensionConnected; | ||
454 | bool checkBatteryLevel; // Set to true when getBatteryLevel() is called otherwise if should be false | ||
455 | bool motionPlusInside; // True if it's a new Wiimote with the Motion Plus extension build into it | ||
456 | |||
457 | /* L2CAP Channels */ | ||
458 | uint8_t control_scid[2]; // L2CAP source CID for HID_Control | ||
459 | uint8_t control_dcid[2]; // 0x0060 | ||
460 | uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt | ||
461 | uint8_t interrupt_dcid[2]; // 0x0061 | ||
462 | |||
463 | /* HID Commands */ | ||
464 | void HID_Command(uint8_t* data, uint8_t nbytes); | ||
465 | void setReportMode(bool continuous, uint8_t mode); | ||
466 | |||
467 | void writeData(uint32_t offset, uint8_t size, uint8_t* data); | ||
468 | void initExtension1(); | ||
469 | void initExtension2(); | ||
470 | |||
471 | void statusRequest(); // Used to update the Wiimote state and battery level | ||
472 | |||
473 | void readData(uint32_t offset, uint16_t size, bool EEPROM); | ||
474 | void readExtensionType(); | ||
475 | void readCalData(); | ||
476 | void readWiiBalanceBoardCalibration(); // Used by the library to read the Wii Balance Board calibration values | ||
477 | |||
478 | void checkMotionPresent(); // Used to see if a Motion Plus is connected to the Wiimote | ||
479 | void initMotionPlus(); | ||
480 | void activateMotionPlus(); | ||
481 | |||
482 | uint16_t wiiBalanceBoardRaw[4]; // Wii Balance Board raw values | ||
483 | uint16_t wiiBalanceBoardCal[3][4]; // Wii Balance Board calibration values | ||
484 | |||
485 | double compPitch; // Fusioned angle using a complimentary filter if the Motion Plus is connected | ||
486 | double compRoll; // Fusioned angle using a complimentary filter if the Motion Plus is connected | ||
487 | |||
488 | bool activateNunchuck; | ||
489 | bool motionValuesReset; // This bool is true when the gyro values has been reset | ||
490 | uint32_t timer; | ||
491 | |||
492 | 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) | ||
493 | uint8_t batteryLevel; | ||
494 | |||
495 | #ifdef WIICAMERA | ||
496 | /* Private function and variables for the readings from the IR Camera */ | ||
497 | void enableIRCamera1(); // Sets bit 2 of output report 13 | ||
498 | void enableIRCamera2(); // Sets bit 2 of output report 1A | ||
499 | void writeSensitivityBlock1(); | ||
500 | void writeSensitivityBlock2(); | ||
501 | void write0x08Value(); | ||
502 | void setWiiModeNumber(uint8_t mode_number); | ||
503 | |||
504 | uint16_t IR_object_x1; // IR x position 10 bits | ||
505 | uint16_t IR_object_y1; // IR y position 10 bits | ||
506 | uint8_t IR_object_s1; // IR size value | ||
507 | uint16_t IR_object_x2; | ||
508 | uint16_t IR_object_y2; | ||
509 | uint8_t IR_object_s2; | ||
510 | uint16_t IR_object_x3; // IR x position 10 bits | ||
511 | uint16_t IR_object_y3; // IR y position 10 bits | ||
512 | uint8_t IR_object_s3; // IR size value | ||
513 | uint16_t IR_object_x4; | ||
514 | uint16_t IR_object_y4; | ||
515 | uint8_t IR_object_s4; | ||
516 | #endif | ||
517 | }; | ||
518 | #endif | ||