2012-08-21 14:31:11 +02:00
/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
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 " ) .
Contact information
- - - - - - - - - - - - - - - - - - -
Kristian Lauszus , TKJ Electronics
Web : http : //www.tkjelectronics.com
e - mail : kristianl @ tkjelectronics . com
2013-01-17 00:07:56 +01:00
IR camera support added by :
Allan Glover
adglover9 .81 @ gmail . com
2012-08-21 14:31:11 +02:00
*/
# ifndef _wii_h_
# define _wii_h_
# include "BTD.h"
2013-01-27 21:25:50 +01:00
# include "controllerEnums.h"
2012-08-21 14:31:11 +02:00
2013-01-17 00:07:56 +01:00
//#define WIICAMERA //uncomment to enable IR camera
2012-08-21 14:31:11 +02:00
/* Bluetooth L2CAP states for L2CAP_task() */
# define L2CAP_WAIT 0
2012-08-23 23:10:12 +02:00
2012-10-07 14:50:51 +02:00
// These states are used if the Wiimote is the host
# define L2CAP_CONTROL_SUCCESS 1
# define L2CAP_INTERRUPT_SETUP 2
2012-08-23 23:10:12 +02:00
2012-10-07 14:50:51 +02:00
// These states are used if the Arduino is the host
# define L2CAP_CONTROL_CONNECT_REQUEST 3
# define L2CAP_CONTROL_CONFIG_REQUEST 4
# define L2CAP_INTERRUPT_CONNECT_REQUEST 5
# define L2CAP_INTERRUPT_CONFIG_REQUEST 6
# define L2CAP_CHECK_MOTION_PLUS_STATE 7
# define L2CAP_CHECK_EXTENSION_STATE 8
# define L2CAP_INIT_MOTION_PLUS_STATE 9
# define L2CAP_LED_STATE 10
# define L2CAP_DONE 11
# define L2CAP_INTERRUPT_DISCONNECT 12
# define L2CAP_CONTROL_DISCONNECT 13
2012-08-21 14:31:11 +02:00
/* L2CAP event flags */
2012-08-23 23:10:12 +02:00
# define L2CAP_FLAG_CONTROL_CONNECTED 0x001
# define L2CAP_FLAG_INTERRUPT_CONNECTED 0x002
# define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS 0x004
# define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS 0x008
# define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE 0x040
# define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE 0x080
2012-10-07 14:50:51 +02:00
# define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST 0x100
# define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST 0x200
2012-08-21 14:31:11 +02:00
2012-08-23 23:10:12 +02:00
/* Macros for L2CAP event flag tests */
2012-08-21 14:31:11 +02:00
# define l2cap_connected_control_flag (l2cap_event_flag & L2CAP_FLAG_CONTROL_CONNECTED)
# define l2cap_connected_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_INTERRUPT_CONNECTED)
# define l2cap_config_success_control_flag (l2cap_event_flag & L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)
# define l2cap_config_success_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS)
# define l2cap_disconnect_response_control_flag (l2cap_event_flag & L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE)
# define l2cap_disconnect_response_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE)
2012-10-07 14:50:51 +02:00
# define l2cap_connection_request_control_flag (l2cap_event_flag & L2CAP_FLAG_CONNECTION_CONTROL_REQUEST)
# define l2cap_connection_request_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST)
2012-08-21 14:31:11 +02:00
2012-08-23 23:10:12 +02:00
/* Wii event flags */
2012-10-07 14:50:51 +02:00
# define WII_FLAG_MOTION_PLUS_CONNECTED 0x400
# define WII_FLAG_NUNCHUCK_CONNECTED 0x800
2012-08-23 23:10:12 +02:00
# define motion_plus_connected_flag (l2cap_event_flag & WII_FLAG_MOTION_PLUS_CONNECTED)
# define nunchuck_connected_flag (l2cap_event_flag & WII_FLAG_NUNCHUCK_CONNECTED)
2012-10-07 14:50:51 +02:00
# define PAIR 1
2013-01-27 21:25:50 +01:00
enum Hat {
2012-08-22 23:41:38 +02:00
HatX = 0 ,
HatY = 1 ,
2012-08-21 14:31:11 +02:00
} ;
class WII : public BluetoothService {
public :
2012-10-07 14:50:51 +02:00
WII ( BTD * p , bool pair = false ) ;
2012-08-21 14:31:11 +02:00
// BluetoothService implementation
virtual void ACLData ( uint8_t * ACLData ) ; // Used to pass acldata to the services
virtual void Run ( ) ; // Used to run part of the state maschine
virtual void Reset ( ) ; // Use this to reset the service
virtual void disconnect ( ) ; // Use this void to disconnect any of the controllers
2012-10-03 21:29:44 +02:00
/*
getButtonPress will return true as long as the button is held down
While getButtonClick will only return it once
So you instance if you need to increase a variable once you would use getButtonClick ,
but if you need to drive a robot forward you would use getButtonPress
*/
2012-08-21 14:31:11 +02:00
bool getButtonPress ( Button b ) ; // This will read true as long as the button is held down
bool getButtonClick ( Button b ) ; // This will only be true when the button is clicked the first time
2012-10-03 21:29:44 +02:00
2013-01-27 21:25:50 +01:00
uint8_t getAnalogHat ( Hat a ) ; // Used to read the joystick of the Nunchuck
2013-02-02 22:14:01 +01:00
uint16_t getAnalogHat ( AnalogHat a ) ; // Used to read the joystick of the Wii U Pro Controller
2012-08-23 23:10:12 +02:00
double getPitch ( ) { return pitch ; } ; // Fusioned angle using a complimentary filter if the Motion Plus is connected
double getRoll ( ) { return roll ; } ; // Fusioned angle using a complimentary filter if the Motion Plus is connected
double getYaw ( ) { return gyroYaw ; } ; // This is the yaw calculated by the gyro
2012-08-21 17:36:37 +02:00
2012-08-21 14:31:11 +02:00
void setAllOff ( ) ; // Turn both rumble and all LEDs off
void setRumbleOff ( ) ;
void setRumbleOn ( ) ;
void setRumbleToggle ( ) ;
void setLedOff ( LED a ) ;
void setLedOn ( LED a ) ;
2012-08-21 17:36:37 +02:00
void setLedToggle ( LED a ) ;
2012-10-06 16:42:00 +02:00
void setLedStatus ( ) ; // This will set the LEDs, so the user can see which connections are active
2013-02-02 22:14:01 +01:00
uint8_t getBatteryLevel ( ) { return batteryLevel ; } ; // Return the battery level
uint8_t getWiiState ( ) { return wiiState ; } ; // Return the wii state, see: http://wiibrew.org/wiki/Wiimote#0x20:_Status
2012-08-21 14:31:11 +02:00
2012-08-22 23:41:38 +02:00
bool wiimoteConnected ; // Variable used to indicate if a Wiimote is connected
bool nunchuckConnected ; // Variable used to indicate if a Nunchuck controller is connected
2012-08-23 23:10:12 +02:00
bool motionPlusConnected ; // Variable used to indicate if a Nunchuck controller is connected
2013-02-02 22:14:01 +01:00
bool wiiUProControllerConnected ; // Variable used to indicate if a Wii U Pro controller is connected
2012-08-23 23:10:12 +02:00
/* IMU Data, might be usefull if you need to do something more advanced than just calculating the angle */
double wiiMotePitch ; // Pitch and roll calculated from the accelerometer inside the Wiimote
double wiiMoteRoll ;
double nunchuckPitch ; // Pitch and roll calculated from the accelerometer inside the Nunchuck
double nunchuckRoll ;
int16_t accX ; // Accelerometer values used to calculate pitch and roll
int16_t accY ;
int16_t accZ ;
/* Variables for the gyro inside the Motion Plus */
double gyroPitch ; // This is the pitch calculated by the gyro - use this to tune pitchGyroScale
double gyroRoll ; // This is the roll calculated by the gyro - use this to tune rollGyroScale
double gyroYaw ; // This is the yaw calculated by the gyro - use this to tune yawGyroScale
double pitchGyroSpeed ; // The speed in deg/s from the gyro
double rollGyroSpeed ;
double yawGyroSpeed ;
uint16_t pitchGyroScale ; // You might need to fine-tune these values
uint16_t rollGyroScale ;
uint16_t yawGyroScale ;
int16_t gyroYawRaw ; // Raw value read directly from the Motion Plus
int16_t gyroRollRaw ;
int16_t gyroPitchRaw ;
int16_t gyroYawZero ; // These values are set when the controller is first initialized
int16_t gyroRollZero ;
int16_t gyroPitchZero ;
2013-01-17 00:07:56 +01:00
# ifdef WIICAMERA
2013-01-17 00:47:19 +01:00
/* These are functions for the IR camera */
void IRinitialize ( ) ; // Initialises the camera as per the steps from http://wiibrew.org/wiki/Wiimote#IR_Camera
2013-01-17 00:07:56 +01:00
2013-01-23 22:28:40 +01:00
uint16_t getIRx1 ( ) { return IR_object_x1 ; } ; // IR object 1 x position (0-1023)
uint16_t getIRy1 ( ) { return IR_object_y1 ; } ; // IR object 1 y position (0-767)
uint8_t getIRs1 ( ) { return IR_object_s1 ; } ; // IR object 1 size (0-15)
uint16_t getIRx2 ( ) { return IR_object_x2 ; } ;
uint16_t getIRy2 ( ) { return IR_object_y2 ; } ;
uint8_t getIRs2 ( ) { return IR_object_s2 ; } ;
uint16_t getIRx3 ( ) { return IR_object_x3 ; } ;
uint16_t getIRy3 ( ) { return IR_object_y3 ; } ;
uint8_t getIRs3 ( ) { return IR_object_s3 ; } ;
uint16_t getIRx4 ( ) { return IR_object_x4 ; } ;
uint16_t getIRy4 ( ) { return IR_object_y4 ; } ;
uint8_t getIRs4 ( ) { return IR_object_s4 ; } ;
2013-01-17 00:07:56 +01:00
2013-01-23 22:28:40 +01:00
bool isIRCameraEnabled ( ) { return ( wiiState & 0x08 ) ; } ;
2013-01-17 00:07:56 +01:00
# endif
2012-08-21 14:31:11 +02:00
private :
/* Mandatory members */
BTD * pBtd ;
void L2CAP_task ( ) ; // L2CAP state machine
/* Variables filled from HCI event management */
uint16_t hci_handle ;
2013-01-20 22:46:04 +01:00
bool activeConnection ; // Used to indicate if it's already has established a connection
2012-08-21 14:31:11 +02:00
/* variables used by high level L2CAP task */
uint8_t l2cap_state ;
uint16_t l2cap_event_flag ; // l2cap flags of received bluetooth events
2012-08-22 23:41:38 +02:00
uint32_t ButtonState ;
uint32_t OldButtonState ;
uint32_t ButtonClickState ;
2013-02-02 22:14:01 +01:00
uint16_t hatValues [ 4 ] ;
2012-08-21 14:31:11 +02:00
uint8_t HIDBuffer [ 3 ] ; // Used to store HID commands
2012-08-23 23:10:12 +02:00
uint16_t stateCounter ;
bool unknownExtensionConnected ;
bool extensionConnected ;
2012-08-21 14:31:11 +02:00
/* L2CAP Channels */
2012-08-22 23:41:38 +02:00
uint8_t control_scid [ 2 ] ; // L2CAP source CID for HID_Control
2012-08-23 23:10:12 +02:00
uint8_t control_dcid [ 2 ] ; // 0x0060
2012-08-22 23:41:38 +02:00
uint8_t interrupt_scid [ 2 ] ; // L2CAP source CID for HID_Interrupt
2012-08-23 23:10:12 +02:00
uint8_t interrupt_dcid [ 2 ] ; // 0x0061
uint8_t identifier ; // Identifier for connection
2012-08-21 14:31:11 +02:00
/* HID Commands */
void HID_Command ( uint8_t * data , uint8_t nbytes ) ;
2012-08-22 23:41:38 +02:00
void setReportMode ( bool continuous , uint8_t mode ) ;
2013-01-23 22:28:40 +01:00
void statusRequest ( ) ;
2012-08-22 23:41:38 +02:00
void writeData ( uint32_t offset , uint8_t size , uint8_t * data ) ;
2012-08-23 23:10:12 +02:00
void initExtension1 ( ) ;
void initExtension2 ( ) ;
2012-08-22 23:41:38 +02:00
void readData ( uint32_t offset , uint16_t size , bool EEPROM ) ;
void readExtensionType ( ) ;
void readCalData ( ) ;
2012-08-23 23:10:12 +02:00
void checkMotionPresent ( ) ; // Used to see if a Motion Plus is connected to the Wiimote
void initMotionPlus ( ) ;
void activateMotionPlus ( ) ;
double pitch ; // Fusioned angle using a complimentary filter if the Motion Plus is connected
double roll ; // Fusioned angle using a complimentary filter if the Motion Plus is connected
2012-08-22 23:41:38 +02:00
2012-08-23 23:10:12 +02:00
bool activateNunchuck ;
bool motionValuesReset ; // This bool is true when the gyro values has been reset
2013-01-17 00:47:19 +01:00
unsigned long timer ;
2013-01-23 22:28:40 +01:00
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)
uint8_t batteryLevel ;
2013-01-17 00:47:19 +01:00
# ifdef WIICAMERA
/* Private function and variables for the readings from teh IR Camera */
void enableIRCamera1 ( ) ; // Sets bit 2 of output report 13
void enableIRCamera2 ( ) ; // Sets bit 2 of output report 1A
void writeSensitivityBlock1 ( ) ;
void writeSensitivityBlock2 ( ) ;
void write0x08Value ( ) ;
void setWiiModeNumber ( uint8_t mode_number ) ;
2013-01-23 22:28:40 +01:00
uint16_t IR_object_x1 ; // IR x position 10 bits
uint16_t IR_object_y1 ; // IR y position 10 bits
uint8_t IR_object_s1 ; // IR size value
uint16_t IR_object_x2 ;
uint16_t IR_object_y2 ;
uint8_t IR_object_s2 ;
uint16_t IR_object_x3 ; // IR x position 10 bits
uint16_t IR_object_y3 ; // IR y position 10 bits
uint8_t IR_object_s3 ; // IR size value
uint16_t IR_object_x4 ;
uint16_t IR_object_y4 ;
uint8_t IR_object_s4 ;
2013-01-17 00:47:19 +01:00
# endif
2012-08-21 14:31:11 +02:00
} ;
# endif