mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
RFCOMM
This commit is contained in:
commit
9a58f9b94d
13 changed files with 2278 additions and 386 deletions
|
@ -1,13 +1,13 @@
|
|||
The PS3BT.cpp PS3BT.h was developed by Kristian Lauszus
|
||||
The PS3BT.cpp, PS3BT.h, PS3USB.cpp, PS3USB.h, XBOXUSB.cpp, and XBOXUSB.h were developed by Kristian Lauszus
|
||||
|
||||
For more information regarding the PS3 protocol etc. visit my blog at: http://blog.tkjelectronics.dk/ or send me an email at kristianl at tkjelectronics dot dk.
|
||||
You could also visit the official wiki: https://github.com/TKJElectronics/USB_Host_Shield_2.0/wiki for information.
|
||||
|
||||
All three PS3 Controllers are supported (Dualshock 3-, Navigation-, and Motioncontroller).
|
||||
They communicate with the Arduino via Bluetooth using the USB Host Shield from http://www.circuitsathome.com/
|
||||
They communicate with the Arduino via Bluetooth or USB using the USB Host Shield from http://www.circuitsathome.com/
|
||||
|
||||
A special thanks go to the following people:
|
||||
"Richard Ibbotson" who made this guide: http://www.circuitsathome.com/mcu/ps3-and-wiimote-game-controllers-on-the-arduino-host-shield-part-1
|
||||
"Richard Ibbotson" who made this excellent guide: http://www.circuitsathome.com/mcu/ps3-and-wiimote-game-controllers-on-the-arduino-host-shield-part-1
|
||||
- It inspired me to get starting and had a lot of good information for the USB communication
|
||||
|
||||
"Tomoyuki Tanaka" for releasing his code for the Arduino USB Host shield connected to the wiimote: http://www.circuitsathome.com/mcu/rc-car-controlled-by-wii-remote-on-arduino
|
||||
|
@ -19,4 +19,8 @@ http://www.copenhagengamecollective.org/unimove/
|
|||
https://github.com/thp/psmoveapi
|
||||
http://code.google.com/p/moveonpc/
|
||||
|
||||
All the information regarding the Xbox 360 controller protocol are form these two sites:
|
||||
http://tattiebogle.net/index.php/ProjectRoot/Xbox360Controller/UsbInfo
|
||||
http://pingus.seul.org/~grumbel/xboxdrv/
|
||||
|
||||
And at last I would like to thank Oleg from http://www.circuitsathome.com/ for making such an awesome shield!
|
297
PS3BT.cpp
297
PS3BT.cpp
|
@ -24,7 +24,7 @@ const uint8_t PS3BT::BTD_EVENT_PIPE = 1;
|
|||
const uint8_t PS3BT::BTD_DATAIN_PIPE = 2;
|
||||
const uint8_t PS3BT::BTD_DATAOUT_PIPE = 3;
|
||||
|
||||
prog_char OUTPUT_REPORT_BUFFER[] PROGMEM = {
|
||||
uint8_t OUTPUT_REPORT_BUFFER[] PROGMEM = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0x27, 0x10, 0x00, 0x32,
|
||||
|
@ -62,25 +62,6 @@ bPollEnable(false) // don't start polling before dongle is connected
|
|||
my_bdaddr[0] = btadr0;
|
||||
}
|
||||
|
||||
PS3BT::PS3BT(USB *p):
|
||||
pUsb(p), // pointer to USB class instance - mandatory
|
||||
bAddress(0), // device address - mandatory
|
||||
bNumEP(1), // if config descriptor needs to be parsed
|
||||
qNextPollTime(0),
|
||||
bPollEnable(false) // don't start polling before dongle is connected
|
||||
{
|
||||
for(uint8_t i=0; i<PS3_MAX_ENDPOINTS; i++)
|
||||
{
|
||||
epInfo[i].epAddr = 0;
|
||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||
epInfo[i].epAttribs = 0;
|
||||
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
||||
}
|
||||
|
||||
if (pUsb) // register in USB subsystem
|
||||
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
|
||||
}
|
||||
|
||||
uint8_t PS3BT::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
||||
{
|
||||
uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)];
|
||||
|
@ -283,7 +264,7 @@ uint8_t PS3BT::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
|||
interrupt_dcid[0] = 0x41;//0x0041
|
||||
interrupt_dcid[1] = 0x00;
|
||||
|
||||
hci_num_reset_loops = 10; // only loop 10 times before trying to send the hci reset command
|
||||
hci_num_reset_loops = 100; // only loop 100 times before trying to send the hci reset command
|
||||
|
||||
hci_state = HCI_INIT_STATE;
|
||||
hci_counter = 0;
|
||||
|
@ -388,6 +369,9 @@ void PS3BT::PrintEndpointDescriptor( const USB_ENDPOINT_DESCRIPTOR* ep_ptr )
|
|||
/* Performs a cleanup after failed Init() attempt */
|
||||
uint8_t PS3BT::Release()
|
||||
{
|
||||
PS3Connected = false;
|
||||
PS3MoveConnected = false;
|
||||
PS3NavigationConnected = false;
|
||||
pUsb->GetAddressPool().FreeAddress(bAddress);
|
||||
bAddress = 0;
|
||||
bPollEnable = false;
|
||||
|
@ -399,24 +383,20 @@ uint8_t PS3BT::Poll()
|
|||
if (!bPollEnable)
|
||||
return 0;
|
||||
if (qNextPollTime <= millis()) { // Don't poll if shorter than polling interval
|
||||
qNextPollTime = millis() + pollInterval; // Set new poll time
|
||||
HCI_event_task(); // poll the HCI event pipe
|
||||
ACL_event_task(); // start polling the ACL input pipe too, though discard data until connected
|
||||
}
|
||||
qNextPollTime = millis() + pollInterval; // Poll time
|
||||
ACL_event_task(); // start polling the ACL input pipe too, though discard data until connected
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
void PS3BT::setBdaddr(uint8_t* BDADDR)
|
||||
{
|
||||
/* Store the bluetooth address */
|
||||
for(uint8_t i = 0; i <6;i++)
|
||||
my_bdaddr[i] = BDADDR[i];
|
||||
|
||||
{
|
||||
/* Set the internal bluetooth address */
|
||||
uint8_t buf[8];
|
||||
buf[0] = 0x01;
|
||||
buf[1] = 0x00;
|
||||
for (uint8_t i = 0; i < 6; i++)
|
||||
buf[i+2] = my_bdaddr[5 - i];//Copy into buffer, has to be written reversed
|
||||
buf[i+2] = BDADDR[5 - i];//Copy into buffer, has to be written reversed
|
||||
|
||||
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
|
||||
pUsb->ctrlReq(bAddress,epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL);
|
||||
|
@ -433,10 +413,6 @@ void PS3BT::setBdaddr(uint8_t* BDADDR)
|
|||
}
|
||||
void PS3BT::setMoveBdaddr(uint8_t* BDADDR)
|
||||
{
|
||||
/* Store the bluetooth address */
|
||||
for(uint8_t i = 0; i <6;i++)
|
||||
my_bdaddr[i] = BDADDR[i];
|
||||
|
||||
/* Set the internal bluetooth address */
|
||||
uint8_t buf[11];
|
||||
buf[0] = 0x05;
|
||||
|
@ -446,7 +422,7 @@ void PS3BT::setMoveBdaddr(uint8_t* BDADDR)
|
|||
buf[10] = 0x12;
|
||||
|
||||
for (uint8_t i = 0; i < 6; i++)
|
||||
buf[i + 1] = my_bdaddr[i];
|
||||
buf[i + 1] = BDADDR[i];
|
||||
|
||||
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x05), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
|
||||
pUsb->ctrlReq(bAddress,epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00,11,11, buf, NULL);
|
||||
|
@ -465,10 +441,17 @@ bool PS3BT::getButton(Button b)
|
|||
{
|
||||
if (l2capinbuf == NULL)
|
||||
return false;
|
||||
if ((l2capinbuf[(uint16_t)b >> 8] & ((uint8_t)b & 0xff)) > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
if(PS3MoveConnected) {
|
||||
if((l2capinbuf[((uint16_t)b >> 8)-1] & ((uint8_t)b & 0xff))) // All the buttons locations are shifted one back on the Move controller
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
} else {
|
||||
if((l2capinbuf[(uint16_t)b >> 8] & ((uint8_t)b & 0xff)))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}
|
||||
uint8_t PS3BT::getAnalogButton(AnalogButton a)
|
||||
{
|
||||
|
@ -482,87 +465,75 @@ uint8_t PS3BT::getAnalogHat(AnalogHat a)
|
|||
return 0;
|
||||
return (uint8_t)(l2capinbuf[(uint16_t)a]);
|
||||
}
|
||||
int32_t PS3BT::getSensor(Sensor a)
|
||||
int16_t PS3BT::getSensor(Sensor a)
|
||||
{
|
||||
if (l2capinbuf == NULL)
|
||||
return 0;
|
||||
if (a == aX || a == aY || a == aZ || a == gZ)
|
||||
return ((l2capinbuf[(uint16_t)a] << 8) | l2capinbuf[(uint16_t)a + 1]);
|
||||
else if (a == mXmove || a == mYmove || a == mZmove)
|
||||
else if (a == mXmove || a == mYmove || a == mZmove) // These are all 12-bits long
|
||||
{
|
||||
// Might not be correct, haven't tested it yet
|
||||
if (a == mXmove)
|
||||
/*if (a == mXmove)
|
||||
return ((l2capinbuf[(uint16_t)a + 1] << 0x04) | (l2capinbuf[(uint16_t)a] << 0x0C));
|
||||
//return (((unsigned char)l2capinbuf[(unsigned int)a + 1]) | (((unsigned char)l2capinbuf[(unsigned int)a] & 0x0F)) << 8);
|
||||
else if (a == mYmove)
|
||||
return ((l2capinbuf[(uint16_t)a + 1] & 0xF0) | (l2capinbuf[(uint16_t)a] << 0x08));
|
||||
//return (((unsigned char)l2capinbuf[(unsigned int)a + 1]) | (((unsigned char)l2capinbuf[(unsigned int)a] & 0x0F)) << 8);
|
||||
else if (a == mZmove)
|
||||
return ((l2capinbuf[(uint16_t)a + 1] << 0x0F) | (l2capinbuf[(uint16_t)a] << 0x0C));
|
||||
//return ((((unsigned char)l2capinbuf[(unsigned int)a + 1] & 0xF0) >> 4) | ((unsigned char)l2capinbuf[(unsigned int)a] << 4));
|
||||
else
|
||||
return 0;
|
||||
return ((l2capinbuf[(uint16_t)a + 1] << 0x0F) | (l2capinbuf[(uint16_t)a] << 0x0C));
|
||||
*/
|
||||
if (a == mXmove || a == mYmove)
|
||||
return (((l2capinbuf[(uint16_t)a] & 0x0F) << 8) | (l2capinbuf[(uint16_t)a + 1]));
|
||||
else // mZmove
|
||||
return ((l2capinbuf[(uint16_t)a] << 4) | (l2capinbuf[(uint16_t)a + 1] >> 4));
|
||||
}
|
||||
else if (a == tempMove)
|
||||
return (((l2capinbuf[(uint16_t)a + 1] & 0xF0) >> 4) | (l2capinbuf[(uint16_t)a] << 4));
|
||||
else if (a == tempMove) // The tempearature is 12 bits long too
|
||||
return ((l2capinbuf[(uint16_t)a] << 4) | ((l2capinbuf[(uint16_t)a + 1] & 0xF0) >> 4));
|
||||
else // aXmove, aYmove, aZmove, gXmove, gYmove and gZmove
|
||||
return ((l2capinbuf[(uint16_t)a + 1] << 8) | l2capinbuf[(uint16_t)a]);
|
||||
return (l2capinbuf[(uint16_t)a] | (l2capinbuf[(uint16_t)a + 1] << 8));
|
||||
}
|
||||
double PS3BT::getAngle(Angle a) {
|
||||
double accXval;
|
||||
double accYval;
|
||||
double accZval;
|
||||
|
||||
if(PS3BTConnected) {
|
||||
if(PS3Connected) {
|
||||
// Data for the Kionix KXPC4 used in the DualShock 3
|
||||
double sensivity = 204.6; // 0.66/3.3*1023 (660mV/g)
|
||||
double zeroG = 511.5; // 1.65/3.3*1023 (1,65V)
|
||||
accXval = ((double)getSensor(aX)-zeroG) / sensivity; // Convert to g's
|
||||
accXval *= 2;
|
||||
accYval = ((double)getSensor(aY)-zeroG) / sensivity; // Convert to g's
|
||||
accYval *= 2;
|
||||
accZval = ((double)getSensor(aZ)-zeroG) / sensivity; // Convert to g's
|
||||
accZval *= 2;
|
||||
} else if(PS3MoveBTConnected) {
|
||||
// It's a Kionix KXSC4 inside the Motion controller
|
||||
const uint16_t sensivity = 28285; // Find by experimenting
|
||||
accXval = (double)getSensor(aXmove)/sensivity;
|
||||
accYval = (double)getSensor(aYmove)/sensivity;
|
||||
accZval = (double)getSensor(aZmove)/sensivity;
|
||||
|
||||
if(accXval < -1) // Convert to g's
|
||||
accXval = ((1+accXval)-(1-1.15))*(-1/0.15);
|
||||
else if(accXval > 1)
|
||||
accXval = ((1+accXval)-(1+1.15))*(-1/0.15);
|
||||
|
||||
if(accYval < -1) // Convert to g's
|
||||
accYval = ((1+accYval)-(1-1.15))*(-1/0.15);
|
||||
else if(accYval > 1)
|
||||
accYval = ((1+accYval)-(1+1.15))*(-1/0.15);
|
||||
|
||||
if(accZval < -1) // Convert to g's
|
||||
accZval = ((1+accZval)-(1-1.15))*(-1/0.15);
|
||||
else if(accZval > 1)
|
||||
accZval = ((1+accZval)-(1+1.15))*(-1/0.15);
|
||||
const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V)
|
||||
accXval = -((double)getSensor(aX)-zeroG);
|
||||
accYval = -((double)getSensor(aY)-zeroG);
|
||||
accZval = -((double)getSensor(aZ)-zeroG);
|
||||
} else if(PS3MoveConnected) {
|
||||
// It's a Kionix KXSC4 inside the Motion controller
|
||||
const uint16_t zeroG = 0x8000;
|
||||
accXval = -(int16_t)(getSensor(aXmove)-zeroG);
|
||||
accYval = (int16_t)(getSensor(aYmove)-zeroG);
|
||||
accZval = (int16_t)(getSensor(aZmove)-zeroG);
|
||||
}
|
||||
|
||||
double R = sqrt(accXval*accXval + accYval*accYval + accZval*accZval); // Calculate the length of the force vector
|
||||
// Normalize vectors
|
||||
accXval = accXval/R;
|
||||
accYval = accYval/R;
|
||||
accZval = accZval/R;
|
||||
|
||||
// Convert to 360 degrees resolution
|
||||
// atan2 outputs the value of -π to π (radians)
|
||||
// We are then converting it to 0 to 2π and then to degrees
|
||||
if (a == Pitch) {
|
||||
double angle = (atan2(-accYval,-accZval)+PI)*RAD_TO_DEG;
|
||||
double angle = (atan2(accYval,accZval)+PI)*RAD_TO_DEG;
|
||||
return angle;
|
||||
} else {
|
||||
double angle = (atan2(-accXval,-accZval)+PI)*RAD_TO_DEG;
|
||||
double angle = (atan2(accXval,accZval)+PI)*RAD_TO_DEG;
|
||||
return angle;
|
||||
}
|
||||
}
|
||||
String PS3BT::getTemperature() {
|
||||
if(PS3MoveConnected) {
|
||||
int16_t input = getSensor(tempMove);
|
||||
|
||||
String output = String(input/100);
|
||||
output += ".";
|
||||
if(input%100 < 10)
|
||||
output += "0";
|
||||
output += String(input%100);
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
bool PS3BT::getStatus(Status c)
|
||||
{
|
||||
if (l2capinbuf == NULL)
|
||||
|
@ -573,7 +544,7 @@ bool PS3BT::getStatus(Status c)
|
|||
}
|
||||
String PS3BT::getStatusString()
|
||||
{
|
||||
if (PS3BTConnected || PS3NavigationBTConnected)
|
||||
if (PS3Connected || PS3NavigationConnected)
|
||||
{
|
||||
char statusOutput[100];
|
||||
|
||||
|
@ -605,7 +576,7 @@ String PS3BT::getStatusString()
|
|||
return statusOutput;
|
||||
|
||||
}
|
||||
else if(PS3MoveBTConnected)
|
||||
else if(PS3MoveConnected)
|
||||
{
|
||||
char statusOutput[50];
|
||||
|
||||
|
@ -625,12 +596,12 @@ String PS3BT::getStatusString()
|
|||
}
|
||||
void PS3BT::disconnect()//Use this void to disconnect any of the controllers
|
||||
{
|
||||
if (PS3BTConnected)
|
||||
PS3BTConnected = false;
|
||||
else if (PS3MoveBTConnected)
|
||||
PS3MoveBTConnected = false;
|
||||
else if (PS3NavigationBTConnected)
|
||||
PS3NavigationBTConnected = false;
|
||||
if (PS3Connected)
|
||||
PS3Connected = false;
|
||||
else if (PS3MoveConnected)
|
||||
PS3MoveConnected = false;
|
||||
else if (PS3NavigationConnected)
|
||||
PS3NavigationConnected = false;
|
||||
|
||||
//First the HID interrupt channel has to be disconencted, then the HID control channel and finally the HCI connection
|
||||
l2cap_disconnection_request(0x0A, interrupt_dcid, interrupt_scid);
|
||||
|
@ -648,10 +619,16 @@ void PS3BT::HCI_event_task()
|
|||
{
|
||||
case EV_COMMAND_COMPLETE:
|
||||
hci_event_flag |= HCI_FLAG_CMD_COMPLETE; // set command complete flag
|
||||
if((hcibuf[3] == 0x09) && (hcibuf[4] == 0x10))// parameters from read local bluetooth address
|
||||
{
|
||||
for (uint8_t i = 0; i < 6; i++)
|
||||
my_bdaddr[i] = hcibuf[6 + i];
|
||||
if (!hcibuf[5]) { // check if command succeeded
|
||||
if((hcibuf[3] == 0x01) && (hcibuf[4] == 0x10)) { // parameters from read local version information
|
||||
hci_version = hcibuf[6]; // Check if it supports 2.0+EDR - see http://www.bluetooth.org/Technical/AssignedNumbers/hci.htm
|
||||
hci_event_flag |= HCI_FLAG_READ_VERSION;
|
||||
}
|
||||
else if((hcibuf[3] == 0x09) && (hcibuf[4] == 0x10)) { // parameters from read local bluetooth address
|
||||
for (uint8_t i = 0; i < 6; i++)
|
||||
my_bdaddr[i] = hcibuf[6 + i];
|
||||
hci_event_flag |= HCI_FLAG_READ_BDADDR;
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -683,10 +660,7 @@ void PS3BT::HCI_event_task()
|
|||
hci_event_flag |= HCI_FLAG_DISCONN_COMPLETE; //set disconnect commend complete flag
|
||||
hci_event_flag &= ~HCI_FLAG_CONN_COMPLETE; // clear connection complete flag
|
||||
}
|
||||
break;
|
||||
|
||||
case EV_NUM_COMPLETE_PKT:
|
||||
break;
|
||||
break;
|
||||
|
||||
case EV_REMOTE_NAME_COMPLETE:
|
||||
if (!hcibuf[2]) // check if reading is OK
|
||||
|
@ -707,7 +681,11 @@ void PS3BT::HCI_event_task()
|
|||
hci_event_flag |= HCI_FLAG_INCOMING_REQUEST;
|
||||
break;
|
||||
|
||||
/* We will just ignore the following events */
|
||||
/* We will just ignore the following events */
|
||||
|
||||
case EV_NUM_COMPLETE_PKT:
|
||||
break;
|
||||
|
||||
case EV_ROLE_CHANGED:
|
||||
break;
|
||||
|
||||
|
@ -782,8 +760,9 @@ void PS3BT::HCI_task()
|
|||
hci_counter = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_BDADDR_STATE:
|
||||
if (hci_cmd_complete)
|
||||
if (hci_read_bdaddr_complete)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nLocal Bluetooth Address: "));
|
||||
|
@ -794,8 +773,25 @@ void PS3BT::HCI_task()
|
|||
}
|
||||
PrintHex<uint8_t>(my_bdaddr[0]);
|
||||
#endif
|
||||
hci_read_local_version_information();
|
||||
hci_state = HCI_LOCAL_VERSION_STATE;
|
||||
}
|
||||
break;
|
||||
|
||||
case HCI_LOCAL_VERSION_STATE:
|
||||
if (hci_read_version_complete)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if(hci_version < 3) {
|
||||
Notify(PSTR("\r\nYour dongle may not support reading the analog buttons, sensors and status\r\nYour HCI Version is: "));
|
||||
Serial.print(hci_version);
|
||||
Notify(PSTR("\r\nBut should be at least 3\r\nThis means that it doesn't support Bluetooth Version 2.0+EDR"));
|
||||
}
|
||||
#endif
|
||||
hci_state = HCI_SCANNING_STATE;
|
||||
}
|
||||
break;
|
||||
|
||||
break;
|
||||
case HCI_SCANNING_STATE:
|
||||
#ifdef DEBUG
|
||||
|
@ -957,14 +953,14 @@ void PS3BT::ACL_event_task()
|
|||
Notify(PSTR(" Identifier: "));
|
||||
PrintHex<uint8_t>(l2capinbuf[9]);
|
||||
*/
|
||||
if ((l2capinbuf[13] | l2capinbuf[12]) == L2CAP_PSM_HID_CTRL)
|
||||
if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == L2CAP_PSM_HID_CTRL)
|
||||
{
|
||||
identifier = l2capinbuf[9];
|
||||
control_scid[0] = l2capinbuf[14];
|
||||
control_scid[1] = l2capinbuf[15];
|
||||
l2cap_event_flag |= L2CAP_EV_CONTROL_CONNECTION_REQUEST;
|
||||
}
|
||||
else if ((l2capinbuf[13] | l2capinbuf[12]) == L2CAP_PSM_HID_INTR)
|
||||
else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == L2CAP_PSM_HID_INTR)
|
||||
{
|
||||
identifier = l2capinbuf[9];
|
||||
interrupt_scid[0] = l2capinbuf[14];
|
||||
|
@ -1011,7 +1007,7 @@ void PS3BT::ACL_event_task()
|
|||
if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1])
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nDisconnected Request: Disconnected Control"));
|
||||
Notify(PSTR("\r\nDisconnect Request: Control Channel"));
|
||||
#endif
|
||||
identifier = l2capinbuf[9];
|
||||
l2cap_disconnection_response(identifier,control_dcid,control_scid);
|
||||
|
@ -1019,7 +1015,7 @@ void PS3BT::ACL_event_task()
|
|||
else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1])
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nDisconnected Request: Disconnected Interrupt"));
|
||||
Notify(PSTR("\r\nDisconnect Request: Interrupt Channel"));
|
||||
#endif
|
||||
identifier = l2capinbuf[9];
|
||||
l2cap_disconnection_response(identifier,interrupt_dcid,interrupt_scid);
|
||||
|
@ -1029,13 +1025,13 @@ void PS3BT::ACL_event_task()
|
|||
{
|
||||
if (l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1])
|
||||
{
|
||||
//Serial.print("\r\nDisconnected Response: Disconnected Control");
|
||||
//Serial.print("\r\nDisconnect Response: Control Channel");
|
||||
identifier = l2capinbuf[9];
|
||||
l2cap_event_flag |= L2CAP_EV_CONTROL_DISCONNECT_RESPONSE;
|
||||
}
|
||||
else if (l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1])
|
||||
{
|
||||
//Serial.print("\r\nDisconnected Response: Disconnected Interrupt");
|
||||
//Serial.print("\r\nDisconnect Response: Interrupt Channel");
|
||||
identifier = l2capinbuf[9];
|
||||
l2cap_event_flag |= L2CAP_EV_INTERRUPT_DISCONNECT_RESPONSE;
|
||||
}
|
||||
|
@ -1044,7 +1040,7 @@ void PS3BT::ACL_event_task()
|
|||
else if (l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1])//l2cap_interrupt
|
||||
{
|
||||
//Serial.print("\r\nL2CAP Interrupt");
|
||||
if(PS3BTConnected || PS3MoveBTConnected || PS3NavigationBTConnected)
|
||||
if(PS3Connected || PS3MoveConnected || PS3NavigationConnected)
|
||||
{
|
||||
readReport();
|
||||
#ifdef PRINTREPORT
|
||||
|
@ -1169,30 +1165,29 @@ void PS3BT::L2CAP_task()
|
|||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nDualshock 3 Controller Enabled\r\n"));
|
||||
#endif
|
||||
PS3BTConnected = true;
|
||||
PS3Connected = true;
|
||||
} else if (remote_name[0] == 'N') { // First letter in Navigation Controller ('N')
|
||||
setLedOn(LED1); // This just turns LED constantly on, on the Navigation controller
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nNavigation Controller Enabled\r\n"));
|
||||
#endif
|
||||
PS3NavigationBTConnected = true;
|
||||
PS3NavigationConnected = true;
|
||||
} else if(remote_name[0] == 'M') { // First letter in Motion Controller ('M')
|
||||
moveSetBulb(Red);
|
||||
timerBulbRumble = millis();
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nMotion Controller Enabled\r\n"));
|
||||
#endif
|
||||
PS3MoveBTConnected = true;
|
||||
PS3MoveConnected = true;
|
||||
}
|
||||
l2cap_state = L2CAP_EV_L2CAP_DONE;
|
||||
}
|
||||
break;
|
||||
|
||||
case L2CAP_EV_L2CAP_DONE:
|
||||
if (PS3MoveBTConnected)//The Bulb and rumble values, has to be send at aproximatly every 5th second for it to stay on
|
||||
if (PS3MoveConnected)//The Bulb and rumble values, has to be send at aproximatly every 5th second for it to stay on
|
||||
{
|
||||
dtimeBulbRumble = millis() - timerBulbRumble;
|
||||
if (dtimeBulbRumble > 4000)//Send at least every 4th second
|
||||
if (millis() - timerBulbRumble > 4000)//Send at least every 4th second
|
||||
{
|
||||
HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE);//The Bulb and rumble values, has to be written again and again, for it to stay turned on
|
||||
timerBulbRumble = millis();
|
||||
|
@ -1231,11 +1226,13 @@ void PS3BT::L2CAP_task()
|
|||
/************************************************************/
|
||||
void PS3BT::readReport()
|
||||
{
|
||||
if (l2capinbuf == NULL)
|
||||
return;
|
||||
if(l2capinbuf[8] == 0xA1)//HID_THDR_DATA_INPUT
|
||||
{
|
||||
if(PS3BTConnected || PS3NavigationBTConnected)
|
||||
if(PS3Connected || PS3NavigationConnected)
|
||||
ButtonState = (uint32_t)(l2capinbuf[11] | ((uint16_t)l2capinbuf[12] << 8) | ((uint32_t)l2capinbuf[13] << 16));
|
||||
else if(PS3MoveBTConnected)
|
||||
else if(PS3MoveConnected)
|
||||
ButtonState = (uint32_t)(l2capinbuf[10] | ((uint16_t)l2capinbuf[11] << 8) | ((uint32_t)l2capinbuf[12] << 16));
|
||||
|
||||
//Notify(PSTR("\r\nButtonState");
|
||||
|
@ -1265,7 +1262,9 @@ void PS3BT::readReport()
|
|||
}
|
||||
|
||||
void PS3BT::printReport() //Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
|
||||
{
|
||||
{
|
||||
if (l2capinbuf == NULL)
|
||||
return;
|
||||
if(l2capinbuf[8] == 0xA1)//HID_THDR_DATA_INPUT
|
||||
{
|
||||
for(uint8_t i = 10; i < 58;i++)
|
||||
|
@ -1319,6 +1318,13 @@ void PS3BT::hci_read_bdaddr()
|
|||
hcibuf[1] = 0x04 << 2; // HCI OGF = 4
|
||||
hcibuf[2] = 0x00;
|
||||
HCI_Command(hcibuf, 3);
|
||||
}
|
||||
void PS3BT::hci_read_local_version_information()
|
||||
{
|
||||
hcibuf[0] = 0x01; // HCI OCF = 1
|
||||
hcibuf[1] = 0x04 << 2; // HCI OGF = 4
|
||||
hcibuf[2] = 0x00;
|
||||
HCI_Command(hcibuf, 3);
|
||||
}
|
||||
void PS3BT::hci_accept_connection()
|
||||
{
|
||||
|
@ -1511,12 +1517,10 @@ void PS3BT::HID_Command(uint8_t* data, uint16_t nbytes)
|
|||
buf[7] = control_scid[1];
|
||||
|
||||
for (uint16_t i = 0; i < nbytes; i++)//L2CAP C-frame
|
||||
buf[8 + i] = data[i];
|
||||
buf[8 + i] = data[i];
|
||||
|
||||
dtimeHID = millis() - timerHID;
|
||||
|
||||
if (dtimeHID <= 250)// Check if is has been more than 250ms since last command
|
||||
delay((uint32_t)(250 - dtimeHID));//There have to be a delay between commands
|
||||
if (millis() - timerHID <= 250)// Check if is has been more than 250ms since last command
|
||||
delay((uint32_t)(250 - (millis() - timerHID)));//There have to be a delay between commands
|
||||
|
||||
pUsb->outTransfer(bAddress, epInfo[ BTD_DATAOUT_PIPE ].epAddr, (8 + nbytes), buf);
|
||||
|
||||
|
@ -1567,19 +1571,17 @@ void PS3BT::setRumbleOn(Rumble mode)
|
|||
}
|
||||
void PS3BT::setLedOff(LED a)
|
||||
{
|
||||
//check if LED is already off
|
||||
if ((uint8_t)((uint8_t)(((uint16_t)a << 1) & HIDBuffer[11])) != 0)
|
||||
{
|
||||
//set the LED into the write buffer
|
||||
HIDBuffer[11] = (uint8_t)((uint8_t)(((uint16_t)a & 0x0f) << 1) ^ HIDBuffer[11]);
|
||||
|
||||
HID_Command(HIDBuffer, HID_BUFFERSIZE);
|
||||
}
|
||||
HIDBuffer[11] &= ~((uint8_t)(((uint16_t)a & 0x0f) << 1));
|
||||
HID_Command(HIDBuffer, HID_BUFFERSIZE);
|
||||
}
|
||||
void PS3BT::setLedOn(LED a)
|
||||
{
|
||||
HIDBuffer[11] = (uint8_t)((uint8_t)(((uint16_t)a & 0x0f) << 1) | HIDBuffer[11]);
|
||||
|
||||
HIDBuffer[11] |= (uint8_t)(((uint16_t)a & 0x0f) << 1);
|
||||
HID_Command(HIDBuffer, HID_BUFFERSIZE);
|
||||
}
|
||||
void PS3BT::setLedToggle(LED a)
|
||||
{
|
||||
HIDBuffer[11] ^= (uint8_t)(((uint16_t)a & 0x0f) << 1);
|
||||
HID_Command(HIDBuffer, HID_BUFFERSIZE);
|
||||
}
|
||||
void PS3BT::enable_sixaxis()//Command used to enable the Dualshock 3 and Navigation controller to send data via USB
|
||||
|
@ -1609,12 +1611,10 @@ void PS3BT::HIDMove_Command(uint8_t* data,uint16_t nbytes)
|
|||
buf[7] = interrupt_scid[1];
|
||||
|
||||
for (uint16_t i = 0; i < nbytes; i++)//L2CAP C-frame
|
||||
buf[8 + i] = data[i];
|
||||
buf[8 + i] = data[i];
|
||||
|
||||
dtimeHID = millis() - timerHID;
|
||||
|
||||
if (dtimeHID <= 250)// Check if is has been less than 200ms since last command
|
||||
delay((uint32_t)(250 - dtimeHID));//There have to be a delay between commands
|
||||
if (millis() - timerHID <= 250)// Check if is has been less than 200ms since last command
|
||||
delay((uint32_t)(250 - (millis() - timerHID)));//There have to be a delay between commands
|
||||
|
||||
pUsb->outTransfer(bAddress, epInfo[ BTD_DATAOUT_PIPE ].epAddr, (8 + nbytes), buf);
|
||||
|
||||
|
@ -1631,15 +1631,14 @@ void PS3BT::moveSetBulb(uint8_t r, uint8_t g, uint8_t b)//Use this to set the Co
|
|||
}
|
||||
void PS3BT::moveSetBulb(Colors color)//Use this to set the Color using the predefined colors in "enums.h"
|
||||
{
|
||||
//set the Bulb's values into the write buffer
|
||||
HIDMoveBuffer[3] = (uint8_t)(color >> 16);
|
||||
HIDMoveBuffer[4] = (uint8_t)(color >> 8);
|
||||
HIDMoveBuffer[5] = (uint8_t)(color);
|
||||
|
||||
HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE);
|
||||
moveSetBulb((uint8_t)(color >> 16),(uint8_t)(color >> 8),(uint8_t)(color));
|
||||
}
|
||||
void PS3BT::moveSetRumble(uint8_t rumble)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if(rumble < 64 && rumble != 0) // The rumble value has to at least 64, or approximately 25% (64/255*100)
|
||||
Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"));
|
||||
#endif
|
||||
//set the rumble value into the write buffer
|
||||
HIDMoveBuffer[7] = rumble;
|
||||
|
||||
|
|
77
PS3BT.h
77
PS3BT.h
|
@ -62,13 +62,14 @@
|
|||
#define HCI_INIT_STATE 0
|
||||
#define HCI_RESET_STATE 1
|
||||
#define HCI_BDADDR_STATE 2
|
||||
#define HCI_SCANNING_STATE 3
|
||||
#define HCI_CONNECT_IN_STATE 4
|
||||
#define HCI_REMOTE_NAME_STATE 5
|
||||
#define HCI_CONNECTED_STATE 6
|
||||
#define HCI_DISABLE_SCAN 7
|
||||
#define HCI_DONE_STATE 8
|
||||
#define HCI_DISCONNECT_STATE 9
|
||||
#define HCI_LOCAL_VERSION_STATE 3
|
||||
#define HCI_SCANNING_STATE 4
|
||||
#define HCI_CONNECT_IN_STATE 5
|
||||
#define HCI_REMOTE_NAME_STATE 6
|
||||
#define HCI_CONNECTED_STATE 7
|
||||
#define HCI_DISABLE_SCAN 8
|
||||
#define HCI_DONE_STATE 9
|
||||
#define HCI_DISCONNECT_STATE 10
|
||||
|
||||
/* HCI event flags*/
|
||||
#define HCI_FLAG_CMD_COMPLETE 0x01
|
||||
|
@ -76,6 +77,8 @@
|
|||
#define HCI_FLAG_DISCONN_COMPLETE 0x04
|
||||
#define HCI_FLAG_REMOTE_NAME_COMPLETE 0x08
|
||||
#define HCI_FLAG_INCOMING_REQUEST 0x10
|
||||
#define HCI_FLAG_READ_BDADDR 0x20
|
||||
#define HCI_FLAG_READ_VERSION 0x40
|
||||
|
||||
/*Macros for HCI event flag tests */
|
||||
#define hci_cmd_complete (hci_event_flag & HCI_FLAG_CMD_COMPLETE)
|
||||
|
@ -83,6 +86,8 @@
|
|||
#define hci_disconnect_complete (hci_event_flag & HCI_FLAG_DISCONN_COMPLETE)
|
||||
#define hci_remote_name_complete (hci_event_flag & HCI_FLAG_REMOTE_NAME_COMPLETE)
|
||||
#define hci_incoming_connect_request (hci_event_flag & HCI_FLAG_INCOMING_REQUEST)
|
||||
#define hci_read_bdaddr_complete (hci_event_flag & HCI_FLAG_READ_BDADDR)
|
||||
#define hci_read_version_complete (hci_event_flag & HCI_FLAG_READ_VERSION)
|
||||
|
||||
/* HCI Events managed */
|
||||
#define EV_COMMAND_COMPLETE 0x0E
|
||||
|
@ -174,24 +179,24 @@ enum LED
|
|||
};
|
||||
enum Colors
|
||||
{
|
||||
//Used to set the colors of the move controller
|
||||
Red = 0xFF0000,//((255 << 16) | (0 << 8) | 0);
|
||||
Green = 0xFF00,//((0 << 16) | (255 << 8) | 0);
|
||||
Blue = 0xFF,//((0 << 16) | (0 << 8) | 255);
|
||||
// Used to set the colors of the move controller
|
||||
Red = 0xFF0000, // r = 255, g = 0, b = 0
|
||||
Green = 0xFF00, // r = 0, g = 255, b = 0
|
||||
Blue = 0xFF, // r = 0, g = 0, b = 255
|
||||
|
||||
Yellow = 0xFFEB04,//((255 << 16) | (235 << 8) | 4);
|
||||
Lightblue = 0xFFFF,//((0 << 16) | (255 << 8) | 255);
|
||||
Purble = 0xFF00FF,//((255 << 16) | (0 << 8) | 255);
|
||||
Yellow = 0xFFEB04, // r = 255, g = 235, b = 4
|
||||
Lightblue = 0xFFFF, // r = 0, g = 255, b = 255
|
||||
Purble = 0xFF00FF, // r = 255, g = 0, b = 255
|
||||
|
||||
White = 0xFFFFFF,//((255 << 16) | (255 << 8) | 255);
|
||||
Off = 0x00,//((0 << 16) | (0 << 8) | 0);
|
||||
White = 0xFFFFFF, // r = 255, g = 255, b = 255
|
||||
Off = 0x00, // r = 0, g = 0, b = 0
|
||||
};
|
||||
|
||||
enum Button
|
||||
{
|
||||
// byte location | bit location
|
||||
|
||||
//Sixaxis Dualshcock 3 & Navigation controller
|
||||
// Sixaxis Dualshcock 3 & Navigation controller
|
||||
SELECT = (11 << 8) | 0x01,
|
||||
L3 = (11 << 8) | 0x02,
|
||||
R3 = (11 << 8) | 0x04,
|
||||
|
@ -212,7 +217,13 @@ enum Button
|
|||
|
||||
PS = (13 << 8) | 0x01,
|
||||
|
||||
//Playstation Move Controller
|
||||
MOVE = (13/*12*/ << 8) | 0x08, // covers 12 bits - we only need to read the top 8
|
||||
T = (13/*12*/ << 8) | 0x10, // covers 12 bits - we only need to read the top 8
|
||||
|
||||
|
||||
// These are the true locations for the Move controller, but to make the same syntax for all controllers, it is handled by getButton()
|
||||
/*
|
||||
// Playstation Move Controller
|
||||
SELECT_MOVE = (10 << 8) | 0x01,
|
||||
START_MOVE = (10 << 8) | 0x08,
|
||||
|
||||
|
@ -222,8 +233,9 @@ enum Button
|
|||
SQUARE_MOVE = (11 << 8) | 0x80,
|
||||
|
||||
PS_MOVE = (12 << 8) | 0x01,
|
||||
MOVE_MOVE = (12 << 8) | 0x08,//covers 12 bits - we only need to read the top 8
|
||||
T_MOVE = (12 << 8) | 0x10,//covers 12 bits - we only need to read the top 8
|
||||
MOVE_MOVE = (12 << 8) | 0x08, // covers 12 bits - we only need to read the top 8
|
||||
T_MOVE = (12 << 8) | 0x10, // covers 12 bits - we only need to read the top 8
|
||||
*/
|
||||
};
|
||||
enum AnalogButton
|
||||
{
|
||||
|
@ -243,7 +255,7 @@ enum AnalogButton
|
|||
SQUARE_ANALOG = 34,
|
||||
|
||||
//Playstation Move Controller
|
||||
T_MOVE_ANALOG = 15,//Both at byte 14 (last reading) and byte 15 (current reading)
|
||||
T_ANALOG = 15, // Both at byte 14 (last reading) and byte 15 (current reading)
|
||||
};
|
||||
enum AnalogHat
|
||||
{
|
||||
|
@ -315,9 +327,8 @@ enum Rumble
|
|||
|
||||
class PS3BT : public USBDeviceConfig, public UsbConfigXtracter
|
||||
{
|
||||
public:
|
||||
PS3BT(USB *pUsb, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0);
|
||||
PS3BT(USB *pUsb);
|
||||
public:
|
||||
PS3BT(USB *pUsb, uint8_t btadr5=0, uint8_t btadr4=0, uint8_t btadr3=0, uint8_t btadr2=0, uint8_t btadr1=0, uint8_t btadr0=0);
|
||||
|
||||
// USBDeviceConfig implementation
|
||||
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
|
||||
|
@ -338,10 +349,11 @@ public:
|
|||
bool getButton(Button b);
|
||||
uint8_t getAnalogButton(AnalogButton a);
|
||||
uint8_t getAnalogHat(AnalogHat a);
|
||||
int32_t getSensor(Sensor a);
|
||||
int16_t getSensor(Sensor a);
|
||||
double getAngle(Angle a);
|
||||
bool getStatus(Status c);
|
||||
String getStatusString();
|
||||
String getTemperature();
|
||||
void disconnect(); // use this void to disconnect any of the controllers
|
||||
|
||||
/* HID Commands */
|
||||
|
@ -351,17 +363,18 @@ public:
|
|||
void setRumbleOn(Rumble mode);
|
||||
void setLedOff(LED a);
|
||||
void setLedOn(LED a);
|
||||
void setLedToggle(LED a);
|
||||
/* Commands for Motion controller only */
|
||||
void moveSetBulb(uint8_t r, uint8_t g, uint8_t b);//Use this to set the Color using RGB values
|
||||
void moveSetBulb(Colors color);//Use this to set the Color using the predefined colors in "enum Colors"
|
||||
void moveSetRumble(uint8_t rumble);
|
||||
|
||||
bool PS3BTConnected;// Variable used to indicate if the normal playstation controller is successfully connected
|
||||
bool PS3MoveBTConnected;// Variable used to indicate if the move controller is successfully connected
|
||||
bool PS3NavigationBTConnected;// Variable used to indicate if the navigation controller is successfully connected
|
||||
bool PS3Connected;// Variable used to indicate if the normal playstation controller is successfully connected
|
||||
bool PS3MoveConnected;// Variable used to indicate if the move controller is successfully connected
|
||||
bool PS3NavigationConnected;// Variable used to indicate if the navigation controller is successfully connected
|
||||
bool buttonChanged;//Indicate if a button has been changed
|
||||
bool buttonPressed;//Indicate if a button has been pressed
|
||||
bool buttonReleased;//Indicate if a button has been pressed
|
||||
bool buttonReleased;//Indicate if a button has been released
|
||||
|
||||
protected:
|
||||
/* mandatory members */
|
||||
|
@ -389,6 +402,7 @@ private:
|
|||
int16_t hci_handle;
|
||||
uint8_t disc_bdaddr[6]; // the bluetooth address is always 6 bytes
|
||||
uint8_t remote_name[30]; // first 30 chars of remote name
|
||||
uint8_t hci_version;
|
||||
|
||||
/* variables used by high level HCI task */
|
||||
uint8_t hci_state; //current state of bluetooth hci connection
|
||||
|
@ -405,11 +419,9 @@ private:
|
|||
uint32_t ButtonState;
|
||||
uint32_t OldButtonState;
|
||||
uint32_t timerHID;// timer used see if there has to be a delay before a new HID command
|
||||
uint32_t dtimeHID;// delta time since last HID command
|
||||
uint32_t timerBulbRumble;// used to continuously set PS3 Move controller Bulb and rumble values
|
||||
uint32_t dtimeBulbRumble;// used to know how longs since last since the Bulb and rumble values was written
|
||||
|
||||
uint8_t my_bdaddr[6]; //Change to your dongles Bluetooth address in PS3BT.cpp
|
||||
uint8_t my_bdaddr[6]; // Change to your dongles Bluetooth address in the constructor
|
||||
uint8_t hcibuf[BULK_MAXPKTSIZE];//General purpose buffer for hci data
|
||||
uint8_t l2capinbuf[BULK_MAXPKTSIZE];//General purpose buffer for l2cap in data
|
||||
uint8_t l2capoutbuf[BULK_MAXPKTSIZE];//General purpose buffer for l2cap out data
|
||||
|
@ -437,6 +449,7 @@ private:
|
|||
void hci_write_scan_enable();
|
||||
void hci_write_scan_disable();
|
||||
void hci_read_bdaddr();
|
||||
void hci_read_local_version_information();
|
||||
void hci_accept_connection();
|
||||
void hci_remote_name();
|
||||
void hci_disconnect();
|
||||
|
|
605
PS3USB.cpp
Normal file
605
PS3USB.cpp
Normal file
|
@ -0,0 +1,605 @@
|
|||
/* 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
|
||||
*/
|
||||
|
||||
#include "PS3USB.h"
|
||||
#define DEBUG // Uncomment to print data for debugging
|
||||
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
||||
//#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers
|
||||
|
||||
prog_char PS3_REPORT_BUFFER[] PROGMEM = {
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0xff, 0x27, 0x10, 0x00, 0x32,
|
||||
0xff, 0x27, 0x10, 0x00, 0x32,
|
||||
0xff, 0x27, 0x10, 0x00, 0x32,
|
||||
0xff, 0x27, 0x10, 0x00, 0x32,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
prog_char MOVE_REPORT_BUFFER[] PROGMEM = {
|
||||
0x02, 0x00, // Always 0x02, 0x00,
|
||||
0x00, 0x00, 0x00, // r, g, b,
|
||||
0x00, // Always 0x00,
|
||||
0x00 // Rumble
|
||||
};
|
||||
|
||||
PS3USB::PS3USB(USB *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0):
|
||||
pUsb(p), // pointer to USB class instance - mandatory
|
||||
bAddress(0), // device address - mandatory
|
||||
bPollEnable(false) // don't start polling before dongle is connected
|
||||
{
|
||||
for(uint8_t i=0; i<PS3_MAX_ENDPOINTS; i++)
|
||||
{
|
||||
epInfo[i].epAddr = 0;
|
||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||
epInfo[i].epAttribs = 0;
|
||||
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
||||
}
|
||||
|
||||
if (pUsb) // register in USB subsystem
|
||||
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
|
||||
|
||||
my_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead
|
||||
my_bdaddr[4] = btadr4;
|
||||
my_bdaddr[3] = btadr3;
|
||||
my_bdaddr[2] = btadr2;
|
||||
my_bdaddr[1] = btadr1;
|
||||
my_bdaddr[0] = btadr0;
|
||||
}
|
||||
|
||||
uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed)
|
||||
{
|
||||
uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)];
|
||||
uint8_t rcode;
|
||||
UsbDevice *p = NULL;
|
||||
EpInfo *oldep_ptr = NULL;
|
||||
uint16_t PID;
|
||||
uint16_t VID;
|
||||
|
||||
// get memory address of USB device address pool
|
||||
AddressPool &addrPool = pUsb->GetAddressPool();
|
||||
#ifdef EXTRADEBUG
|
||||
Notify(PSTR("\r\nPS3USB Init"));
|
||||
#endif
|
||||
// check if address has already been assigned to an instance
|
||||
if (bAddress)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nAddress in use"));
|
||||
#endif
|
||||
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
||||
}
|
||||
|
||||
// Get pointer to pseudo device with address 0 assigned
|
||||
p = addrPool.GetUsbDevicePtr(0);
|
||||
|
||||
if (!p)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nAddress not found"));
|
||||
#endif
|
||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||
}
|
||||
|
||||
if (!p->epinfo)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nepinfo is null"));
|
||||
#endif
|
||||
return USB_ERROR_EPINFO_IS_NULL;
|
||||
}
|
||||
|
||||
// Save old pointer to EP_RECORD of address 0
|
||||
oldep_ptr = p->epinfo;
|
||||
|
||||
// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
|
||||
p->epinfo = epInfo;
|
||||
|
||||
p->lowspeed = lowspeed;
|
||||
|
||||
// Get device descriptor
|
||||
rcode = pUsb->getDevDescr(0, 0, sizeof(USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);// Get device descriptor - addr, ep, nbytes, data
|
||||
|
||||
// Restore p->epinfo
|
||||
p->epinfo = oldep_ptr;
|
||||
|
||||
if(rcode)
|
||||
goto FailGetDevDescr;
|
||||
|
||||
// Allocate new address according to device class
|
||||
bAddress = addrPool.AllocAddress(parent, false, port);
|
||||
|
||||
if (!bAddress)
|
||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||
|
||||
// Extract Max Packet Size from device descriptor
|
||||
epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
|
||||
|
||||
// Assign new address to the device
|
||||
rcode = pUsb->setAddr( 0, 0, bAddress );
|
||||
if (rcode)
|
||||
{
|
||||
p->lowspeed = false;
|
||||
addrPool.FreeAddress(bAddress);
|
||||
bAddress = 0;
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nsetAddr: "));
|
||||
#endif
|
||||
PrintHex<uint8_t>(rcode);
|
||||
return rcode;
|
||||
}
|
||||
#ifdef EXTRADEBUG
|
||||
Notify(PSTR("\r\nAddr: "));
|
||||
PrintHex<uint8_t>(bAddress);
|
||||
#endif
|
||||
p->lowspeed = false;
|
||||
|
||||
//get pointer to assigned address record
|
||||
p = addrPool.GetUsbDevicePtr(bAddress);
|
||||
if (!p)
|
||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||
|
||||
p->lowspeed = lowspeed;
|
||||
|
||||
// Assign epInfo to epinfo pointer - only EP0 is known
|
||||
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
||||
if (rcode)
|
||||
goto FailSetDevTblEntry;
|
||||
|
||||
VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor;
|
||||
PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct;
|
||||
|
||||
if(VID == PS3_VID && (PID == PS3_PID || PID == PS3NAVIGATION_PID || PID == PS3MOVE_PID)) {
|
||||
/* The application will work in reduced host mode, so we can save program and data
|
||||
memory space. After verifying the PID and VID we will use known values for the
|
||||
configuration values for device, interface, endpoints and HID for the PS3 Controllers */
|
||||
|
||||
/* Initialize data structures for endpoints of device */
|
||||
epInfo[ PS3_OUTPUT_PIPE ].epAddr = 0x02; // PS3 output endpoint
|
||||
epInfo[ PS3_OUTPUT_PIPE ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ PS3_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ PS3_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ PS3_OUTPUT_PIPE ].bmSndToggle = bmSNDTOG0;
|
||||
epInfo[ PS3_OUTPUT_PIPE ].bmRcvToggle = bmRCVTOG0;
|
||||
epInfo[ PS3_INPUT_PIPE ].epAddr = 0x01; // PS3 report endpoint
|
||||
epInfo[ PS3_INPUT_PIPE ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ PS3_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ PS3_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ PS3_INPUT_PIPE ].bmSndToggle = bmSNDTOG0;
|
||||
epInfo[ PS3_INPUT_PIPE ].bmRcvToggle = bmRCVTOG0;
|
||||
|
||||
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
|
||||
if( rcode )
|
||||
goto FailSetDevTblEntry;
|
||||
|
||||
delay(200);//Give time for address change
|
||||
|
||||
rcode = pUsb->setConf(bAddress, epInfo[ PS3_CONTROL_PIPE ].epAddr, 1);
|
||||
if( rcode )
|
||||
goto FailSetConf;
|
||||
|
||||
if(PID == PS3_PID || PID == PS3NAVIGATION_PID)
|
||||
{
|
||||
if(PID == PS3_PID) {
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nDualshock 3 Controller Connected"));
|
||||
#endif
|
||||
PS3Connected = true;
|
||||
} else { // must be a navigation controller
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nNavigation Controller Connected"));
|
||||
#endif
|
||||
PS3NavigationConnected = true;
|
||||
}
|
||||
/* Set internal bluetooth address and request for data */
|
||||
setBdaddr(my_bdaddr);
|
||||
enable_sixaxis();
|
||||
setLedOn(LED1);
|
||||
|
||||
// Needed for PS3 Dualshock and Navigation commands to work
|
||||
for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
|
||||
writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]);
|
||||
|
||||
for (uint8_t i = 6; i < 10; i++)
|
||||
readBuf[i] = 0x7F; // Set the analog joystick values to center position
|
||||
}
|
||||
else // must be a Motion controller
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nMotion Controller Connected"));
|
||||
#endif
|
||||
PS3MoveConnected = true;
|
||||
setMoveBdaddr(my_bdaddr); // Set internal bluetooth address
|
||||
moveSetBulb(Red);
|
||||
|
||||
// Needed for Move commands to work
|
||||
for (uint8_t i = 0; i < MOVE_REPORT_BUFFER_SIZE; i++)
|
||||
writeBuf[i] = pgm_read_byte(&MOVE_REPORT_BUFFER[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
goto FailUnknownDevice;
|
||||
|
||||
bPollEnable = true;
|
||||
Notify(PSTR("\r\n"));
|
||||
timer = millis();
|
||||
return 0; // successful configuration
|
||||
|
||||
/* diagnostic messages */
|
||||
FailGetDevDescr:
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\ngetDevDescr:"));
|
||||
#endif
|
||||
goto Fail;
|
||||
FailSetDevTblEntry:
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nsetDevTblEn:"));
|
||||
#endif
|
||||
goto Fail;
|
||||
FailSetConf:
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nsetConf:"));
|
||||
#endif
|
||||
goto Fail;
|
||||
FailUnknownDevice:
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nUnknown Device Connected - VID: "));
|
||||
PrintHex<uint16_t>(VID);
|
||||
Notify(PSTR(" PID: "));
|
||||
PrintHex<uint16_t>(PID);
|
||||
#endif
|
||||
goto Fail;
|
||||
Fail:
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nPS3 Init Failed, error code: "));
|
||||
Serial.print(rcode);
|
||||
#endif
|
||||
Release();
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/* Performs a cleanup after failed Init() attempt */
|
||||
uint8_t PS3USB::Release()
|
||||
{
|
||||
PS3Connected = false;
|
||||
PS3MoveConnected = false;
|
||||
PS3NavigationConnected = false;
|
||||
pUsb->GetAddressPool().FreeAddress(bAddress);
|
||||
bAddress = 0;
|
||||
bPollEnable = false;
|
||||
return 0;
|
||||
}
|
||||
uint8_t PS3USB::Poll()
|
||||
{
|
||||
if (!bPollEnable)
|
||||
return 0;
|
||||
|
||||
if(PS3Connected || PS3NavigationConnected) {
|
||||
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
|
||||
pUsb->inTransfer(bAddress, epInfo[ PS3_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
|
||||
if(millis() - timer > 100) { // Loop 100ms before processing data
|
||||
readReport();
|
||||
#ifdef PRINTREPORT
|
||||
printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else if(PS3MoveConnected) { // One can only set the color of the bulb, set the rumble, set and get the bluetooth address and calibrate the magnetometer via USB
|
||||
if (millis() - timer > 4000) // Send at least every 4th second
|
||||
{
|
||||
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE); // The Bulb and rumble values, has to be written again and again, for it to stay turned on
|
||||
timer = millis();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void PS3USB::readReport()
|
||||
{
|
||||
if (readBuf == NULL)
|
||||
return;
|
||||
|
||||
ButtonState = (uint32_t)(readBuf[2] | ((uint16_t)readBuf[3] << 8) | ((uint32_t)readBuf[4] << 16));
|
||||
|
||||
//Notify(PSTR("\r\nButtonState");
|
||||
//PrintHex<uint32_t>(ButtonState);
|
||||
|
||||
if(ButtonState != OldButtonState)
|
||||
{
|
||||
buttonChanged = true;
|
||||
if(ButtonState != 0x00) {
|
||||
buttonPressed = true;
|
||||
buttonReleased = false;
|
||||
} else {
|
||||
buttonPressed = false;
|
||||
buttonReleased = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
buttonChanged = false;
|
||||
buttonPressed = false;
|
||||
buttonReleased = false;
|
||||
}
|
||||
|
||||
OldButtonState = ButtonState;
|
||||
}
|
||||
|
||||
void PS3USB::printReport() //Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
|
||||
{
|
||||
if (readBuf == NULL)
|
||||
return;
|
||||
for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE;i++)
|
||||
{
|
||||
PrintHex<uint8_t>(readBuf[i]);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
bool PS3USB::getButton(Button b)
|
||||
{
|
||||
if (readBuf == NULL)
|
||||
return false;
|
||||
if ((readBuf[(uint16_t)b >> 8] & ((uint8_t)b & 0xff)) > 0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
uint8_t PS3USB::getAnalogButton(AnalogButton a)
|
||||
{
|
||||
if (readBuf == NULL)
|
||||
return 0;
|
||||
return (uint8_t)(readBuf[(uint16_t)a]);
|
||||
}
|
||||
uint8_t PS3USB::getAnalogHat(AnalogHat a)
|
||||
{
|
||||
if (readBuf == NULL)
|
||||
return 0;
|
||||
return (uint8_t)(readBuf[(uint16_t)a]);
|
||||
}
|
||||
uint16_t PS3USB::getSensor(Sensor a)
|
||||
{
|
||||
if (readBuf == NULL)
|
||||
return 0;
|
||||
return ((readBuf[(uint16_t)a] << 8) | readBuf[(uint16_t)a + 1]);
|
||||
}
|
||||
double PS3USB::getAngle(Angle a) {
|
||||
if(PS3Connected) {
|
||||
double accXval;
|
||||
double accYval;
|
||||
double accZval;
|
||||
|
||||
// Data for the Kionix KXPC4 used in the DualShock 3
|
||||
const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V)
|
||||
accXval = -((double)getSensor(aX)-zeroG);
|
||||
accYval = -((double)getSensor(aY)-zeroG);
|
||||
accZval = -((double)getSensor(aZ)-zeroG);
|
||||
|
||||
// Convert to 360 degrees resolution
|
||||
// atan2 outputs the value of -π to π (radians)
|
||||
// We are then converting it to 0 to 2π and then to degrees
|
||||
if (a == Pitch) {
|
||||
double angle = (atan2(accYval,accZval)+PI)*RAD_TO_DEG;
|
||||
return angle;
|
||||
} else {
|
||||
double angle = (atan2(accXval,accZval)+PI)*RAD_TO_DEG;
|
||||
return angle;
|
||||
}
|
||||
} else
|
||||
return 0;
|
||||
|
||||
}
|
||||
bool PS3USB::getStatus(Status c)
|
||||
{
|
||||
if (readBuf == NULL)
|
||||
return false;
|
||||
if (readBuf[(uint16_t)c >> 8] == ((uint8_t)c & 0xff))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
String PS3USB::getStatusString()
|
||||
{
|
||||
if (PS3Connected || PS3NavigationConnected)
|
||||
{
|
||||
char statusOutput[100];
|
||||
|
||||
strcpy(statusOutput,"ConnectionStatus: ");
|
||||
|
||||
if (getStatus(Plugged)) strcat(statusOutput,"Plugged");
|
||||
else if (getStatus(Unplugged)) strcat(statusOutput,"Unplugged");
|
||||
else strcat(statusOutput,"Error");
|
||||
|
||||
|
||||
strcat(statusOutput," - PowerRating: ");
|
||||
|
||||
if (getStatus(Charging)) strcat(statusOutput,"Charging");
|
||||
else if (getStatus(NotCharging)) strcat(statusOutput,"Not Charging");
|
||||
else if (getStatus(Shutdown)) strcat(statusOutput,"Shutdown");
|
||||
else if (getStatus(Dying)) strcat(statusOutput,"Dying");
|
||||
else if (getStatus(Low)) strcat(statusOutput,"Low");
|
||||
else if (getStatus(High)) strcat(statusOutput,"High");
|
||||
else if (getStatus(Full)) strcat(statusOutput,"Full");
|
||||
else strcat(statusOutput,"Error");
|
||||
|
||||
strcat(statusOutput," - WirelessStatus: ");
|
||||
|
||||
if (getStatus(CableRumble)) strcat(statusOutput,"Cable - Rumble is on");
|
||||
else if (getStatus(Cable)) strcat(statusOutput,"Cable - Rumble is off");
|
||||
else if (getStatus(BluetoothRumble)) strcat(statusOutput,"Bluetooth - Rumble is on");
|
||||
else if (getStatus(Bluetooth)) strcat(statusOutput,"Bluetooth - Rumble is off");
|
||||
else strcat(statusOutput,"Error");
|
||||
|
||||
return statusOutput;
|
||||
}
|
||||
}
|
||||
|
||||
/* Playstation Sixaxis Dualshock and Navigation Controller commands */
|
||||
void PS3USB::PS3_Command(uint8_t* data, uint16_t nbytes)
|
||||
{
|
||||
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x01), Report Type (Output 0x02), interface (0x00), datalength, datalength, data)
|
||||
pUsb->ctrlReq(bAddress,epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x01, 0x02, 0x00, nbytes, nbytes, data, NULL);
|
||||
}
|
||||
void PS3USB::setAllOff()
|
||||
{
|
||||
for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
|
||||
writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); // Reset buffer
|
||||
|
||||
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
||||
}
|
||||
void PS3USB::setRumbleOff()
|
||||
{
|
||||
writeBuf[1] = 0x00;
|
||||
writeBuf[2] = 0x00;//low mode off
|
||||
writeBuf[3] = 0x00;
|
||||
writeBuf[4] = 0x00;//high mode off
|
||||
|
||||
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
||||
}
|
||||
void PS3USB::setRumbleOn(Rumble mode)
|
||||
{
|
||||
/* Still not totally sure how it works, maybe something like this instead?
|
||||
* 3 - duration_right
|
||||
* 4 - power_right
|
||||
* 5 - duration_left
|
||||
* 6 - power_left
|
||||
*/
|
||||
if ((mode & 0x30) > 0)
|
||||
{
|
||||
writeBuf[1] = 0xfe;
|
||||
writeBuf[3] = 0xfe;
|
||||
|
||||
if (mode == RumbleHigh)
|
||||
{
|
||||
writeBuf[2] = 0;//low mode off
|
||||
writeBuf[4] = 0xff;//high mode on
|
||||
}
|
||||
else
|
||||
{
|
||||
writeBuf[2] = 0xff;//low mode on
|
||||
writeBuf[4] = 0;//high mode off
|
||||
}
|
||||
|
||||
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
||||
}
|
||||
}
|
||||
void PS3USB::setLedOff(LED a)
|
||||
{
|
||||
writeBuf[9] &= ~((uint8_t)(((uint16_t)a & 0x0f) << 1));
|
||||
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
||||
}
|
||||
void PS3USB::setLedOn(LED a)
|
||||
{
|
||||
writeBuf[9] |= (uint8_t)(((uint16_t)a & 0x0f) << 1);
|
||||
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
||||
}
|
||||
void PS3USB::setLedToggle(LED a)
|
||||
{
|
||||
writeBuf[9] ^= (uint8_t)(((uint16_t)a & 0x0f) << 1);
|
||||
PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
|
||||
}
|
||||
void PS3USB::setBdaddr(uint8_t* BDADDR)
|
||||
{
|
||||
/* Set the internal bluetooth address */
|
||||
uint8_t buf[8];
|
||||
buf[0] = 0x01;
|
||||
buf[1] = 0x00;
|
||||
for (uint8_t i = 0; i < 6; i++)
|
||||
buf[i+2] = BDADDR[5 - i];//Copy into buffer, has to be written reversed
|
||||
|
||||
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
|
||||
pUsb->ctrlReq(bAddress,epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL);
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nBluetooth Address was set to: "));
|
||||
for(int8_t i = 5; i > 0; i--)
|
||||
{
|
||||
PrintHex<uint8_t>(my_bdaddr[i]);
|
||||
Serial.print(":");
|
||||
}
|
||||
PrintHex<uint8_t>(my_bdaddr[0]);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
void PS3USB::enable_sixaxis()//Command used to enable the Dualshock 3 and Navigation controller to send data via USB
|
||||
{
|
||||
uint8_t cmd_buf[4];
|
||||
cmd_buf[0] = 0x42;// Special PS3 Controller enable commands
|
||||
cmd_buf[1] = 0x0c;
|
||||
cmd_buf[2] = 0x00;
|
||||
cmd_buf[3] = 0x00;
|
||||
|
||||
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF4), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
|
||||
pUsb->ctrlReq(bAddress,epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF4, 0x03, 0x00, 4, 4, cmd_buf, NULL);
|
||||
}
|
||||
|
||||
/* Playstation Move Controller commands */
|
||||
void PS3USB::Move_Command(uint8_t* data, uint16_t nbytes)
|
||||
{
|
||||
pUsb->outTransfer(bAddress, epInfo[ PS3_OUTPUT_PIPE ].epAddr, nbytes, data);
|
||||
}
|
||||
|
||||
void PS3USB::moveSetBulb(uint8_t r, uint8_t g, uint8_t b)//Use this to set the Color using RGB values
|
||||
{
|
||||
// set the Bulb's values into the write buffer
|
||||
writeBuf[2] = r;
|
||||
writeBuf[3] = g;
|
||||
writeBuf[4] = b;
|
||||
|
||||
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
|
||||
}
|
||||
void PS3USB::moveSetBulb(Colors color)//Use this to set the Color using the predefined colors in "enums.h"
|
||||
{
|
||||
moveSetBulb((uint8_t)(color >> 16),(uint8_t)(color >> 8),(uint8_t)(color));
|
||||
}
|
||||
void PS3USB::moveSetRumble(uint8_t rumble)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if(rumble < 64 && rumble != 0) // The rumble value has to at least 64, or approximately 25% (64/255*100)
|
||||
Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"));
|
||||
#endif
|
||||
//set the rumble value into the write buffer
|
||||
writeBuf[6] = rumble;
|
||||
|
||||
Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
|
||||
}
|
||||
void PS3USB::setMoveBdaddr(uint8_t* BDADDR)
|
||||
{
|
||||
/* Set the internal bluetooth address */
|
||||
uint8_t buf[11];
|
||||
buf[0] = 0x05;
|
||||
buf[7] = 0x10;
|
||||
buf[8] = 0x01;
|
||||
buf[9] = 0x02;
|
||||
buf[10] = 0x12;
|
||||
|
||||
for (uint8_t i = 0; i < 6; i++)
|
||||
buf[i + 1] = BDADDR[i];
|
||||
|
||||
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x05), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
|
||||
pUsb->ctrlReq(bAddress,epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00,11,11, buf, NULL);
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nBluetooth Address was set to: "));
|
||||
for(int8_t i = 5; i > 0; i--)
|
||||
{
|
||||
PrintHex<uint8_t>(my_bdaddr[i]);
|
||||
Serial.print(":");
|
||||
}
|
||||
PrintHex<uint8_t>(my_bdaddr[0]);
|
||||
#endif
|
||||
return;
|
||||
}
|
241
PS3USB.h
Normal file
241
PS3USB.h
Normal file
|
@ -0,0 +1,241 @@
|
|||
/* 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
|
||||
*/
|
||||
|
||||
#ifndef _ps3usb_h_
|
||||
#define _ps3usb_h_
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#include "Usb.h"
|
||||
|
||||
/* PS3 data taken from descriptors */
|
||||
#define EP_MAXPKTSIZE 64 // max size for data via USB
|
||||
|
||||
/* Endpoint types */
|
||||
#define EP_INTERRUPT 0x03
|
||||
|
||||
/* Names we give to the 3 ps3 pipes - this is only used for setting the bluetooth address into the ps3 controllers */
|
||||
#define PS3_CONTROL_PIPE 0
|
||||
#define PS3_OUTPUT_PIPE 1
|
||||
#define PS3_INPUT_PIPE 2
|
||||
|
||||
//PID and VID of the different devices
|
||||
#define PS3_VID 0x054C // Sony Corporation
|
||||
#define PS3_PID 0x0268 // PS3 Controller DualShock 3
|
||||
#define PS3NAVIGATION_PID 0x042F // Navigation controller
|
||||
#define PS3MOVE_PID 0x03D5 // Motion controller
|
||||
|
||||
#define PS3_REPORT_BUFFER_SIZE 48 // Size of the output report buffer for the Dualshock and Navigation controllers
|
||||
#define MOVE_REPORT_BUFFER_SIZE 7 // Size of the output report buffer for the Move Controller
|
||||
|
||||
// used in control endpoint header for HID Commands
|
||||
#define bmREQ_HID_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
|
||||
#define HID_REQUEST_SET_REPORT 0x09
|
||||
|
||||
#define PS3_MAX_ENDPOINTS 3
|
||||
|
||||
enum LED
|
||||
{
|
||||
LED1 = 0x01,
|
||||
LED2 = 0x02,
|
||||
LED3 = 0x04,
|
||||
LED4 = 0x08,
|
||||
|
||||
LED5 = 0x09,
|
||||
LED6 = 0x0A,
|
||||
LED7 = 0x0C,
|
||||
LED8 = 0x0D,
|
||||
LED9 = 0x0E,
|
||||
LED10 = 0x0F,
|
||||
};
|
||||
enum Colors
|
||||
{
|
||||
// Used to set the colors of the move controller
|
||||
Red = 0xFF0000, // r = 255, g = 0, b = 0
|
||||
Green = 0xFF00, // r = 0, g = 255, b = 0
|
||||
Blue = 0xFF, // r = 0, g = 0, b = 255
|
||||
|
||||
Yellow = 0xFFEB04, // r = 255, g = 235, b = 4
|
||||
Lightblue = 0xFFFF, // r = 0, g = 255, b = 255
|
||||
Purble = 0xFF00FF, // r = 255, g = 0, b = 255
|
||||
|
||||
White = 0xFFFFFF, // r = 255, g = 255, b = 255
|
||||
Off = 0x00, // r = 0, g = 0, b = 0
|
||||
};
|
||||
|
||||
enum Button
|
||||
{
|
||||
// byte location | bit location
|
||||
|
||||
// Sixaxis Dualshcock 3 & Navigation controller
|
||||
SELECT = (2 << 8) | 0x01,
|
||||
L3 = (2 << 8) | 0x02,
|
||||
R3 = (2 << 8) | 0x04,
|
||||
START = (2 << 8) | 0x08,
|
||||
UP = (2 << 8) | 0x10,
|
||||
RIGHT = (2 << 8) | 0x20,
|
||||
DOWN = (2 << 8) | 0x40,
|
||||
LEFT = (2 << 8) | 0x80,
|
||||
|
||||
L2 = (3 << 8) | 0x01,
|
||||
R2 = (3 << 8) | 0x02,
|
||||
L1 = (3 << 8) | 0x04,
|
||||
R1 = (3 << 8) | 0x08,
|
||||
TRIANGLE = (3 << 8) | 0x10,
|
||||
CIRCLE = (3 << 8) | 0x20,
|
||||
CROSS = (3 << 8) | 0x40,
|
||||
SQUARE = (3 << 8) | 0x80,
|
||||
|
||||
PS = (4 << 8) | 0x01,
|
||||
};
|
||||
enum AnalogButton
|
||||
{
|
||||
// Sixaxis Dualshcock 3 & Navigation controller
|
||||
UP_ANALOG = 14,
|
||||
RIGHT_ANALOG = 15,
|
||||
DOWN_ANALOG = 16,
|
||||
LEFT_ANALOG = 17,
|
||||
|
||||
L2_ANALOG = 18,
|
||||
R2_ANALOG = 19,
|
||||
L1_ANALOG = 20,
|
||||
R1_ANALOG = 21,
|
||||
TRIANGLE_ANALOG = 22,
|
||||
CIRCLE_ANALOG = 23,
|
||||
CROSS_ANALOG = 24,
|
||||
SQUARE_ANALOG = 25,
|
||||
};
|
||||
enum AnalogHat
|
||||
{
|
||||
LeftHatX = 6,
|
||||
LeftHatY = 7,
|
||||
RightHatX = 8,
|
||||
RightHatY = 9,
|
||||
};
|
||||
enum Sensor
|
||||
{
|
||||
// Sensors inside the Sixaxis Dualshock 3 controller
|
||||
aX = 41,
|
||||
aY = 43,
|
||||
aZ = 45,
|
||||
gZ = 47,
|
||||
};
|
||||
enum Angle
|
||||
{
|
||||
Pitch = 0x01,
|
||||
Roll = 0x02,
|
||||
};
|
||||
enum Status
|
||||
{
|
||||
// byte location | bit location
|
||||
Plugged = (29 << 8) | 0x02,
|
||||
Unplugged = (29 << 8) | 0x03,
|
||||
|
||||
Charging = (30 << 8) | 0xEE,
|
||||
NotCharging = (30 << 8) | 0xF1,
|
||||
Shutdown = (30 << 8) | 0x01,
|
||||
Dying = (30 << 8) | 0x02,
|
||||
Low = (30 << 8) | 0x03,
|
||||
High = (30 << 8) | 0x04,
|
||||
Full = (30 << 8) | 0x05,
|
||||
|
||||
CableRumble = (31 << 8) | 0x10, // Opperating by USB and rumble is turned on
|
||||
Cable = (31 << 8) | 0x12, // Opperating by USB and rumble is turned off
|
||||
BluetoothRumble = (31 << 8) | 0x14, // Opperating by bluetooth and rumble is turned on
|
||||
Bluetooth = (31 << 8) | 0x16, // Opperating by bluetooth and rumble is turned off
|
||||
};
|
||||
enum Rumble
|
||||
{
|
||||
RumbleHigh = 0x10,
|
||||
RumbleLow = 0x20,
|
||||
};
|
||||
|
||||
class PS3USB : public USBDeviceConfig
|
||||
{
|
||||
public:
|
||||
PS3USB(USB *pUsb, uint8_t btadr5=0, uint8_t btadr4=0, uint8_t btadr3=0, uint8_t btadr2=0, uint8_t btadr1=0, uint8_t btadr0=0);
|
||||
|
||||
// USBDeviceConfig implementation
|
||||
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
|
||||
virtual uint8_t Release();
|
||||
virtual uint8_t Poll();
|
||||
virtual uint8_t GetAddress() { return bAddress; };
|
||||
virtual bool isReady() { return bPollEnable; };
|
||||
|
||||
void setBdaddr(uint8_t* BDADDR);
|
||||
void setMoveBdaddr(uint8_t* BDADDR);
|
||||
|
||||
/* PS3 Controller Commands */
|
||||
bool getButton(Button b);
|
||||
uint8_t getAnalogButton(AnalogButton a);
|
||||
uint8_t getAnalogHat(AnalogHat a);
|
||||
uint16_t getSensor(Sensor a);
|
||||
double getAngle(Angle a);
|
||||
bool getStatus(Status c);
|
||||
String getStatusString();
|
||||
|
||||
/* Commands for Dualshock 3 and Navigation controller */
|
||||
void setAllOff();
|
||||
void setRumbleOff();
|
||||
void setRumbleOn(Rumble mode);
|
||||
void setLedOff(LED a);
|
||||
void setLedOn(LED a);
|
||||
void setLedToggle(LED a);
|
||||
|
||||
/* Commands for Motion controller only */
|
||||
void moveSetBulb(uint8_t r, uint8_t g, uint8_t b);//Use this to set the Color using RGB values
|
||||
void moveSetBulb(Colors color);//Use this to set the Color using the predefined colors in "enum Colors"
|
||||
void moveSetRumble(uint8_t rumble);
|
||||
|
||||
bool PS3Connected;// Variable used to indicate if the normal playstation controller is successfully connected
|
||||
bool PS3MoveConnected;// Variable used to indicate if the move controller is successfully connected
|
||||
bool PS3NavigationConnected;// Variable used to indicate if the navigation controller is successfully connected */
|
||||
bool buttonChanged;//Indicate if a button has been changed
|
||||
bool buttonPressed;//Indicate if a button has been pressed
|
||||
bool buttonReleased;//Indicate if a button has been released
|
||||
|
||||
protected:
|
||||
/* mandatory members */
|
||||
USB *pUsb;
|
||||
uint8_t bAddress; // device address
|
||||
EpInfo epInfo[PS3_MAX_ENDPOINTS]; //endpoint info structure
|
||||
|
||||
private:
|
||||
bool bPollEnable;
|
||||
|
||||
uint32_t timer; // used to continuously set PS3 Move controller Bulb and rumble values
|
||||
|
||||
uint32_t ButtonState;
|
||||
uint32_t OldButtonState;
|
||||
|
||||
uint8_t my_bdaddr[6]; // Change to your dongles Bluetooth address in the constructor
|
||||
uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data
|
||||
uint8_t writeBuf[EP_MAXPKTSIZE]; // General purpose buffer for output data
|
||||
|
||||
void readReport(); // read incoming data
|
||||
void printReport(); // print incoming date - Uncomment for debugging
|
||||
|
||||
/* Private commands */
|
||||
void PS3_Command(uint8_t* data, uint16_t nbytes);
|
||||
void enable_sixaxis();//Command used to enable the Dualshock 3 and Navigation controller to send data via USB
|
||||
void Move_Command(uint8_t* data, uint16_t nbytes);
|
||||
};
|
||||
#endif
|
355
XBOXUSB.cpp
Normal file
355
XBOXUSB.cpp
Normal file
|
@ -0,0 +1,355 @@
|
|||
/* 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
|
||||
*/
|
||||
|
||||
#include "XBOXUSB.h"
|
||||
#define DEBUG // Uncomment to print data for debugging
|
||||
//#define EXTRADEBUG // Uncomment to get even more debugging data
|
||||
//#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller
|
||||
|
||||
XBOXUSB::XBOXUSB(USB *p):
|
||||
pUsb(p), // pointer to USB class instance - mandatory
|
||||
bAddress(0), // device address - mandatory
|
||||
bPollEnable(false) { // don't start polling before dongle is connected
|
||||
for(uint8_t i=0; i<XBOX_MAX_ENDPOINTS; i++) {
|
||||
epInfo[i].epAddr = 0;
|
||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||
epInfo[i].epAttribs = 0;
|
||||
epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
|
||||
}
|
||||
|
||||
if (pUsb) // register in USB subsystem
|
||||
pUsb->RegisterDeviceClass(this); //set devConfig[] entry
|
||||
}
|
||||
|
||||
uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||
uint8_t buf[sizeof(USB_DEVICE_DESCRIPTOR)];
|
||||
uint8_t rcode;
|
||||
UsbDevice *p = NULL;
|
||||
EpInfo *oldep_ptr = NULL;
|
||||
uint16_t PID;
|
||||
uint16_t VID;
|
||||
|
||||
// get memory address of USB device address pool
|
||||
AddressPool &addrPool = pUsb->GetAddressPool();
|
||||
#ifdef EXTRADEBUG
|
||||
Notify(PSTR("\r\nXBOXUSB Init"));
|
||||
#endif
|
||||
// check if address has already been assigned to an instance
|
||||
if (bAddress)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nAddress in use"));
|
||||
#endif
|
||||
return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
|
||||
}
|
||||
|
||||
// Get pointer to pseudo device with address 0 assigned
|
||||
p = addrPool.GetUsbDevicePtr(0);
|
||||
|
||||
if (!p)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nAddress not found"));
|
||||
#endif
|
||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||
}
|
||||
|
||||
if (!p->epinfo)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nepinfo is null"));
|
||||
#endif
|
||||
return USB_ERROR_EPINFO_IS_NULL;
|
||||
}
|
||||
|
||||
// Save old pointer to EP_RECORD of address 0
|
||||
oldep_ptr = p->epinfo;
|
||||
|
||||
// Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
|
||||
p->epinfo = epInfo;
|
||||
|
||||
p->lowspeed = lowspeed;
|
||||
|
||||
// Get device descriptor
|
||||
rcode = pUsb->getDevDescr(0, 0, sizeof(USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);// Get device descriptor - addr, ep, nbytes, data
|
||||
|
||||
// Restore p->epinfo
|
||||
p->epinfo = oldep_ptr;
|
||||
|
||||
if(rcode)
|
||||
goto FailGetDevDescr;
|
||||
|
||||
// Allocate new address according to device class
|
||||
bAddress = addrPool.AllocAddress(parent, false, port);
|
||||
|
||||
if (!bAddress)
|
||||
return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
|
||||
|
||||
// Extract Max Packet Size from device descriptor
|
||||
epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0;
|
||||
|
||||
// Assign new address to the device
|
||||
rcode = pUsb->setAddr( 0, 0, bAddress );
|
||||
if (rcode)
|
||||
{
|
||||
p->lowspeed = false;
|
||||
addrPool.FreeAddress(bAddress);
|
||||
bAddress = 0;
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nsetAddr: "));
|
||||
#endif
|
||||
PrintHex<uint8_t>(rcode);
|
||||
return rcode;
|
||||
}
|
||||
#ifdef EXTRADEBUG
|
||||
Notify(PSTR("\r\nAddr: "));
|
||||
PrintHex<uint8_t>(bAddress);
|
||||
#endif
|
||||
p->lowspeed = false;
|
||||
|
||||
//get pointer to assigned address record
|
||||
p = addrPool.GetUsbDevicePtr(bAddress);
|
||||
if (!p)
|
||||
return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
|
||||
|
||||
p->lowspeed = lowspeed;
|
||||
|
||||
// Assign epInfo to epinfo pointer - only EP0 is known
|
||||
rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
|
||||
if (rcode)
|
||||
goto FailSetDevTblEntry;
|
||||
|
||||
VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor;
|
||||
PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct;
|
||||
|
||||
if(VID == XBOX_VID) { // We just check if it's a xbox controller using the Vendor ID
|
||||
if(PID == XBOX_WIRELESS_PID) {
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nYou have plugged in a wireless Xbox 360 controller - it doesn't support USB communication"));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
else if(PID == XBOX_WIRELESS_RECEIVER_PID || PID == XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID) {
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nThis library only supports Xbox 360 controllers via USB"));
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* The application will work in reduced host mode, so we can save program and data
|
||||
memory space. After verifying the VID we will use known values for the
|
||||
configuration values for device, interface, endpoints and HID for the XBOX360 Controllers */
|
||||
|
||||
/* Initialize data structures for endpoints of device */
|
||||
epInfo[ XBOX_INPUT_PIPE ].epAddr = 0x01; // XBOX 360 report endpoint
|
||||
epInfo[ XBOX_INPUT_PIPE ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ XBOX_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ XBOX_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ XBOX_INPUT_PIPE ].bmSndToggle = bmSNDTOG0;
|
||||
epInfo[ XBOX_INPUT_PIPE ].bmRcvToggle = bmRCVTOG0;
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].epAddr = 0x02; // XBOX 360 output endpoint
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].epAttribs = EP_INTERRUPT;
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].bmSndToggle = bmSNDTOG0;
|
||||
epInfo[ XBOX_OUTPUT_PIPE ].bmRcvToggle = bmRCVTOG0;
|
||||
|
||||
rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
|
||||
if( rcode )
|
||||
goto FailSetDevTblEntry;
|
||||
|
||||
delay(200);//Give time for address change
|
||||
|
||||
rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
|
||||
if( rcode )
|
||||
goto FailSetConf;
|
||||
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nXbox 360 Controller Connected"));
|
||||
#endif
|
||||
setLedMode(ROTATING);
|
||||
Xbox360Connected = true;
|
||||
}
|
||||
else
|
||||
goto FailUnknownDevice;
|
||||
|
||||
bPollEnable = true;
|
||||
Notify(PSTR("\r\n"));
|
||||
return 0; // successful configuration
|
||||
|
||||
/* diagnostic messages */
|
||||
FailGetDevDescr:
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\ngetDevDescr:"));
|
||||
#endif
|
||||
goto Fail;
|
||||
FailSetDevTblEntry:
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nsetDevTblEn:"));
|
||||
#endif
|
||||
goto Fail;
|
||||
FailSetConf:
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nsetConf:"));
|
||||
#endif
|
||||
goto Fail;
|
||||
FailUnknownDevice:
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nUnknown Device Connected - VID: "));
|
||||
PrintHex<uint16_t>(VID);
|
||||
Notify(PSTR(" PID: "));
|
||||
PrintHex<uint16_t>(PID);
|
||||
#endif
|
||||
goto Fail;
|
||||
Fail:
|
||||
#ifdef DEBUG
|
||||
Notify(PSTR("\r\nXbox 360 Init Failed, error code: "));
|
||||
Serial.print(rcode);
|
||||
#endif
|
||||
Release();
|
||||
return rcode;
|
||||
}
|
||||
|
||||
/* Performs a cleanup after failed Init() attempt */
|
||||
uint8_t XBOXUSB::Release() {
|
||||
Xbox360Connected = false;
|
||||
pUsb->GetAddressPool().FreeAddress(bAddress);
|
||||
bAddress = 0;
|
||||
bPollEnable = false;
|
||||
return 0;
|
||||
}
|
||||
uint8_t XBOXUSB::Poll() {
|
||||
if (!bPollEnable)
|
||||
return 0;
|
||||
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
|
||||
pUsb->inTransfer(bAddress, epInfo[ XBOX_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
|
||||
readReport();
|
||||
#ifdef PRINTREPORT
|
||||
printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
void XBOXUSB::readReport() {
|
||||
if (readBuf == NULL)
|
||||
return;
|
||||
if(readBuf[0] != 0x00 || readBuf[1] != 0x14) { // Check if it's the correct report - the controller also sends different status reports
|
||||
return;
|
||||
}
|
||||
|
||||
ButtonState = (uint32_t)(readBuf[2] | ((uint16_t)readBuf[3] << 8) | ((uint32_t)readBuf[4] << 16) | ((uint32_t)readBuf[5] << 24));
|
||||
|
||||
//Notify(PSTR("\r\nButtonState");
|
||||
//PrintHex<uint32_t>(ButtonState);
|
||||
|
||||
if(ButtonState != OldButtonState) {
|
||||
buttonChanged = true;
|
||||
if(ButtonState != 0x00) {
|
||||
buttonPressed = true;
|
||||
buttonReleased = false;
|
||||
} else {
|
||||
buttonPressed = false;
|
||||
buttonReleased = true;
|
||||
}
|
||||
} else {
|
||||
buttonChanged = false;
|
||||
buttonPressed = false;
|
||||
buttonReleased = false;
|
||||
}
|
||||
|
||||
OldButtonState = ButtonState;
|
||||
}
|
||||
|
||||
void XBOXUSB::printReport() { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller
|
||||
if (readBuf == NULL)
|
||||
return;
|
||||
for(uint8_t i = 0; i < XBOX_REPORT_BUFFER_SIZE;i++) {
|
||||
PrintHex<uint8_t>(readBuf[i]);
|
||||
Serial.print(" ");
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
uint8_t XBOXUSB::getButton(Button b) {
|
||||
if (readBuf == NULL)
|
||||
return false;
|
||||
if(b == L2 || b == R2) { // These are analog buttons
|
||||
return (uint8_t)(readBuf[(uint8_t)b]);
|
||||
}
|
||||
else {
|
||||
if ((readBuf[(uint16_t)b >> 8] & ((uint8_t)b & 0xff)) > 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
int16_t XBOXUSB::getAnalogHat(AnalogHat a) {
|
||||
if (readBuf == NULL)
|
||||
return 0;
|
||||
return (int16_t)(readBuf[(uint8_t)a+1] << 8 | readBuf[(uint8_t)a]);
|
||||
}
|
||||
|
||||
/* Playstation Sixaxis Dualshock and Navigation Controller commands */
|
||||
void XBOXUSB::XboxCommand(uint8_t* data, uint16_t nbytes) {
|
||||
//bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x00), Report Type (Output 0x02), interface (0x00), datalength, datalength, data)
|
||||
pUsb->ctrlReq(bAddress,epInfo[XBOX_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x00, 0x02, 0x00, nbytes, nbytes, data, NULL);
|
||||
}
|
||||
void XBOXUSB::setLedOn(LED l) {
|
||||
if(l == ALL) // All LEDs can't be on a the same time
|
||||
return;
|
||||
writeBuf[0] = 0x01;
|
||||
writeBuf[1] = 0x03;
|
||||
writeBuf[2] = (uint8_t)l;
|
||||
writeBuf[2] += 4;
|
||||
|
||||
XboxCommand(writeBuf, 3);
|
||||
}
|
||||
void XBOXUSB::setLedOff() {
|
||||
writeBuf[0] = 0x01;
|
||||
writeBuf[1] = 0x03;
|
||||
writeBuf[2] = 0x00;
|
||||
|
||||
XboxCommand(writeBuf, 3);
|
||||
}
|
||||
void XBOXUSB::setLedBlink(LED l) {
|
||||
writeBuf[0] = 0x01;
|
||||
writeBuf[1] = 0x03;
|
||||
writeBuf[2] = (uint8_t)l;
|
||||
|
||||
XboxCommand(writeBuf, 3);
|
||||
}
|
||||
void XBOXUSB::setLedMode(LEDMode lm) { // This function is used to do some speciel LED stuff the controller supports
|
||||
writeBuf[0] = 0x01;
|
||||
writeBuf[1] = 0x03;
|
||||
writeBuf[2] = (uint8_t)lm;
|
||||
|
||||
XboxCommand(writeBuf, 3);
|
||||
}
|
||||
void XBOXUSB::setRumbleOn(uint8_t lValue, uint8_t rValue) {
|
||||
writeBuf[0] = 0x00;
|
||||
writeBuf[1] = 0x08;
|
||||
writeBuf[2] = 0x00;
|
||||
writeBuf[3] = lValue; // big weight
|
||||
writeBuf[4] = rValue; // small weight
|
||||
writeBuf[5] = 0x00;
|
||||
writeBuf[6] = 0x00;
|
||||
writeBuf[7] = 0x00;
|
||||
|
||||
XboxCommand(writeBuf, 8);
|
||||
}
|
152
XBOXUSB.h
Normal file
152
XBOXUSB.h
Normal file
|
@ -0,0 +1,152 @@
|
|||
/* 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
|
||||
*/
|
||||
|
||||
#ifndef _xboxusb_h_
|
||||
#define _xboxusb_h_
|
||||
|
||||
#if defined(ARDUINO) && ARDUINO >= 100
|
||||
#include "Arduino.h"
|
||||
#else
|
||||
#include "WProgram.h"
|
||||
#endif
|
||||
|
||||
#include "Usb.h"
|
||||
|
||||
/* Data Xbox 360 taken from descriptors */
|
||||
#define EP_MAXPKTSIZE 32 // max size for data via USB
|
||||
|
||||
/* Endpoint types */
|
||||
#define EP_INTERRUPT 0x03
|
||||
|
||||
/* Names we give to the 3 Xbox360 pipes */
|
||||
#define XBOX_CONTROL_PIPE 0
|
||||
#define XBOX_INPUT_PIPE 1
|
||||
#define XBOX_OUTPUT_PIPE 2
|
||||
|
||||
//PID and VID of the different devices
|
||||
#define XBOX_VID 0x045E // Microsoft Corporation
|
||||
#define XBOX_WIRELESS_PID 0x028F // Wireless controller only support charging
|
||||
#define XBOX_WIRELESS_RECEIVER_PID 0x0719 // Microsoft Wireless Gaming Receiver
|
||||
#define XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID 0x0291 // Third party Wireless Gaming Receiver
|
||||
|
||||
#define XBOX_REPORT_BUFFER_SIZE 14 // Size of the input report buffer
|
||||
|
||||
// used in control endpoint header for HID Commands
|
||||
#define bmREQ_HID_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE
|
||||
#define HID_REQUEST_SET_REPORT 0x09
|
||||
|
||||
#define XBOX_MAX_ENDPOINTS 3
|
||||
|
||||
enum LED {
|
||||
ALL = 0x01, // Used to blink all LEDs
|
||||
LED1 = 0x02,
|
||||
LED2 = 0x03,
|
||||
LED3 = 0x04,
|
||||
LED4 = 0x05,
|
||||
};
|
||||
enum LEDMode {
|
||||
ROTATING = 0x0A,
|
||||
FASTBLINK = 0x0B,
|
||||
SLOWBLINK = 0x0C,
|
||||
ALTERNATING = 0x0D,
|
||||
};
|
||||
|
||||
enum Button {
|
||||
// byte location | bit location
|
||||
UP = (2 << 8) | 0x01,
|
||||
DOWN = (2 << 8) | 0x02,
|
||||
LEFT = (2 << 8) | 0x04,
|
||||
RIGHT = (2 << 8) | 0x08,
|
||||
|
||||
START = (2 << 8) | 0x10,
|
||||
BACK = (2 << 8) | 0x20,
|
||||
L3 = (2 << 8) | 0x40,
|
||||
R3 = (2 << 8) | 0x80,
|
||||
|
||||
L1 = (3 << 8) | 0x01,
|
||||
R1 = (3 << 8) | 0x02,
|
||||
XBOX = (3 << 8) | 0x04,
|
||||
|
||||
A = (3 << 8) | 0x10,
|
||||
B = (3 << 8) | 0x20,
|
||||
X = (3 << 8) | 0x40,
|
||||
Y = (3 << 8) | 0x80,
|
||||
|
||||
// These buttons are analog
|
||||
L2 = 4,
|
||||
R2 = 5,
|
||||
};
|
||||
enum AnalogHat
|
||||
{
|
||||
LeftHatX = 6,
|
||||
LeftHatY = 8,
|
||||
RightHatX = 10,
|
||||
RightHatY = 12,
|
||||
};
|
||||
|
||||
class XBOXUSB : public USBDeviceConfig
|
||||
{
|
||||
public:
|
||||
XBOXUSB(USB *pUsb);
|
||||
|
||||
// USBDeviceConfig implementation
|
||||
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
|
||||
virtual uint8_t Release();
|
||||
virtual uint8_t Poll();
|
||||
virtual uint8_t GetAddress() { return bAddress; };
|
||||
virtual bool isReady() { return bPollEnable; };
|
||||
|
||||
/* XBOX Controller Readings */
|
||||
uint8_t getButton(Button b);
|
||||
int16_t getAnalogHat(AnalogHat a);
|
||||
|
||||
/* Commands for Dualshock 3 and Navigation controller */
|
||||
void setAllOff() { setRumbleOn(0,0); setLedOff(); };
|
||||
void setRumbleOff() { setRumbleOn(0,0); };
|
||||
void setRumbleOn(uint8_t lValue, uint8_t rValue);
|
||||
void setLedOff();
|
||||
void setLedOn(LED l);
|
||||
void setLedBlink(LED l);
|
||||
void setLedMode(LEDMode lm);
|
||||
|
||||
bool Xbox360Connected;// Variable used to indicate if the XBOX 360 controller is successfully connected
|
||||
bool buttonChanged;//Indicate if a button has been changed
|
||||
bool buttonPressed;//Indicate if a button has been pressed
|
||||
bool buttonReleased;//Indicate if a button has been released
|
||||
|
||||
protected:
|
||||
/* mandatory members */
|
||||
USB *pUsb;
|
||||
uint8_t bAddress; // device address
|
||||
EpInfo epInfo[XBOX_MAX_ENDPOINTS]; //endpoint info structure
|
||||
|
||||
private:
|
||||
bool bPollEnable;
|
||||
|
||||
uint32_t ButtonState;
|
||||
uint32_t OldButtonState;
|
||||
|
||||
uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data
|
||||
uint8_t writeBuf[EP_MAXPKTSIZE]; // General purpose buffer for output data
|
||||
|
||||
void readReport(); // read incoming data
|
||||
void printReport(); // print incoming date - Uncomment for debugging
|
||||
|
||||
/* Private commands */
|
||||
void XboxCommand(uint8_t* data, uint16_t nbytes);
|
||||
};
|
||||
#endif
|
46
avrpins.h
46
avrpins.h
|
@ -20,9 +20,13 @@ e-mail : support@circuitsathome.com
|
|||
#ifndef _avrpins_h_
|
||||
#define _avrpins_h_
|
||||
|
||||
#if defined(__AVR_ATmega1280__) || (__AVR_ATmega2560__)
|
||||
/* Uncomment the following if you have Arduino Mega ADK board with MAX3421e built-in */
|
||||
//#define BOARD_MEGA_ADK
|
||||
#endif
|
||||
|
||||
/* Uncomment the following if you are using a Teensy 2.0 */
|
||||
//#define BOARD_TEENSY
|
||||
|
||||
#include <avr/io.h>
|
||||
|
||||
|
@ -501,7 +505,47 @@ template<typename Tp_pin, typename Tc_bit>
|
|||
|
||||
#endif // "Classic" Arduino pin numbers
|
||||
|
||||
#if defined(__AVR_ATmega32U4__)
|
||||
#if !defined(BOARD_TEENSY) && defined(__AVR_ATmega32U4__)
|
||||
// Arduino Leonardo pin numbers
|
||||
|
||||
#define P0 Pd2 // D0 - PD2
|
||||
#define P1 Pd3 // D1 - PD3
|
||||
#define P2 Pd1 // D2 - PD1
|
||||
#define P3 Pd0 // D3 - PD0
|
||||
#define P4 Pd4 // D4 - PD4
|
||||
#define P5 Pc6 // D5 - PC6
|
||||
#define P6 Pd7 // D6 - PD7
|
||||
#define P7 Pe6 // D7 - PE6
|
||||
|
||||
#define P8 Pb4 // D8 - PB4
|
||||
#define P9 Pb5 // D9 - PB5
|
||||
#define P10 Pb6 // D10 - PB6
|
||||
#define P11 Pb7 // D11 - PB7
|
||||
#define P12 Pd6 // D12 - PD6
|
||||
#define P13 Pc7 // D13 - PC7
|
||||
|
||||
#define P14 Pb3 // D14 - MISO - PB3
|
||||
#define P15 Pb1 // D15 - SCK - PB1
|
||||
#define P16 Pb2 // D16 - MOSI - PB2
|
||||
#define P17 Pb0 // D17 - SS - PB0
|
||||
|
||||
#define P18 Pf7 // D18 - A0 - PF7
|
||||
#define P19 Pf6 // D19 - A1 - PF6
|
||||
#define P20 Pf5 // D20 - A2 - PF5
|
||||
#define P21 Pf4 // D21 - A3 - PF4
|
||||
#define P22 Pf1 // D22 - A4 - PF1
|
||||
#define P23 Pf0 // D23 - A5 - PF0
|
||||
|
||||
#define P24 Pd4 // D24 / D4 - A6 - PD4
|
||||
#define P25 Pd7 // D25 / D6 - A7 - PD7
|
||||
#define P26 Pb4 // D26 / D8 - A8 - PB4
|
||||
#define P27 Pb5 // D27 / D9 - A9 - PB5
|
||||
#define P28 Pb6 // D28 / D10 - A10 - PB6
|
||||
#define P29 Pd6 // D29 / D12 - A11 - PD6
|
||||
|
||||
#endif // Arduino Leonardo pin numbers
|
||||
|
||||
#if defined(BOARD_TEENSY) && defined(__AVR_ATmega32U4__)
|
||||
// Teensy 2.0 pin numbers
|
||||
// http://www.pjrc.com/teensy/pinout.html
|
||||
#define P0 Pb0
|
||||
|
|
197
examples/PS3/PS3BT/PS3BT.ino
Normal file
197
examples/PS3/PS3BT/PS3BT.ino
Normal file
|
@ -0,0 +1,197 @@
|
|||
/*
|
||||
Example sketch for the PS3 Bluetooth library - developed by Kristian Lauszus
|
||||
For more information visit my blog: http://blog.tkjelectronics.dk/ or
|
||||
send me an e-mail: kristianl@tkjelectronics.com
|
||||
*/
|
||||
|
||||
#include <PS3BT.h>
|
||||
USB Usb;
|
||||
/* You can create the instance of the class in two ways */
|
||||
PS3BT PS3(&Usb); // This will just create the instance
|
||||
//PS3BT PS3(&Usb,0x00,0x15,0x83,0x3D,0x0A,0x57); // This will also store the bluetooth address - this can be obtained from the dongle when running the sketch
|
||||
|
||||
boolean printTemperature;
|
||||
boolean printAngle;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
if (Usb.Init() == -1) {
|
||||
Serial.print(F("\r\nOSC did not start"));
|
||||
while(1); //halt
|
||||
}
|
||||
Serial.print(F("\r\nPS3 Bluetooth Library Started"));
|
||||
}
|
||||
void loop()
|
||||
{
|
||||
Usb.Task();
|
||||
|
||||
if(PS3.PS3Connected || PS3.PS3NavigationConnected) {
|
||||
if(PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
|
||||
if(PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117) {
|
||||
Serial.print(F("LeftHatX: "));
|
||||
Serial.print(PS3.getAnalogHat(LeftHatX));
|
||||
Serial.print("\t");
|
||||
} if(PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117) {
|
||||
Serial.print(F("LeftHatY: "));
|
||||
Serial.print(PS3.getAnalogHat(LeftHatY));
|
||||
Serial.print("\t");
|
||||
} if(PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117) {
|
||||
Serial.print(F("RightHatX: "));
|
||||
Serial.print(PS3.getAnalogHat(RightHatX));
|
||||
Serial.print("\t");
|
||||
} if(PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
|
||||
Serial.print(F("RightHatY: "));
|
||||
Serial.print(PS3.getAnalogHat(RightHatY));
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
//Analog button values can be read from almost all buttons
|
||||
if(PS3.getAnalogButton(L2_ANALOG) > 0 || PS3.getAnalogButton(R2_ANALOG) > 0) {
|
||||
if(PS3.getAnalogButton(L2_ANALOG) > 0) {
|
||||
Serial.print(F("L2: "));
|
||||
Serial.print(PS3.getAnalogButton(L2_ANALOG));
|
||||
Serial.print("\t");
|
||||
} if(PS3.getAnalogButton(R2_ANALOG) > 0) {
|
||||
Serial.print(F("R2: "));
|
||||
Serial.print(PS3.getAnalogButton(R2_ANALOG));
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
if(PS3.buttonPressed)
|
||||
{
|
||||
Serial.print(F("PS3 Controller"));
|
||||
|
||||
if(PS3.getButton(PS)) {
|
||||
Serial.print(F(" - PS"));
|
||||
PS3.disconnect();
|
||||
} else {
|
||||
if(PS3.getButton(TRIANGLE))
|
||||
Serial.print(F(" - Traingle"));
|
||||
if(PS3.getButton(CIRCLE))
|
||||
Serial.print(F(" - Circle"));
|
||||
if(PS3.getButton(CROSS))
|
||||
Serial.print(F(" - Cross"));
|
||||
if(PS3.getButton(SQUARE))
|
||||
Serial.print(F(" - Square"));
|
||||
|
||||
if(PS3.getButton(UP)) {
|
||||
Serial.print(F(" - Up"));
|
||||
if(PS3.PS3Connected) {
|
||||
PS3.setAllOff();
|
||||
PS3.setLedOn(LED4);
|
||||
}
|
||||
} if(PS3.getButton(RIGHT)) {
|
||||
Serial.print(F(" - Right"));
|
||||
if(PS3.PS3Connected) {
|
||||
PS3.setAllOff();
|
||||
PS3.setLedOn(LED1);
|
||||
}
|
||||
} if(PS3.getButton(DOWN)) {
|
||||
Serial.print(F(" - Down"));
|
||||
if(PS3.PS3Connected) {
|
||||
PS3.setAllOff();
|
||||
PS3.setLedOn(LED2);
|
||||
}
|
||||
} if(PS3.getButton(LEFT)) {
|
||||
Serial.print(F(" - Left"));
|
||||
if(PS3.PS3Connected) {
|
||||
PS3.setAllOff();
|
||||
PS3.setLedOn(LED3);
|
||||
}
|
||||
}
|
||||
|
||||
if(PS3.getButton(L1))
|
||||
Serial.print(F(" - L1"));
|
||||
//if(PS3.getButton(L2))
|
||||
//Serial.print(F(" - L2"));
|
||||
if(PS3.getButton(L3))
|
||||
Serial.print(F(" - L3"));
|
||||
if(PS3.getButton(R1))
|
||||
Serial.print(F(" - R1"));
|
||||
//if(PS3.getButton(R2))
|
||||
//Serial.print(F(" - R2"));
|
||||
if(PS3.getButton(R3))
|
||||
Serial.print(F(" - R3"));
|
||||
|
||||
if(PS3.getButton(SELECT)) {
|
||||
Serial.print(F(" - Select - "));
|
||||
Serial.print(PS3.getStatusString());
|
||||
} if(PS3.getButton(START)) {
|
||||
Serial.print(F(" - Start"));
|
||||
printAngle = !printAngle;
|
||||
while(PS3.getButton(START))
|
||||
Usb.Task();
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
}
|
||||
if(printAngle) {
|
||||
Serial.print(F("Pitch: "));
|
||||
Serial.print(PS3.getAngle(Pitch));
|
||||
Serial.print(F("\tRoll: "));
|
||||
Serial.println(PS3.getAngle(Roll));
|
||||
}
|
||||
}
|
||||
else if(PS3.PS3MoveConnected)
|
||||
{
|
||||
if(PS3.getAnalogButton(T_ANALOG) > 0) {
|
||||
Serial.print(F("T: "));
|
||||
Serial.println(PS3.getAnalogButton(T_ANALOG));
|
||||
} if(PS3.buttonPressed) {
|
||||
Serial.print(F("PS3 Move Controller"));
|
||||
|
||||
if(PS3.getButton(PS)) {
|
||||
Serial.print(F(" - PS"));
|
||||
PS3.disconnect();
|
||||
} else {
|
||||
if(PS3.getButton(SELECT)) {
|
||||
Serial.print(F(" - Select"));
|
||||
printTemperature = !printTemperature;
|
||||
while(PS3.getButton(SELECT))
|
||||
Usb.Task();
|
||||
} if(PS3.getButton(START)) {
|
||||
Serial.print(F(" - Start"));
|
||||
printAngle = !printAngle;
|
||||
while(PS3.getButton(START))
|
||||
Usb.Task();
|
||||
} if(PS3.getButton(TRIANGLE)) {
|
||||
Serial.print(F(" - Triangle"));
|
||||
PS3.moveSetBulb(Red);
|
||||
} if(PS3.getButton(CIRCLE)) {
|
||||
Serial.print(F(" - Circle"));
|
||||
PS3.moveSetBulb(Green);
|
||||
} if(PS3.getButton(SQUARE)) {
|
||||
Serial.print(F(" - Square"));
|
||||
PS3.moveSetBulb(Blue);
|
||||
} if(PS3.getButton(CROSS)) {
|
||||
Serial.print(F(" - Cross"));
|
||||
PS3.moveSetBulb(Yellow);
|
||||
} if(PS3.getButton(MOVE)) {
|
||||
PS3.moveSetBulb(Off);
|
||||
Serial.print(F(" - Move"));
|
||||
Serial.print(F(" - "));
|
||||
Serial.print(PS3.getStatusString());
|
||||
}
|
||||
//if(PS3.getButton(T))
|
||||
//Serial.print(F(" - T"));
|
||||
|
||||
Serial.println("");
|
||||
}
|
||||
}
|
||||
if(printAngle) {
|
||||
Serial.print(F("Pitch: "));
|
||||
Serial.print(PS3.getAngle(Pitch));
|
||||
Serial.print(F("\tRoll: "));
|
||||
Serial.println(PS3.getAngle(Roll));
|
||||
}
|
||||
else if(printTemperature) {
|
||||
Serial.print(F("Temperature: "));
|
||||
Serial.println(PS3.getTemperature());
|
||||
}
|
||||
}
|
||||
delay(1);
|
||||
}
|
188
examples/PS3/PS3USB/PS3USB.ino
Normal file
188
examples/PS3/PS3USB/PS3USB.ino
Normal file
|
@ -0,0 +1,188 @@
|
|||
/*
|
||||
Example sketch for the PS3 USB library - developed by Kristian Lauszus
|
||||
For more information visit my blog: http://blog.tkjelectronics.dk/ or
|
||||
send me an e-mail: kristianl@tkjelectronics.com
|
||||
*/
|
||||
|
||||
#include <PS3USB.h>
|
||||
USB Usb;
|
||||
/* You can create the instance of the class in two ways */
|
||||
PS3USB PS3(&Usb); // This will just create the instance
|
||||
//PS3USB PS3(&Usb,0x00,0x15,0x83,0x3D,0x0A,0x57); // This will also store the bluetooth address - this can be obtained from the dongle when running the sketch
|
||||
|
||||
boolean printAngle;
|
||||
uint8_t state = 0;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
if (Usb.Init() == -1) {
|
||||
Serial.print(F("\r\nOSC did not start"));
|
||||
while(1); //halt
|
||||
}
|
||||
Serial.print(F("\r\nPS3 USB Library Started"));
|
||||
}
|
||||
void loop() {
|
||||
Usb.Task();
|
||||
|
||||
if(PS3.PS3Connected || PS3.PS3NavigationConnected) {
|
||||
if(PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
|
||||
if(PS3.getAnalogHat(LeftHatX) > 137 || PS3.getAnalogHat(LeftHatX) < 117) {
|
||||
Serial.print(F("LeftHatX: "));
|
||||
Serial.print(PS3.getAnalogHat(LeftHatX));
|
||||
Serial.print("\t");
|
||||
}
|
||||
if(PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117) {
|
||||
Serial.print(F("LeftHatY: "));
|
||||
Serial.print(PS3.getAnalogHat(LeftHatY));
|
||||
Serial.print("\t");
|
||||
}
|
||||
if(PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117) {
|
||||
Serial.print(F("RightHatX: "));
|
||||
Serial.print(PS3.getAnalogHat(RightHatX));
|
||||
Serial.print("\t");
|
||||
}
|
||||
if(PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) {
|
||||
Serial.print(F("RightHatY: "));
|
||||
Serial.print(PS3.getAnalogHat(RightHatY));
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
// Analog button values can be read from almost all buttons
|
||||
if(PS3.getAnalogButton(L2_ANALOG) > 0 || PS3.getAnalogButton(R2_ANALOG) > 0) {
|
||||
if(PS3.getAnalogButton(L2_ANALOG) > 0) {
|
||||
Serial.print(F("L2: "));
|
||||
Serial.print(PS3.getAnalogButton(L2_ANALOG));
|
||||
Serial.print("\t");
|
||||
}
|
||||
if(PS3.getAnalogButton(R2_ANALOG) > 0) {
|
||||
Serial.print(F("R2: "));
|
||||
Serial.print(PS3.getAnalogButton(R2_ANALOG));
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
if(PS3.buttonPressed)
|
||||
{
|
||||
Serial.print(F("PS3 Controller"));
|
||||
|
||||
if(PS3.getButton(PS))
|
||||
Serial.print(F(" - PS"));
|
||||
|
||||
if(PS3.getButton(TRIANGLE))
|
||||
Serial.print(F(" - Traingle"));
|
||||
if(PS3.getButton(CIRCLE))
|
||||
Serial.print(F(" - Circle"));
|
||||
if(PS3.getButton(CROSS))
|
||||
Serial.print(F(" - Cross"));
|
||||
if(PS3.getButton(SQUARE))
|
||||
Serial.print(F(" - Square"));
|
||||
|
||||
if(PS3.getButton(UP)) {
|
||||
Serial.print(F(" - Up"));
|
||||
PS3.setAllOff();
|
||||
PS3.setLedOn(LED4);
|
||||
}
|
||||
if(PS3.getButton(RIGHT)) {
|
||||
Serial.print(F(" - Right"));
|
||||
PS3.setAllOff();
|
||||
PS3.setLedOn(LED1);
|
||||
}
|
||||
if(PS3.getButton(DOWN)) {
|
||||
Serial.print(F(" - Down"));
|
||||
PS3.setAllOff();
|
||||
PS3.setLedOn(LED2);
|
||||
}
|
||||
if(PS3.getButton(LEFT)) {
|
||||
Serial.print(F(" - Left"));
|
||||
PS3.setAllOff();
|
||||
PS3.setLedOn(LED3);
|
||||
}
|
||||
|
||||
if(PS3.getButton(L1))
|
||||
Serial.print(F(" - L1"));
|
||||
//if(PS3.getButton(L2))
|
||||
//Serial.print(F(" - L2"));
|
||||
if(PS3.getButton(L3))
|
||||
Serial.print(F(" - L3"));
|
||||
if(PS3.getButton(R1))
|
||||
Serial.print(F(" - R1"));
|
||||
//if(PS3.getButton(R2))
|
||||
//Serial.print(F(" - R2"));
|
||||
if(PS3.getButton(R3))
|
||||
Serial.print(F(" - R3"));
|
||||
|
||||
if(PS3.getButton(SELECT)) {
|
||||
Serial.print(F(" - Select - "));
|
||||
Serial.print(PS3.getStatusString());
|
||||
}
|
||||
if(PS3.getButton(START)) {
|
||||
Serial.print(F(" - Start"));
|
||||
printAngle = !printAngle;
|
||||
while(PS3.getButton(START))
|
||||
Usb.Task();
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
if(printAngle) {
|
||||
Serial.print(F("Pitch: "));
|
||||
Serial.print(PS3.getAngle(Pitch));
|
||||
Serial.print(F("\tRoll: "));
|
||||
Serial.println(PS3.getAngle(Roll));
|
||||
}
|
||||
}
|
||||
else if(PS3.PS3MoveConnected) { // One can only set the color of the bulb, set the rumble, set and get the bluetooth address and calibrate the magnetometer via USB
|
||||
switch(state) {
|
||||
case 0:
|
||||
PS3.moveSetRumble(0);
|
||||
PS3.moveSetBulb(Off);
|
||||
state = 1;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
PS3.moveSetRumble(75);
|
||||
PS3.moveSetBulb(Red);
|
||||
state = 2;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
PS3.moveSetRumble(125);
|
||||
PS3.moveSetBulb(Green);
|
||||
state = 3;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
PS3.moveSetRumble(150);
|
||||
PS3.moveSetBulb(Blue);
|
||||
state = 4;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
PS3.moveSetRumble(175);
|
||||
PS3.moveSetBulb(Yellow);
|
||||
state = 5;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
PS3.moveSetRumble(200);
|
||||
PS3.moveSetBulb(Lightblue);
|
||||
state = 6;
|
||||
break;
|
||||
|
||||
case 6:
|
||||
PS3.moveSetRumble(225);
|
||||
PS3.moveSetBulb(Purble);
|
||||
state = 7;
|
||||
break;
|
||||
|
||||
case 7:
|
||||
PS3.moveSetRumble(250);
|
||||
PS3.moveSetBulb(White);
|
||||
state = 0;
|
||||
break;
|
||||
}
|
||||
delay(1000);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,201 +0,0 @@
|
|||
/*
|
||||
Example sketch for the PS3 Bluetooth library - developed by Kristian Lauszus
|
||||
For more information visit my blog: http://blog.tkjelectronics.dk/ or
|
||||
send me an e-mail: kristianl@tkjelectronics.com
|
||||
*/
|
||||
|
||||
#include <PS3BT.h>
|
||||
USB Usb;
|
||||
/* You can create the instance of the class in two ways */
|
||||
PS3BT BT(&Usb); // This will just create the instance
|
||||
//PS3BT BT(&Usb,0x00,0x15,0x83,0x3D,0x0A,0x57); // This will also store the bluetooth address - this can be obtained from the dongle when running the sketch
|
||||
|
||||
boolean printTemperature;
|
||||
boolean printAngle;
|
||||
|
||||
void setup()
|
||||
{
|
||||
Serial.begin(115200);
|
||||
|
||||
if (Usb.Init() == -1) {
|
||||
Serial.print(F("\r\nOSC did not start"));
|
||||
while(1); //halt
|
||||
}
|
||||
Serial.print(F("\r\nPS3 Bluetooth Library Started"));
|
||||
}
|
||||
void loop()
|
||||
{
|
||||
Usb.Task();
|
||||
|
||||
if(BT.PS3BTConnected || BT.PS3NavigationBTConnected) {
|
||||
if(BT.getAnalogHat(LeftHatX) > 137 || BT.getAnalogHat(LeftHatX) < 117 || BT.getAnalogHat(LeftHatY) > 137 || BT.getAnalogHat(LeftHatY) < 117 || BT.getAnalogHat(RightHatX) > 137 || BT.getAnalogHat(RightHatX) < 117 || BT.getAnalogHat(RightHatY) > 137 || BT.getAnalogHat(RightHatY) < 117) {
|
||||
if(BT.getAnalogHat(LeftHatX) > 137 || BT.getAnalogHat(LeftHatX) < 117) {
|
||||
Serial.print(F("LeftHatX: "));
|
||||
Serial.print(BT.getAnalogHat(LeftHatX));
|
||||
Serial.print("\t");
|
||||
} if(BT.getAnalogHat(LeftHatY) > 137 || BT.getAnalogHat(LeftHatY) < 117) {
|
||||
Serial.print(F("LeftHatY: "));
|
||||
Serial.print(BT.getAnalogHat(LeftHatY));
|
||||
Serial.print("\t");
|
||||
} if(BT.getAnalogHat(RightHatX) > 137 || BT.getAnalogHat(RightHatX) < 117) {
|
||||
Serial.print(F("RightHatX: "));
|
||||
Serial.print(BT.getAnalogHat(RightHatX));
|
||||
Serial.print("\t");
|
||||
} if(BT.getAnalogHat(RightHatY) > 137 || BT.getAnalogHat(RightHatY) < 117) {
|
||||
Serial.print(F("RightHatY: "));
|
||||
Serial.print(BT.getAnalogHat(RightHatY));
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
//Analog button values can be read from almost all buttons
|
||||
if(BT.getAnalogButton(L2_ANALOG) > 0 || BT.getAnalogButton(R2_ANALOG) > 0) {
|
||||
if(BT.getAnalogButton(L2_ANALOG) > 0) {
|
||||
Serial.print(F("L2: "));
|
||||
Serial.print(BT.getAnalogButton(L2_ANALOG));
|
||||
Serial.print("\t");
|
||||
} if(BT.getAnalogButton(R2_ANALOG) > 0) {
|
||||
Serial.print(F("R2: "));
|
||||
Serial.print(BT.getAnalogButton(R2_ANALOG));
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
if(BT.buttonPressed)
|
||||
{
|
||||
Serial.print(F("PS3 Controller"));
|
||||
|
||||
if(BT.getButton(PS)) {
|
||||
Serial.print(F(" - PS"));
|
||||
BT.disconnect();
|
||||
} else {
|
||||
if(BT.getButton(TRIANGLE))
|
||||
Serial.print(F(" - Traingle"));
|
||||
if(BT.getButton(CIRCLE))
|
||||
Serial.print(F(" - Circle"));
|
||||
if(BT.getButton(CROSS))
|
||||
Serial.print(F(" - Cross"));
|
||||
if(BT.getButton(SQUARE))
|
||||
Serial.print(F(" - Square"));
|
||||
|
||||
if(BT.getButton(UP)) {
|
||||
Serial.print(F(" - Up"));
|
||||
BT.setAllOff();
|
||||
BT.setLedOn(LED4);
|
||||
} if(BT.getButton(RIGHT)) {
|
||||
Serial.print(F(" - Right"));
|
||||
BT.setAllOff();
|
||||
BT.setLedOn(LED1);
|
||||
} if(BT.getButton(DOWN)) {
|
||||
Serial.print(F(" - Down"));
|
||||
BT.setAllOff();
|
||||
BT.setLedOn(LED2);
|
||||
} if(BT.getButton(LEFT)) {
|
||||
Serial.print(F(" - Left"));
|
||||
BT.setAllOff();
|
||||
BT.setLedOn(LED3);
|
||||
}
|
||||
|
||||
if(BT.getButton(L1))
|
||||
Serial.print(F(" - L1"));
|
||||
//if(BT.getButton(L2))
|
||||
//Serial.print(F(" - L2"));
|
||||
if(BT.getButton(L3))
|
||||
Serial.print(F(" - L3"));
|
||||
if(BT.getButton(R1))
|
||||
Serial.print(F(" - R1"));
|
||||
//if(BT.getButton(R2))
|
||||
//Serial.print(F(" - R2"));
|
||||
if(BT.getButton(R3))
|
||||
Serial.print(F(" - R3"));
|
||||
|
||||
if(BT.getButton(SELECT)) {
|
||||
Serial.print(F(" - Select - "));
|
||||
Serial.print(BT.getStatusString());
|
||||
} if(BT.getButton(START)) {
|
||||
Serial.print(F(" - Start"));
|
||||
printAngle = !printAngle;
|
||||
while(BT.getButton(START))
|
||||
Usb.Task();
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
}
|
||||
if(printAngle) {
|
||||
Serial.print(F("Pitch: "));
|
||||
Serial.print(BT.getAngle(Pitch));
|
||||
Serial.print(F("\tRoll: "));
|
||||
Serial.println(BT.getAngle(Roll));
|
||||
}
|
||||
}
|
||||
else if(BT.PS3MoveBTConnected)
|
||||
{
|
||||
if(BT.getAnalogButton(T_MOVE_ANALOG) > 0) {
|
||||
Serial.print(F("T: "));
|
||||
Serial.println(BT.getAnalogButton(T_MOVE_ANALOG));
|
||||
} if(BT.buttonPressed) {
|
||||
Serial.print(F("PS3 Move Controller"));
|
||||
|
||||
if(BT.getButton(PS_MOVE)) {
|
||||
Serial.print(F(" - PS"));
|
||||
BT.disconnect();
|
||||
} else {
|
||||
if(BT.getButton(SELECT_MOVE)) {
|
||||
Serial.print(F(" - Select"));
|
||||
printTemperature = !printTemperature;
|
||||
while(BT.getButton(SELECT_MOVE))
|
||||
Usb.Task();
|
||||
} if(BT.getButton(START_MOVE)) {
|
||||
Serial.print(F(" - Start"));
|
||||
printAngle = !printAngle;
|
||||
while(BT.getButton(START_MOVE))
|
||||
Usb.Task();
|
||||
} if(BT.getButton(TRIANGLE_MOVE)) {
|
||||
Serial.print(F(" - Triangle"));
|
||||
BT.moveSetBulb(Red);
|
||||
} if(BT.getButton(CIRCLE_MOVE)) {
|
||||
Serial.print(F(" - Circle"));
|
||||
BT.moveSetBulb(Green);
|
||||
} if(BT.getButton(SQUARE_MOVE)) {
|
||||
Serial.print(F(" - Square"));
|
||||
BT.moveSetBulb(Blue);
|
||||
} if(BT.getButton(CROSS_MOVE)) {
|
||||
Serial.print(F(" - Cross"));
|
||||
BT.moveSetBulb(Yellow);
|
||||
} if(BT.getButton(MOVE_MOVE)) {
|
||||
BT.moveSetBulb(Off);
|
||||
Serial.print(F(" - Move"));
|
||||
Serial.print(F(" - "));
|
||||
Serial.print(BT.getStatusString());
|
||||
}
|
||||
//if(BT.getButton(T))
|
||||
//Serial.print(F(" - T"));
|
||||
|
||||
Serial.println("");
|
||||
}
|
||||
}
|
||||
if(printAngle) {
|
||||
Serial.print(F("Pitch: "));
|
||||
Serial.print(BT.getAngle(Pitch));
|
||||
Serial.print(F("\tRoll: "));
|
||||
Serial.println(BT.getAngle(Roll));
|
||||
}
|
||||
else if(printTemperature) {
|
||||
String templow;
|
||||
String temphigh;
|
||||
String input = String(BT.getSensor(tempMove));
|
||||
|
||||
if (input.length() > 3) {
|
||||
temphigh = input.substring(0, 2);
|
||||
templow = input.substring(2);
|
||||
} else {
|
||||
temphigh = input.substring(0, 1);
|
||||
templow = input.substring(1);
|
||||
}
|
||||
Serial.print(F("Temperature: "));
|
||||
Serial.print(temphigh);
|
||||
Serial.print(F("."));
|
||||
Serial.println(templow);
|
||||
}
|
||||
}
|
||||
}
|
109
examples/XBOX360USB/XBOX360USB.ino
Normal file
109
examples/XBOX360USB/XBOX360USB.ino
Normal file
|
@ -0,0 +1,109 @@
|
|||
/*
|
||||
Example sketch for the Xbox 360 USB library - developed by Kristian Lauszus
|
||||
For more information visit my blog: http://blog.tkjelectronics.dk/ or
|
||||
send me an e-mail: kristianl@tkjelectronics.com
|
||||
*/
|
||||
|
||||
#include <XBOXUSB.h>
|
||||
USB Usb;
|
||||
XBOXUSB Xbox(&Usb);
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
|
||||
if (Usb.Init() == -1) {
|
||||
Serial.print(F("\r\nOSC did not start"));
|
||||
while(1); //halt
|
||||
}
|
||||
Serial.print(F("\r\nXBOX USB Library Started"));
|
||||
}
|
||||
void loop() {
|
||||
Usb.Task();
|
||||
if(Xbox.Xbox360Connected) {
|
||||
if(Xbox.getAnalogHat(LeftHatX) > 7500 || Xbox.getAnalogHat(LeftHatX) < -7500 || Xbox.getAnalogHat(LeftHatY) > 7500 || Xbox.getAnalogHat(LeftHatY) < -7500 || Xbox.getAnalogHat(RightHatX) > 7500 || Xbox.getAnalogHat(RightHatX) < -7500 || Xbox.getAnalogHat(RightHatY) > 7500 || Xbox.getAnalogHat(RightHatY) < -7500) {
|
||||
if(Xbox.getAnalogHat(LeftHatX) > 7500 || Xbox.getAnalogHat(LeftHatX) < -7500) {
|
||||
Serial.print(F("LeftHatX: "));
|
||||
Serial.print(Xbox.getAnalogHat(LeftHatX));
|
||||
Serial.print("\t");
|
||||
}
|
||||
if(Xbox.getAnalogHat(LeftHatY) > 7500 || Xbox.getAnalogHat(LeftHatY) < -7500) {
|
||||
Serial.print(F("LeftHatY: "));
|
||||
Serial.print(Xbox.getAnalogHat(LeftHatY));
|
||||
Serial.print("\t");
|
||||
}
|
||||
if(Xbox.getAnalogHat(RightHatX) > 7500 || Xbox.getAnalogHat(RightHatX) < -7500) {
|
||||
Serial.print(F("RightHatX: "));
|
||||
Serial.print(Xbox.getAnalogHat(RightHatX));
|
||||
Serial.print("\t");
|
||||
}
|
||||
if(Xbox.getAnalogHat(RightHatY) > 7500 || Xbox.getAnalogHat(RightHatY) < -7500) {
|
||||
Serial.print(F("RightHatY: "));
|
||||
Serial.print(Xbox.getAnalogHat(RightHatY));
|
||||
}
|
||||
Serial.println("");
|
||||
}
|
||||
|
||||
if(Xbox.buttonPressed) {
|
||||
Serial.print(F("Xbox 360 Controller"));
|
||||
if(Xbox.getButton(UP)) {
|
||||
Xbox.setLedOn(LED1);
|
||||
Serial.print(F(" - UP"));
|
||||
}
|
||||
if(Xbox.getButton(DOWN)) {
|
||||
Xbox.setLedOn(LED4);
|
||||
Serial.print(F(" - DOWN"));
|
||||
}
|
||||
if(Xbox.getButton(LEFT)) {
|
||||
Xbox.setLedOn(LED3);
|
||||
Serial.print(F(" - LEFT"));
|
||||
}
|
||||
if(Xbox.getButton(RIGHT)) {
|
||||
Xbox.setLedOn(LED2);
|
||||
Serial.print(F(" - RIGHT"));
|
||||
}
|
||||
|
||||
if(Xbox.getButton(START)) {
|
||||
Xbox.setLedMode(ALTERNATING);
|
||||
Serial.print(F(" - START"));
|
||||
}
|
||||
if(Xbox.getButton(BACK)) {
|
||||
Xbox.setLedBlink(ALL);
|
||||
Serial.print(F(" - BACK"));
|
||||
}
|
||||
if(Xbox.getButton(L3))
|
||||
Serial.print(F(" - L3"));
|
||||
if(Xbox.getButton(R3))
|
||||
Serial.print(F(" - R3"));
|
||||
|
||||
if(Xbox.getButton(L1))
|
||||
Serial.print(F(" - L1"));
|
||||
if(Xbox.getButton(R1))
|
||||
Serial.print(F(" - R1"));
|
||||
if(Xbox.getButton(XBOX)) {
|
||||
Xbox.setLedMode(ROTATING);
|
||||
Serial.print(F(" - XBOX"));
|
||||
}
|
||||
|
||||
if(Xbox.getButton(A))
|
||||
Serial.print(F(" - A"));
|
||||
if(Xbox.getButton(B))
|
||||
Serial.print(F(" - B"));
|
||||
if(Xbox.getButton(X))
|
||||
Serial.print(F(" - X"));
|
||||
if(Xbox.getButton(Y))
|
||||
Serial.print(F(" - Y"));
|
||||
|
||||
if(Xbox.getButton(L2)) {
|
||||
Serial.print(F(" - L2:"));
|
||||
Serial.print(Xbox.getButton(L2));
|
||||
}
|
||||
if(Xbox.getButton(R2)) {
|
||||
Serial.print(F(" - R2:"));
|
||||
Serial.print(Xbox.getButton(R2));
|
||||
}
|
||||
Xbox.setRumbleOn(Xbox.getButton(L2),Xbox.getButton(R2));
|
||||
Serial.println();
|
||||
}
|
||||
}
|
||||
delay(1);
|
||||
}
|
186
keywords.txt
Normal file
186
keywords.txt
Normal file
|
@ -0,0 +1,186 @@
|
|||
####################################################
|
||||
# Syntax Coloring Map For PS3 Bluetooth/USB Library
|
||||
####################################################
|
||||
|
||||
####################################################
|
||||
# Datatypes (KEYWORD1)
|
||||
####################################################
|
||||
|
||||
PS3BT KEYWORD1
|
||||
PS3USB KEYWORD1
|
||||
|
||||
####################################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
####################################################
|
||||
setBdaddr KEYWORD2
|
||||
setMoveBdaddr KEYWORD2
|
||||
|
||||
getButton KEYWORD2
|
||||
getAnalogButton KEYWORD2
|
||||
getAnalogHat KEYWORD2
|
||||
getSensor KEYWORD2
|
||||
getAngle KEYWORD2
|
||||
getStatus KEYWORD2
|
||||
getStatusString KEYWORD2
|
||||
getTemperature KEYWORD2
|
||||
disconnect KEYWORD2
|
||||
|
||||
setAllOff KEYWORD2
|
||||
setRumbleOff KEYWORD2
|
||||
setRumbleOn KEYWORD2
|
||||
setLedOff KEYWORD2
|
||||
setLedOn KEYWORD2
|
||||
setLedToggle KEYWORD2
|
||||
moveSetBulb KEYWORD2
|
||||
moveSetRumble KEYWORD2
|
||||
|
||||
PS3Connected KEYWORD2
|
||||
PS3MoveConnected KEYWORD2
|
||||
PS3NavigationConnected KEYWORD2
|
||||
buttonChanged KEYWORD2
|
||||
buttonPressed KEYWORD2
|
||||
buttonReleased KEYWORD2
|
||||
|
||||
isWatingForConnection KEYWORD2
|
||||
|
||||
####################################################
|
||||
# Constants and enums (LITERAL1)
|
||||
####################################################
|
||||
LED1 LITERAL1
|
||||
LED2 LITERAL1
|
||||
LED3 LITERAL1
|
||||
LED4 LITERAL1
|
||||
LED5 LITERAL1
|
||||
LED6 LITERAL1
|
||||
LED7 LITERAL1
|
||||
LED8 LITERAL1
|
||||
LED9 LITERAL1
|
||||
LED10 LITERAL1
|
||||
|
||||
Red LITERAL1
|
||||
Green LITERAL1
|
||||
Blue LITERAL1
|
||||
Yellow LITERAL1
|
||||
Lightblue LITERAL1
|
||||
Purble LITERAL1
|
||||
White LITERAL1
|
||||
Off LITERAL1
|
||||
|
||||
SELECT LITERAL1
|
||||
L3 LITERAL1
|
||||
R3 LITERAL1
|
||||
START LITERAL1
|
||||
UP LITERAL1
|
||||
RIGHT LITERAL1
|
||||
DOWN LITERAL1
|
||||
LEFT LITERAL1
|
||||
L2 LITERAL1
|
||||
R2 LITERAL1
|
||||
L1 LITERAL1
|
||||
R1 LITERAL1
|
||||
TRIANGLE LITERAL1
|
||||
CIRCLE LITERAL1
|
||||
CROSS LITERAL1
|
||||
SQUARE LITERAL1
|
||||
PS LITERAL1
|
||||
MOVE LITERAL1
|
||||
T LITERAL1
|
||||
|
||||
UP_ANALOG LITERAL1
|
||||
RIGHT_ANALOG LITERAL1
|
||||
DOWN_ANALOG LITERAL1
|
||||
LEFT_ANALOG LITERAL1
|
||||
L2_ANALOG LITERAL1
|
||||
R2_ANALOG LITERAL1
|
||||
L1_ANALOG LITERAL1
|
||||
R1_ANALOG LITERAL1
|
||||
TRIANGLE_ANALOG LITERAL1
|
||||
CIRCLE_ANALOG LITERAL1
|
||||
CROSS_ANALOG LITERAL1
|
||||
SQUARE_ANALOG LITERAL1
|
||||
T_ANALOG LITERAL1
|
||||
|
||||
LeftHatX LITERAL1
|
||||
LeftHatY LITERAL1
|
||||
RightHatX LITERAL1
|
||||
RightHatY LITERAL1
|
||||
|
||||
aX LITERAL1
|
||||
aY LITERAL1
|
||||
aZ LITERAL1
|
||||
gZ LITERAL1
|
||||
aXmove LITERAL1
|
||||
aYmove LITERAL1
|
||||
aZmove LITERAL1
|
||||
gXmove LITERAL1
|
||||
gYmove LITERAL1
|
||||
gZmove LITERAL1
|
||||
tempMove LITERAL1
|
||||
mXmove LITERAL1
|
||||
mZmove LITERAL1
|
||||
mYmove LITERAL1
|
||||
|
||||
Pitch LITERAL1
|
||||
Roll LITERAL1
|
||||
|
||||
Plugged LITERAL1
|
||||
Unplugged LITERAL1
|
||||
Charging LITERAL1
|
||||
NotCharging LITERAL1
|
||||
Shutdown LITERAL1
|
||||
Dying LITERAL1
|
||||
Low LITERAL1
|
||||
High LITERAL1
|
||||
Full LITERAL1
|
||||
MoveCharging LITERAL1
|
||||
MoveNotCharging LITERAL1
|
||||
MoveShutdown LITERAL1
|
||||
MoveDying LITERAL1
|
||||
MoveLow LITERAL1
|
||||
MoveHigh LITERAL1
|
||||
MoveFull LITERAL1
|
||||
CableRumble LITERAL1
|
||||
Cable LITERAL1
|
||||
BluetoothRumble LITERAL1
|
||||
Bluetooth LITERAL1
|
||||
|
||||
RumbleHigh LITERAL1
|
||||
RumbleLow LITERAL1
|
||||
|
||||
####################################################
|
||||
# Syntax Coloring Map For Xbox 360 USB Library
|
||||
####################################################
|
||||
|
||||
####################################################
|
||||
# Datatypes (KEYWORD1)
|
||||
####################################################
|
||||
|
||||
XBOXUSB KEYWORD1
|
||||
|
||||
####################################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
####################################################
|
||||
|
||||
setLedBlink KEYWORD2
|
||||
setLedMode KEYWORD2
|
||||
Xbox360Connected KEYWORD2
|
||||
|
||||
####################################################
|
||||
# Constants and enums (LITERAL1)
|
||||
####################################################
|
||||
|
||||
ALL LITERAL1
|
||||
|
||||
ROTATING LITERAL1
|
||||
FASTBLINK LITERAL1
|
||||
SLOWBLINK LITERAL1
|
||||
ALTERNATING LITERAL1
|
||||
|
||||
BACK LITERAL1
|
||||
|
||||
XBOX LITERAL1
|
||||
|
||||
A LITERAL1
|
||||
B LITERAL1
|
||||
X LITERAL1
|
||||
Y LITERAL1
|
Loading…
Reference in a new issue