2012-08-21 14:31:11 +02:00
/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
2013-03-28 09:37:09 +01:00
2012-08-21 14:31:11 +02:00
This software may be distributed and modified under the terms of the GNU
General Public License version 2 ( GPL2 ) as published by the Free Software
Foundation and appearing in the file GPL2 . TXT included in the packaging of
this file . Please note that GPL2 Section 2 [ b ] requires that all works based
on this software must also be made publicly available under the terms of
the GPL2 ( " Copyleft " ) .
2013-03-28 09:37:09 +01:00
2012-08-21 14:31:11 +02:00
Contact information
- - - - - - - - - - - - - - - - - - -
2013-03-28 09:37:09 +01:00
2012-08-21 14:31:11 +02:00
Kristian Lauszus , TKJ Electronics
Web : http : //www.tkjelectronics.com
e - mail : kristianl @ tkjelectronics . com
2013-01-17 00:07:56 +01:00
2013-07-18 19:43:21 +02:00
IR camera support added by Allan Glover ( adglover9 .81 @ gmail . com ) and Kristian Lauszus
2012-08-21 14:31:11 +02:00
*/
# include "Wii.h"
2013-11-11 11:48:09 +01:00
// To enable serial debugging see "settings.h"
2012-08-21 14:31:11 +02:00
//#define EXTRADEBUG // Uncomment to get even more debugging data
2012-08-22 23:41:38 +02:00
//#define PRINTREPORT // Uncomment to print the report send by the Wii controllers
2012-08-21 14:31:11 +02:00
2014-01-04 13:43:49 +01:00
const uint8_t WII_LEDS [ ] PROGMEM = {
0x00 , // OFF
2013-03-28 09:46:43 +01:00
0x10 , // LED1
0x20 , // LED2
0x40 , // LED3
0x80 , // LED4
0x90 , // LED5
0xA0 , // LED6
0xC0 , // LED7
0xD0 , // LED8
0xE0 , // LED9
2014-01-04 13:43:49 +01:00
0xF0 , // LED10
2013-03-28 09:46:43 +01:00
} ;
2013-01-27 21:25:50 +01:00
2014-01-04 13:43:49 +01:00
const uint32_t WII_BUTTONS [ ] PROGMEM = {
2013-03-28 09:46:43 +01:00
0x00008 , // UP
0x00002 , // RIGHT
0x00004 , // DOWN
0x00001 , // LEFT
0 , // Skip
0x00010 , // PLUS
0x00100 , // TWO
0x00200 , // ONE
0x01000 , // MINUS
0x08000 , // HOME
0x10000 , // Z
0x20000 , // C
0x00400 , // B
2014-01-04 13:43:49 +01:00
0x00800 , // A
2013-01-27 21:25:50 +01:00
} ;
2014-01-04 13:43:49 +01:00
const uint32_t WII_PROCONTROLLER_BUTTONS [ ] PROGMEM = {
2013-03-28 09:46:43 +01:00
0x00100 , // UP
0x00080 , // RIGHT
0x00040 , // DOWN
0x00200 , // LEFT
0 , // Skip
0x00004 , // PLUS
0x20000 , // L3
0x10000 , // R3
0x00010 , // MINUS
0x00008 , // HOME
0 , 0 , // Skip
0x04000 , // B
0x01000 , // A
0x00800 , // X
0x02000 , // Y
0x00020 , // L
0x00002 , // R
0x08000 , // ZL
2014-01-04 13:43:49 +01:00
0x00400 , // ZR
2013-02-02 22:14:01 +01:00
} ;
2013-01-27 21:25:50 +01:00
2013-03-28 09:46:43 +01:00
WII : : WII ( BTD * p , bool pair ) :
2014-09-02 11:02:17 +02:00
BluetoothService ( p ) // Pointer to USB class instance - mandatory
2012-08-21 14:31:11 +02:00
{
2013-03-28 09:46:43 +01:00
pBtd - > pairWithWii = pair ;
2013-03-28 09:37:09 +01:00
2013-03-28 09:46:43 +01:00
HIDBuffer [ 0 ] = 0xA2 ; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
2013-03-28 09:37:09 +01:00
2013-03-28 09:46:43 +01:00
/* Set device cid for the control and intterrupt channelse - LSB */
2014-09-10 01:32:46 +02:00
control_dcid [ 0 ] = 0x60 ; // 0x0060
2013-03-28 09:46:43 +01:00
control_dcid [ 1 ] = 0x00 ;
2014-09-10 01:32:46 +02:00
interrupt_dcid [ 0 ] = 0x61 ; // 0x0061
2013-03-28 09:46:43 +01:00
interrupt_dcid [ 1 ] = 0x00 ;
2013-03-28 09:37:09 +01:00
2013-03-28 09:46:43 +01:00
Reset ( ) ;
2012-08-21 14:31:11 +02:00
}
2013-03-28 09:46:43 +01:00
2012-08-21 14:31:11 +02:00
void WII : : Reset ( ) {
2013-03-28 09:46:43 +01:00
wiimoteConnected = false ;
nunchuckConnected = false ;
motionPlusConnected = false ;
activateNunchuck = false ;
motionValuesReset = false ;
activeConnection = false ;
2013-07-18 19:43:21 +02:00
motionPlusInside = false ;
2013-03-28 09:46:43 +01:00
pBtd - > wiiUProController = false ;
wiiUProControllerConnected = false ;
2015-04-16 01:57:00 +02:00
wiiBalanceBoardConnected = false ;
2013-03-28 09:46:43 +01:00
l2cap_event_flag = 0 ; // Reset flags
l2cap_state = L2CAP_WAIT ;
2012-08-21 14:31:11 +02:00
}
void WII : : disconnect ( ) { // Use this void to disconnect any of the controllers
2013-12-25 11:09:57 +01:00
if ( ! motionPlusInside ) { // The old Wiimote needs a delay after the first command or it will automatically reconnect
if ( motionPlusConnected ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-07-18 19:43:21 +02:00
Notify ( PSTR ( " \r \n Deactivating Motion Plus " ) , 0x80 ) ;
2013-03-05 18:51:44 +01:00
# endif
2013-07-18 19:43:21 +02:00
initExtension1 ( ) ; // This will disable the Motion Plus extension
}
2017-02-12 16:58:14 +01:00
timer = ( uint32_t ) millis ( ) + 1000 ; // We have to wait for the message before the rest of the channels can be deactivated
2013-07-18 19:43:21 +02:00
} else
2017-02-12 16:58:14 +01:00
timer = ( uint32_t ) millis ( ) ; // Don't wait
2013-07-18 19:43:21 +02:00
// First the HID interrupt channel has to be disconnected, then the HID control channel and finally the HCI connection
2013-12-13 10:38:41 +01:00
pBtd - > l2cap_disconnection_request ( hci_handle , + + identifier , interrupt_scid , interrupt_dcid ) ;
2013-03-28 09:46:43 +01:00
Reset ( ) ;
l2cap_state = L2CAP_INTERRUPT_DISCONNECT ;
2012-08-21 14:31:11 +02:00
}
void WII : : ACLData ( uint8_t * l2capinbuf ) {
2013-12-25 11:09:57 +01:00
if ( ! pBtd - > l2capConnectionClaimed & & pBtd - > incomingWii & & ! wiimoteConnected & & ! activeConnection ) {
if ( l2capinbuf [ 8 ] = = L2CAP_CMD_CONNECTION_REQUEST ) {
if ( ( l2capinbuf [ 12 ] | ( l2capinbuf [ 13 ] < < 8 ) ) = = HID_CTRL_PSM ) {
2013-07-18 19:43:21 +02:00
motionPlusInside = pBtd - > motionPlusInside ;
2013-03-28 09:46:43 +01:00
pBtd - > incomingWii = false ;
pBtd - > l2capConnectionClaimed = true ; // Claim that the incoming connection belongs to this service
activeConnection = true ;
hci_handle = pBtd - > hci_handle ; // Store the HCI Handle for the connection
l2cap_state = L2CAP_WAIT ;
}
}
2013-01-31 21:58:13 +01:00
}
2014-09-10 01:38:42 +02:00
if ( checkHciHandle ( l2capinbuf , hci_handle ) ) { // acl_handle_ok
if ( ( l2capinbuf [ 6 ] | ( l2capinbuf [ 7 ] < < 8 ) ) = = 0x0001U ) { // l2cap_control - Channel ID for ACL-U
2013-12-25 11:09:57 +01:00
if ( l2capinbuf [ 8 ] = = L2CAP_CMD_COMMAND_REJECT ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n L2CAP Command Rejected - Reason: " ) , 0x80 ) ;
2013-06-17 21:37:09 +02:00
D_PrintHex < uint8_t > ( l2capinbuf [ 13 ] , 0x80 ) ;
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " " ) , 0x80 ) ;
2013-06-17 21:37:09 +02:00
D_PrintHex < uint8_t > ( l2capinbuf [ 12 ] , 0x80 ) ;
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " " ) , 0x80 ) ;
2013-06-17 21:37:09 +02:00
D_PrintHex < uint8_t > ( l2capinbuf [ 17 ] , 0x80 ) ;
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " " ) , 0x80 ) ;
2013-06-17 21:37:09 +02:00
D_PrintHex < uint8_t > ( l2capinbuf [ 16 ] , 0x80 ) ;
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " " ) , 0x80 ) ;
2013-06-17 21:37:09 +02:00
D_PrintHex < uint8_t > ( l2capinbuf [ 15 ] , 0x80 ) ;
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " " ) , 0x80 ) ;
2013-06-17 21:37:09 +02:00
D_PrintHex < uint8_t > ( l2capinbuf [ 14 ] , 0x80 ) ;
2012-08-21 14:31:11 +02:00
# endif
2013-12-25 11:09:57 +01:00
} else if ( l2capinbuf [ 8 ] = = L2CAP_CMD_CONNECTION_RESPONSE ) {
if ( ( ( l2capinbuf [ 16 ] | ( l2capinbuf [ 17 ] < < 8 ) ) = = 0x0000 ) & & ( ( l2capinbuf [ 18 ] | ( l2capinbuf [ 19 ] < < 8 ) ) = = SUCCESSFUL ) ) { // Success
if ( l2capinbuf [ 14 ] = = control_dcid [ 0 ] & & l2capinbuf [ 15 ] = = control_dcid [ 1 ] ) {
2013-04-26 23:50:39 +02:00
//Notify(PSTR("\r\nHID Control Connection Complete"), 0x80);
2013-03-28 09:46:43 +01:00
identifier = l2capinbuf [ 9 ] ;
control_scid [ 0 ] = l2capinbuf [ 12 ] ;
control_scid [ 1 ] = l2capinbuf [ 13 ] ;
2013-12-11 09:59:58 +01:00
l2cap_set_flag ( L2CAP_FLAG_CONTROL_CONNECTED ) ;
2013-12-25 11:09:57 +01:00
} else if ( l2capinbuf [ 14 ] = = interrupt_dcid [ 0 ] & & l2capinbuf [ 15 ] = = interrupt_dcid [ 1 ] ) {
2013-04-26 23:50:39 +02:00
//Notify(PSTR("\r\nHID Interrupt Connection Complete"), 0x80);
2013-03-28 09:46:43 +01:00
identifier = l2capinbuf [ 9 ] ;
interrupt_scid [ 0 ] = l2capinbuf [ 12 ] ;
interrupt_scid [ 1 ] = l2capinbuf [ 13 ] ;
2013-12-11 09:59:58 +01:00
l2cap_set_flag ( L2CAP_FLAG_INTERRUPT_CONNECTED ) ;
2013-03-28 09:46:43 +01:00
}
}
2013-12-25 11:09:57 +01:00
} else if ( l2capinbuf [ 8 ] = = L2CAP_CMD_CONNECTION_REQUEST ) {
2012-10-07 14:50:51 +02:00
# ifdef EXTRADEBUG
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n L2CAP Connection Request - PSM: " ) , 0x80 ) ;
2013-06-17 21:37:09 +02:00
D_PrintHex < uint8_t > ( l2capinbuf [ 13 ] , 0x80 ) ;
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " " ) , 0x80 ) ;
2013-06-17 21:37:09 +02:00
D_PrintHex < uint8_t > ( l2capinbuf [ 12 ] , 0x80 ) ;
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " SCID: " ) , 0x80 ) ;
2013-06-17 21:37:09 +02:00
D_PrintHex < uint8_t > ( l2capinbuf [ 15 ] , 0x80 ) ;
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " " ) , 0x80 ) ;
2013-06-17 21:37:09 +02:00
D_PrintHex < uint8_t > ( l2capinbuf [ 14 ] , 0x80 ) ;
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " Identifier: " ) , 0x80 ) ;
2013-06-17 21:37:09 +02:00
D_PrintHex < uint8_t > ( l2capinbuf [ 9 ] , 0x80 ) ;
2012-10-07 14:50:51 +02:00
# endif
2013-12-25 11:09:57 +01:00
if ( ( l2capinbuf [ 12 ] | ( l2capinbuf [ 13 ] < < 8 ) ) = = HID_CTRL_PSM ) {
2013-03-28 09:46:43 +01:00
identifier = l2capinbuf [ 9 ] ;
control_scid [ 0 ] = l2capinbuf [ 14 ] ;
control_scid [ 1 ] = l2capinbuf [ 15 ] ;
2013-12-11 09:59:58 +01:00
l2cap_set_flag ( L2CAP_FLAG_CONNECTION_CONTROL_REQUEST ) ;
2013-12-25 11:09:57 +01:00
} else if ( ( l2capinbuf [ 12 ] | ( l2capinbuf [ 13 ] < < 8 ) ) = = HID_INTR_PSM ) {
2013-03-28 09:46:43 +01:00
identifier = l2capinbuf [ 9 ] ;
interrupt_scid [ 0 ] = l2capinbuf [ 14 ] ;
interrupt_scid [ 1 ] = l2capinbuf [ 15 ] ;
2013-12-11 09:59:58 +01:00
l2cap_set_flag ( L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST ) ;
2013-03-28 09:46:43 +01:00
}
2013-12-25 11:09:57 +01:00
} else if ( l2capinbuf [ 8 ] = = L2CAP_CMD_CONFIG_RESPONSE ) {
if ( ( l2capinbuf [ 16 ] | ( l2capinbuf [ 17 ] < < 8 ) ) = = 0x0000 ) { // Success
if ( l2capinbuf [ 12 ] = = control_dcid [ 0 ] & & l2capinbuf [ 13 ] = = control_dcid [ 1 ] ) {
2013-04-26 23:50:39 +02:00
//Notify(PSTR("\r\nHID Control Configuration Complete"), 0x80);
2013-03-28 09:46:43 +01:00
identifier = l2capinbuf [ 9 ] ;
2013-12-11 09:59:58 +01:00
l2cap_set_flag ( L2CAP_FLAG_CONFIG_CONTROL_SUCCESS ) ;
2013-12-25 11:09:57 +01:00
} else if ( l2capinbuf [ 12 ] = = interrupt_dcid [ 0 ] & & l2capinbuf [ 13 ] = = interrupt_dcid [ 1 ] ) {
2013-04-26 23:50:39 +02:00
//Notify(PSTR("\r\nHID Interrupt Configuration Complete"), 0x80);
2013-03-28 09:46:43 +01:00
identifier = l2capinbuf [ 9 ] ;
2013-12-11 09:59:58 +01:00
l2cap_set_flag ( L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS ) ;
2013-03-28 09:46:43 +01:00
}
}
2013-12-25 11:09:57 +01:00
} else if ( l2capinbuf [ 8 ] = = L2CAP_CMD_CONFIG_REQUEST ) {
if ( l2capinbuf [ 12 ] = = control_dcid [ 0 ] & & l2capinbuf [ 13 ] = = control_dcid [ 1 ] ) {
2013-04-26 23:50:39 +02:00
//Notify(PSTR("\r\nHID Control Configuration Request"), 0x80);
2013-03-28 09:46:43 +01:00
pBtd - > l2cap_config_response ( hci_handle , l2capinbuf [ 9 ] , control_scid ) ;
2013-12-25 11:09:57 +01:00
} else if ( l2capinbuf [ 12 ] = = interrupt_dcid [ 0 ] & & l2capinbuf [ 13 ] = = interrupt_dcid [ 1 ] ) {
2013-04-26 23:50:39 +02:00
//Notify(PSTR("\r\nHID Interrupt Configuration Request"), 0x80);
2013-03-28 09:46:43 +01:00
pBtd - > l2cap_config_response ( hci_handle , l2capinbuf [ 9 ] , interrupt_scid ) ;
}
2013-12-25 11:09:57 +01:00
} else if ( l2capinbuf [ 8 ] = = L2CAP_CMD_DISCONNECT_REQUEST ) {
if ( l2capinbuf [ 12 ] = = control_dcid [ 0 ] & & l2capinbuf [ 13 ] = = control_dcid [ 1 ] ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n Disconnect Request: Control Channel " ) , 0x80 ) ;
2012-08-21 14:31:11 +02:00
# endif
2013-03-28 09:46:43 +01:00
identifier = l2capinbuf [ 9 ] ;
pBtd - > l2cap_disconnection_response ( hci_handle , identifier , control_dcid , control_scid ) ;
Reset ( ) ;
2013-12-25 11:09:57 +01:00
} else if ( l2capinbuf [ 12 ] = = interrupt_dcid [ 0 ] & & l2capinbuf [ 13 ] = = interrupt_dcid [ 1 ] ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n Disconnect Request: Interrupt Channel " ) , 0x80 ) ;
2012-08-21 14:31:11 +02:00
# endif
2013-03-28 09:46:43 +01:00
identifier = l2capinbuf [ 9 ] ;
pBtd - > l2cap_disconnection_response ( hci_handle , identifier , interrupt_dcid , interrupt_scid ) ;
Reset ( ) ;
}
2013-12-25 11:09:57 +01:00
} else if ( l2capinbuf [ 8 ] = = L2CAP_CMD_DISCONNECT_RESPONSE ) {
if ( l2capinbuf [ 12 ] = = control_scid [ 0 ] & & l2capinbuf [ 13 ] = = control_scid [ 1 ] ) {
2013-04-26 23:50:39 +02:00
//Notify(PSTR("\r\nDisconnect Response: Control Channel"), 0x80);
2013-03-28 09:46:43 +01:00
identifier = l2capinbuf [ 9 ] ;
2013-12-11 09:59:58 +01:00
l2cap_set_flag ( L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE ) ;
2013-12-25 11:09:57 +01:00
} else if ( l2capinbuf [ 12 ] = = interrupt_scid [ 0 ] & & l2capinbuf [ 13 ] = = interrupt_scid [ 1 ] ) {
2013-04-26 23:50:39 +02:00
//Notify(PSTR("\r\nDisconnect Response: Interrupt Channel"), 0x80);
2013-03-28 09:46:43 +01:00
identifier = l2capinbuf [ 9 ] ;
2013-12-11 09:59:58 +01:00
l2cap_set_flag ( L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE ) ;
2013-03-28 09:46:43 +01:00
}
}
2012-08-21 14:31:11 +02:00
# ifdef EXTRADEBUG
2013-03-28 09:46:43 +01:00
else {
identifier = l2capinbuf [ 9 ] ;
Notify ( PSTR ( " \r \n L2CAP Unknown Signaling Command: " ) , 0x80 ) ;
2013-06-17 21:37:09 +02:00
D_PrintHex < uint8_t > ( l2capinbuf [ 8 ] , 0x80 ) ;
2012-08-23 23:10:12 +02:00
}
2013-03-28 09:46:43 +01:00
# endif
2013-12-25 11:09:57 +01:00
} else if ( l2capinbuf [ 6 ] = = interrupt_dcid [ 0 ] & & l2capinbuf [ 7 ] = = interrupt_dcid [ 1 ] ) { // l2cap_interrupt
2013-04-26 23:50:39 +02:00
//Notify(PSTR("\r\nL2CAP Interrupt"), 0x80);
2013-12-25 11:09:57 +01:00
if ( l2capinbuf [ 8 ] = = 0xA1 ) { // HID_THDR_DATA_INPUT
if ( ( l2capinbuf [ 9 ] > = 0x20 & & l2capinbuf [ 9 ] < = 0x22 ) | | ( l2capinbuf [ 9 ] > = 0x30 & & l2capinbuf [ 9 ] < = 0x37 ) | | l2capinbuf [ 9 ] = = 0x3e | | l2capinbuf [ 9 ] = = 0x3f ) { // These reports include the buttons
if ( ( l2capinbuf [ 9 ] > = 0x20 & & l2capinbuf [ 9 ] < = 0x22 ) | | l2capinbuf [ 9 ] = = 0x31 | | l2capinbuf [ 9 ] = = 0x33 ) // These reports have no extensions bytes
2013-07-18 19:53:18 +02:00
ButtonState = ( uint32_t ) ( ( l2capinbuf [ 10 ] & 0x1F ) | ( ( uint16_t ) ( l2capinbuf [ 11 ] & 0x9F ) < < 8 ) ) ;
2013-12-25 11:09:57 +01:00
else if ( wiiUProControllerConnected )
2013-07-18 19:53:18 +02:00
ButtonState = ( uint32_t ) ( ( ( ~ l2capinbuf [ 23 ] ) & 0xFE ) | ( ( uint16_t ) ( ~ l2capinbuf [ 24 ] ) < < 8 ) | ( ( uint32_t ) ( ( ~ l2capinbuf [ 25 ] ) & 0x03 ) < < 16 ) ) ;
2013-12-25 11:09:57 +01:00
else if ( motionPlusConnected ) {
2015-04-16 20:19:33 +02:00
if ( l2capinbuf [ 20 ] & 0x02 ) // Only update the Wiimote buttons, since the extension bytes are from the Motion Plus
2013-07-18 19:53:18 +02:00
ButtonState = ( uint32_t ) ( ( l2capinbuf [ 10 ] & 0x1F ) | ( ( uint16_t ) ( l2capinbuf [ 11 ] & 0x9F ) < < 8 ) | ( ( uint32_t ) ( ButtonState & 0xFFFF0000 ) ) ) ;
2013-12-25 11:09:57 +01:00
else if ( nunchuckConnected ) // Update if it's a report from the Nunchuck
2013-07-18 19:53:18 +02:00
ButtonState = ( uint32_t ) ( ( l2capinbuf [ 10 ] & 0x1F ) | ( ( uint16_t ) ( l2capinbuf [ 11 ] & 0x9F ) < < 8 ) | ( ( uint32_t ) ( ( ~ l2capinbuf [ 20 ] ) & 0x0C ) < < 14 ) ) ;
//else if(classicControllerConnected) // Update if it's a report from the Classic Controller
2013-12-25 11:09:57 +01:00
} else if ( nunchuckConnected ) // The Nunchuck is directly connected
2013-07-18 19:53:18 +02:00
ButtonState = ( uint32_t ) ( ( l2capinbuf [ 10 ] & 0x1F ) | ( ( uint16_t ) ( l2capinbuf [ 11 ] & 0x9F ) < < 8 ) | ( ( uint32_t ) ( ( ~ l2capinbuf [ 20 ] ) & 0x03 ) < < 16 ) ) ;
//else if(classicControllerConnected) // The Classic Controller is directly connected
2013-12-25 11:09:57 +01:00
else if ( ! unknownExtensionConnected )
2013-07-18 19:53:18 +02:00
ButtonState = ( uint32_t ) ( ( l2capinbuf [ 10 ] & 0x1F ) | ( ( uint16_t ) ( l2capinbuf [ 11 ] & 0x9F ) < < 8 ) ) ;
2012-08-21 17:36:37 +02:00
# ifdef PRINTREPORT
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " ButtonState: " ) , 0x80 ) ;
D_PrintHex < uint32_t > ( ButtonState , 0x80 ) ;
Notify ( PSTR ( " \r \n " ) , 0x80 ) ;
2012-08-21 17:36:37 +02:00
# endif
2013-12-25 11:09:57 +01:00
if ( ButtonState ! = OldButtonState ) {
2013-07-18 19:53:18 +02:00
ButtonClickState = ButtonState & ~ OldButtonState ; // Update click state variable
OldButtonState = ButtonState ;
2013-03-28 09:46:43 +01:00
}
2013-07-18 19:53:18 +02:00
}
2013-12-25 11:09:57 +01:00
if ( l2capinbuf [ 9 ] = = 0x31 | | l2capinbuf [ 9 ] = = 0x33 | | l2capinbuf [ 9 ] = = 0x35 | | l2capinbuf [ 9 ] = = 0x37 ) { // Read the accelerometer
2013-10-21 18:41:47 +02:00
accXwiimote = ( ( l2capinbuf [ 12 ] < < 2 ) | ( l2capinbuf [ 10 ] & 0x60 > > 5 ) ) - 500 ;
accYwiimote = ( ( l2capinbuf [ 13 ] < < 2 ) | ( l2capinbuf [ 11 ] & 0x20 > > 4 ) ) - 500 ;
accZwiimote = ( ( l2capinbuf [ 14 ] < < 2 ) | ( l2capinbuf [ 11 ] & 0x40 > > 5 ) ) - 500 ;
2013-07-18 19:53:18 +02:00
}
2013-12-25 11:09:57 +01:00
switch ( l2capinbuf [ 9 ] ) {
2013-07-18 19:53:18 +02:00
case 0x20 : // Status Information - (a1) 20 BB BB LF 00 00 VV
2013-07-18 19:43:21 +02:00
# ifdef EXTRADEBUG
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " \r \n Status report was received " ) , 0x80 ) ;
2013-07-18 19:43:21 +02:00
# endif
2013-07-18 19:53:18 +02:00
wiiState = 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)
batteryLevel = l2capinbuf [ 15 ] ; // Update battery level
2015-04-16 16:50:08 +02:00
if ( ! checkBatteryLevel ) { // If this is true it means that the user must have called getBatteryLevel()
2013-12-25 11:09:57 +01:00
if ( l2capinbuf [ 12 ] & 0x02 ) { // Check if a extension is connected
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-12-25 11:09:57 +01:00
if ( ! unknownExtensionConnected )
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " \r \n Extension connected " ) , 0x80 ) ;
2012-08-22 23:41:38 +02:00
# endif
2013-07-18 19:53:18 +02:00
unknownExtensionConnected = true ;
2013-01-24 00:23:09 +01:00
# ifdef WIICAMERA
2013-12-25 11:09:57 +01:00
if ( ! isIRCameraEnabled ( ) ) // Don't activate the Motion Plus if we are trying to initialize the IR camera
2013-03-28 09:37:09 +01:00
# endif
2013-12-25 11:09:57 +01:00
setReportMode ( false , 0x35 ) ; // Also read the extension
2013-07-18 19:53:18 +02:00
} else {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " \r \n Extension disconnected " ) , 0x80 ) ;
2012-08-22 23:41:38 +02:00
# endif
2013-12-25 11:09:57 +01:00
if ( motionPlusConnected ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " - from Motion Plus " ) , 0x80 ) ;
2012-08-23 23:10:12 +02:00
# endif
2013-12-11 09:59:58 +01:00
wii_clear_flag ( WII_FLAG_NUNCHUCK_CONNECTED ) ;
2013-12-25 11:09:57 +01:00
if ( ! activateNunchuck ) // If it's already trying to initialize the Nunchuck don't set it to false
2013-07-18 19:53:18 +02:00
nunchuckConnected = false ;
//else if(classicControllerConnected)
2013-12-25 11:09:57 +01:00
} else if ( nunchuckConnected ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " - Nunchuck " ) , 0x80 ) ;
2012-08-23 23:10:12 +02:00
# endif
2013-07-18 19:53:18 +02:00
nunchuckConnected = false ; // It must be the Nunchuck controller then
2013-12-11 09:59:58 +01:00
wii_clear_flag ( WII_FLAG_NUNCHUCK_CONNECTED ) ;
2013-07-18 19:53:18 +02:00
onInit ( ) ;
2016-07-02 19:42:32 +02:00
# ifdef WIICAMERA
if ( ! isIRCameraEnabled ( ) ) // We still want to read from the IR camera, so do not change the report mode
# endif
setReportMode ( false , 0x31 ) ; // If there is no extension connected we will read the buttons and accelerometer
} else {
# ifdef WIICAMERA
if ( ! isIRCameraEnabled ( ) ) // We still want to read from the IR camera, so do not change the report mode
# endif
setReportMode ( false , 0x31 ) ; // If there is no extension connected we will read the buttons and accelerometer
}
2013-07-18 19:53:18 +02:00
}
2015-04-16 16:50:08 +02:00
}
2015-04-20 23:40:34 +02:00
else {
2015-04-16 20:19:33 +02:00
# ifdef EXTRADEBUG
2015-04-16 16:50:08 +02:00
Notify ( PSTR ( " \r \n Checking battery level " ) , 0x80 ) ;
2015-04-16 20:19:33 +02:00
# endif
2015-04-20 23:40:34 +02:00
checkBatteryLevel = false ; // Check for extensions by default
}
2015-04-16 20:19:33 +02:00
# ifdef DEBUG_USB_HOST
2015-04-16 16:50:08 +02:00
if ( l2capinbuf [ 12 ] & 0x01 )
Notify ( PSTR ( " \r \n WARNING: Battery is nearly empty " ) , 0x80 ) ;
# endif
2013-07-18 19:53:18 +02:00
break ;
case 0x21 : // Read Memory Data
2013-12-25 11:09:57 +01:00
if ( ( l2capinbuf [ 12 ] & 0x0F ) = = 0 ) { // No error
2015-04-16 16:55:35 +02:00
uint8_t reportLength = ( l2capinbuf [ 12 ] > > 4 ) + 1 ; // // Bit 4-7 is the length - 1
2013-07-18 19:53:18 +02:00
// See: http://wiibrew.org/wiki/Wiimote/Extension_Controllers
2013-12-25 11:09:57 +01:00
if ( l2capinbuf [ 16 ] = = 0x00 & & l2capinbuf [ 17 ] = = 0xA4 & & l2capinbuf [ 18 ] = = 0x20 & & l2capinbuf [ 19 ] = = 0x00 & & l2capinbuf [ 20 ] = = 0x00 ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " \r \n Nunchuck connected " ) , 0x80 ) ;
2012-08-23 23:10:12 +02:00
# endif
2013-12-11 09:59:58 +01:00
wii_set_flag ( WII_FLAG_NUNCHUCK_CONNECTED ) ;
2013-12-25 11:09:57 +01:00
} else if ( l2capinbuf [ 16 ] = = 0x00 & & ( l2capinbuf [ 17 ] = = 0xA6 | | l2capinbuf [ 17 ] = = 0xA4 ) & & l2capinbuf [ 18 ] = = 0x20 & & l2capinbuf [ 19 ] = = 0x00 & & l2capinbuf [ 20 ] = = 0x05 ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " \r \n Motion Plus connected " ) , 0x80 ) ;
2012-08-23 23:10:12 +02:00
# endif
2013-12-11 09:59:58 +01:00
wii_set_flag ( WII_FLAG_MOTION_PLUS_CONNECTED ) ;
2013-12-25 11:09:57 +01:00
} else if ( l2capinbuf [ 16 ] = = 0x00 & & l2capinbuf [ 17 ] = = 0xA4 & & l2capinbuf [ 18 ] = = 0x20 & & l2capinbuf [ 19 ] = = 0x04 & & l2capinbuf [ 20 ] = = 0x05 ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " \r \n Motion Plus activated in normal mode " ) , 0x80 ) ;
2012-08-22 23:41:38 +02:00
# endif
2013-07-18 19:53:18 +02:00
motionPlusConnected = true ;
2013-08-13 22:31:51 +02:00
# ifdef WIICAMERA
2013-12-25 11:09:57 +01:00
if ( ! isIRCameraEnabled ( ) ) // Don't activate the Motion Plus if we are trying to initialize the IR camera
2013-08-13 22:31:51 +02:00
# endif
setReportMode ( false , 0x35 ) ; // Also read the extension
2013-12-25 11:09:57 +01:00
} else if ( l2capinbuf [ 16 ] = = 0x00 & & l2capinbuf [ 17 ] = = 0xA4 & & l2capinbuf [ 18 ] = = 0x20 & & l2capinbuf [ 19 ] = = 0x05 & & l2capinbuf [ 20 ] = = 0x05 ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " \r \n Motion Plus activated in Nunchuck pass-through mode " ) , 0x80 ) ;
2012-08-22 23:41:38 +02:00
# endif
2013-07-18 19:53:18 +02:00
activateNunchuck = false ;
motionPlusConnected = true ;
nunchuckConnected = true ;
2013-08-13 22:31:51 +02:00
# ifdef WIICAMERA
2013-12-25 11:09:57 +01:00
if ( ! isIRCameraEnabled ( ) ) // Don't activate the Motion Plus if we are trying to initialize the IR camera
2013-08-13 22:31:51 +02:00
# endif
setReportMode ( false , 0x35 ) ; // Also read the extension
2013-12-25 11:09:57 +01:00
} else if ( l2capinbuf [ 16 ] = = 0x00 & & l2capinbuf [ 17 ] = = 0xA6 & & l2capinbuf [ 18 ] = = 0x20 & & ( l2capinbuf [ 19 ] = = 0x00 | | l2capinbuf [ 19 ] = = 0x04 | | l2capinbuf [ 19 ] = = 0x05 | | l2capinbuf [ 19 ] = = 0x07 ) & & l2capinbuf [ 20 ] = = 0x05 ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " \r \n Inactive Wii Motion Plus " ) , 0x80 ) ;
Notify ( PSTR ( " \r \n Please unplug the Motion Plus, disconnect the Wiimote and then replug the Motion Plus Extension " ) , 0x80 ) ;
2012-10-07 20:07:48 +02:00
# endif
2013-12-11 09:29:38 +01:00
stateCounter = 300 ; // Skip the rest in "WII_CHECK_MOTION_PLUS_STATE"
2013-12-25 11:09:57 +01:00
} else if ( l2capinbuf [ 16 ] = = 0x00 & & l2capinbuf [ 17 ] = = 0xA4 & & l2capinbuf [ 18 ] = = 0x20 & & l2capinbuf [ 19 ] = = 0x01 & & l2capinbuf [ 20 ] = = 0x20 ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " \r \n Wii U Pro Controller connected " ) , 0x80 ) ;
2012-08-23 23:10:12 +02:00
# endif
2013-07-18 19:53:18 +02:00
wiiUProControllerConnected = true ;
2015-04-16 01:57:00 +02:00
} else if ( l2capinbuf [ 16 ] = = 0x00 & & l2capinbuf [ 17 ] = = 0xA4 & & l2capinbuf [ 18 ] = = 0x20 & & l2capinbuf [ 19 ] = = 0x04 & & l2capinbuf [ 20 ] = = 0x02 ) {
# ifdef DEBUG_USB_HOST
Notify ( PSTR ( " \r \n Wii Balance Board connected " ) , 0x80 ) ;
# endif
setReportMode ( false , 0x32 ) ; // Read the Wii Balance Board extension
2015-04-20 23:39:57 +02:00
wii_set_flag ( WII_FLAG_CALIBRATE_BALANCE_BOARD ) ;
2013-03-28 09:46:43 +01:00
}
2015-04-16 16:55:35 +02:00
// Wii Balance Board calibration reports (24 bits in total)
else if ( l2capinbuf [ 13 ] = = 0x00 & & l2capinbuf [ 14 ] = = 0x24 & & reportLength = = 16 ) { // First 16-bit
for ( uint8_t i = 0 ; i < 2 ; i + + ) {
for ( uint8_t j = 0 ; j < 4 ; j + + )
2015-04-16 19:45:03 +02:00
wiiBalanceBoardCal [ i ] [ j ] = l2capinbuf [ 16 + 8 * i + 2 * j ] | l2capinbuf [ 15 + 8 * i + 2 * j ] < < 8 ;
2015-04-16 16:55:35 +02:00
}
} else if ( l2capinbuf [ 13 ] = = 0x00 & & l2capinbuf [ 14 ] = = 0x34 & & reportLength = = 8 ) { // Last 8-bit
for ( uint8_t j = 0 ; j < 4 ; j + + )
2015-04-16 19:45:03 +02:00
wiiBalanceBoardCal [ 2 ] [ j ] = l2capinbuf [ 16 + 2 * j ] | l2capinbuf [ 15 + 2 * j ] < < 8 ;
2015-04-16 16:55:35 +02:00
# ifdef DEBUG_USB_HOST
2015-04-16 20:19:33 +02:00
Notify ( PSTR ( " \r \n Wii Balance Board calibration values read successfully " ) , 0x80 ) ;
2015-04-16 16:55:35 +02:00
# endif
2015-04-20 23:39:57 +02:00
wii_clear_flag ( WII_FLAG_CALIBRATE_BALANCE_BOARD ) ;
wiiBalanceBoardConnected = true ;
2015-04-16 16:55:35 +02:00
}
2013-07-18 19:53:18 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
else {
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " \r \n Unknown Device: " ) , 0x80 ) ;
2013-06-17 21:37:09 +02:00
D_PrintHex < uint8_t > ( l2capinbuf [ 13 ] , 0x80 ) ;
D_PrintHex < uint8_t > ( l2capinbuf [ 14 ] , 0x80 ) ;
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " \r \n Data: " ) , 0x80 ) ;
2015-04-16 16:55:35 +02:00
for ( uint8_t i = 0 ; i < reportLength ; i + + ) {
2013-07-18 19:53:18 +02:00
D_PrintHex < uint8_t > ( l2capinbuf [ 15 + i ] , 0x80 ) ;
Notify ( PSTR ( " " ) , 0x80 ) ;
}
2013-03-28 09:46:43 +01:00
}
2012-08-23 23:10:12 +02:00
# endif
2013-07-18 19:53:18 +02:00
}
# ifdef EXTRADEBUG
else {
Notify ( PSTR ( " \r \n Report Error: " ) , 0x80 ) ;
D_PrintHex < uint8_t > ( l2capinbuf [ 13 ] , 0x80 ) ;
D_PrintHex < uint8_t > ( l2capinbuf [ 14 ] , 0x80 ) ;
}
# endif
break ;
case 0x22 : // Acknowledge output report, return function result
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-12-25 11:09:57 +01:00
if ( l2capinbuf [ 13 ] ! = 0x00 ) { // Check if there is an error
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " \r \n Command failed: " ) , 0x80 ) ;
D_PrintHex < uint8_t > ( l2capinbuf [ 12 ] , 0x80 ) ;
}
2013-03-28 09:37:09 +01:00
# endif
2013-07-18 19:53:18 +02:00
break ;
case 0x30 : // Core buttons - (a1) 30 BB BB
break ;
case 0x31 : // Core Buttons and Accelerometer - (a1) 31 BB BB AA AA AA
break ;
2015-04-16 02:26:18 +02:00
case 0x32 : // Core Buttons with 8 Extension bytes - (a1) 32 BB BB EE EE EE EE EE EE EE EE
// See: http://wiibrew.org/wiki/Wii_Balance_Board#Data_Format
2015-04-16 19:45:03 +02:00
wiiBalanceBoardRaw [ TopRight ] = l2capinbuf [ 13 ] | l2capinbuf [ 12 ] < < 8 ; // Top right
wiiBalanceBoardRaw [ BotRight ] = l2capinbuf [ 15 ] | l2capinbuf [ 14 ] < < 8 ; // Bottom right
wiiBalanceBoardRaw [ TopLeft ] = l2capinbuf [ 17 ] | l2capinbuf [ 16 ] < < 8 ; // Top left
wiiBalanceBoardRaw [ BotLeft ] = l2capinbuf [ 19 ] | l2capinbuf [ 18 ] < < 8 ; // Bottom left
2015-04-16 02:26:18 +02:00
break ;
2013-07-18 19:53:18 +02:00
case 0x33 : // Core Buttons with Accelerometer and 12 IR bytes - (a1) 33 BB BB AA AA AA II II II II II II II II II II II II
2013-01-17 00:07:56 +01:00
# ifdef WIICAMERA
2013-07-18 19:53:18 +02:00
// Read the IR data
IR_object_x1 = ( l2capinbuf [ 15 ] | ( ( uint16_t ) ( l2capinbuf [ 17 ] & 0x30 ) < < 4 ) ) ; // x position
IR_object_y1 = ( l2capinbuf [ 16 ] | ( ( uint16_t ) ( l2capinbuf [ 17 ] & 0xC0 ) < < 2 ) ) ; // y position
2015-04-16 02:15:52 +02:00
IR_object_s1 = ( l2capinbuf [ 17 ] & 0x0F ) ; // Size value, 0-15
2013-07-18 19:53:18 +02:00
IR_object_x2 = ( l2capinbuf [ 18 ] | ( ( uint16_t ) ( l2capinbuf [ 20 ] & 0x30 ) < < 4 ) ) ;
IR_object_y2 = ( l2capinbuf [ 19 ] | ( ( uint16_t ) ( l2capinbuf [ 20 ] & 0xC0 ) < < 2 ) ) ;
IR_object_s2 = ( l2capinbuf [ 20 ] & 0x0F ) ;
IR_object_x3 = ( l2capinbuf [ 21 ] | ( ( uint16_t ) ( l2capinbuf [ 23 ] & 0x30 ) < < 4 ) ) ;
IR_object_y3 = ( l2capinbuf [ 22 ] | ( ( uint16_t ) ( l2capinbuf [ 23 ] & 0xC0 ) < < 2 ) ) ;
IR_object_s3 = ( l2capinbuf [ 23 ] & 0x0F ) ;
IR_object_x4 = ( l2capinbuf [ 24 ] | ( ( uint16_t ) ( l2capinbuf [ 26 ] & 0x30 ) < < 4 ) ) ;
IR_object_y4 = ( l2capinbuf [ 25 ] | ( ( uint16_t ) ( l2capinbuf [ 26 ] & 0xC0 ) < < 2 ) ) ;
IR_object_s4 = ( l2capinbuf [ 26 ] & 0x0F ) ;
2013-01-17 00:07:56 +01:00
# endif
2013-07-18 19:53:18 +02:00
break ;
case 0x34 : // Core Buttons with 19 Extension bytes - (a1) 34 BB BB EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
break ;
/* 0x3e and 0x3f both give unknown report types when report mode is 0x3e or 0x3f with mode number 0x05 */
case 0x3E : // Core Buttons with Accelerometer and 32 IR bytes
// (a1) 31 BB BB AA AA AA II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II
// corresponds to output report mode 0x3e
/**** for reading in full mode: DOES NOT WORK YET ****/
/* When it works it will also have intensity and bounding box data */
/*
IR_object_x1 = ( l2capinbuf [ 13 ] | ( ( uint16_t ) ( l2capinbuf [ 15 ] & 0x30 ) < < 4 ) ) ;
IR_object_y1 = ( l2capinbuf [ 14 ] | ( ( uint16_t ) ( l2capinbuf [ 15 ] & 0xC0 ) < < 2 ) ) ;
IR_object_s1 = ( l2capinbuf [ 15 ] & 0x0F ) ;
*/
break ;
case 0x3F :
/*
IR_object_x1 = ( l2capinbuf [ 13 ] | ( ( uint16_t ) ( l2capinbuf [ 15 ] & 0x30 ) < < 4 ) ) ;
IR_object_y1 = ( l2capinbuf [ 14 ] | ( ( uint16_t ) ( l2capinbuf [ 15 ] & 0xC0 ) < < 2 ) ) ;
IR_object_s1 = ( l2capinbuf [ 15 ] & 0x0F ) ;
*/
break ;
case 0x35 : // Core Buttons and Accelerometer with 16 Extension Bytes
// (a1) 35 BB BB AA AA AA EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
2015-04-16 20:20:27 +02:00
# if 1 // Set this to 0 if you don't want to use an extension, this reduceds the size of the library a lot!
2013-12-25 11:09:57 +01:00
if ( motionPlusConnected ) {
if ( l2capinbuf [ 20 ] & 0x02 ) { // Check if it's a report from the Motion controller or the extension
if ( motionValuesReset ) { // We will only use the values when the gyro value has been set
2013-07-18 19:53:18 +02:00
gyroYawRaw = ( ( l2capinbuf [ 15 ] | ( ( l2capinbuf [ 18 ] & 0xFC ) < < 6 ) ) - gyroYawZero ) ;
gyroRollRaw = ( ( l2capinbuf [ 16 ] | ( ( l2capinbuf [ 19 ] & 0xFC ) < < 6 ) ) - gyroRollZero ) ;
gyroPitchRaw = ( ( l2capinbuf [ 17 ] | ( ( l2capinbuf [ 20 ] & 0xFC ) < < 6 ) ) - gyroPitchZero ) ;
2015-10-12 13:20:48 +02:00
yawGyroSpeed = ( float ) gyroYawRaw / ( ( float ) gyroYawZero / yawGyroScale ) ;
rollGyroSpeed = - ( float ) gyroRollRaw / ( ( float ) gyroRollZero / rollGyroScale ) ; // We invert these values so they will fit the acc values
pitchGyroSpeed = ( float ) gyroPitchRaw / ( ( float ) gyroPitchZero / pitchGyroScale ) ;
2013-07-18 19:53:18 +02:00
/* The onboard gyro has two ranges for slow and fast mode */
2013-12-25 11:09:57 +01:00
if ( ! ( l2capinbuf [ 18 ] & 0x02 ) ) // Check if fast mode is used
2013-07-18 19:53:18 +02:00
yawGyroSpeed * = 4.545 ;
2013-12-25 11:09:57 +01:00
if ( ! ( l2capinbuf [ 18 ] & 0x01 ) ) // Check if fast mode is used
2013-07-18 19:53:18 +02:00
pitchGyroSpeed * = 4.545 ;
2013-12-25 11:09:57 +01:00
if ( ! ( l2capinbuf [ 19 ] & 0x02 ) ) // Check if fast mode is used
2013-07-18 19:53:18 +02:00
rollGyroSpeed * = 4.545 ;
2017-02-12 16:58:14 +01:00
compPitch = ( 0.93f * ( compPitch + ( pitchGyroSpeed * ( float ) ( ( uint32_t ) micros ( ) - timer ) / 1000000.0f ) ) ) + ( 0.07f * getWiimotePitch ( ) ) ; // Use a complimentary filter to calculate the angle
compRoll = ( 0.93f * ( compRoll + ( rollGyroSpeed * ( float ) ( ( uint32_t ) micros ( ) - timer ) / 1000000.0f ) ) ) + ( 0.07f * getWiimoteRoll ( ) ) ;
2013-07-18 19:53:18 +02:00
2017-02-12 16:58:14 +01:00
gyroYaw + = ( yawGyroSpeed * ( ( float ) ( ( uint32_t ) micros ( ) - timer ) / 1000000.0f ) ) ;
gyroRoll + = ( rollGyroSpeed * ( ( float ) ( ( uint32_t ) micros ( ) - timer ) / 1000000.0f ) ) ;
gyroPitch + = ( pitchGyroSpeed * ( ( float ) ( ( uint32_t ) micros ( ) - timer ) / 1000000.0f ) ) ;
timer = ( uint32_t ) micros ( ) ;
2013-07-18 19:53:18 +02:00
/*
// Uncomment these lines to tune the gyro scale variabels
Notify ( PSTR ( " \r \n gyroYaw: " ) , 0x80 ) ;
Notify ( gyroYaw , 0x80 ) ;
Notify ( PSTR ( " \t gyroRoll: " ) , 0x80 ) ;
Notify ( gyroRoll , 0x80 ) ;
Notify ( PSTR ( " \t gyroPitch: " ) , 0x80 ) ;
Notify ( gyroPitch , 0x80 ) ;
2013-12-25 11:09:57 +01:00
*/
2013-07-18 19:53:18 +02:00
/*
Notify ( PSTR ( " \t wiimoteRoll: " ) , 0x80 ) ;
Notify ( wiimoteRoll , 0x80 ) ;
Notify ( PSTR ( " \t wiimotePitch: " ) , 0x80 ) ;
Notify ( wiimotePitch , 0x80 ) ;
2013-12-25 11:09:57 +01:00
*/
2013-07-18 19:53:18 +02:00
} else {
2017-02-12 16:58:14 +01:00
if ( ( int32_t ) ( ( uint32_t ) micros ( ) - timer ) > 1000000 ) { // Loop for 1 sec before resetting the values
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " \r \n The gyro values has been reset " ) , 0x80 ) ;
2012-08-23 23:10:12 +02:00
# endif
2013-07-18 19:53:18 +02:00
gyroYawZero = ( l2capinbuf [ 15 ] | ( ( l2capinbuf [ 18 ] & 0xFC ) < < 6 ) ) ;
gyroRollZero = ( l2capinbuf [ 16 ] | ( ( l2capinbuf [ 19 ] & 0xFC ) < < 6 ) ) ;
gyroPitchZero = ( l2capinbuf [ 17 ] | ( ( l2capinbuf [ 20 ] & 0xFC ) < < 6 ) ) ;
2013-03-28 09:46:43 +01:00
2013-07-18 19:53:18 +02:00
rollGyroScale = 500 ; // You might need to adjust these
pitchGyroScale = 400 ;
yawGyroScale = 415 ;
2013-03-28 09:46:43 +01:00
2013-07-18 19:53:18 +02:00
gyroYaw = 0 ;
gyroRoll = 0 ;
gyroPitch = 0 ;
2013-03-28 09:46:43 +01:00
2013-07-18 19:53:18 +02:00
motionValuesReset = true ;
2017-02-12 16:58:14 +01:00
timer = ( uint32_t ) micros ( ) ;
2013-03-28 09:46:43 +01:00
}
}
2013-07-18 19:53:18 +02:00
} else {
2013-12-25 11:09:57 +01:00
if ( nunchuckConnected ) {
2013-07-18 19:53:18 +02:00
hatValues [ HatX ] = l2capinbuf [ 15 ] ;
hatValues [ HatY ] = l2capinbuf [ 16 ] ;
2013-10-21 18:41:47 +02:00
accXnunchuck = ( ( l2capinbuf [ 17 ] < < 2 ) | ( l2capinbuf [ 20 ] & 0x10 > > 3 ) ) - 416 ;
accYnunchuck = ( ( l2capinbuf [ 18 ] < < 2 ) | ( l2capinbuf [ 20 ] & 0x20 > > 4 ) ) - 416 ;
accZnunchuck = ( ( ( l2capinbuf [ 19 ] & 0xFE ) < < 2 ) | ( l2capinbuf [ 20 ] & 0xC0 > > 5 ) ) - 416 ;
2013-07-18 19:53:18 +02:00
}
//else if(classicControllerConnected) { }
}
2013-12-25 11:09:57 +01:00
if ( l2capinbuf [ 19 ] & 0x01 ) {
if ( ! extensionConnected ) {
2013-07-18 19:53:18 +02:00
extensionConnected = true ;
unknownExtensionConnected = true ;
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " \r \n Extension connected to Motion Plus " ) , 0x80 ) ;
2012-08-24 00:59:43 +02:00
# endif
2013-07-18 19:53:18 +02:00
}
} else {
2013-12-25 11:09:57 +01:00
if ( extensionConnected & & ! unknownExtensionConnected ) {
2013-07-18 19:53:18 +02:00
extensionConnected = false ;
unknownExtensionConnected = true ;
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-07-18 19:53:18 +02:00
Notify ( PSTR ( " \r \n Extension disconnected from Motion Plus " ) , 0x80 ) ;
2012-08-24 00:59:43 +02:00
# endif
2013-07-18 19:53:18 +02:00
nunchuckConnected = false ; // There is no extension connected to the Motion Plus if this report is sent
2013-03-28 09:46:43 +01:00
}
}
2013-07-18 19:53:18 +02:00
2013-12-25 11:09:57 +01:00
} else if ( nunchuckConnected ) {
2013-07-18 19:53:18 +02:00
hatValues [ HatX ] = l2capinbuf [ 15 ] ;
hatValues [ HatY ] = l2capinbuf [ 16 ] ;
2013-10-21 18:41:47 +02:00
accXnunchuck = ( ( l2capinbuf [ 17 ] < < 2 ) | ( l2capinbuf [ 20 ] & 0x0C > > 2 ) ) - 416 ;
accYnunchuck = ( ( l2capinbuf [ 18 ] < < 2 ) | ( l2capinbuf [ 20 ] & 0x30 > > 4 ) ) - 416 ;
accZnunchuck = ( ( l2capinbuf [ 19 ] < < 2 ) | ( l2capinbuf [ 20 ] & 0xC0 > > 6 ) ) - 416 ;
2013-12-25 11:09:57 +01:00
} else if ( wiiUProControllerConnected ) {
2013-07-18 19:53:18 +02:00
hatValues [ LeftHatX ] = ( l2capinbuf [ 15 ] | l2capinbuf [ 16 ] < < 8 ) ;
hatValues [ RightHatX ] = ( l2capinbuf [ 17 ] | l2capinbuf [ 18 ] < < 8 ) ;
hatValues [ LeftHatY ] = ( l2capinbuf [ 19 ] | l2capinbuf [ 20 ] < < 8 ) ;
hatValues [ RightHatY ] = ( l2capinbuf [ 21 ] | l2capinbuf [ 22 ] < < 8 ) ;
}
2015-04-16 20:20:27 +02:00
# endif
2013-07-18 19:53:18 +02:00
break ;
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-07-18 19:53:18 +02:00
default :
Notify ( PSTR ( " \r \n Unknown Report type: " ) , 0x80 ) ;
D_PrintHex < uint8_t > ( l2capinbuf [ 9 ] , 0x80 ) ;
break ;
2012-08-21 14:31:11 +02:00
# endif
2013-03-28 09:46:43 +01:00
}
2013-07-18 19:53:18 +02:00
}
2012-08-21 14:31:11 +02:00
}
2013-03-28 09:46:43 +01:00
L2CAP_task ( ) ;
2012-08-21 14:31:11 +02:00
}
}
2013-03-28 09:46:43 +01:00
2012-08-21 14:31:11 +02:00
void WII : : L2CAP_task ( ) {
2013-12-25 11:09:57 +01:00
switch ( l2cap_state ) {
2013-03-28 09:46:43 +01:00
/* These states are used if the Wiimote is the host */
case L2CAP_CONTROL_SUCCESS :
2013-12-25 11:09:57 +01:00
if ( l2cap_check_flag ( L2CAP_FLAG_CONFIG_CONTROL_SUCCESS ) ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n HID Control Successfully Configured " ) , 0x80 ) ;
2012-10-07 14:50:51 +02:00
# endif
2013-03-28 09:46:43 +01:00
l2cap_state = L2CAP_INTERRUPT_SETUP ;
}
break ;
2013-03-28 09:37:09 +01:00
2013-03-28 09:46:43 +01:00
case L2CAP_INTERRUPT_SETUP :
2013-12-25 11:09:57 +01:00
if ( l2cap_check_flag ( L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST ) ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n HID Interrupt Incoming Connection Request " ) , 0x80 ) ;
2012-10-07 14:50:51 +02:00
# endif
2013-03-28 09:46:43 +01:00
pBtd - > l2cap_connection_response ( hci_handle , identifier , interrupt_dcid , interrupt_scid , PENDING ) ;
delay ( 1 ) ;
pBtd - > l2cap_connection_response ( hci_handle , identifier , interrupt_dcid , interrupt_scid , SUCCESSFUL ) ;
identifier + + ;
delay ( 1 ) ;
pBtd - > l2cap_config_request ( hci_handle , identifier , interrupt_scid ) ;
l2cap_state = L2CAP_INTERRUPT_CONFIG_REQUEST ;
}
break ;
/* These states are used if the Arduino is the host */
case L2CAP_CONTROL_CONNECT_REQUEST :
2013-12-25 11:09:57 +01:00
if ( l2cap_check_flag ( L2CAP_FLAG_CONTROL_CONNECTED ) ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n Send HID Control Config Request " ) , 0x80 ) ;
2012-08-21 14:31:11 +02:00
# endif
2013-03-28 09:46:43 +01:00
identifier + + ;
pBtd - > l2cap_config_request ( hci_handle , identifier , control_scid ) ;
l2cap_state = L2CAP_CONTROL_CONFIG_REQUEST ;
}
break ;
case L2CAP_CONTROL_CONFIG_REQUEST :
2013-12-25 11:09:57 +01:00
if ( l2cap_check_flag ( L2CAP_FLAG_CONFIG_CONTROL_SUCCESS ) ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n Send HID Interrupt Connection Request " ) , 0x80 ) ;
2012-08-21 14:31:11 +02:00
# endif
2013-03-28 09:46:43 +01:00
identifier + + ;
pBtd - > l2cap_connection_request ( hci_handle , identifier , interrupt_dcid , HID_INTR_PSM ) ;
l2cap_state = L2CAP_INTERRUPT_CONNECT_REQUEST ;
}
break ;
case L2CAP_INTERRUPT_CONNECT_REQUEST :
2013-12-25 11:09:57 +01:00
if ( l2cap_check_flag ( L2CAP_FLAG_INTERRUPT_CONNECTED ) ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n Send HID Interrupt Config Request " ) , 0x80 ) ;
2012-08-21 14:31:11 +02:00
# endif
2013-03-28 09:46:43 +01:00
identifier + + ;
pBtd - > l2cap_config_request ( hci_handle , identifier , interrupt_scid ) ;
l2cap_state = L2CAP_INTERRUPT_CONFIG_REQUEST ;
}
break ;
case L2CAP_INTERRUPT_CONFIG_REQUEST :
2013-12-25 11:09:57 +01:00
if ( l2cap_check_flag ( L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS ) ) { // Now the HID channels is established
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n HID Channels Established " ) , 0x80 ) ;
2012-08-21 14:31:11 +02:00
# endif
2013-03-28 09:46:43 +01:00
pBtd - > connectToWii = false ;
pBtd - > pairWithWii = false ;
stateCounter = 0 ;
2013-12-11 09:29:38 +01:00
l2cap_state = WII_CHECK_MOTION_PLUS_STATE ;
2013-03-28 09:46:43 +01:00
}
break ;
/* The next states are in run() */
case L2CAP_INTERRUPT_DISCONNECT :
2017-02-12 16:58:14 +01:00
if ( l2cap_check_flag ( L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE ) & & ( ( int32_t ) ( ( uint32_t ) millis ( ) - timer ) > = 0L ) ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n Disconnected Interrupt Channel " ) , 0x80 ) ;
2012-08-21 14:31:11 +02:00
# endif
2013-03-28 09:46:43 +01:00
identifier + + ;
pBtd - > l2cap_disconnection_request ( hci_handle , identifier , control_scid , control_dcid ) ;
l2cap_state = L2CAP_CONTROL_DISCONNECT ;
}
break ;
case L2CAP_CONTROL_DISCONNECT :
2013-12-25 11:09:57 +01:00
if ( l2cap_check_flag ( L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE ) ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n Disconnected Control Channel " ) , 0x80 ) ;
2012-08-21 14:31:11 +02:00
# endif
2013-03-28 09:46:43 +01:00
pBtd - > hci_disconnect ( hci_handle ) ;
hci_handle = - 1 ; // Reset handle
l2cap_event_flag = 0 ; // Reset flags
l2cap_state = L2CAP_WAIT ;
}
break ;
}
2012-08-21 14:31:11 +02:00
}
2013-03-28 09:46:43 +01:00
2012-08-21 14:31:11 +02:00
void WII : : Run ( ) {
2017-02-12 16:58:14 +01:00
if ( l2cap_state = = L2CAP_INTERRUPT_DISCONNECT & & ( ( int32_t ) ( ( uint32_t ) millis ( ) - timer ) > = 0L ) )
2013-07-18 19:43:21 +02:00
L2CAP_task ( ) ; // Call the rest of the disconnection routine after we have waited long enough
2013-12-25 11:09:57 +01:00
switch ( l2cap_state ) {
2013-03-28 09:46:43 +01:00
case L2CAP_WAIT :
2013-12-25 11:09:57 +01:00
if ( pBtd - > connectToWii & & ! pBtd - > l2capConnectionClaimed & & ! wiimoteConnected & & ! activeConnection ) {
2013-03-28 09:46:43 +01:00
pBtd - > l2capConnectionClaimed = true ;
activeConnection = true ;
2013-07-18 19:43:21 +02:00
motionPlusInside = pBtd - > motionPlusInside ;
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n Send HID Control Connection Request " ) , 0x80 ) ;
2012-08-21 14:31:11 +02:00
# endif
2013-03-28 09:46:43 +01:00
hci_handle = pBtd - > hci_handle ; // Store the HCI Handle for the connection
l2cap_event_flag = 0 ; // Reset flags
identifier = 0 ;
pBtd - > l2cap_connection_request ( hci_handle , identifier , control_dcid , HID_CTRL_PSM ) ;
l2cap_state = L2CAP_CONTROL_CONNECT_REQUEST ;
2013-12-25 11:09:57 +01:00
} else if ( l2cap_check_flag ( L2CAP_FLAG_CONNECTION_CONTROL_REQUEST ) ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n HID Control Incoming Connection Request " ) , 0x80 ) ;
2012-10-07 14:50:51 +02:00
# endif
2013-03-28 09:46:43 +01:00
pBtd - > l2cap_connection_response ( hci_handle , identifier , control_dcid , control_scid , PENDING ) ;
delay ( 1 ) ;
pBtd - > l2cap_connection_response ( hci_handle , identifier , control_dcid , control_scid , SUCCESSFUL ) ;
identifier + + ;
delay ( 1 ) ;
pBtd - > l2cap_config_request ( hci_handle , identifier , control_scid ) ;
l2cap_state = L2CAP_CONTROL_SUCCESS ;
}
break ;
2013-12-11 09:29:38 +01:00
case WII_CHECK_MOTION_PLUS_STATE :
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-12-25 11:09:57 +01:00
if ( stateCounter = = 0 ) // Only print onnce
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n Checking if a Motion Plus is connected " ) , 0x80 ) ;
2012-08-23 23:10:12 +02:00
# endif
2013-03-28 09:46:43 +01:00
stateCounter + + ;
2013-12-25 11:09:57 +01:00
if ( stateCounter % 200 = = 0 )
2013-03-28 09:46:43 +01:00
checkMotionPresent ( ) ; // Check if there is a motion plus connected
2013-12-25 11:09:57 +01:00
if ( wii_check_flag ( WII_FLAG_MOTION_PLUS_CONNECTED ) ) {
2013-03-28 09:46:43 +01:00
stateCounter = 0 ;
2013-12-11 09:29:38 +01:00
l2cap_state = WII_INIT_MOTION_PLUS_STATE ;
2017-02-12 16:58:14 +01:00
timer = ( uint32_t ) micros ( ) ;
2013-03-28 09:46:43 +01:00
2013-12-25 11:09:57 +01:00
if ( unknownExtensionConnected ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n A extension is also connected " ) , 0x80 ) ;
2012-08-23 23:10:12 +02:00
# endif
2013-03-28 09:46:43 +01:00
activateNunchuck = true ; // For we will just set this to true as this the only extension supported so far
}
2013-03-28 09:37:09 +01:00
2013-12-25 11:09:57 +01:00
} else if ( stateCounter = = 601 ) { // We will try three times to check for the motion plus
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n No Motion Plus was detected " ) , 0x80 ) ;
2012-08-23 23:10:12 +02:00
# endif
2013-03-28 09:46:43 +01:00
stateCounter = 0 ;
2013-12-11 09:29:38 +01:00
l2cap_state = WII_CHECK_EXTENSION_STATE ;
2013-03-28 09:46:43 +01:00
}
break ;
2013-03-28 09:37:09 +01:00
2013-12-11 09:29:38 +01:00
case WII_CHECK_EXTENSION_STATE : // This is used to check if there is anything plugged in to the extension port
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-12-25 11:09:57 +01:00
if ( stateCounter = = 0 ) // Only print onnce
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n Checking if there is any extension connected " ) , 0x80 ) ;
2012-08-23 23:10:12 +02:00
# endif
2013-03-28 09:46:43 +01:00
stateCounter + + ; // We use this counter as there has to be a short delay between the commands
2013-12-25 11:09:57 +01:00
if ( stateCounter = = 1 )
2013-03-28 09:46:43 +01:00
statusRequest ( ) ; // See if a new device has connected
2013-12-25 11:09:57 +01:00
if ( stateCounter = = 100 ) {
if ( unknownExtensionConnected ) // Check if there is a extension is connected to the port
2013-03-28 09:46:43 +01:00
initExtension1 ( ) ;
else
2015-04-16 16:55:35 +02:00
stateCounter = 499 ;
2013-12-25 11:09:57 +01:00
} else if ( stateCounter = = 200 )
2013-03-28 09:46:43 +01:00
initExtension2 ( ) ;
2013-12-25 11:09:57 +01:00
else if ( stateCounter = = 300 ) {
2013-03-28 09:46:43 +01:00
readExtensionType ( ) ;
unknownExtensionConnected = false ;
2013-12-25 11:09:57 +01:00
} else if ( stateCounter = = 400 ) {
2015-04-20 23:39:57 +02:00
if ( wii_check_flag ( WII_FLAG_CALIBRATE_BALANCE_BOARD ) ) {
2015-04-16 16:55:35 +02:00
# ifdef DEBUG_USB_HOST
2015-04-16 20:19:33 +02:00
Notify ( PSTR ( " \r \n Reading Wii Balance Board calibration values " ) , 0x80 ) ;
2015-04-16 16:55:35 +02:00
# endif
2015-04-16 20:19:33 +02:00
readWiiBalanceBoardCalibration ( ) ;
2015-04-16 16:55:35 +02:00
} else
stateCounter = 499 ;
} else if ( stateCounter = = 500 ) {
2013-03-28 09:46:43 +01:00
stateCounter = 0 ;
2013-12-11 09:29:38 +01:00
l2cap_state = TURN_ON_LED ;
2013-03-28 09:46:43 +01:00
}
break ;
2013-12-11 09:29:38 +01:00
case WII_INIT_MOTION_PLUS_STATE :
2013-03-28 09:46:43 +01:00
stateCounter + + ;
2013-12-25 11:09:57 +01:00
if ( stateCounter = = 1 )
2013-03-28 09:46:43 +01:00
initMotionPlus ( ) ;
2013-12-25 11:09:57 +01:00
else if ( stateCounter = = 100 )
2013-03-28 09:46:43 +01:00
activateMotionPlus ( ) ;
2013-12-25 11:09:57 +01:00
else if ( stateCounter = = 200 )
2013-03-28 09:46:43 +01:00
readExtensionType ( ) ; // Check if it has been activated
2013-12-25 11:09:57 +01:00
else if ( stateCounter = = 300 ) {
2013-03-28 09:46:43 +01:00
stateCounter = 0 ;
unknownExtensionConnected = false ; // The motion plus will send a status report when it's activated, we will set this to false so it doesn't reinitialize the Motion Plus
2013-12-11 09:29:38 +01:00
l2cap_state = TURN_ON_LED ;
2013-03-28 09:46:43 +01:00
}
break ;
2013-12-11 09:29:38 +01:00
case TURN_ON_LED :
2013-12-25 11:09:57 +01:00
if ( wii_check_flag ( WII_FLAG_NUNCHUCK_CONNECTED ) )
2013-03-28 09:46:43 +01:00
nunchuckConnected = true ;
2013-07-18 19:43:21 +02:00
wiimoteConnected = true ;
2013-07-14 00:43:35 +02:00
onInit ( ) ;
2013-03-28 09:46:43 +01:00
l2cap_state = L2CAP_DONE ;
break ;
case L2CAP_DONE :
2013-12-25 11:09:57 +01:00
if ( unknownExtensionConnected ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-12-25 11:09:57 +01:00
if ( stateCounter = = 0 ) // Only print once
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n Checking extension port " ) , 0x80 ) ;
2012-08-23 23:10:12 +02:00
# endif
2013-03-28 09:46:43 +01:00
stateCounter + + ; // We will use this counter as there has to be a short delay between the commands
2013-12-25 11:09:57 +01:00
if ( stateCounter = = 50 )
2013-03-28 09:46:43 +01:00
statusRequest ( ) ;
2013-12-25 11:09:57 +01:00
else if ( stateCounter = = 100 )
2013-03-28 09:46:43 +01:00
initExtension1 ( ) ;
2013-12-25 11:09:57 +01:00
else if ( stateCounter = = 150 )
if ( ( extensionConnected & & motionPlusConnected ) | | ( unknownExtensionConnected & & ! motionPlusConnected ) )
2013-03-28 09:46:43 +01:00
initExtension2 ( ) ;
else
stateCounter = 299 ; // There is no extension connected
2013-12-25 11:09:57 +01:00
else if ( stateCounter = = 200 )
2013-03-28 09:46:43 +01:00
readExtensionType ( ) ;
2013-12-25 11:09:57 +01:00
else if ( stateCounter = = 250 ) {
if ( wii_check_flag ( WII_FLAG_NUNCHUCK_CONNECTED ) ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n Nunchuck was reconnected " ) , 0x80 ) ;
2012-08-23 23:10:12 +02:00
# endif
2013-03-28 09:46:43 +01:00
activateNunchuck = true ;
nunchuckConnected = true ;
}
2013-12-25 11:09:57 +01:00
if ( ! motionPlusConnected )
2013-03-28 09:46:43 +01:00
stateCounter = 449 ;
2013-12-25 11:09:57 +01:00
} else if ( stateCounter = = 300 ) {
if ( motionPlusConnected ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n Reactivating the Motion Plus " ) , 0x80 ) ;
2012-08-23 23:10:12 +02:00
# endif
2013-03-28 09:46:43 +01:00
initMotionPlus ( ) ;
} else
stateCounter = 449 ;
2013-12-25 11:09:57 +01:00
} else if ( stateCounter = = 350 )
2013-03-28 09:46:43 +01:00
activateMotionPlus ( ) ;
2013-12-25 11:09:57 +01:00
else if ( stateCounter = = 400 )
2013-03-28 09:46:43 +01:00
readExtensionType ( ) ; // Check if it has been activated
2013-12-25 11:09:57 +01:00
else if ( stateCounter = = 450 ) {
2013-07-14 00:43:35 +02:00
onInit ( ) ;
2013-03-28 09:46:43 +01:00
stateCounter = 0 ;
unknownExtensionConnected = false ;
}
} else
stateCounter = 0 ;
break ;
}
2012-08-21 14:31:11 +02:00
}
/************************************************************/
/* HID Commands */
/************************************************************/
2015-04-16 17:00:07 +02:00
2012-08-21 14:31:11 +02:00
void WII : : HID_Command ( uint8_t * data , uint8_t nbytes ) {
2013-12-25 11:09:57 +01:00
if ( motionPlusInside )
2014-01-04 13:43:49 +01:00
pBtd - > L2CAP_Command ( hci_handle , data , nbytes , interrupt_scid [ 0 ] , interrupt_scid [ 1 ] ) ; // It's the new Wiimote with the Motion Plus Inside or Wii U Pro controller
2013-03-28 09:46:43 +01:00
else
pBtd - > L2CAP_Command ( hci_handle , data , nbytes , control_scid [ 0 ] , control_scid [ 1 ] ) ;
2012-08-21 14:31:11 +02:00
}
2013-03-28 09:46:43 +01:00
2012-08-21 14:31:11 +02:00
void WII : : setAllOff ( ) {
2013-03-28 09:46:43 +01:00
HIDBuffer [ 1 ] = 0x11 ;
HIDBuffer [ 2 ] = 0x00 ;
HID_Command ( HIDBuffer , 3 ) ;
2012-08-21 14:31:11 +02:00
}
2013-03-28 09:46:43 +01:00
2012-08-21 14:31:11 +02:00
void WII : : setRumbleOff ( ) {
2013-03-28 09:46:43 +01:00
HIDBuffer [ 1 ] = 0x11 ;
HIDBuffer [ 2 ] & = ~ 0x01 ; // Bit 0 control the rumble
HID_Command ( HIDBuffer , 3 ) ;
2012-08-21 14:31:11 +02:00
}
2013-03-28 09:46:43 +01:00
2012-08-21 14:31:11 +02:00
void WII : : setRumbleOn ( ) {
2013-03-28 09:46:43 +01:00
HIDBuffer [ 1 ] = 0x11 ;
HIDBuffer [ 2 ] | = 0x01 ; // Bit 0 control the rumble
HID_Command ( HIDBuffer , 3 ) ;
2012-08-21 14:31:11 +02:00
}
2013-03-28 09:46:43 +01:00
2012-08-21 14:31:11 +02:00
void WII : : setRumbleToggle ( ) {
2013-03-28 09:46:43 +01:00
HIDBuffer [ 1 ] = 0x11 ;
HIDBuffer [ 2 ] ^ = 0x01 ; // Bit 0 control the rumble
HID_Command ( HIDBuffer , 3 ) ;
2012-08-21 14:31:11 +02:00
}
2013-03-28 09:46:43 +01:00
2013-04-01 15:38:15 +02:00
void WII : : setLedRaw ( uint8_t value ) {
HIDBuffer [ 1 ] = 0x11 ;
HIDBuffer [ 2 ] = value | ( HIDBuffer [ 2 ] & 0x01 ) ; // Keep the rumble bit
HID_Command ( HIDBuffer , 3 ) ;
}
2013-12-25 11:09:57 +01:00
2014-01-04 13:43:49 +01:00
void WII : : setLedOff ( LEDEnum a ) {
2013-03-28 09:46:43 +01:00
HIDBuffer [ 1 ] = 0x11 ;
2014-01-04 13:43:49 +01:00
HIDBuffer [ 2 ] & = ~ ( pgm_read_byte ( & WII_LEDS [ ( uint8_t ) a ] ) ) ;
2013-03-28 09:46:43 +01:00
HID_Command ( HIDBuffer , 3 ) ;
2012-08-21 14:31:11 +02:00
}
2013-03-28 09:46:43 +01:00
2014-01-04 13:43:49 +01:00
void WII : : setLedOn ( LEDEnum a ) {
if ( a = = OFF )
setLedRaw ( 0 ) ;
else {
HIDBuffer [ 1 ] = 0x11 ;
HIDBuffer [ 2 ] | = pgm_read_byte ( & WII_LEDS [ ( uint8_t ) a ] ) ;
HID_Command ( HIDBuffer , 3 ) ;
}
2012-08-21 14:31:11 +02:00
}
2013-03-28 09:46:43 +01:00
2014-01-04 13:43:49 +01:00
void WII : : setLedToggle ( LEDEnum a ) {
2013-03-28 09:46:43 +01:00
HIDBuffer [ 1 ] = 0x11 ;
2014-01-04 13:43:49 +01:00
HIDBuffer [ 2 ] ^ = pgm_read_byte ( & WII_LEDS [ ( uint8_t ) a ] ) ;
2013-03-28 09:46:43 +01:00
HID_Command ( HIDBuffer , 3 ) ;
2012-08-21 17:36:37 +02:00
}
2013-03-28 09:46:43 +01:00
2012-10-06 16:42:00 +02:00
void WII : : setLedStatus ( ) {
2013-03-28 09:46:43 +01:00
HIDBuffer [ 1 ] = 0x11 ;
HIDBuffer [ 2 ] = ( HIDBuffer [ 2 ] & 0x01 ) ; // Keep the rumble bit
2013-12-25 11:09:57 +01:00
if ( wiimoteConnected )
2013-03-28 09:46:43 +01:00
HIDBuffer [ 2 ] | = 0x10 ; // If it's connected LED1 will light up
2013-12-25 11:09:57 +01:00
if ( motionPlusConnected )
2013-03-28 09:46:43 +01:00
HIDBuffer [ 2 ] | = 0x20 ; // If it's connected LED2 will light up
2013-12-25 11:09:57 +01:00
if ( nunchuckConnected )
2013-03-28 09:46:43 +01:00
HIDBuffer [ 2 ] | = 0x40 ; // If it's connected LED3 will light up
HID_Command ( HIDBuffer , 3 ) ;
2012-10-06 16:42:00 +02:00
}
2013-03-28 09:46:43 +01:00
2013-07-18 19:43:21 +02:00
uint8_t WII : : getBatteryLevel ( ) {
2015-04-16 16:50:08 +02:00
checkBatteryLevel = true ; // This is needed so the library knows that the status response is a response to this function
2013-07-18 19:43:21 +02:00
statusRequest ( ) ; // This will update the battery level
return batteryLevel ;
} ;
2012-08-21 17:36:37 +02:00
void WII : : setReportMode ( bool continuous , uint8_t mode ) {
2016-07-02 19:42:32 +02:00
# ifdef EXTRADEBUG
Notify ( PSTR ( " \r \n Report mode was changed to: " ) , 0x80 ) ;
D_PrintHex < uint8_t > ( mode , 0x80 ) ;
# endif
2013-03-28 09:46:43 +01:00
uint8_t cmd_buf [ 4 ] ;
cmd_buf [ 0 ] = 0xA2 ; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
cmd_buf [ 1 ] = 0x12 ;
2013-12-25 11:09:57 +01:00
if ( continuous )
2013-03-28 09:46:43 +01:00
cmd_buf [ 2 ] = 0x04 | ( HIDBuffer [ 2 ] & 0x01 ) ; // Keep the rumble bit
else
cmd_buf [ 2 ] = 0x00 | ( HIDBuffer [ 2 ] & 0x01 ) ; // Keep the rumble bit
cmd_buf [ 3 ] = mode ;
HID_Command ( cmd_buf , 4 ) ;
2012-08-21 17:36:37 +02:00
}
2013-03-28 09:46:43 +01:00
2012-08-21 17:36:37 +02:00
void WII : : statusRequest ( ) {
2013-03-28 09:46:43 +01:00
uint8_t cmd_buf [ 3 ] ;
cmd_buf [ 0 ] = 0xA2 ; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
cmd_buf [ 1 ] = 0x15 ;
cmd_buf [ 2 ] = ( HIDBuffer [ 2 ] & 0x01 ) ; // Keep the rumble bit
HID_Command ( cmd_buf , 3 ) ;
2012-08-21 14:31:11 +02:00
}
2012-08-22 23:41:38 +02:00
/************************************************************/
/* Memmory Commands */
/************************************************************/
2015-04-16 17:00:07 +02:00
2012-08-22 23:41:38 +02:00
void WII : : writeData ( uint32_t offset , uint8_t size , uint8_t * data ) {
2013-03-28 09:46:43 +01:00
uint8_t cmd_buf [ 23 ] ;
cmd_buf [ 0 ] = 0xA2 ; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
cmd_buf [ 1 ] = 0x16 ; // Write data
cmd_buf [ 2 ] = 0x04 | ( HIDBuffer [ 2 ] & 0x01 ) ; // Write to memory, clear bit 2 to write to EEPROM
cmd_buf [ 3 ] = ( uint8_t ) ( ( offset & 0xFF0000 ) > > 16 ) ;
cmd_buf [ 4 ] = ( uint8_t ) ( ( offset & 0xFF00 ) > > 8 ) ;
cmd_buf [ 5 ] = ( uint8_t ) ( offset & 0xFF ) ;
cmd_buf [ 6 ] = size ;
uint8_t i = 0 ;
2013-12-25 11:09:57 +01:00
for ( ; i < size ; i + + )
2013-03-28 09:46:43 +01:00
cmd_buf [ 7 + i ] = data [ i ] ;
2013-12-25 11:09:57 +01:00
for ( ; i < 16 ; i + + ) // Set the rest to zero
2013-03-28 09:46:43 +01:00
cmd_buf [ 7 + i ] = 0x00 ;
HID_Command ( cmd_buf , 23 ) ;
2012-08-22 23:41:38 +02:00
}
2013-03-28 09:46:43 +01:00
2012-08-23 23:10:12 +02:00
void WII : : initExtension1 ( ) {
2013-03-28 09:46:43 +01:00
uint8_t buf [ 1 ] ;
buf [ 0 ] = 0x55 ;
writeData ( 0xA400F0 , 1 , buf ) ;
2012-08-22 23:41:38 +02:00
}
2013-03-28 09:46:43 +01:00
2012-08-23 23:10:12 +02:00
void WII : : initExtension2 ( ) {
2013-03-28 09:46:43 +01:00
uint8_t buf [ 1 ] ;
buf [ 0 ] = 0x00 ;
writeData ( 0xA400FB , 1 , buf ) ;
2012-08-22 23:41:38 +02:00
}
2013-03-28 09:46:43 +01:00
2012-08-23 23:10:12 +02:00
void WII : : initMotionPlus ( ) {
2013-03-28 09:46:43 +01:00
uint8_t buf [ 1 ] ;
buf [ 0 ] = 0x55 ;
writeData ( 0xA600F0 , 1 , buf ) ;
2012-08-23 23:10:12 +02:00
}
2013-03-28 09:46:43 +01:00
2012-08-23 23:10:12 +02:00
void WII : : activateMotionPlus ( ) {
2013-03-28 09:46:43 +01:00
uint8_t buf [ 1 ] ;
2013-12-25 11:09:57 +01:00
if ( pBtd - > wiiUProController ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n Activating Wii U Pro Controller " ) , 0x80 ) ;
2013-02-02 22:14:01 +01:00
# endif
2013-03-28 09:46:43 +01:00
buf [ 0 ] = 0x00 ; // It seems like you can send anything but 0x04, 0x05, and 0x07
2013-12-25 11:09:57 +01:00
} else if ( activateNunchuck ) {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n Activating Motion Plus in pass-through mode " ) , 0x80 ) ;
2012-08-23 23:10:12 +02:00
# endif
2013-03-28 09:46:43 +01:00
buf [ 0 ] = 0x05 ; // Activate nunchuck pass-through mode
2013-12-25 11:09:57 +01:00
} //else if(classicControllerConnected && extensionConnected)
2013-03-28 09:46:43 +01:00
//buf[0] = 0x07;
else {
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:46:43 +01:00
Notify ( PSTR ( " \r \n Activating Motion Plus in normal mode " ) , 0x80 ) ;
2012-08-23 23:10:12 +02:00
# endif
2013-03-28 09:46:43 +01:00
buf [ 0 ] = 0x04 ; // Don't use any extension
}
writeData ( 0xA600FE , 1 , buf ) ;
2012-08-23 23:10:12 +02:00
}
2013-03-28 09:46:43 +01:00
2012-08-22 23:41:38 +02:00
void WII : : readData ( uint32_t offset , uint16_t size , bool EEPROM ) {
2013-03-28 09:46:43 +01:00
uint8_t cmd_buf [ 8 ] ;
cmd_buf [ 0 ] = 0xA2 ; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
cmd_buf [ 1 ] = 0x17 ; // Read data
2013-12-25 11:09:57 +01:00
if ( EEPROM )
2013-03-28 09:46:43 +01:00
cmd_buf [ 2 ] = 0x00 | ( HIDBuffer [ 2 ] & 0x01 ) ; // Read from EEPROM
else
cmd_buf [ 2 ] = 0x04 | ( HIDBuffer [ 2 ] & 0x01 ) ; // Read from memory
cmd_buf [ 3 ] = ( uint8_t ) ( ( offset & 0xFF0000 ) > > 16 ) ;
cmd_buf [ 4 ] = ( uint8_t ) ( ( offset & 0xFF00 ) > > 8 ) ;
cmd_buf [ 5 ] = ( uint8_t ) ( offset & 0xFF ) ;
cmd_buf [ 6 ] = ( uint8_t ) ( ( size & 0xFF00 ) > > 8 ) ;
cmd_buf [ 7 ] = ( uint8_t ) ( size & 0xFF ) ;
HID_Command ( cmd_buf , 8 ) ;
2012-08-22 23:41:38 +02:00
}
2013-03-28 09:46:43 +01:00
2012-08-22 23:41:38 +02:00
void WII : : readExtensionType ( ) {
2013-03-28 09:46:43 +01:00
readData ( 0xA400FA , 6 , false ) ;
2012-08-22 23:41:38 +02:00
}
2013-03-28 09:46:43 +01:00
2012-08-22 23:41:38 +02:00
void WII : : readCalData ( ) {
2013-03-28 09:46:43 +01:00
readData ( 0x0016 , 8 , true ) ;
2012-08-22 23:41:38 +02:00
}
2013-03-28 09:46:43 +01:00
2012-08-23 23:10:12 +02:00
void WII : : checkMotionPresent ( ) {
2013-03-28 09:46:43 +01:00
readData ( 0xA600FA , 6 , false ) ;
2012-08-23 23:10:12 +02:00
}
2012-08-22 23:41:38 +02:00
2015-04-16 20:19:33 +02:00
void WII : : readWiiBalanceBoardCalibration ( ) {
2015-04-16 16:55:35 +02:00
readData ( 0xA40024 , 24 , false ) ;
}
2012-08-21 14:31:11 +02:00
/************************************************************/
/* WII Commands */
/************************************************************/
2021-03-27 13:35:55 +01:00
int8_t WII : : getButtonIndexWii ( ButtonEnum b ) {
const int8_t index = ButtonIndex ( b ) ;
2021-03-27 12:22:57 +01:00
if ( ( uint8_t ) index > = ( sizeof ( WII_BUTTONS ) / sizeof ( WII_BUTTONS [ 0 ] ) ) ) return - 1 ;
return index ;
2021-03-25 21:18:36 +01:00
}
2021-03-27 13:35:55 +01:00
int8_t WII : : getButtonIndexWiiPro ( ButtonEnum b ) {
const int8_t index = ButtonIndex ( b ) ;
2021-03-27 12:22:57 +01:00
if ( ( uint8_t ) index > = ( sizeof ( WII_PROCONTROLLER_BUTTONS ) / sizeof ( WII_PROCONTROLLER_BUTTONS [ 0 ] ) ) ) return - 1 ;
return index ;
2021-03-25 21:18:36 +01:00
}
2014-01-04 13:43:49 +01:00
bool WII : : getButtonPress ( ButtonEnum b ) { // Return true when a button is pressed
2021-03-25 21:18:36 +01:00
if ( wiiUProControllerConnected ) {
2021-03-27 13:35:55 +01:00
const int8_t index = getButtonIndexWiiPro ( b ) ; if ( index < 0 ) return 0 ;
2021-03-25 21:18:36 +01:00
return ( ButtonState & pgm_read_dword ( & WII_PROCONTROLLER_BUTTONS [ index ] ) ) ;
}
else {
2021-03-27 13:35:55 +01:00
const int8_t index = getButtonIndexWii ( b ) ; if ( index < 0 ) return 0 ;
2021-03-25 21:18:36 +01:00
return ( ButtonState & pgm_read_dword ( & WII_BUTTONS [ index ] ) ) ;
}
2012-08-21 14:31:11 +02:00
}
2013-03-28 09:46:43 +01:00
2014-01-04 13:43:49 +01:00
bool WII : : getButtonClick ( ButtonEnum b ) { // Only return true when a button is clicked
2013-03-28 09:46:43 +01:00
uint32_t button ;
2021-03-25 21:18:36 +01:00
if ( wiiUProControllerConnected ) {
2021-03-27 13:35:55 +01:00
const int8_t index = getButtonIndexWiiPro ( b ) ; if ( index < 0 ) return 0 ;
2021-03-25 21:18:36 +01:00
button = pgm_read_dword ( & WII_PROCONTROLLER_BUTTONS [ index ] ) ;
}
else {
2021-03-27 13:35:55 +01:00
const int8_t index = getButtonIndexWii ( b ) ; if ( index < 0 ) return 0 ;
2021-03-25 21:18:36 +01:00
button = pgm_read_dword ( & WII_BUTTONS [ index ] ) ;
}
2013-03-28 09:46:43 +01:00
bool click = ( ButtonClickState & button ) ;
ButtonClickState & = ~ button ; // clear "click" event
return click ;
2012-08-22 23:41:38 +02:00
}
2013-03-28 09:46:43 +01:00
2014-01-04 13:43:49 +01:00
uint8_t WII : : getAnalogHat ( HatEnum a ) {
2013-12-25 11:09:57 +01:00
if ( ! nunchuckConnected )
2013-03-28 09:46:43 +01:00
return 127 ; // Return center position
else {
uint8_t output = hatValues [ ( uint8_t ) a ] ;
2013-12-25 11:09:57 +01:00
if ( output = = 0xFF | | output = = 0x00 ) // The joystick will only read 255 or 0 when the cable is unplugged or initializing, so we will just return the center position
2013-03-28 09:46:43 +01:00
return 127 ;
else
return output ;
}
2013-01-17 00:07:56 +01:00
}
2013-03-28 09:46:43 +01:00
2014-01-04 13:43:49 +01:00
uint16_t WII : : getAnalogHat ( AnalogHatEnum a ) {
2013-12-25 11:09:57 +01:00
if ( ! wiiUProControllerConnected )
2013-03-28 09:46:43 +01:00
return 2000 ;
else {
uint16_t output = hatValues [ ( uint8_t ) a ] ;
2013-12-25 11:09:57 +01:00
if ( output = = 0x00 ) // The joystick will only read 0 when it is first initializing, so we will just return the center position
2013-03-28 09:46:43 +01:00
return 2000 ;
else
return output ;
}
2013-02-02 22:14:01 +01:00
}
2013-07-14 00:43:35 +02:00
void WII : : onInit ( ) {
2013-12-25 11:09:57 +01:00
if ( pFuncOnInit )
2013-07-14 00:43:35 +02:00
pFuncOnInit ( ) ; // Call the user function
else
setLedStatus ( ) ;
}
2015-04-16 17:00:07 +02:00
/************************************************************/
/* Wii Balance Board Commands */
/************************************************************/
float WII : : getWeight ( BalanceBoardEnum pos ) {
2015-04-16 19:45:03 +02:00
// Use interpolating between two points - based on: https://github.com/skorokithakis/gr8w8upd8m8/blob/master/gr8w8upd8m8.py
// wiiBalanceBoardCal[pos][0] is calibration values for 0 kg
// wiiBalanceBoardCal[pos][1] is calibration values for 17 kg
// wiiBalanceBoardCal[pos][2] is calibration values for 34 kg
if ( wiiBalanceBoardRaw [ pos ] < wiiBalanceBoardCal [ 0 ] [ pos ] )
return 0.0f ; // Below 0 kg
else if ( wiiBalanceBoardRaw [ pos ] < wiiBalanceBoardCal [ 1 ] [ pos ] ) // Between 0 and 17 kg
return 17.0f * ( float ) ( wiiBalanceBoardRaw [ pos ] - wiiBalanceBoardCal [ 0 ] [ pos ] ) / ( float ) ( wiiBalanceBoardCal [ 1 ] [ pos ] - wiiBalanceBoardCal [ 0 ] [ pos ] ) ;
else // More than 17 kg
return 17.0f + 17.0f * ( float ) ( wiiBalanceBoardRaw [ pos ] - wiiBalanceBoardCal [ 1 ] [ pos ] ) / ( float ) ( wiiBalanceBoardCal [ 2 ] [ pos ] - wiiBalanceBoardCal [ 1 ] [ pos ] ) ;
2015-04-16 17:00:07 +02:00
} ;
float WII : : getTotalWeight ( ) {
return getWeight ( TopRight ) + getWeight ( BotRight ) + getWeight ( TopLeft ) + getWeight ( BotLeft ) ;
} ;
2013-01-17 00:07:56 +01:00
/************************************************************/
/* The following functions are for the IR camera */
/************************************************************/
# ifdef WIICAMERA
2013-03-28 09:46:43 +01:00
void WII : : IRinitialize ( ) { // Turns on and initialises the IR camera
2013-03-28 09:37:09 +01:00
2013-01-17 00:47:19 +01:00
enableIRCamera1 ( ) ;
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:37:09 +01:00
Notify ( PSTR ( " \r \n Enable IR Camera1 Complete " ) , 0x80 ) ;
2013-01-17 00:07:56 +01:00
# endif
delay ( 80 ) ;
2013-03-28 09:37:09 +01:00
2013-01-17 00:47:19 +01:00
enableIRCamera2 ( ) ;
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:37:09 +01:00
Notify ( PSTR ( " \r \n Enable IR Camera2 Complete " ) , 0x80 ) ;
2013-01-17 00:07:56 +01:00
# endif
delay ( 80 ) ;
2013-03-28 09:37:09 +01:00
2013-01-17 00:07:56 +01:00
write0x08Value ( ) ;
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:37:09 +01:00
Notify ( PSTR ( " \r \n Wrote hex number 0x08 " ) , 0x80 ) ;
2013-01-17 00:07:56 +01:00
# endif
delay ( 80 ) ;
2013-03-28 09:37:09 +01:00
2013-01-17 00:47:19 +01:00
writeSensitivityBlock1 ( ) ;
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:37:09 +01:00
Notify ( PSTR ( " \r \n Wrote Sensitivity Block 1 " ) , 0x80 ) ;
2013-01-17 00:07:56 +01:00
# endif
delay ( 80 ) ;
2013-03-28 09:37:09 +01:00
2013-01-17 00:47:19 +01:00
writeSensitivityBlock2 ( ) ;
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:37:09 +01:00
Notify ( PSTR ( " \r \n Wrote Sensitivity Block 2 " ) , 0x80 ) ;
2013-01-17 00:07:56 +01:00
# endif
delay ( 80 ) ;
2013-01-17 00:47:19 +01:00
uint8_t mode_num = 0x03 ;
setWiiModeNumber ( mode_num ) ; // Change input for whatever mode you want i.e. 0x01, 0x03, or 0x05
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:37:09 +01:00
Notify ( PSTR ( " \r \n Set Wii Mode Number To 0x " ) , 0x80 ) ;
2013-06-17 21:37:09 +02:00
D_PrintHex < uint8_t > ( mode_num , 0x80 ) ;
2013-01-17 00:07:56 +01:00
# endif
delay ( 80 ) ;
2013-03-28 09:37:09 +01:00
2013-01-17 00:07:56 +01:00
write0x08Value ( ) ;
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:37:09 +01:00
Notify ( PSTR ( " \r \n Wrote Hex Number 0x08 " ) , 0x80 ) ;
2013-01-17 00:07:56 +01:00
# endif
delay ( 80 ) ;
2013-01-23 22:28:40 +01:00
setReportMode ( false , 0x33 ) ;
2013-01-17 00:47:19 +01:00
//setReportMode(false, 0x3f); // For full reporting mode, doesn't work yet
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:37:09 +01:00
Notify ( PSTR ( " \r \n Set Report Mode to 0x33 " ) , 0x80 ) ;
2013-01-17 00:07:56 +01:00
# endif
2013-01-23 22:28:40 +01:00
delay ( 80 ) ;
2013-03-28 09:37:09 +01:00
2013-01-23 22:28:40 +01:00
statusRequest ( ) ; // Used to update wiiState - call isIRCameraEnabled() afterwards to check if it actually worked
2013-06-12 05:11:43 +02:00
# ifdef DEBUG_USB_HOST
2013-03-28 09:37:09 +01:00
Notify ( PSTR ( " \r \n IR Initialized " ) , 0x80 ) ;
# endif
2013-01-17 00:07:56 +01:00
}
2013-03-28 09:46:43 +01:00
void WII : : enableIRCamera1 ( ) {
uint8_t cmd_buf [ 3 ] ;
cmd_buf [ 0 ] = 0xA2 ; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
cmd_buf [ 1 ] = 0x13 ; // Output report 13
cmd_buf [ 2 ] = 0x04 | ( HIDBuffer [ 2 ] & 0x01 ) ; // Keep the rumble bit and sets bit 2
HID_Command ( cmd_buf , 3 ) ;
2013-01-17 00:07:56 +01:00
}
2013-03-28 09:46:43 +01:00
void WII : : enableIRCamera2 ( ) {
uint8_t cmd_buf [ 3 ] ;
cmd_buf [ 0 ] = 0xA2 ; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
cmd_buf [ 1 ] = 0x1A ; // Output report 1A
cmd_buf [ 2 ] = 0x04 | ( HIDBuffer [ 2 ] & 0x01 ) ; // Keep the rumble bit and sets bit 2
HID_Command ( cmd_buf , 3 ) ;
2013-01-17 00:07:56 +01:00
}
2013-03-28 09:46:43 +01:00
void WII : : writeSensitivityBlock1 ( ) {
uint8_t buf [ 9 ] ;
buf [ 0 ] = 0x00 ;
buf [ 1 ] = 0x00 ;
buf [ 2 ] = 0x00 ;
buf [ 3 ] = 0x00 ;
buf [ 4 ] = 0x00 ;
buf [ 5 ] = 0x00 ;
buf [ 6 ] = 0x90 ;
buf [ 7 ] = 0x00 ;
buf [ 8 ] = 0x41 ;
writeData ( 0xB00000 , 9 , buf ) ;
2013-01-17 00:07:56 +01:00
}
2013-03-28 09:46:43 +01:00
void WII : : writeSensitivityBlock2 ( ) {
uint8_t buf [ 2 ] ;
buf [ 0 ] = 0x40 ;
buf [ 1 ] = 0x00 ;
2013-01-17 00:07:56 +01:00
2013-03-28 09:46:43 +01:00
writeData ( 0xB0001A , 2 , buf ) ;
2013-01-17 00:07:56 +01:00
}
2013-03-28 09:46:43 +01:00
void WII : : write0x08Value ( ) {
uint8_t cmd = 0x08 ;
writeData ( 0xb00030 , 1 , & cmd ) ;
2013-01-17 00:07:56 +01:00
}
2013-03-28 09:46:43 +01:00
void WII : : setWiiModeNumber ( uint8_t mode_number ) { // mode_number in hex i.e. 0x03 for extended mode
writeData ( 0xb00033 , 1 , & mode_number ) ;
2013-01-17 00:07:56 +01:00
}
2013-03-28 09:37:09 +01:00
# endif