diff --git a/PS3BT.cpp b/PS3BT.cpp index d80f0b52..34afd011 100644 --- a/PS3BT.cpp +++ b/PS3BT.cpp @@ -516,25 +516,23 @@ void PS3BT::Run() { case L2CAP_HID_PS3_LED: if (millis() - timer > 1000) { // loop 1 second before sending the command if (remote_name[0] == 'P') { // First letter in PLAYSTATION(R)3 Controller ('P') - setLedOn(LED1); #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nDualshock 3 Controller Enabled\r\n"), 0x80); #endif 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_USB_HOST Notify(PSTR("\r\nNavigation Controller Enabled\r\n"), 0x80); #endif PS3NavigationConnected = true; } else if (remote_name[0] == 'M') { // First letter in Motion Controller ('M') - moveSetBulb(Red); timerBulbRumble = millis(); #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nMotion Controller Enabled\r\n"), 0x80); #endif PS3MoveConnected = true; } + onInit(); // Turn on the LED on the controller l2cap_state = L2CAP_DONE; } break; @@ -659,3 +657,14 @@ void PS3BT::moveSetRumble(uint8_t rumble) { HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE); } + +void PS3BT::onInit() { + if (pFuncOnInit) + pFuncOnInit(); // Call the user function + else { + if (PS3MoveConnected) + moveSetBulb(Red); + else // Dualshock 3 or Navigation controller + setLedOn(LED1); + } +} \ No newline at end of file diff --git a/PS3BT.h b/PS3BT.h index 1336828e..5b00232f 100644 --- a/PS3BT.h +++ b/PS3BT.h @@ -207,19 +207,35 @@ public: * @param rumble The desired value in the range from 64-255. */ void moveSetRumble(uint8_t rumble); + + /** + * Used to call your own function when the controller is successfully initialized. + * @param funcOnInit Function to call. + */ + void attachOnInit(void (*funcOnInit)(void)) { + pFuncOnInit = funcOnInit; + }; /**@}*/ - /** Variable used to indicate if the normal playstation controller is successfully connected. */ + /** Variable used to indicate if the normal Playstation controller is successfully connected. */ bool PS3Connected; - /** Variable used to indicate if the move controller is successfully connected. */ + /** Variable used to indicate if the Move controller is successfully connected. */ bool PS3MoveConnected; - /** Variable used to indicate if the navigation controller is successfully connected. */ + /** Variable used to indicate if the Navigation controller is successfully connected. */ bool PS3NavigationConnected; private: - /* mandatory members */ + /* Mandatory members */ BTD *pBtd; + /** + * Called when the controller is successfully initialized. + * Use attachOnInit(void (*funcOnInit)(void)) to call your own function. + * This is useful for instance if you want to set the LEDs in a specific way. + */ + void onInit(); + void (*pFuncOnInit)(void); // Pointer to function called in onInit() + void L2CAP_task(); // L2CAP state machine /* Variables filled from HCI event management */ @@ -229,7 +245,7 @@ private: /* variables used by high level L2CAP task */ uint8_t l2cap_state; - uint16_t l2cap_event_flag; // L2CAP flags of received bluetooth events + uint16_t l2cap_event_flag; // L2CAP flags of received Bluetooth events unsigned long timer; diff --git a/PS3USB.cpp b/PS3USB.cpp index 844ab3af..4fe12575 100644 --- a/PS3USB.cpp +++ b/PS3USB.cpp @@ -186,7 +186,6 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) { PS3NavigationConnected = true; } enable_sixaxis(); // The PS3 controller needs a special command before it starts sending data - setLedOn(LED1); // Needed for PS3 Dualshock and Navigation commands to work for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) @@ -199,8 +198,6 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) { Notify(PSTR("\r\nMotion Controller Connected"), 0x80); #endif PS3MoveConnected = true; - moveSetBulb(Red); - writeBuf[0] = 0x02; // Set report ID, this is needed for Move commands to work } if (my_bdaddr[0] != 0x00 || my_bdaddr[1] != 0x00 || my_bdaddr[2] != 0x00 || my_bdaddr[3] != 0x00 || my_bdaddr[4] != 0x00 || my_bdaddr[5] != 0x00) { @@ -218,6 +215,7 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) { D_PrintHex (my_bdaddr[0], 0x80); #endif } + onInit(); bPollEnable = true; Notify(PSTR("\r\n"), 0x80); @@ -543,3 +541,14 @@ void PS3USB::setMoveBdaddr(uint8_t* BDADDR) { //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); } + +void PS3USB::onInit() { + if (pFuncOnInit) + pFuncOnInit(); // Call the user function + else { + if (PS3MoveConnected) + moveSetBulb(Red); + else // Dualshock 3 or Navigation controller + setLedOn(LED1); + } +} diff --git a/PS3USB.h b/PS3USB.h index 666a3859..92628197 100644 --- a/PS3USB.h +++ b/PS3USB.h @@ -234,6 +234,14 @@ public: * @param rumble The desired value in the range from 64-255. */ void moveSetRumble(uint8_t rumble); + + /** + * Used to call your own function when the controller is successfully initialized. + * @param funcOnInit Function to call. + */ + void attachOnInit(void (*funcOnInit)(void)) { + pFuncOnInit = funcOnInit; + }; /**@}*/ /** Variable used to indicate if the normal playstation controller is successfully connected. */ @@ -252,6 +260,14 @@ protected: EpInfo epInfo[PS3_MAX_ENDPOINTS]; private: + /** + * Called when the controller is successfully initialized. + * Use attachOnInit(void (*funcOnInit)(void)) to call your own function. + * This is useful for instance if you want to set the LEDs in a specific way. + */ + void onInit(); + void (*pFuncOnInit)(void); // Pointer to function called in onInit() + bool bPollEnable; uint32_t timer; // used to continuously set PS3 Move controller Bulb and rumble values diff --git a/SPP.cpp b/SPP.cpp index b60cd72a..cfaf37f2 100644 --- a/SPP.cpp +++ b/SPP.cpp @@ -231,7 +231,7 @@ void SPP::ACLData(uint8_t* l2capinbuf) { } #ifdef EXTRADEBUG else { - Notify(PSTR("\r\nUnknown PDU: ")); + Notify(PSTR("\r\nUnknown PDU: "), 0x80); D_PrintHex (l2capinbuf[8], 0x80); } #endif diff --git a/Wii.cpp b/Wii.cpp index 9948354f..751bdd9b 100755 --- a/Wii.cpp +++ b/Wii.cpp @@ -326,7 +326,7 @@ void WII::ACLData(uint8_t* l2capinbuf) { #endif nunchuckConnected = false; // It must be the Nunchuck controller then l2cap_event_flag &= ~WII_FLAG_NUNCHUCK_CONNECTED; - setLedStatus(); + onInit(); setReportMode(false, 0x31); // If there is no extension connected we will read the button and accelerometer } else { setReportMode(false, 0x31); // If there is no extension connected we will read the button and accelerometer @@ -779,7 +779,7 @@ void WII::Run() { case L2CAP_LED_STATE: if (nunchuck_connected_flag) nunchuckConnected = true; - setLedStatus(); + onInit(); l2cap_state = L2CAP_DONE; break; @@ -824,7 +824,7 @@ void WII::Run() { else if (stateCounter == 400) readExtensionType(); // Check if it has been activated else if (stateCounter == 450) { - //setLedStatus(); + onInit(); stateCounter = 0; unknownExtensionConnected = false; } @@ -1062,6 +1062,14 @@ uint16_t WII::getAnalogHat(AnalogHat a) { return output; } } + +void WII::onInit() { + if (pFuncOnInit) + pFuncOnInit(); // Call the user function + else + setLedStatus(); +} + /************************************************************/ /* The following functions are for the IR camera */ /************************************************************/ diff --git a/Wii.h b/Wii.h index 753947ba..60c9f07e 100755 --- a/Wii.h +++ b/Wii.h @@ -233,6 +233,14 @@ public: uint8_t getWiiState() { return wiiState; }; + + /** + * Used to call your own function when the controller is successfully initialized. + * @param funcOnInit Function to call. + */ + void attachOnInit(void (*funcOnInit)(void)) { + pFuncOnInit = funcOnInit; + }; /**@}*/ /**@{*/ @@ -418,8 +426,15 @@ public: #endif private: - /* Mandatory members */ - BTD *pBtd; + BTD *pBtd; // Pointer to BTD instance + + /** + * Called when the controller is successfully initialized. + * Use attachOnInit(void (*funcOnInit)(void)) to call your own function. + * This is useful for instance if you want to set the LEDs in a specific way. + */ + void onInit(); + void (*pFuncOnInit)(void); // Pointer to function called in onInit() void L2CAP_task(); // L2CAP state machine @@ -427,9 +442,9 @@ private: uint16_t hci_handle; bool activeConnection; // Used to indicate if it's already has established a connection - /* variables used by high level L2CAP task */ + /* Variables used by high level L2CAP task */ uint8_t l2cap_state; - uint16_t l2cap_event_flag; // l2cap flags of received bluetooth events + uint16_t l2cap_event_flag; // l2cap flags of received Bluetooth events uint32_t ButtonState; uint32_t OldButtonState; diff --git a/XBOXRECV.cpp b/XBOXRECV.cpp index 34cba4b0..8a90aa97 100644 --- a/XBOXRECV.cpp +++ b/XBOXRECV.cpp @@ -312,7 +312,7 @@ void XBOXRECV::readReport(uint8_t controller) { #endif if (Xbox360Connected[controller]) { #ifdef DEBUG_USB_HOST - char* str = 0; + const char* str = 0; switch (readBuf[1]) { case 0x80: str = PSTR(" as controller\r\n"); break; @@ -324,18 +324,7 @@ void XBOXRECV::readReport(uint8_t controller) { Notify(PSTR(": connected"), 0x80); Notify(str, 0x80); #endif - LED led; - switch (controller) { - case 0: led = LED1; - break; - case 1: led = LED2; - break; - case 2: led = LED3; - break; - case 3: led = LED4; - break; - } - setLedOn(led, controller); + onInit(controller); } #ifdef DEBUG_USB_HOST else @@ -531,3 +520,20 @@ void XBOXRECV::setRumbleOn(uint8_t lValue, uint8_t rValue, uint8_t controller) { XboxCommand(controller, writeBuf, 7); } + +void XBOXRECV::onInit(uint8_t controller) { + if (pFuncOnInit) + pFuncOnInit(); // Call the user function + else { + LED led; + if (controller == 0) + led = LED1; + else if (controller == 1) + led = LED2; + else if (controller == 2) + led = LED3; + else + led = LED4; + setLedOn(led, controller); + } +} diff --git a/XBOXRECV.h b/XBOXRECV.h index 86364ca6..2425f8ac 100644 --- a/XBOXRECV.h +++ b/XBOXRECV.h @@ -211,6 +211,14 @@ public: * @return True if a button has changed. */ bool buttonChanged(uint8_t controller = 0); + + /** + * Used to call your own function when the controller is successfully initialized. + * @param funcOnInit Function to call. + */ + void attachOnInit(void (*funcOnInit)(void)) { + pFuncOnInit = funcOnInit; + }; /**@}*/ /** True if a wireless receiver is connected. */ @@ -227,6 +235,15 @@ protected: EpInfo epInfo[XBOX_MAX_ENDPOINTS]; private: + /** + * Called when the controller is successfully initialized. + * Use attachOnInit(void (*funcOnInit)(void)) to call your own function. + * This is useful for instance if you want to set the LEDs in a specific way. + * @param controller The initialized controller. + */ + void onInit(uint8_t controller); + void (*pFuncOnInit)(void); // Pointer to function called in onInit() + bool bPollEnable; /* Variables to store the buttons */ diff --git a/XBOXUSB.cpp b/XBOXUSB.cpp index 2692ffd1..461bf894 100644 --- a/XBOXUSB.cpp +++ b/XBOXUSB.cpp @@ -169,7 +169,7 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) { if (rcode) goto FailSetDevTblEntry; - delay(200); //Give time for address change + delay(200); // Give time for address change rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1); if (rcode) @@ -178,12 +178,12 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) { #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nXbox 360 Controller Connected\r\n"), 0x80); #endif - setLedOn(LED1); + onInit(); Xbox360Connected = true; bPollEnable = true; - return 0; // successful configuration + return 0; // Successful configuration - /* diagnostic messages */ + /* Diagnostic messages */ FailGetDevDescr: #ifdef DEBUG_USB_HOST NotifyFailGetDevDescr(); @@ -347,3 +347,10 @@ void XBOXUSB::setRumbleOn(uint8_t lValue, uint8_t rValue) { XboxCommand(writeBuf, 8); } + +void XBOXUSB::onInit() { + if (pFuncOnInit) + pFuncOnInit(); // Call the user function + else + setLedOn(LED1); +} diff --git a/XBOXUSB.h b/XBOXUSB.h index 661a54bf..7c866b8c 100644 --- a/XBOXUSB.h +++ b/XBOXUSB.h @@ -178,6 +178,14 @@ public: * @param lm See ::LEDMode. */ void setLedMode(LEDMode lm); + + /** + * Used to call your own function when the controller is successfully initialized. + * @param funcOnInit Function to call. + */ + void attachOnInit(void (*funcOnInit)(void)) { + pFuncOnInit = funcOnInit; + }; /**@}*/ /** True if a Xbox 360 controller is connected. */ @@ -192,6 +200,14 @@ protected: EpInfo epInfo[XBOX_MAX_ENDPOINTS]; private: + /** + * Called when the controller is successfully initialized. + * Use attachOnInit(void (*funcOnInit)(void)) to call your own function. + * This is useful for instance if you want to set the LEDs in a specific way. + */ + void onInit(); + void (*pFuncOnInit)(void); // Pointer to function called in onInit() + bool bPollEnable; /* Variables to store the buttons */ diff --git a/examples/Bluetooth/PS3Multi/PS3Multi.ino b/examples/Bluetooth/PS3Multi/PS3Multi.ino index 6bcdcdf5..6c4805bb 100644 --- a/examples/Bluetooth/PS3Multi/PS3Multi.ino +++ b/examples/Bluetooth/PS3Multi/PS3Multi.ino @@ -8,13 +8,16 @@ #include USB Usb; BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so -PS3BT* PS3[2]; // We will use this pointer to store the two instance, you can easily make it larger if you like, but it will use a lot of RAM! +PS3BT *PS3[2]; // We will use this pointer to store the two instance, you can easily make it larger if you like, but it will use a lot of RAM! const uint8_t length = sizeof(PS3)/sizeof(PS3[0]); // Get the lenght of the array boolean printAngle[length]; +boolean oldControllerState[length]; void setup() { - for(uint8_t i=0;iattachOnInit(onInit); // onInit() is called upon a new connection - you can call the function whatever you like + } Serial.begin(115200); if (Usb.Init() == -1) { @@ -31,28 +34,29 @@ void loop() { if(PS3[i]->getAnalogHat(LeftHatX) > 137 || PS3[i]->getAnalogHat(LeftHatX) < 117 || PS3[i]->getAnalogHat(LeftHatY) > 137 || PS3[i]->getAnalogHat(LeftHatY) < 117 || PS3[i]->getAnalogHat(RightHatX) > 137 || PS3[i]->getAnalogHat(RightHatX) < 117 || PS3[i]->getAnalogHat(RightHatY) > 137 || PS3[i]->getAnalogHat(RightHatY) < 117) { Serial.print(F("\r\nLeftHatX: ")); Serial.print(PS3[i]->getAnalogHat(LeftHatX)); - Serial.print(F("\tLeftHatY: ")); + Serial.print(F("\tLeftHatY: ")); Serial.print(PS3[i]->getAnalogHat(LeftHatY)); if(!PS3[i]->PS3NavigationConnected) { // The Navigation controller only have one joystick - Serial.print(F("\tRightHatX: ")); + Serial.print(F("\tRightHatX: ")); Serial.print(PS3[i]->getAnalogHat(RightHatX)); - Serial.print(F("\tRightHatY: ")); - Serial.print(PS3[i]->getAnalogHat(RightHatY)); + Serial.print(F("\tRightHatY: ")); + Serial.print(PS3[i]->getAnalogHat(RightHatY)); } } //Analog button values can be read from almost all buttons if(PS3[i]->getAnalogButton(L2) || PS3[i]->getAnalogButton(R2)) { - Serial.print(F("\r\nL2: ")); + Serial.print(F("\r\nL2: ")); Serial.print(PS3[i]->getAnalogButton(L2)); if(!PS3[i]->PS3NavigationConnected) { - Serial.print(F("\tR2: ")); + Serial.print(F("\tR2: ")); Serial.print(PS3[i]->getAnalogButton(R2)); } } if(PS3[i]->getButtonClick(PS)) { Serial.print(F("\r\nPS")); PS3[i]->disconnect(); - } + oldControllerState[i] = false; // Reset value + } else { if(PS3[i]->getButtonClick(TRIANGLE)) Serial.print(F("\r\nTraingle")); @@ -64,56 +68,56 @@ void loop() { Serial.print(F("\r\nSquare")); if(PS3[i]->getButtonClick(UP)) { - Serial.print(F("\r\nUp")); + Serial.print(F("\r\nUp")); if(PS3[i]->PS3Connected) { PS3[i]->setAllOff(); PS3[i]->setLedOn(LED4); } - } + } if(PS3[i]->getButtonClick(RIGHT)) { Serial.print(F("\r\nRight")); if(PS3[i]->PS3Connected) { PS3[i]->setAllOff(); - PS3[i]->setLedOn(LED1); - } - } + PS3[i]->setLedOn(LED1); + } + } if(PS3[i]->getButtonClick(DOWN)) { Serial.print(F("\r\nDown")); if(PS3[i]->PS3Connected) { PS3[i]->setAllOff(); - PS3[i]->setLedOn(LED2); + PS3[i]->setLedOn(LED2); } - } - if(PS3[i]->getButtonClick(LEFT)) { - Serial.print(F("\r\nLeft")); + } + if(PS3[i]->getButtonClick(LEFT)) { + Serial.print(F("\r\nLeft")); if(PS3[i]->PS3Connected) { - PS3[i]->setAllOff(); - PS3[i]->setLedOn(LED3); - } + PS3[i]->setAllOff(); + PS3[i]->setLedOn(LED3); + } } if(PS3[i]->getButtonClick(L1)) - Serial.print(F("\r\nL1")); + Serial.print(F("\r\nL1")); if(PS3[i]->getButtonClick(L3)) - Serial.print(F("\r\nL3")); + Serial.print(F("\r\nL3")); if(PS3[i]->getButtonClick(R1)) - Serial.print(F("\r\nR1")); + Serial.print(F("\r\nR1")); if(PS3[i]->getButtonClick(R3)) Serial.print(F("\r\nR3")); if(PS3[i]->getButtonClick(SELECT)) { - Serial.print(F("\r\nSelect - ")); - Serial.print(PS3[i]->getStatusString()); - } + Serial.print(F("\r\nSelect - ")); + Serial.print(PS3[i]->getStatusString()); + } if(PS3[i]->getButtonClick(START)) { - Serial.print(F("\r\nStart")); + Serial.print(F("\r\nStart")); printAngle[i] = !printAngle[i]; - } + } } if(printAngle[i]) { - Serial.print(F("\r\nPitch: ")); - Serial.print(PS3[i]->getAngle(Pitch)); - Serial.print(F("\tRoll: ")); + Serial.print(F("\r\nPitch: ")); + Serial.print(PS3[i]->getAngle(Pitch)); + Serial.print(F("\tRoll: ")); Serial.print(PS3[i]->getAngle(Roll)); } } @@ -121,3 +125,12 @@ void loop() { //else if(PS3[i]->PS3MoveConnected) { } } + +void onInit() { + for (uint8_t i=0;iPS3Connected || PS3[i]->PS3NavigationConnected) && !oldControllerState[i]) { + oldControllerState[i] = true; // Used to check which is the new controller + PS3[i]->setLedOn((LED)i); // Cast directly to LED enum - see: "controllerEnums.h" + } + } +} diff --git a/examples/Bluetooth/WiiMulti/WiiMulti.ino b/examples/Bluetooth/WiiMulti/WiiMulti.ino index c0705d6e..c9bac283 100644 --- a/examples/Bluetooth/WiiMulti/WiiMulti.ino +++ b/examples/Bluetooth/WiiMulti/WiiMulti.ino @@ -8,14 +8,17 @@ #include USB Usb; BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so -WII* Wii[2]; // We will use this pointer to store the two instance, you can easily make it larger if you like, but it will use a lot of RAM! +WII *Wii[2]; // We will use this pointer to store the two instance, you can easily make it larger if you like, but it will use a lot of RAM! const uint8_t length = sizeof(Wii)/sizeof(Wii[0]); // Get the lenght of the array -bool printAngle[length]; +boolean printAngle[length]; +boolean oldControllerState[length]; void setup() { - for(uint8_t i=0;iattachOnInit(onInit); // onInit() is called upon a new connection - you can call the function whatever you like + } + Serial.begin(115200); if (Usb.Init() == -1) { Serial.print(F("\r\nOSC did not start")); @@ -31,6 +34,7 @@ void loop() { if(Wii[i]->getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down Serial.print(F("\r\nHOME")); Wii[i]->disconnect(); + oldControllerState[i] = false; // Reset value delay(1000); // This delay is needed for some Wiimotes, so it doesn't try to reconnect right away } else { @@ -105,3 +109,12 @@ void loop() { } } } + +void onInit() { + for (uint8_t i=0;iwiimoteConnected && !oldControllerState[i]) { + oldControllerState[i] = true; // Used to check which is the new controller + Wii[i]->setLedOn((LED)i); // Cast directly to LED enum - see: "controllerEnums.h" + } + } +} diff --git a/keywords.txt b/keywords.txt index 01dcbdc1..2575d9a1 100644 --- a/keywords.txt +++ b/keywords.txt @@ -56,10 +56,13 @@ setLedToggle KEYWORD2 moveSetBulb KEYWORD2 moveSetRumble KEYWORD2 +attachOnInit KEYWORD2 + PS3Connected KEYWORD2 PS3MoveConnected KEYWORD2 PS3NavigationConnected KEYWORD2 +isReady KEYWORD2 watingForConnection KEYWORD2 ####################################################