From 8a397bdf8f53efe5eba7d99da4b2877d15dd3b93 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Sat, 3 Aug 2013 02:12:55 +0200 Subject: [PATCH 01/53] Check FCS of incoming bytes Source: http://lxr.free-electrons.com/source/net/bluetooth/rfcomm/core.c#L172 --- SPP.cpp | 52 ++++++++++++++++++++++++++++++++++++---------------- SPP.h | 9 +++++---- 2 files changed, 41 insertions(+), 20 deletions(-) diff --git a/SPP.cpp b/SPP.cpp index cfaf37f2..f307ab25 100644 --- a/SPP.cpp +++ b/SPP.cpp @@ -269,19 +269,31 @@ void SPP::ACLData(uint8_t* l2capinbuf) { /* Read the incoming message */ if (rfcommChannelType == RFCOMM_UIH && rfcommChannel == rfcommChannelConnection) { uint8_t length = l2capinbuf[10] >> 1; // Get length - uint8_t offset = l2capinbuf[4] - length - 4; // See if there is credit - if (rfcommAvailable + length <= sizeof (rfcommDataBuffer)) { // Don't add data to buffer if it would be full - for (uint8_t i = 0; i < length; i++) + uint8_t offset = l2capinbuf[4] - length - 4; // Check if there is credit + if (checkFcs(&l2capinbuf[8], l2capinbuf[11 + length + offset])) { + uint8_t i = 0; + for (; i < length; i++) { + if (rfcommAvailable + i >= sizeof (rfcommDataBuffer)) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nWarning: Buffer is full!"), 0x80); +#endif + break; + } rfcommDataBuffer[rfcommAvailable + i] = l2capinbuf[11 + i + offset]; - rfcommAvailable += length; - } + } + rfcommAvailable += i; #ifdef EXTRADEBUG - Notify(PSTR("\r\nRFCOMM Data Available: "), 0x80); - Notify(rfcommAvailable, 0x80); - if (offset) { - Notify(PSTR(" - Credit: 0x"), 0x80); - D_PrintHex (l2capinbuf[11], 0x80); + Notify(PSTR("\r\nRFCOMM Data Available: "), 0x80); + Notify(rfcommAvailable, 0x80); + if (offset) { + Notify(PSTR(" - Credit: 0x"), 0x80); + D_PrintHex (l2capinbuf[11], 0x80); + } +#endif } +#ifdef DEBUG_USB_HOST + else + Notify(PSTR("\r\nError in FCS checksum!"), 0x80); #endif #ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send to the Arduino via Bluetooth for (uint8_t i = 0; i < length; i++) @@ -722,16 +734,24 @@ void SPP::sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8 } /* CRC on 2 bytes */ -uint8_t SPP::__crc(uint8_t* data) { - return (pgm_read_byte(&rfcomm_crc_table[pgm_read_byte(&rfcomm_crc_table[0xff ^ data[0]]) ^ data[1]])); +uint8_t SPP::crc(uint8_t *data) { + return (pgm_read_byte(&rfcomm_crc_table[pgm_read_byte(&rfcomm_crc_table[0xFF ^ data[0]]) ^ data[1]])); } -/* Calculate FCS - we never actually check if the host sends correct FCS to the Arduino */ +/* Calculate FCS */ uint8_t SPP::calcFcs(uint8_t *data) { if ((data[1] & 0xEF) == RFCOMM_UIH) - return (0xff - __crc(data)); // FCS on 2 bytes + return (0xFF - crc(data)); // FCS on 2 bytes else - return (0xff - pgm_read_byte(&rfcomm_crc_table[__crc(data) ^ data[2]])); // FCS on 3 bytes + return (0xFF - pgm_read_byte(&rfcomm_crc_table[crc(data) ^ data[2]])); // FCS on 3 bytes +} + +/* Check FCS */ +bool SPP::checkFcs(uint8_t *data, uint8_t fcs) { + uint8_t temp = crc(data); + if ((data[1] & 0xEF) != RFCOMM_UIH) + temp = pgm_read_byte(&rfcomm_crc_table[temp ^ data[2]]); // FCS on 3 bytes + return (pgm_read_byte(&rfcomm_crc_table[temp ^ fcs]) == 0xCF); } /* Serial commands */ @@ -739,7 +759,7 @@ size_t SPP::write(uint8_t data) { return write(&data,1); } -size_t SPP::write(const uint8_t* data, size_t size) { +size_t SPP::write(const uint8_t *data, size_t size) { for(uint8_t i = 0; i < size; i++) { if(sppIndex >= sizeof(sppOutputBuffer)/sizeof(sppOutputBuffer[0])) send(); // Send the current data in the buffer diff --git a/SPP.h b/SPP.h index 7a4f90e0..558f16bc 100644 --- a/SPP.h +++ b/SPP.h @@ -215,7 +215,7 @@ private: void RFCOMM_task(); // RFCOMM state machine /* SDP Commands */ - void SDP_Command(uint8_t* data, uint8_t nbytes); + void SDP_Command(uint8_t *data, uint8_t nbytes); void serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLow); void serialPortResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow); void serialPortResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow); @@ -223,10 +223,11 @@ private: void l2capResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow); /* RFCOMM Commands */ - void RFCOMM_Command(uint8_t* data, uint8_t nbytes); - void sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t* data, uint8_t length); + void RFCOMM_Command(uint8_t *data, uint8_t nbytes); + void sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t *data, uint8_t length); void sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t credit); uint8_t calcFcs(uint8_t *data); - uint8_t __crc(uint8_t* data); + bool checkFcs(uint8_t *data, uint8_t fcs); + uint8_t crc(uint8_t *data); }; #endif \ No newline at end of file From 859c9d0f800740cfddcd8c77d1f4822a30d1d90e Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 11 Nov 2013 00:10:39 +0100 Subject: [PATCH 02/53] Implemented ConfigureDevice, so receiver can be plugged in and out without problems --- XBOXRECV.cpp | 203 +++++++++++++++++++++++++++++---------------------- XBOXRECV.h | 8 ++ 2 files changed, 124 insertions(+), 87 deletions(-) diff --git a/XBOXRECV.cpp b/XBOXRECV.cpp index 3784f25a..e0bcc55f 100644 --- a/XBOXRECV.cpp +++ b/XBOXRECV.cpp @@ -37,29 +37,27 @@ bPollEnable(false) { // don't start polling before dongle is connected pUsb->RegisterDeviceClass(this); //set devConfig[] entry } -uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) { - uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)]; +uint8_t XBOXRECV::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) { + const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR); + uint8_t buf[constBufSize]; uint8_t rcode; UsbDevice *p = NULL; EpInfo *oldep_ptr = NULL; - uint16_t PID; - uint16_t VID; + uint16_t PID, VID; - // get memory address of USB device address pool - AddressPool &addrPool = pUsb->GetAddressPool(); + AddressPool &addrPool = pUsb->GetAddressPool(); // Get memory address of USB device address pool #ifdef EXTRADEBUG Notify(PSTR("\r\nXBOXRECV Init"), 0x80); #endif - // check if address has already been assigned to an instance - if (bAddress) { + + if (bAddress) { // Check if address has already been assigned to an instance #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nAddress in use"), 0x80); #endif return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; } - // Get pointer to pseudo device with address 0 assigned - p = addrPool.GetUsbDevicePtr(0); + p = addrPool.GetUsbDevicePtr(0); // Get pointer to pseudo device with address 0 assigned if (!p) { #ifdef DEBUG_USB_HOST @@ -75,18 +73,13 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) { 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; - + oldep_ptr = p->epinfo; // Save old pointer to EP_RECORD of address 0 + p->epinfo = epInfo; // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence 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; + rcode = pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data + + p->epinfo = oldep_ptr; // Restore p->epinfo if (rcode) goto FailGetDevDescr; @@ -94,53 +87,98 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) { VID = ((USB_DEVICE_DESCRIPTOR*)buf)->idVendor; PID = ((USB_DEVICE_DESCRIPTOR*)buf)->idProduct; - if (VID != XBOX_VID && VID != MADCATZ_VID) // We just check if it's a Xbox receiver using the Vendor ID - goto FailUnknownDevice; - else if (PID != XBOX_WIRELESS_RECEIVER_PID && PID != XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID) { // Check the PID as well + if ((VID != XBOX_VID && VID != MADCATZ_VID) || (PID != XBOX_WIRELESS_RECEIVER_PID && PID != XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID)) { // Check if it's a Xbox receiver using the Vendor ID and Product ID #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nYou'll need a wireless receiver for this libary to work"), 0x80); #endif goto FailUnknownDevice; } - // Allocate new address according to device class - bAddress = addrPool.AllocAddress(parent, false, port); + bAddress = addrPool.AllocAddress(parent, false, port); // Allocate new address according to device class - if (!bAddress) + if (!bAddress) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nOut of address space"), 0x80); +#endif 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; + epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; // Extract Max Packet Size from device descriptor + epInfo[1].epAddr = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations; // Steal and abuse from epInfo structure to save memory - // Assign new address to the device - rcode = pUsb->setAddr(0, 0, bAddress); + return USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET; + + /* Diagnostic messages */ +FailGetDevDescr: +#ifdef DEBUG_USB_HOST + NotifyFailGetDevDescr(rcode); +#endif + if (rcode != hrJERR) + rcode = USB_ERROR_FailGetDevDescr; + goto Fail; + +FailUnknownDevice: +#ifdef DEBUG_USB_HOST + NotifyFailUnknownDevice(VID,PID); +#endif + rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; + +Fail: +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80); + NotifyFail(rcode); +#endif + Release(); + return rcode; +}; + +uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) { + uint8_t rcode; + uint8_t num_of_conf = epInfo[1].epAddr; // Number of configurations + epInfo[1].epAddr = 0; + + AddressPool &addrPool = pUsb->GetAddressPool(); +#ifdef EXTRADEBUG + Notify(PSTR("\r\nBTD Init"), 0x80); +#endif + UsbDevice *p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record + + if (!p) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nAddress not found"), 0x80); +#endif + return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; + } + + delay(300); // Assign new address to the device + + rcode = pUsb->setAddr(0, 0, bAddress); // Assign new address to the device if (rcode) { - p->lowspeed = false; - addrPool.FreeAddress(bAddress); - bAddress = 0; #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nsetAddr: "), 0x80); D_PrintHex (rcode, 0x80); #endif - return rcode; + p->lowspeed = false; + goto Fail; } #ifdef EXTRADEBUG Notify(PSTR("\r\nAddr: "), 0x80); D_PrintHex (bAddress, 0x80); #endif - delay(300); // Spec says you should wait at least 200ms - + p->lowspeed = false; - //get pointer to assigned address record - p = addrPool.GetUsbDevicePtr(bAddress); - if (!p) + p = addrPool.GetUsbDevicePtr(bAddress); // Get pointer to assigned address record + if (!p) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nAddress not found"), 0x80); +#endif 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); + rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); // Assign epInfo to epinfo pointer - only EP0 is known if (rcode) goto FailSetDevTblEntry; @@ -216,9 +254,9 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) { #endif XboxReceiverConnected = true; bPollEnable = true; - return 0; // successful configuration + return 0; // Successful configuration - /* diagnostic messages */ + /* Diagnostic messages */ FailGetDevDescr: #ifdef DEBUG_USB_HOST NotifyFailGetDevDescr(); @@ -237,12 +275,6 @@ FailSetConfDescr: #endif goto Fail; -FailUnknownDevice: -#ifdef DEBUG_USB_HOST - NotifyFailUnknownDevice(VID,PID); -#endif - rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; - Fail: #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80); @@ -273,16 +305,15 @@ uint8_t XBOXRECV::Poll() { uint8_t inputPipe; uint16_t bufferSize; for (uint8_t i = 0; i < 4; i++) { - switch (i) { - case 0: inputPipe = XBOX_INPUT_PIPE_1; - break; - case 1: inputPipe = XBOX_INPUT_PIPE_2; - break; - case 2: inputPipe = XBOX_INPUT_PIPE_3; - break; - case 3: inputPipe = XBOX_INPUT_PIPE_4; - break; - } + if (i == 0) + inputPipe = XBOX_INPUT_PIPE_1; + else if (i == 1) + inputPipe = XBOX_INPUT_PIPE_2; + else if (i == 2) + inputPipe = XBOX_INPUT_PIPE_3; + else + inputPipe = XBOX_INPUT_PIPE_4; + bufferSize = EP_MAXPKTSIZE; // This is the maximum number of bytes we want to receive pUsb->inTransfer(bAddress, epInfo[ inputPipe ].epAddr, &bufferSize, readBuf); if (bufferSize > 0) { // The number of received bytes @@ -420,41 +451,39 @@ bool XBOXRECV::buttonChanged(uint8_t controller) { /* ControllerStatus Breakdown - ControllerStatus[controller] & 0x0001 // 0 - ControllerStatus[controller] & 0x0002 // normal batteries, no rechargeable battery pack - ControllerStatus[controller] & 0x0004 // controller starting up / settling - ControllerStatus[controller] & 0x0008 // headset adapter plugged in, but no headphones connected (mute?) - ControllerStatus[controller] & 0x0010 // 0 - ControllerStatus[controller] & 0x0020 // 1 - ControllerStatus[controller] & 0x0040 // battery level (high bit) - ControllerStatus[controller] & 0x0080 // battery level (low bit) - ControllerStatus[controller] & 0x0100 // 1 - ControllerStatus[controller] & 0x0200 // 1 - ControllerStatus[controller] & 0x0400 // headset adapter plugged in - ControllerStatus[controller] & 0x0800 // 0 - ControllerStatus[controller] & 0x1000 // 1 - ControllerStatus[controller] & 0x2000 // 0 - ControllerStatus[controller] & 0x4000 // 0 - ControllerStatus[controller] & 0x8000 // 0 +ControllerStatus[controller] & 0x0001 // 0 +ControllerStatus[controller] & 0x0002 // normal batteries, no rechargeable battery pack +ControllerStatus[controller] & 0x0004 // controller starting up / settling +ControllerStatus[controller] & 0x0008 // headset adapter plugged in, but no headphones connected (mute?) +ControllerStatus[controller] & 0x0010 // 0 +ControllerStatus[controller] & 0x0020 // 1 +ControllerStatus[controller] & 0x0040 // battery level (high bit) +ControllerStatus[controller] & 0x0080 // battery level (low bit) +ControllerStatus[controller] & 0x0100 // 1 +ControllerStatus[controller] & 0x0200 // 1 +ControllerStatus[controller] & 0x0400 // headset adapter plugged in +ControllerStatus[controller] & 0x0800 // 0 +ControllerStatus[controller] & 0x1000 // 1 +ControllerStatus[controller] & 0x2000 // 0 +ControllerStatus[controller] & 0x4000 // 0 +ControllerStatus[controller] & 0x8000 // 0 */ uint8_t XBOXRECV::getBatteryLevel(uint8_t controller) { return ((controllerStatus[controller] & 0x00C0) >> 6); } void XBOXRECV::XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes) { - uint8_t rcode; uint8_t outputPipe; - switch (controller) { - case 0: outputPipe = XBOX_OUTPUT_PIPE_1; - break; - case 1: outputPipe = XBOX_OUTPUT_PIPE_2; - break; - case 2: outputPipe = XBOX_OUTPUT_PIPE_3; - break; - case 3: outputPipe = XBOX_OUTPUT_PIPE_4; - break; - } - rcode = pUsb->outTransfer(bAddress, epInfo[ outputPipe ].epAddr, nbytes, data); + if (controller == 0) + outputPipe = XBOX_OUTPUT_PIPE_1; + else if (controller == 1) + outputPipe = XBOX_OUTPUT_PIPE_2; + else if (controller == 2) + outputPipe = XBOX_OUTPUT_PIPE_3; + else + outputPipe = XBOX_OUTPUT_PIPE_4; + + uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ outputPipe ].epAddr, nbytes, data); #ifdef EXTRADEBUG if (rcode) Notify(PSTR("Error sending Xbox message\r\n"), 0x80); diff --git a/XBOXRECV.h b/XBOXRECV.h index c5a7f147..02e4ef07 100644 --- a/XBOXRECV.h +++ b/XBOXRECV.h @@ -64,6 +64,14 @@ public: XBOXRECV(USB *pUsb); /** @name USBDeviceConfig implementation */ + /** + * Address assignment and basic initilization is done here. + * @param parent Hub number. + * @param port Port number on the hub. + * @param lowspeed Speed of the device. + * @return 0 on success. + */ + virtual uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed); /** * Initialize the Xbox wireless receiver. * @param parent Hub number. From 52858d502b802551d95c34ae171ba50b48c9a5e0 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 11 Nov 2013 00:38:56 +0100 Subject: [PATCH 03/53] Added delay before bus reset and renamed some variables and cleanup example --- XBOXRECV.cpp | 10 ++- XBOXRECV.h | 2 +- examples/Xbox/XBOXRECV/XBOXRECV.ino | 103 ++++++++++++++-------------- 3 files changed, 59 insertions(+), 56 deletions(-) diff --git a/XBOXRECV.cpp b/XBOXRECV.cpp index e0bcc55f..dfa6b2a4 100644 --- a/XBOXRECV.cpp +++ b/XBOXRECV.cpp @@ -18,7 +18,7 @@ */ #include "XBOXRECV.h" -// To enable serial debugging uncomment "#define DEBUG_USB_HOST" in message.h +// To enable serial debugging see "settings.h" //#define EXTRADEBUG // Uncomment to get even more debugging data //#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller @@ -106,6 +106,8 @@ uint8_t XBOXRECV::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) { epInfo[0].maxPktSize = (uint8_t)((USB_DEVICE_DESCRIPTOR*)buf)->bMaxPacketSize0; // Extract Max Packet Size from device descriptor epInfo[1].epAddr = ((USB_DEVICE_DESCRIPTOR*)buf)->bNumConfigurations; // Steal and abuse from epInfo structure to save memory + delay(20); // Wait a little before resetting device + return USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET; /* Diagnostic messages */ @@ -254,6 +256,7 @@ uint8_t XBOXRECV::Init(uint8_t parent, uint8_t port, bool lowspeed) { #endif XboxReceiverConnected = true; bPollEnable = true; + checkStatusTimer = 0; // Reset timer return 0; // Successful configuration /* Diagnostic messages */ @@ -298,10 +301,11 @@ uint8_t XBOXRECV::Release() { uint8_t XBOXRECV::Poll() { if (!bPollEnable) return 0; - if (!timer || ((millis() - timer) > 3000)) { // Run checkStatus every 3 seconds - timer = millis(); + if (!checkStatusTimer || ((millis() - checkStatusTimer) > 3000)) { // Run checkStatus every 3 seconds + checkStatusTimer = millis(); checkStatus(); } + uint8_t inputPipe; uint16_t bufferSize; for (uint8_t i = 0; i < 4; i++) { diff --git a/XBOXRECV.h b/XBOXRECV.h index 02e4ef07..bb0b53d7 100644 --- a/XBOXRECV.h +++ b/XBOXRECV.h @@ -259,7 +259,7 @@ private: bool L2Clicked[4]; // These buttons are analog, so we use we use these bools to check if they where clicked or not bool R2Clicked[4]; - unsigned long timer; // Timing for checkStatus() signals + uint32_t checkStatusTimer; // Timing for checkStatus() signals uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data uint8_t writeBuf[7]; // General purpose buffer for output data diff --git a/examples/Xbox/XBOXRECV/XBOXRECV.ino b/examples/Xbox/XBOXRECV/XBOXRECV.ino index 6bd33b0e..2143098e 100644 --- a/examples/Xbox/XBOXRECV/XBOXRECV.ino +++ b/examples/Xbox/XBOXRECV/XBOXRECV.ino @@ -1,7 +1,7 @@ /* Example sketch for the Xbox Wireless Reciver library - developed by Kristian Lauszus It supports up to four controllers wirelessly - For more information see the blog post: http://blog.tkjelectronics.dk/2012/12/xbox-360-receiver-added-to-the-usb-host-library/ or + For more information see the blog post: http://blog.tkjelectronics.dk/2012/12/xbox-360-receiver-added-to-the-usb-host-library/ or send me an e-mail: kristianl@tkjelectronics.com */ @@ -15,81 +15,81 @@ void setup() { while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection if (Usb.Init() == -1) { Serial.print(F("\r\nOSC did not start")); - while(1); //halt + while (1); //halt } Serial.print(F("\r\nXbox Wireless Receiver Library Started")); } void loop() { Usb.Task(); - if(Xbox.XboxReceiverConnected) { - for(uint8_t i=0;i<4;i++) { - if(Xbox.Xbox360Connected[i]) { - if(Xbox.getButtonPress(L2,i) || Xbox.getButtonPress(R2,i)) { + if (Xbox.XboxReceiverConnected) { + for (uint8_t i = 0; i < 4; i++) { + if (Xbox.Xbox360Connected[i]) { + if (Xbox.getButtonPress(L2, i) || Xbox.getButtonPress(R2, i)) { Serial.print("L2: "); - Serial.print(Xbox.getButtonPress(L2,i)); + Serial.print(Xbox.getButtonPress(L2, i)); Serial.print("\tR2: "); - Serial.println(Xbox.getButtonPress(R2,i)); - Xbox.setRumbleOn(Xbox.getButtonPress(L2,i),Xbox.getButtonPress(R2,i),i); + Serial.println(Xbox.getButtonPress(R2, i)); + Xbox.setRumbleOn(Xbox.getButtonPress(L2, i), Xbox.getButtonPress(R2, i), i); } - if(Xbox.getAnalogHat(LeftHatX,i) > 7500 || Xbox.getAnalogHat(LeftHatX,i) < -7500 || Xbox.getAnalogHat(LeftHatY,i) > 7500 || Xbox.getAnalogHat(LeftHatY,i) < -7500 || Xbox.getAnalogHat(RightHatX,i) > 7500 || Xbox.getAnalogHat(RightHatX,i) < -7500 || Xbox.getAnalogHat(RightHatY,i) > 7500 || Xbox.getAnalogHat(RightHatY,i) < -7500) { - if(Xbox.getAnalogHat(LeftHatX,i) > 7500 || Xbox.getAnalogHat(LeftHatX,i) < -7500) { - Serial.print(F("LeftHatX: ")); - Serial.print(Xbox.getAnalogHat(LeftHatX,i)); + if (Xbox.getAnalogHat(LeftHatX, i) > 7500 || Xbox.getAnalogHat(LeftHatX, i) < -7500 || Xbox.getAnalogHat(LeftHatY, i) > 7500 || Xbox.getAnalogHat(LeftHatY, i) < -7500 || Xbox.getAnalogHat(RightHatX, i) > 7500 || Xbox.getAnalogHat(RightHatX, i) < -7500 || Xbox.getAnalogHat(RightHatY, i) > 7500 || Xbox.getAnalogHat(RightHatY, i) < -7500) { + if (Xbox.getAnalogHat(LeftHatX, i) > 7500 || Xbox.getAnalogHat(LeftHatX, i) < -7500) { + Serial.print(F("LeftHatX: ")); + Serial.print(Xbox.getAnalogHat(LeftHatX, i)); Serial.print("\t"); - } - if(Xbox.getAnalogHat(LeftHatY,i) > 7500 || Xbox.getAnalogHat(LeftHatY,i) < -7500) { - Serial.print(F("LeftHatY: ")); - Serial.print(Xbox.getAnalogHat(LeftHatY,i)); + } + if (Xbox.getAnalogHat(LeftHatY, i) > 7500 || Xbox.getAnalogHat(LeftHatY, i) < -7500) { + Serial.print(F("LeftHatY: ")); + Serial.print(Xbox.getAnalogHat(LeftHatY, i)); Serial.print("\t"); - } - if(Xbox.getAnalogHat(RightHatX,i) > 7500 || Xbox.getAnalogHat(RightHatX,i) < -7500) { - Serial.print(F("RightHatX: ")); - Serial.print(Xbox.getAnalogHat(RightHatX,i)); - Serial.print("\t"); - } - if(Xbox.getAnalogHat(RightHatY,i) > 7500 || Xbox.getAnalogHat(RightHatY,i) < -7500) { - Serial.print(F("RightHatY: ")); - Serial.print(Xbox.getAnalogHat(RightHatY,i)); + } + if (Xbox.getAnalogHat(RightHatX, i) > 7500 || Xbox.getAnalogHat(RightHatX, i) < -7500) { + Serial.print(F("RightHatX: ")); + Serial.print(Xbox.getAnalogHat(RightHatX, i)); + Serial.print("\t"); + } + if (Xbox.getAnalogHat(RightHatY, i) > 7500 || Xbox.getAnalogHat(RightHatY, i) < -7500) { + Serial.print(F("RightHatY: ")); + Serial.print(Xbox.getAnalogHat(RightHatY, i)); } Serial.println(); } - if(Xbox.getButtonClick(UP,i)) { - Xbox.setLedOn(LED1,i); + if (Xbox.getButtonClick(UP, i)) { + Xbox.setLedOn(LED1, i); Serial.println(F("Up")); - } - if(Xbox.getButtonClick(DOWN,i)) { - Xbox.setLedOn(LED4,i); + } + if (Xbox.getButtonClick(DOWN, i)) { + Xbox.setLedOn(LED4, i); Serial.println(F("Down")); } - if(Xbox.getButtonClick(LEFT,i)) { - Xbox.setLedOn(LED3,i); + if (Xbox.getButtonClick(LEFT, i)) { + Xbox.setLedOn(LED3, i); Serial.println(F("Left")); } - if(Xbox.getButtonClick(RIGHT,i)) { - Xbox.setLedOn(LED2,i); + if (Xbox.getButtonClick(RIGHT, i)) { + Xbox.setLedOn(LED2, i); Serial.println(F("Right")); - } + } - if(Xbox.getButtonClick(START,i)) { - Xbox.setLedMode(ALTERNATING,i); + if (Xbox.getButtonClick(START, i)) { + Xbox.setLedMode(ALTERNATING, i); Serial.println(F("Start")); } - if(Xbox.getButtonClick(BACK,i)) { - Xbox.setLedBlink(ALL,i); + if (Xbox.getButtonClick(BACK, i)) { + Xbox.setLedBlink(ALL, i); Serial.println(F("Back")); } - if(Xbox.getButtonClick(L3,i)) + if (Xbox.getButtonClick(L3, i)) Serial.println(F("L3")); - if(Xbox.getButtonClick(R3,i)) + if (Xbox.getButtonClick(R3, i)) Serial.println(F("R3")); - if(Xbox.getButtonClick(L1,i)) + if (Xbox.getButtonClick(L1, i)) Serial.println(F("L1")); - if(Xbox.getButtonClick(R1,i)) + if (Xbox.getButtonClick(R1, i)) Serial.println(F("R1")); - if(Xbox.getButtonClick(XBOX,i)) { - Xbox.setLedMode(ROTATING,i); + if (Xbox.getButtonClick(XBOX, i)) { + Xbox.setLedMode(ROTATING, i); Serial.print(F("Xbox (Battery: ")); Serial.print(Xbox.getBatteryLevel(i)); // The battery level in the range 0-3 Serial.println(F(")")); @@ -97,16 +97,15 @@ void loop() { if(Xbox.getButtonClick(SYNC,i)) Serial.println(F("Sync")); - if(Xbox.getButtonClick(A,i)) + if (Xbox.getButtonClick(A, i)) Serial.println(F("A")); - if(Xbox.getButtonClick(B,i)) + if (Xbox.getButtonClick(B, i)) Serial.println(F("B")); - if(Xbox.getButtonClick(X,i)) + if (Xbox.getButtonClick(X, i)) Serial.println(F("X")); - if(Xbox.getButtonClick(Y,i)) + if (Xbox.getButtonClick(Y, i)) Serial.println(F("Y")); } } - } - delay(1); + } } From 764e74c94c96de2b7216ecb987b276519920b4e3 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 11 Nov 2013 00:43:18 +0100 Subject: [PATCH 04/53] Can now disconnect a wireless controller --- XBOXRECV.cpp | 9 +++++++++ XBOXRECV.h | 6 ++++++ examples/Xbox/XBOXRECV/XBOXRECV.ino | 4 +++- 3 files changed, 18 insertions(+), 1 deletion(-) diff --git a/XBOXRECV.cpp b/XBOXRECV.cpp index dfa6b2a4..5f54e059 100644 --- a/XBOXRECV.cpp +++ b/XBOXRECV.cpp @@ -494,6 +494,15 @@ void XBOXRECV::XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes) { #endif } +void XBOXRECV::disconnect(uint8_t controller) { + writeBuf[0] = 0x00; + writeBuf[1] = 0x00; + writeBuf[2] = 0x08; + writeBuf[3] = 0xC0; + + XboxCommand(controller, writeBuf, 4); +} + void XBOXRECV::setLedRaw(uint8_t value, uint8_t controller) { writeBuf[0] = 0x00; writeBuf[1] = 0x00; diff --git a/XBOXRECV.h b/XBOXRECV.h index bb0b53d7..eee75cda 100644 --- a/XBOXRECV.h +++ b/XBOXRECV.h @@ -144,6 +144,12 @@ public: */ int16_t getAnalogHat(AnalogHat a, uint8_t controller = 0); + /** + * Used to disconnect any of the controllers. + * @param controller The controller to disconnect. Default to 0. + */ + void disconnect(uint8_t controller = 0); + /** * Turn rumble off and all the LEDs on the specific controller. * @param controller The controller to write to. Default to 0. diff --git a/examples/Xbox/XBOXRECV/XBOXRECV.ino b/examples/Xbox/XBOXRECV/XBOXRECV.ino index 2143098e..512e176e 100644 --- a/examples/Xbox/XBOXRECV/XBOXRECV.ino +++ b/examples/Xbox/XBOXRECV/XBOXRECV.ino @@ -94,8 +94,10 @@ void loop() { Serial.print(Xbox.getBatteryLevel(i)); // The battery level in the range 0-3 Serial.println(F(")")); } - if(Xbox.getButtonClick(SYNC,i)) + if (Xbox.getButtonClick(SYNC, i)) { Serial.println(F("Sync")); + Xbox.disconnect(i); + } if (Xbox.getButtonClick(A, i)) Serial.println(F("A")); From 0dc2b8150949fdcfc05c880c0101809332c13c2a Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 11 Nov 2013 00:43:50 +0100 Subject: [PATCH 05/53] Read buttons a little smarter --- XBOXOLD.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/XBOXOLD.cpp b/XBOXOLD.cpp index 4c9bcb20..b08f857b 100644 --- a/XBOXOLD.cpp +++ b/XBOXOLD.cpp @@ -16,7 +16,7 @@ */ #include "XBOXOLD.h" -// To enable serial debugging uncomment "#define DEBUG_USB_HOST" in message.h +// To enable serial debugging see "settings.h" //#define EXTRADEBUG // Uncomment to get even more debugging data //#define PRINTREPORT // Uncomment to print the report send by the Xbox controller @@ -290,15 +290,15 @@ void XBOXOLD::printReport(uint16_t length) { //Uncomment "#define PRINTREPORT" t } uint8_t XBOXOLD::getButtonPress(Button b) { + uint8_t button = pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b]); if (b == A || b == B || b == X || b == Y || b == BLACK || b == WHITE || b == L1 || b == R1) // A, B, X, Y, BLACK, WHITE, L1, and R1 are analog buttons - return buttonValues[pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b])]; // Analog buttons - return (ButtonState & pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b])); // Digital buttons + return buttonValues[button]; // Analog buttons + return (ButtonState & button); // Digital buttons } bool XBOXOLD::getButtonClick(Button b) { - uint8_t button; + uint8_t button = pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b]); if (b == A || b == B || b == X || b == Y || b == BLACK || b == WHITE || b == L1 || b == R1) { // A, B, X, Y, BLACK, WHITE, L1, and R1 are analog buttons - button = pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b]); if (buttonClicked[button]) { buttonClicked[button] = false; return true; @@ -306,7 +306,6 @@ bool XBOXOLD::getButtonClick(Button b) { return false; } - button = pgm_read_byte(&XBOXOLDBUTTONS[(uint8_t)b]); // Digital buttons bool click = (ButtonClickState & button); ButtonClickState &= ~button; // clear "click" event return click; From a03df2519b12b6326c9f7102b26f1d3f595b8e8c Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 11 Nov 2013 00:45:27 +0100 Subject: [PATCH 06/53] Limit number of retries --- Usb.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/Usb.cpp b/Usb.cpp index 6bcf092e..e47383c6 100644 --- a/Usb.cpp +++ b/Usb.cpp @@ -567,6 +567,7 @@ uint8_t USB::DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed) { uint8_t USB::AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lowspeed) { //printf("AttemptConfig: parent = %i, port = %i\r\n", parent, port); + uint8_t retries = 0; again: uint8_t rcode = devConfig[driver]->ConfigureDevice(parent, port, lowspeed); @@ -579,15 +580,17 @@ again: // reset parent port devConfig[parent]->ResetHubPort(port); } - } else if (rcode == hrJERR) { // Some devices returns this when plugged in - trying to initialize the device again usually works + } else if (rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works delay(100); + retries++; goto again; } else if (rcode) return rcode; rcode = devConfig[driver]->Init(parent, port, lowspeed); - if (rcode == hrJERR) { // Some devices returns this when plugged in - trying to initialize the device again usually works + if (rcode == hrJERR && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works delay(100); + retries++; goto again; } if (rcode) { From b08e89a6f9eb8a0b02ae1666e1c1390bfa0474e3 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 11 Nov 2013 11:48:09 +0100 Subject: [PATCH 07/53] Updated comment about how to activate serial debugging --- BTD.cpp | 2 +- PS3BT.cpp | 2 +- PS3USB.cpp | 2 +- SPP.cpp | 2 +- Wii.cpp | 2 +- WiiCameraReadme.md | 4 +--- XBOXUSB.cpp | 2 +- 7 files changed, 7 insertions(+), 9 deletions(-) diff --git a/BTD.cpp b/BTD.cpp index 9cf2436b..a1fa1841 100755 --- a/BTD.cpp +++ b/BTD.cpp @@ -16,7 +16,7 @@ */ #include "BTD.h" -// To enable serial debugging uncomment "#define DEBUG_USB_HOST" in message.h +// To enable serial debugging see "settings.h" //#define EXTRADEBUG // Uncomment to get even more debugging data const uint8_t BTD::BTD_CONTROL_PIPE = 0; diff --git a/PS3BT.cpp b/PS3BT.cpp index 6f9a4d23..0638ef5b 100644 --- a/PS3BT.cpp +++ b/PS3BT.cpp @@ -16,7 +16,7 @@ */ #include "PS3BT.h" -// To enable serial debugging uncomment "#define DEBUG_USB_HOST" in message.h +// To enable serial debugging see "settings.h" //#define EXTRADEBUG // Uncomment to get even more debugging data //#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers diff --git a/PS3USB.cpp b/PS3USB.cpp index 0d02a9e1..47009497 100644 --- a/PS3USB.cpp +++ b/PS3USB.cpp @@ -16,7 +16,7 @@ */ #include "PS3USB.h" -// To enable serial debugging uncomment "#define DEBUG_USB_HOST" in message.h +// To enable serial debugging see "settings.h" //#define EXTRADEBUG // Uncomment to get even more debugging data //#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers diff --git a/SPP.cpp b/SPP.cpp index 5eba1617..b016aed3 100644 --- a/SPP.cpp +++ b/SPP.cpp @@ -16,7 +16,7 @@ */ #include "SPP.h" -// To enable serial debugging uncomment "#define DEBUG_USB_HOST" in message.h +// To enable serial debugging see "settings.h" //#define EXTRADEBUG // Uncomment to get even more debugging data //#define PRINTREPORT // Uncomment to print the report sent to the Arduino diff --git a/Wii.cpp b/Wii.cpp index 0689f43c..57be934e 100755 --- a/Wii.cpp +++ b/Wii.cpp @@ -18,7 +18,7 @@ */ #include "Wii.h" -// To enable serial debugging uncomment "#define DEBUG_USB_HOST" in message.h +// To enable serial debugging see "settings.h" //#define EXTRADEBUG // Uncomment to get even more debugging data //#define PRINTREPORT // Uncomment to print the report send by the Wii controllers diff --git a/WiiCameraReadme.md b/WiiCameraReadme.md index d9bcb78a..d3fc11ae 100644 --- a/WiiCameraReadme.md +++ b/WiiCameraReadme.md @@ -1,8 +1,6 @@ Please see for the complete capabilities of the Wii camera. The IR camera code was written based on the above website and with support from Kristian Lauszus. -Must omit the "." in the name of the USB\_Host\_Shiled\_2.0 library folder when inserting into the Arudino library folder. - -This library is large, if you run into memory problems when uploading to the Arduino, comment out the \#define DEBUG in the BTD.cpp and Wii.cpp files. +This library is large, if you run into memory problems when uploading to the Arduino, disable serial debugging. To enable the IR camera code, uncomment \#define WIICAMERA in Wii.h. diff --git a/XBOXUSB.cpp b/XBOXUSB.cpp index 21b9d18e..4b635f43 100644 --- a/XBOXUSB.cpp +++ b/XBOXUSB.cpp @@ -16,7 +16,7 @@ */ #include "XBOXUSB.h" -// To enable serial debugging uncomment "#define DEBUG_USB_HOST" in message.h +// To enable serial debugging see "settings.h" //#define EXTRADEBUG // Uncomment to get even more debugging data //#define PRINTREPORT // Uncomment to print the report send by the Xbox 360 Controller From 3a93571c8707ed2c4a3a75b17dbcfaae4691b8fb Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 11 Nov 2013 20:50:25 +0100 Subject: [PATCH 08/53] Replaced tab with a space --- settings.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/settings.h b/settings.h index add3ee03..423bcd69 100644 --- a/settings.h +++ b/settings.h @@ -6,7 +6,7 @@ */ #ifndef USB_HOST_SHIELD_SETTINGS_H -#define USB_HOST_SHIELD_SETTINGS_H +#define USB_HOST_SHIELD_SETTINGS_H #include "macros.h" //////////////////////////////////////////////////////////////////////////////// From 0bd0078c6d83c77d80f63447759590b57be2f4d6 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Tue, 12 Nov 2013 19:38:18 +0100 Subject: [PATCH 09/53] Updated comments --- BTD.cpp | 24 ++++++++++-------------- PS3BT.cpp | 4 ++-- Wii.cpp | 6 +++--- 3 files changed, 15 insertions(+), 19 deletions(-) diff --git a/BTD.cpp b/BTD.cpp index a1fa1841..d6ccc5b6 100755 --- a/BTD.cpp +++ b/BTD.cpp @@ -402,14 +402,10 @@ void BTD::HCI_event_task() { break; case EV_COMMAND_STATUS: - if (hcibuf[2]) { // show status on serial if not OK + if (hcibuf[2]) { // Show status on serial if not OK #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nHCI Command Failed: "), 0x80); D_PrintHex (hcibuf[2], 0x80); - Notify(PSTR(" "), 0x80); - D_PrintHex (hcibuf[4], 0x80); - Notify(PSTR(" "), 0x80); - D_PrintHex (hcibuf[5], 0x80); #endif } break; @@ -467,13 +463,13 @@ void BTD::HCI_event_task() { if (!hcibuf[2]) { // check if connected OK hci_handle = hcibuf[3] | ((hcibuf[4] & 0x0F) << 8); // store the handle for the ACL connection hci_event_flag |= HCI_FLAG_CONN_COMPLETE; // set connection complete flag - } -#ifdef DEBUG_USB_HOST - else { - Notify(PSTR("\r\nConnection Failed"), 0x80); + } else { hci_state = HCI_CHECK_WII_SERVICE; - } +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nConnection Failed: "), 0x80); + D_PrintHex (hcibuf[2], 0x80); #endif + } break; case EV_DISCONNECT_COMPLETE: @@ -1078,7 +1074,7 @@ void BTD::hci_disconnect(uint16_t handle) { // This is called by the different s } void BTD::hci_write_class_of_device() { // See http://bluetooth-pentest.narod.ru/software/bluetooth_class_of_device-service_generator.html - hcibuf[0] = 0x24; // HCI OCF = 3 + hcibuf[0] = 0x24; // HCI OCF = 24 hcibuf[1] = 0x03 << 2; // HCI OGF = 3 hcibuf[2] = 0x03; // parameter length = 3 hcibuf[3] = 0x04; // Robot @@ -1258,9 +1254,9 @@ void BTD::setBdaddr(uint8_t* bdaddr) { 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 + buf[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed, so it is MSB first - // 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) + // 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[BTD_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL); } @@ -1276,6 +1272,6 @@ void BTD::setMoveBdaddr(uint8_t* bdaddr) { 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) + // 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[BTD_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00, 11, 11, buf, NULL); } diff --git a/PS3BT.cpp b/PS3BT.cpp index 0638ef5b..7fb6b8b4 100644 --- a/PS3BT.cpp +++ b/PS3BT.cpp @@ -611,7 +611,7 @@ void PS3BT::setLedToggle(LED a) { HID_Command(HIDBuffer, HID_BUFFERSIZE); } -void PS3BT::enable_sixaxis() { //Command used to enable the Dualshock 3 and Navigation controller to send data via USB +void PS3BT::enable_sixaxis() { // Command used to enable the Dualshock 3 and Navigation controller to send data via Bluetooth uint8_t cmd_buf[6]; cmd_buf[0] = 0x53; // HID BT Set_report (0x50) | Report Type (Feature 0x03) cmd_buf[1] = 0xF4; // Report ID @@ -623,7 +623,7 @@ void PS3BT::enable_sixaxis() { //Command used to enable the Dualshock 3 and Navi HID_Command(cmd_buf, 6); } -//Playstation Move Controller commands +// Playstation Move Controller commands void PS3BT::HIDMove_Command(uint8_t* data, uint8_t nbytes) { if (millis() - timerHID <= 250)// Check if is has been less than 200ms since last command diff --git a/Wii.cpp b/Wii.cpp index 57be934e..2e8669db 100755 --- a/Wii.cpp +++ b/Wii.cpp @@ -473,11 +473,11 @@ void WII::ACLData(uint8_t* l2capinbuf) { pitchGyroSpeed = (double)gyroPitchRaw / ((double)gyroPitchZero / pitchGyroScale); /* The onboard gyro has two ranges for slow and fast mode */ - if (!(l2capinbuf[18] & 0x02)) // Check if fast more is used + if (!(l2capinbuf[18] & 0x02)) // Check if fast mode is used yawGyroSpeed *= 4.545; - if (!(l2capinbuf[18] & 0x01)) // Check if fast more is used + if (!(l2capinbuf[18] & 0x01)) // Check if fast mode is used pitchGyroSpeed *= 4.545; - if (!(l2capinbuf[19] & 0x02)) // Check if fast more is used + if (!(l2capinbuf[19] & 0x02)) // Check if fast mode is used rollGyroSpeed *= 4.545; compPitch = (0.93 * (compPitch + (pitchGyroSpeed * (double)(micros() - timer) / 1000000)))+(0.07 * getWiimotePitch()); // Use a complimentary filter to calculate the angle From 16c427235803b9d21be7c74a711b2c2a5ec95c31 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Tue, 12 Nov 2013 19:44:12 +0100 Subject: [PATCH 10/53] Can now get Bluetooth address inside PS3 controller - can also get calibration data inside move controller Also updated some comments and cleanup --- PS3USB.cpp | 111 ++++++++++++++++++++++++++++----------------------- PS3USB.h | 61 +++++++++++++++++++--------- keywords.txt | 3 ++ 3 files changed, 107 insertions(+), 68 deletions(-) diff --git a/PS3USB.cpp b/PS3USB.cpp index 47009497..1e0cb4fc 100644 --- a/PS3USB.cpp +++ b/PS3USB.cpp @@ -129,7 +129,7 @@ uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) { D_PrintHex (bAddress, 0x80); #endif delay(300); // Spec says you should wait at least 200ms - + p->lowspeed = false; //get pointer to assigned address record @@ -279,8 +279,7 @@ uint8_t PS3USB::Poll() { #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 - { + 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(); } @@ -289,9 +288,6 @@ uint8_t PS3USB::Poll() { } 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", 0x80); @@ -303,10 +299,8 @@ void PS3USB::readReport() { } } -void PS3USB::printReport() { //Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers +void PS3USB::printReport() { // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers #ifdef PRINTREPORT - if (readBuf == NULL) - return; for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) { D_PrintHex (readBuf[i], 0x80); Notify(PSTR(" "), 0x80); @@ -322,25 +316,19 @@ bool PS3USB::getButtonPress(Button b) { bool PS3USB::getButtonClick(Button b) { uint32_t button = pgm_read_dword(&BUTTONS[(uint8_t)b]); bool click = (ButtonClickState & button); - ButtonClickState &= ~button; // clear "click" event + ButtonClickState &= ~button; // Clear "click" event return click; } uint8_t PS3USB::getAnalogButton(Button a) { - if (readBuf == NULL) - return 0; return (uint8_t)(readBuf[(pgm_read_byte(&ANALOGBUTTONS[(uint8_t)a])) - 9]); } uint8_t PS3USB::getAnalogHat(AnalogHat a) { - if (readBuf == NULL) - return 0; return (uint8_t)(readBuf[((uint8_t)a + 6)]); } uint16_t PS3USB::getSensor(Sensor a) { - if (readBuf == NULL) - return 0; return ((readBuf[((uint16_t)a) - 9] << 8) | readBuf[((uint16_t)a + 1) - 9]); } @@ -359,23 +347,16 @@ double PS3USB::getAngle(Angle a) { // 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; - } + if (a == Pitch) + return (atan2(accYval, accZval) + PI) * RAD_TO_DEG; + else + return (atan2(accXval, accZval) + PI) * RAD_TO_DEG; } else return 0; } bool PS3USB::getStatus(Status c) { - if (readBuf == NULL) - return false; - if (readBuf[((uint16_t)c >> 8) - 9] == ((uint8_t)c & 0xff)) - return true; - return false; + return (readBuf[((uint16_t)c >> 8) - 9] == ((uint8_t)c & 0xff)); } String PS3USB::getStatusString() { @@ -414,8 +395,8 @@ String PS3USB::getStatusString() { } /* 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) +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); } @@ -428,9 +409,9 @@ void PS3USB::setAllOff() { void PS3USB::setRumbleOff() { writeBuf[1] = 0x00; - writeBuf[2] = 0x00; //low mode off + writeBuf[2] = 0x00; // Low mode off writeBuf[3] = 0x00; - writeBuf[4] = 0x00; //high mode off + writeBuf[4] = 0x00; // High mode off PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE); } @@ -474,36 +455,47 @@ void PS3USB::setLedToggle(LED a) { PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE); } -void PS3USB::setBdaddr(uint8_t* BDADDR) { - /* Set the internal bluetooth address */ +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) + for (uint8_t i = 0; i < 6; i++) + buf[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed, so it is MSB first + + // 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); } -void PS3USB::enable_sixaxis() { //Command used to enable the Dualshock 3 and Navigation controller to send data via USB +void PS3USB::getBdaddr(uint8_t *bdaddr) { + uint8_t buf[8]; + + // bmRequest = Device to host (0x80) | Class (0x20) | Interface (0x01) = 0xA1, bRequest = Get Report (0x01), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data + pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL); + + for (uint8_t i = 0; i < 6; i++) + bdaddr[5 - i] = buf[i + 2]; // Copy into buffer reversed, so it is LSB first +} + +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) + // 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) { +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 +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; @@ -511,7 +503,7 @@ void PS3USB::moveSetBulb(uint8_t r, uint8_t g, uint8_t b) { //Use this to set th 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" +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)); } @@ -520,14 +512,13 @@ void PS3USB::moveSetRumble(uint8_t rumble) { 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%"), 0x80); #endif - //set the rumble value into the write buffer - writeBuf[6] = rumble; + writeBuf[6] = rumble; // Set the rumble value into the write buffer Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE); } -void PS3USB::setMoveBdaddr(uint8_t* BDADDR) { - /* Set the internal bluetooth address */ +void PS3USB::setMoveBdaddr(uint8_t *bdaddr) { + /* Set the internal Bluetooth address */ uint8_t buf[11]; buf[0] = 0x05; buf[7] = 0x10; @@ -536,12 +527,34 @@ void PS3USB::setMoveBdaddr(uint8_t* BDADDR) { buf[10] = 0x12; for (uint8_t i = 0; i < 6; i++) - buf[i + 1] = 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) + // 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::getMoveBdaddr(uint8_t *bdaddr) { + uint8_t buf[16]; + + // bmRequest = Device to host (0x80) | Class (0x20) | Interface (0x01) = 0xA1, bRequest = Get Report (0x01), Report ID (0x04), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data + pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0x04, 0x03, 0x00, 16, 16, buf, NULL); + + for (uint8_t i = 0; i < 6; i++) + bdaddr[i] = buf[10 + i]; +} + +void PS3USB::getMoveCalibration(uint8_t *data) { + uint8_t buf[49]; + + for (uint8_t i = 0; i < 3; i++) { + // bmRequest = Device to host (0x80) | Class (0x20) | Interface (0x01) = 0xA1, bRequest = Get Report (0x01), Report ID (0x10), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data + pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0x10, 0x03, 0x00, 49, 49, buf, NULL); + + for (byte j = 0; j < 49; j++) + data[49 * i + j] = buf[j]; + } +} + void PS3USB::onInit() { if (pFuncOnInit) pFuncOnInit(); // Call the user function diff --git a/PS3USB.h b/PS3USB.h index 775ce56d..2fac0fbe 100644 --- a/PS3USB.h +++ b/PS3USB.h @@ -22,27 +22,30 @@ #include "PS3Enums.h" /* PS3 data taken from descriptors */ -#define EP_MAXPKTSIZE 64 // max size for data via USB +#define EP_MAXPKTSIZE 64 // max size for data via USB /* Endpoint types */ -#define EP_INTERRUPT 0x03 +#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 +#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_VID 0x054C // Sony Corporation +#define PS3_PID 0x0268 // PS3 Controller DualShock 3 +#define PS3NAVIGATION_PID 0x042F // Navigation controller +#define PS3MOVE_PID 0x03D5 // Motion 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 +// 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 bmREQ_HID_IN USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE -#define PS3_MAX_ENDPOINTS 3 +#define HID_REQUEST_GET_REPORT 0x01 +#define HID_REQUEST_SET_REPORT 0x09 + +#define PS3_MAX_ENDPOINTS 3 /** * This class implements support for all the official PS3 Controllers: @@ -112,14 +115,34 @@ public: /** * Used to set the Bluetooth address inside the Dualshock 3 and Navigation controller. - * @param BDADDR Your dongles Bluetooth address. + * Set using LSB first. + * @param bdaddr Your dongles Bluetooth address. */ - void setBdaddr(uint8_t* BDADDR); + void setBdaddr(uint8_t *bdaddr); + /** + * Used to get the Bluetooth address inside the Dualshock 3 and Navigation controller. + * Will return LSB first. + * @param bdaddr Your dongles Bluetooth address. + */ + void getBdaddr(uint8_t *bdaddr); + /** * Used to set the Bluetooth address inside the Move controller. - * @param BDADDR Your dongles Bluetooth address. + * Set using LSB first. + * @param bdaddr Your dongles Bluetooth address. */ - void setMoveBdaddr(uint8_t* BDADDR); + void setMoveBdaddr(uint8_t *bdaddr); + /** + * Used to get the Bluetooth address inside the Move controller. + * Will return LSB first. + * @param bdaddr Your dongles Bluetooth address. + */ + void getMoveBdaddr(uint8_t *bdaddr); + /** + * Used to get the calibration data inside the Move controller. + * @param bdaddr Buffer to store data in. Must be at least 147 bytes + */ + void getMoveCalibration(uint8_t *data); /** @name PS3 Controller functions */ /** @@ -278,8 +301,8 @@ private: void printReport(); // print incoming date - Uncomment for debugging /* Private commands */ - void PS3_Command(uint8_t* data, uint16_t nbytes); + 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); + void Move_Command(uint8_t *data, uint16_t nbytes); }; #endif diff --git a/keywords.txt b/keywords.txt index b68eda9c..6847bb09 100644 --- a/keywords.txt +++ b/keywords.txt @@ -34,7 +34,10 @@ PS3USB KEYWORD1 # Methods and Functions (KEYWORD2) #################################################### setBdaddr KEYWORD2 +getBdaddr KEYWORD2 setMoveBdaddr KEYWORD2 +getMoveBdaddr KEYWORD2 +getMoveCalibration KEYWORD2 getButtonPress KEYWORD2 getButtonClick KEYWORD2 From b50919b077f6b9e8b3a6e54cd2b83af87c27c0fd Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Tue, 12 Nov 2013 19:45:06 +0100 Subject: [PATCH 11/53] Format PS3 examples --- examples/Bluetooth/PS3BT/PS3BT.ino | 178 +++++++++++++-------------- examples/PS3USB/PS3USB.ino | 188 +++++++++++++---------------- 2 files changed, 173 insertions(+), 193 deletions(-) diff --git a/examples/Bluetooth/PS3BT/PS3BT.ino b/examples/Bluetooth/PS3BT/PS3BT.ino index 3cb83213..253f17b9 100644 --- a/examples/Bluetooth/PS3BT/PS3BT.ino +++ b/examples/Bluetooth/PS3BT/PS3BT.ino @@ -1,6 +1,6 @@ /* Example sketch for the PS3 Bluetooth library - developed by Kristian Lauszus - For more information visit my blog: http://blog.tkjelectronics.dk/ or + For more information visit my blog: http://blog.tkjelectronics.dk/ or send me an e-mail: kristianl@tkjelectronics.com */ @@ -22,152 +22,152 @@ void setup() { while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection if (Usb.Init() == -1) { Serial.print(F("\r\nOSC did not start")); - while(1); //halt + 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) { - Serial.print(F("\r\nLeftHatX: ")); + 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) { + Serial.print(F("\r\nLeftHatX: ")); Serial.print(PS3.getAnalogHat(LeftHatX)); - Serial.print(F("\tLeftHatY: ")); + Serial.print(F("\tLeftHatY: ")); Serial.print(PS3.getAnalogHat(LeftHatY)); - if(!PS3.PS3NavigationConnected) { - Serial.print(F("\tRightHatX: ")); + if (!PS3.PS3NavigationConnected) { + Serial.print(F("\tRightHatX: ")); Serial.print(PS3.getAnalogHat(RightHatX)); - Serial.print(F("\tRightHatY: ")); + Serial.print(F("\tRightHatY: ")); Serial.print(PS3.getAnalogHat(RightHatY)); - } + } } - //Analog button values can be read from almost all buttons - if(PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2)) { - Serial.print(F("\r\nL2: ")); + // Analog button values can be read from almost all buttons + if (PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2)) { + Serial.print(F("\r\nL2: ")); Serial.print(PS3.getAnalogButton(L2)); - if(!PS3.PS3NavigationConnected) { - Serial.print(F("\tR2: ")); + if (!PS3.PS3NavigationConnected) { + Serial.print(F("\tR2: ")); Serial.print(PS3.getAnalogButton(R2)); } } - if(PS3.getButtonClick(PS)) { + if (PS3.getButtonClick(PS)) { Serial.print(F("\r\nPS")); PS3.disconnect(); - } + } else { - if(PS3.getButtonClick(TRIANGLE)) + if (PS3.getButtonClick(TRIANGLE)) Serial.print(F("\r\nTraingle")); - if(PS3.getButtonClick(CIRCLE)) + if (PS3.getButtonClick(CIRCLE)) Serial.print(F("\r\nCircle")); - if(PS3.getButtonClick(CROSS)) + if (PS3.getButtonClick(CROSS)) Serial.print(F("\r\nCross")); - if(PS3.getButtonClick(SQUARE)) + if (PS3.getButtonClick(SQUARE)) Serial.print(F("\r\nSquare")); - if(PS3.getButtonClick(UP)) { - Serial.print(F("\r\nUp")); - if(PS3.PS3Connected) { + if (PS3.getButtonClick(UP)) { + Serial.print(F("\r\nUp")); + if (PS3.PS3Connected) { PS3.setAllOff(); PS3.setLedOn(LED4); } - } - if(PS3.getButtonClick(RIGHT)) { + } + if (PS3.getButtonClick(RIGHT)) { Serial.print(F("\r\nRight")); - if(PS3.PS3Connected) { + if (PS3.PS3Connected) { PS3.setAllOff(); - PS3.setLedOn(LED1); - } - } - if(PS3.getButtonClick(DOWN)) { - Serial.print(F("\r\nDown")); - if(PS3.PS3Connected) { - PS3.setAllOff(); - PS3.setLedOn(LED2); + PS3.setLedOn(LED1); } - } - if(PS3.getButtonClick(LEFT)) { - Serial.print(F("\r\nLeft")); - if(PS3.PS3Connected) { - PS3.setAllOff(); - PS3.setLedOn(LED3); - } - } + } + if (PS3.getButtonClick(DOWN)) { + Serial.print(F("\r\nDown")); + if (PS3.PS3Connected) { + PS3.setAllOff(); + PS3.setLedOn(LED2); + } + } + if (PS3.getButtonClick(LEFT)) { + Serial.print(F("\r\nLeft")); + if (PS3.PS3Connected) { + PS3.setAllOff(); + PS3.setLedOn(LED3); + } + } - if(PS3.getButtonClick(L1)) - Serial.print(F("\r\nL1")); - if(PS3.getButtonClick(L3)) - Serial.print(F("\r\nL3")); - if(PS3.getButtonClick(R1)) - Serial.print(F("\r\nR1")); - if(PS3.getButtonClick(R3)) + if (PS3.getButtonClick(L1)) + Serial.print(F("\r\nL1")); + if (PS3.getButtonClick(L3)) + Serial.print(F("\r\nL3")); + if (PS3.getButtonClick(R1)) + Serial.print(F("\r\nR1")); + if (PS3.getButtonClick(R3)) Serial.print(F("\r\nR3")); - if(PS3.getButtonClick(SELECT)) { - Serial.print(F("\r\nSelect - ")); - Serial.print(PS3.getStatusString()); - } - if(PS3.getButtonClick(START)) { - Serial.print(F("\r\nStart")); + if (PS3.getButtonClick(SELECT)) { + Serial.print(F("\r\nSelect - ")); + Serial.print(PS3.getStatusString()); + } + if (PS3.getButtonClick(START)) { + Serial.print(F("\r\nStart")); printAngle = !printAngle; - } + } } - if(printAngle) { - Serial.print(F("\r\nPitch: ")); - Serial.print(PS3.getAngle(Pitch)); - Serial.print(F("\tRoll: ")); + if (printAngle) { + Serial.print(F("\r\nPitch: ")); + Serial.print(PS3.getAngle(Pitch)); + Serial.print(F("\tRoll: ")); Serial.print(PS3.getAngle(Roll)); } } - else if(PS3.PS3MoveConnected) { - if(PS3.getAnalogButton(T)) { - Serial.print(F("\r\nT: ")); - Serial.print(PS3.getAnalogButton(T)); - } - if(PS3.getButtonClick(PS)) { + else if (PS3.PS3MoveConnected) { + if (PS3.getAnalogButton(T)) { + Serial.print(F("\r\nT: ")); + Serial.print(PS3.getAnalogButton(T)); + } + if (PS3.getButtonClick(PS)) { Serial.print(F("\r\nPS")); PS3.disconnect(); - } + } else { - if(PS3.getButtonClick(SELECT)) { + if (PS3.getButtonClick(SELECT)) { Serial.print(F("\r\nSelect")); printTemperature = !printTemperature; - } - if(PS3.getButtonClick(START)) { + } + if (PS3.getButtonClick(START)) { Serial.print(F("\r\nStart")); - printAngle = !printAngle; - } - if(PS3.getButtonClick(TRIANGLE)) { + printAngle = !printAngle; + } + if (PS3.getButtonClick(TRIANGLE)) { Serial.print(F("\r\nTriangle")); PS3.moveSetBulb(Red); - } - if(PS3.getButtonClick(CIRCLE)) { + } + if (PS3.getButtonClick(CIRCLE)) { Serial.print(F("\r\nCircle")); PS3.moveSetBulb(Green); - } - if(PS3.getButtonClick(SQUARE)) { + } + if (PS3.getButtonClick(SQUARE)) { Serial.print(F("\r\nSquare")); PS3.moveSetBulb(Blue); - } - if(PS3.getButtonClick(CROSS)) { + } + if (PS3.getButtonClick(CROSS)) { Serial.print(F("\r\nCross")); PS3.moveSetBulb(Yellow); - } - if(PS3.getButtonClick(MOVE)) { - PS3.moveSetBulb(Off); + } + if (PS3.getButtonClick(MOVE)) { + PS3.moveSetBulb(Off); Serial.print(F("\r\nMove")); - Serial.print(F(" - ")); + Serial.print(F(" - ")); Serial.print(PS3.getStatusString()); } } - if(printAngle) { - Serial.print(F("\r\nPitch: ")); - Serial.print(PS3.getAngle(Pitch)); - Serial.print(F("\tRoll: ")); + if (printAngle) { + Serial.print(F("\r\nPitch: ")); + Serial.print(PS3.getAngle(Pitch)); + Serial.print(F("\tRoll: ")); Serial.print(PS3.getAngle(Roll)); } - else if(printTemperature) { + else if (printTemperature) { Serial.print(F("\r\nTemperature: ")); Serial.print(PS3.getTemperature()); } diff --git a/examples/PS3USB/PS3USB.ino b/examples/PS3USB/PS3USB.ino index 2a627a93..6e6943a9 100644 --- a/examples/PS3USB/PS3USB.ino +++ b/examples/PS3USB/PS3USB.ino @@ -1,6 +1,6 @@ /* Example sketch for the PS3 USB library - developed by Kristian Lauszus - For more information visit my blog: http://blog.tkjelectronics.dk/ or + For more information visit my blog: http://blog.tkjelectronics.dk/ or send me an e-mail: kristianl@tkjelectronics.com */ @@ -19,142 +19,122 @@ void setup() { while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection if (Usb.Init() == -1) { Serial.print(F("\r\nOSC did not start")); - while(1); //halt - } + 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) { - Serial.print(F("\r\nLeftHatX: ")); + 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) { + Serial.print(F("\r\nLeftHatX: ")); Serial.print(PS3.getAnalogHat(LeftHatX)); - Serial.print(F("\tLeftHatY: ")); + Serial.print(F("\tLeftHatY: ")); Serial.print(PS3.getAnalogHat(LeftHatY)); - if(!PS3.PS3NavigationConnected) { - Serial.print(F("\tRightHatX: ")); + if (!PS3.PS3NavigationConnected) { + Serial.print(F("\tRightHatX: ")); Serial.print(PS3.getAnalogHat(RightHatX)); - Serial.print(F("\tRightHatY: ")); + Serial.print(F("\tRightHatY: ")); Serial.print(PS3.getAnalogHat(RightHatY)); - } + } } // Analog button values can be read from almost all buttons - if(PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2)) { - Serial.print(F("\r\nL2: ")); + if (PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2)) { + Serial.print(F("\r\nL2: ")); Serial.print(PS3.getAnalogButton(L2)); - if(!PS3.PS3NavigationConnected) { - Serial.print(F("\tR2: ")); + if (!PS3.PS3NavigationConnected) { + Serial.print(F("\tR2: ")); Serial.print(PS3.getAnalogButton(R2)); - } + } } - if(PS3.getButtonClick(PS)) + if (PS3.getButtonClick(PS)) Serial.print(F("\r\nPS")); - if(PS3.getButtonClick(TRIANGLE)) + if (PS3.getButtonClick(TRIANGLE)) Serial.print(F("\r\nTraingle")); - if(PS3.getButtonClick(CIRCLE)) + if (PS3.getButtonClick(CIRCLE)) Serial.print(F("\r\nCircle")); - if(PS3.getButtonClick(CROSS)) + if (PS3.getButtonClick(CROSS)) Serial.print(F("\r\nCross")); - if(PS3.getButtonClick(SQUARE)) + if (PS3.getButtonClick(SQUARE)) Serial.print(F("\r\nSquare")); - if(PS3.getButtonClick(UP)) { + if (PS3.getButtonClick(UP)) { Serial.print(F("\r\nUp")); PS3.setAllOff(); PS3.setLedOn(LED4); - } - if(PS3.getButtonClick(RIGHT)) { + } + if (PS3.getButtonClick(RIGHT)) { Serial.print(F("\r\nRight")); PS3.setAllOff(); - PS3.setLedOn(LED1); - } - if(PS3.getButtonClick(DOWN)) { + PS3.setLedOn(LED1); + } + if (PS3.getButtonClick(DOWN)) { Serial.print(F("\r\nDown")); PS3.setAllOff(); - PS3.setLedOn(LED2); - } - if(PS3.getButtonClick(LEFT)) { + PS3.setLedOn(LED2); + } + if (PS3.getButtonClick(LEFT)) { Serial.print(F("\r\nLeft")); - PS3.setAllOff(); - PS3.setLedOn(LED3); - } + PS3.setAllOff(); + PS3.setLedOn(LED3); + } - if(PS3.getButtonClick(L1)) - Serial.print(F("\r\nL1")); - if(PS3.getButtonClick(L3)) - Serial.print(F("\r\nL3")); - if(PS3.getButtonClick(R1)) - Serial.print(F("\r\nR1")); - if(PS3.getButtonClick(R3)) + if (PS3.getButtonClick(L1)) + Serial.print(F("\r\nL1")); + if (PS3.getButtonClick(L3)) + Serial.print(F("\r\nL3")); + if (PS3.getButtonClick(R1)) + Serial.print(F("\r\nR1")); + if (PS3.getButtonClick(R3)) Serial.print(F("\r\nR3")); - if(PS3.getButtonClick(SELECT)) { - Serial.print(F("\r\nSelect - ")); - Serial.print(PS3.getStatusString()); - } - if(PS3.getButtonClick(START)) { - Serial.print(F("\r\nStart")); - printAngle = !printAngle; - } - } - if(printAngle) { - Serial.print(F("\r\nPitch: ")); - Serial.print(PS3.getAngle(Pitch)); - Serial.print(F("\tRoll: ")); - Serial.print(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; + if (PS3.getButtonClick(SELECT)) { + Serial.print(F("\r\nSelect - ")); + Serial.print(PS3.getStatusString()); } + if (PS3.getButtonClick(START)) { + Serial.print(F("\r\nStart")); + printAngle = !printAngle; + } + if (printAngle) { + Serial.print(F("\r\nPitch: ")); + Serial.print(PS3.getAngle(Pitch)); + Serial.print(F("\tRoll: ")); + Serial.print(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 + if (state == 0) { + PS3.moveSetRumble(0); + PS3.moveSetBulb(Off); + } else if (state == 1) { + PS3.moveSetRumble(75); + PS3.moveSetBulb(Red); + } else if (state == 2) { + PS3.moveSetRumble(125); + PS3.moveSetBulb(Green); + } else if (state == 3) { + PS3.moveSetRumble(150); + PS3.moveSetBulb(Blue); + } else if (state == 4) { + PS3.moveSetRumble(175); + PS3.moveSetBulb(Yellow); + } else if (state == 5) { + PS3.moveSetRumble(200); + PS3.moveSetBulb(Lightblue); + } else if (state == 6) { + PS3.moveSetRumble(225); + PS3.moveSetBulb(Purble); + } else if (state == 7) { + PS3.moveSetRumble(250); + PS3.moveSetBulb(White); + } + + state++; + if (state > 7) + state = 0; delay(1000); } } From 87cb83276bf8e365f84b0a71e9dee656a93d94fc Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Fri, 15 Nov 2013 19:05:25 +0100 Subject: [PATCH 12/53] Updated formatting --- examples/Bluetooth/PS3Multi/PS3Multi.ino | 64 +++++----- examples/Bluetooth/PS3SPP/PS3SPP.ino | 110 +++++++++--------- examples/Bluetooth/SPP/SPP.ino | 18 +-- examples/Bluetooth/SPPMulti/SPPMulti.ino | 46 ++++---- examples/Bluetooth/Wii/Wii.ino | 54 ++++----- .../Bluetooth/WiiIRCamera/WiiIRCamera.ino | 68 +++++------ examples/Bluetooth/WiiMulti/WiiMulti.ino | 62 +++++----- .../WiiUProController/WiiUProController.ino | 54 ++++----- examples/Xbox/XBOXOLD/XBOXOLD.ino | 72 ++++++------ examples/Xbox/XBOXUSB/XBOXUSB.ino | 78 ++++++------- 10 files changed, 313 insertions(+), 313 deletions(-) diff --git a/examples/Bluetooth/PS3Multi/PS3Multi.ino b/examples/Bluetooth/PS3Multi/PS3Multi.ino index d3f172b6..56f8da94 100644 --- a/examples/Bluetooth/PS3Multi/PS3Multi.ino +++ b/examples/Bluetooth/PS3Multi/PS3Multi.ino @@ -1,7 +1,7 @@ /* Example sketch for the PS3 Bluetooth library - developed by Kristian Lauszus This example show how one can use multiple controllers with the library - For more information visit my blog: http://blog.tkjelectronics.dk/ or + For more information visit my blog: http://blog.tkjelectronics.dk/ or send me an e-mail: kristianl@tkjelectronics.com */ @@ -12,12 +12,12 @@ USB Usb; USBHub Hub1(&Usb); // Some dongles have a hub inside 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! -const uint8_t length = sizeof(PS3)/sizeof(PS3[0]); // Get the lenght of the array +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 } @@ -26,21 +26,21 @@ void setup() { while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection if (Usb.Init() == -1) { Serial.print(F("\r\nOSC did not start")); - while(1); //halt + while (1); //halt } Serial.print(F("\r\nPS3 Bluetooth Library Started")); } void loop() { Usb.Task(); - for(uint8_t i=0;iPS3Connected || PS3[i]->PS3NavigationConnected) { - 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) { + for (uint8_t i = 0; i < length; i++) { + if (PS3[i]->PS3Connected || PS3[i]->PS3NavigationConnected) { + 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(PS3[i]->getAnalogHat(LeftHatY)); - if(!PS3[i]->PS3NavigationConnected) { // The Navigation controller only have one joystick + if (!PS3[i]->PS3NavigationConnected) { // The Navigation controller only have one joystick Serial.print(F("\tRightHatX: ")); Serial.print(PS3[i]->getAnalogHat(RightHatX)); Serial.print(F("\tRightHatY: ")); @@ -48,77 +48,77 @@ void loop() { } } //Analog button values can be read from almost all buttons - if(PS3[i]->getAnalogButton(L2) || PS3[i]->getAnalogButton(R2)) { + if (PS3[i]->getAnalogButton(L2) || PS3[i]->getAnalogButton(R2)) { Serial.print(F("\r\nL2: ")); Serial.print(PS3[i]->getAnalogButton(L2)); - if(!PS3[i]->PS3NavigationConnected) { + if (!PS3[i]->PS3NavigationConnected) { Serial.print(F("\tR2: ")); Serial.print(PS3[i]->getAnalogButton(R2)); } } - if(PS3[i]->getButtonClick(PS)) { + if (PS3[i]->getButtonClick(PS)) { Serial.print(F("\r\nPS")); PS3[i]->disconnect(); oldControllerState[i] = false; // Reset value } else { - if(PS3[i]->getButtonClick(TRIANGLE)) + if (PS3[i]->getButtonClick(TRIANGLE)) Serial.print(F("\r\nTraingle")); - if(PS3[i]->getButtonClick(CIRCLE)) + if (PS3[i]->getButtonClick(CIRCLE)) Serial.print(F("\r\nCircle")); - if(PS3[i]->getButtonClick(CROSS)) + if (PS3[i]->getButtonClick(CROSS)) Serial.print(F("\r\nCross")); - if(PS3[i]->getButtonClick(SQUARE)) + if (PS3[i]->getButtonClick(SQUARE)) Serial.print(F("\r\nSquare")); - if(PS3[i]->getButtonClick(UP)) { + if (PS3[i]->getButtonClick(UP)) { Serial.print(F("\r\nUp")); - if(PS3[i]->PS3Connected) { + if (PS3[i]->PS3Connected) { PS3[i]->setAllOff(); PS3[i]->setLedOn(LED4); } } - if(PS3[i]->getButtonClick(RIGHT)) { + if (PS3[i]->getButtonClick(RIGHT)) { Serial.print(F("\r\nRight")); - if(PS3[i]->PS3Connected) { + if (PS3[i]->PS3Connected) { PS3[i]->setAllOff(); PS3[i]->setLedOn(LED1); } } - if(PS3[i]->getButtonClick(DOWN)) { + if (PS3[i]->getButtonClick(DOWN)) { Serial.print(F("\r\nDown")); - if(PS3[i]->PS3Connected) { + if (PS3[i]->PS3Connected) { PS3[i]->setAllOff(); PS3[i]->setLedOn(LED2); } } - if(PS3[i]->getButtonClick(LEFT)) { + if (PS3[i]->getButtonClick(LEFT)) { Serial.print(F("\r\nLeft")); - if(PS3[i]->PS3Connected) { + if (PS3[i]->PS3Connected) { PS3[i]->setAllOff(); PS3[i]->setLedOn(LED3); } } - if(PS3[i]->getButtonClick(L1)) + if (PS3[i]->getButtonClick(L1)) Serial.print(F("\r\nL1")); - if(PS3[i]->getButtonClick(L3)) + if (PS3[i]->getButtonClick(L3)) Serial.print(F("\r\nL3")); - if(PS3[i]->getButtonClick(R1)) + if (PS3[i]->getButtonClick(R1)) Serial.print(F("\r\nR1")); - if(PS3[i]->getButtonClick(R3)) + if (PS3[i]->getButtonClick(R3)) Serial.print(F("\r\nR3")); - if(PS3[i]->getButtonClick(SELECT)) { + if (PS3[i]->getButtonClick(SELECT)) { Serial.print(F("\r\nSelect - ")); Serial.print(PS3[i]->getStatusString()); } - if(PS3[i]->getButtonClick(START)) { + if (PS3[i]->getButtonClick(START)) { Serial.print(F("\r\nStart")); printAngle[i] = !printAngle[i]; } } - if(printAngle[i]) { + if (printAngle[i]) { Serial.print(F("\r\nPitch: ")); Serial.print(PS3[i]->getAngle(Pitch)); Serial.print(F("\tRoll: ")); @@ -126,12 +126,12 @@ void loop() { } } /* I have removed the PS3 Move code as an Uno will run out of RAM if it's included */ - //else if(PS3[i]->PS3MoveConnected) { + //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/PS3SPP/PS3SPP.ino b/examples/Bluetooth/PS3SPP/PS3SPP.ino index 8f8e751d..734de065 100644 --- a/examples/Bluetooth/PS3SPP/PS3SPP.ino +++ b/examples/Bluetooth/PS3SPP/PS3SPP.ino @@ -1,6 +1,6 @@ /* Example sketch for the Bluetooth library - developed by Kristian Lauszus - For more information visit my blog: http://blog.tkjelectronics.dk/ or + For more information visit my blog: http://blog.tkjelectronics.dk/ or send me an e-mail: kristianl@tkjelectronics.com This example show how one can combine all the difference Bluetooth services in one single code. @@ -31,7 +31,7 @@ void setup() { while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection if (Usb.Init() == -1) { Serial.print(F("\r\nOSC did not start")); - while(1); //halt + while (1); //halt } Serial.print(F("\r\nBluetooth Library Started")); output.reserve(200); // Reserve 200 bytes for the output string @@ -39,27 +39,27 @@ void setup() { void loop() { Usb.Task(); // The SPP data is actually not send until this is called, one could call SerialBT.send() directly as well - if(SerialBT.connected) { - if(firstMessage) { + if (SerialBT.connected) { + if (firstMessage) { firstMessage = false; SerialBT.println(F("Hello from Arduino")); // Send welcome message } - if(Serial.available()) + if (Serial.available()) SerialBT.write(Serial.read()); - if(SerialBT.available()) + if (SerialBT.available()) Serial.write(SerialBT.read()); - } - else + } + else firstMessage = true; - if(PS3.PS3Connected || PS3.PS3NavigationConnected) { + if (PS3.PS3Connected || PS3.PS3NavigationConnected) { output = ""; // Reset output string - 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 || PS3.getAnalogHat(LeftHatY) > 137 || PS3.getAnalogHat(LeftHatY) < 117 || PS3.getAnalogHat(RightHatX) > 137 || PS3.getAnalogHat(RightHatX) < 117 || PS3.getAnalogHat(RightHatY) > 137 || PS3.getAnalogHat(RightHatY) < 117) { output += "LeftHatX: "; output += PS3.getAnalogHat(LeftHatX); output += "\tLeftHatY: "; output += PS3.getAnalogHat(LeftHatY); - if(!PS3.PS3NavigationConnected) { + if (!PS3.PS3NavigationConnected) { output += "\tRightHatX: "; output += PS3.getAnalogHat(RightHatX); output += "\tRightHatY: "; @@ -67,85 +67,85 @@ void loop() { } } //Analog button values can be read from almost all buttons - if(PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2)) { - if(output != "") + if (PS3.getAnalogButton(L2) || PS3.getAnalogButton(R2)) { + if (output != "") output += "\r\n"; output += "L2: "; output += PS3.getAnalogButton(L2); - if(!PS3.PS3NavigationConnected) { + if (!PS3.PS3NavigationConnected) { output += "\tR2: "; output += PS3.getAnalogButton(R2); - } + } } - if(output != "") { + if (output != "") { Serial.println(output); - if(SerialBT.connected) + if (SerialBT.connected) SerialBT.println(output); output = ""; // Reset output string } - if(PS3.getButtonClick(PS)) { + if (PS3.getButtonClick(PS)) { output += " - PS"; PS3.disconnect(); - } + } else { - if(PS3.getButtonClick(TRIANGLE)) + if (PS3.getButtonClick(TRIANGLE)) output += " - Traingle"; - if(PS3.getButtonClick(CIRCLE)) + if (PS3.getButtonClick(CIRCLE)) output += " - Circle"; - if(PS3.getButtonClick(CROSS)) + if (PS3.getButtonClick(CROSS)) output += " - Cross"; - if(PS3.getButtonClick(SQUARE)) + if (PS3.getButtonClick(SQUARE)) output += " - Square"; - if(PS3.getButtonClick(UP)) { + if (PS3.getButtonClick(UP)) { output += " - Up"; - if(PS3.PS3Connected) { + if (PS3.PS3Connected) { PS3.setAllOff(); PS3.setLedOn(LED4); } - } - if(PS3.getButtonClick(RIGHT)) { + } + if (PS3.getButtonClick(RIGHT)) { output += " - Right"; - if(PS3.PS3Connected) { + if (PS3.PS3Connected) { PS3.setAllOff(); - PS3.setLedOn(LED1); - } - } - if(PS3.getButtonClick(DOWN)) { - output += " - Down"; - if(PS3.PS3Connected) { - PS3.setAllOff(); - PS3.setLedOn(LED2); + PS3.setLedOn(LED1); } - } - if(PS3.getButtonClick(LEFT)) { - output += " - Left"; - if(PS3.PS3Connected) { + } + if (PS3.getButtonClick(DOWN)) { + output += " - Down"; + if (PS3.PS3Connected) { + PS3.setAllOff(); + PS3.setLedOn(LED2); + } + } + if (PS3.getButtonClick(LEFT)) { + output += " - Left"; + if (PS3.PS3Connected) { PS3.setAllOff(); - PS3.setLedOn(LED3); - } - } + PS3.setLedOn(LED3); + } + } - if(PS3.getButtonClick(L1)) + if (PS3.getButtonClick(L1)) output += " - L1"; - if(PS3.getButtonClick(L3)) - output += " - L3"; - if(PS3.getButtonClick(R1)) - output += " - R1"; - if(PS3.getButtonClick(R3)) - output += " - R3"; + if (PS3.getButtonClick(L3)) + output += " - L3"; + if (PS3.getButtonClick(R1)) + output += " - R1"; + if (PS3.getButtonClick(R3)) + output += " - R3"; - if(PS3.getButtonClick(SELECT)) { + if (PS3.getButtonClick(SELECT)) { output += " - Select - "; output += PS3.getStatusString(); } - if(PS3.getButtonClick(START)) - output += " - Start"; + if (PS3.getButtonClick(START)) + output += " - Start"; - if(output != "") { + if (output != "") { String string = "PS3 Controller" + output; Serial.println(string); - if(SerialBT.connected) + if (SerialBT.connected) SerialBT.println(string); } } diff --git a/examples/Bluetooth/SPP/SPP.ino b/examples/Bluetooth/SPP/SPP.ino index eb91459c..8ac79a45 100644 --- a/examples/Bluetooth/SPP/SPP.ino +++ b/examples/Bluetooth/SPP/SPP.ino @@ -1,6 +1,6 @@ /* Example sketch for the RFCOMM/SPP Bluetooth library - developed by Kristian Lauszus - For more information visit my blog: http://blog.tkjelectronics.dk/ or + For more information visit my blog: http://blog.tkjelectronics.dk/ or send me an e-mail: kristianl@tkjelectronics.com */ @@ -21,23 +21,23 @@ void setup() { while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection if (Usb.Init() == -1) { Serial.print(F("\r\nOSC did not start")); - while(1); //halt + while (1); //halt } Serial.print(F("\r\nSPP Bluetooth Library Started")); } void loop() { Usb.Task(); // The SPP data is actually not send until this is called, one could call SerialBT.send() directly as well - - if(SerialBT.connected) { - if(firstMessage) { + + if (SerialBT.connected) { + if (firstMessage) { firstMessage = false; SerialBT.println(F("Hello from Arduino")); // Send welcome message } - if(Serial.available()) + if (Serial.available()) SerialBT.write(Serial.read()); - if(SerialBT.available()) + if (SerialBT.available()) Serial.write(SerialBT.read()); - } - else + } + else firstMessage = true; } diff --git a/examples/Bluetooth/SPPMulti/SPPMulti.ino b/examples/Bluetooth/SPPMulti/SPPMulti.ino index 483bdfbd..c846b1a1 100644 --- a/examples/Bluetooth/SPPMulti/SPPMulti.ino +++ b/examples/Bluetooth/SPPMulti/SPPMulti.ino @@ -1,6 +1,6 @@ /* Example sketch for the RFCOMM/SPP Bluetooth library - developed by Kristian Lauszus - For more information visit my blog: http://blog.tkjelectronics.dk/ or + For more information visit my blog: http://blog.tkjelectronics.dk/ or send me an e-mail: kristianl@tkjelectronics.com */ @@ -10,54 +10,54 @@ USB Usb; USBHub Hub1(&Usb); // Some dongles have a hub inside BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so -SPP* SerialBT[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(SerialBT)/sizeof(SerialBT[0]); // Get the lenght of the array +SPP *SerialBT[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(SerialBT) / sizeof(SerialBT[0]); // Get the lenght of the array boolean firstMessage[length] = { true }; // Set all to true uint8_t buffer[50]; void setup() { - for(uint8_t i=0;iconnected) { - if(firstMessage[i]) { + + for (uint8_t i = 0; i < length; i++) { + if (SerialBT[i]->connected) { + if (firstMessage[i]) { firstMessage[i] = false; SerialBT[i]->println(F("Hello from Arduino")); // Send welcome message } - if(SerialBT[i]->available()) + if (SerialBT[i]->available()) Serial.write(SerialBT[i]->read()); - } + } else firstMessage[i] = true; } - if(Serial.available()) { + if (Serial.available()) { delay(10); // Wait for the rest of the data to arrive uint8_t i = 0; - while(Serial.available() && i < sizeof(buffer)) // Read the data + while (Serial.available() && i < sizeof(buffer)) // Read the data buffer[i++] = Serial.read(); - /* + /* Set the connection you want to send to using the first character - For instace "0Hello World" would send "Hello World" to connection 0 + For instace "0Hello World" would send "Hello World" to connection 0 */ - uint8_t id = buffer[0]-'0'; // Convert from ASCII - if(id < length && i > 1) { // And then compare to length and make sure there is any text - if(SerialBT[id]->connected) { // Check if a device is actually connected - for(uint8_t i2 = 0; i2 < i-1; i2++) // Don't include the first character - buffer[i2] = buffer[i2+1]; - SerialBT[id]->write(buffer,i-1); // Send the data + uint8_t id = buffer[0] - '0'; // Convert from ASCII + if (id < length && i > 1) { // And then compare to length and make sure there is any text + if (SerialBT[id]->connected) { // Check if a device is actually connected + for (uint8_t i2 = 0; i2 < i - 1; i2++) // Don't include the first character + buffer[i2] = buffer[i2 + 1]; + SerialBT[id]->write(buffer, i - 1); // Send the data } } - } + } } diff --git a/examples/Bluetooth/Wii/Wii.ino b/examples/Bluetooth/Wii/Wii.ino index 815c16fe..e377ad24 100644 --- a/examples/Bluetooth/Wii/Wii.ino +++ b/examples/Bluetooth/Wii/Wii.ino @@ -1,6 +1,6 @@ /* Example sketch for the Wiimote Bluetooth library - developed by Kristian Lauszus - For more information visit my blog: http://blog.tkjelectronics.dk/ or + For more information visit my blog: http://blog.tkjelectronics.dk/ or send me an e-mail: kristianl@tkjelectronics.com */ @@ -11,7 +11,7 @@ USB Usb; USBHub Hub1(&Usb); // Some dongles have a hub inside BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so /* You can create the instance of the class in two ways */ -WII Wii(&Btd,PAIR); // This will start an inquiry and then pair with your Wiimote - you only have to do this once +WII Wii(&Btd, PAIR); // This will start an inquiry and then pair with your Wiimote - you only have to do this once //WII Wii(&Btd); // After that you can simply create the instance like so and then press any button on the Wiimote bool printAngle; @@ -21,68 +21,68 @@ void setup() { while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection if (Usb.Init() == -1) { Serial.print(F("\r\nOSC did not start")); - while(1); //halt + while (1); //halt } Serial.print(F("\r\nWiimote Bluetooth Library Started")); } void loop() { Usb.Task(); - if(Wii.wiimoteConnected) { - if(Wii.getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down + if (Wii.wiimoteConnected) { + if (Wii.getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down Serial.print(F("\r\nHOME")); Wii.disconnect(); - } + } else { - if(Wii.getButtonClick(LEFT)) { + if (Wii.getButtonClick(LEFT)) { Wii.setAllOff(); Wii.setLedOn(LED1); Serial.print(F("\r\nLeft")); } - if(Wii.getButtonClick(RIGHT)) { + if (Wii.getButtonClick(RIGHT)) { Wii.setAllOff(); Wii.setLedOn(LED3); Serial.print(F("\r\nRight")); } - if(Wii.getButtonClick(DOWN)) { + if (Wii.getButtonClick(DOWN)) { Wii.setAllOff(); Wii.setLedOn(LED4); Serial.print(F("\r\nDown")); - } - if(Wii.getButtonClick(UP)) { + } + if (Wii.getButtonClick(UP)) { Wii.setAllOff(); - Wii.setLedOn(LED2); + Wii.setLedOn(LED2); Serial.print(F("\r\nUp")); } - if(Wii.getButtonClick(PLUS)) + if (Wii.getButtonClick(PLUS)) Serial.print(F("\r\nPlus")); - if(Wii.getButtonClick(MINUS)) + if (Wii.getButtonClick(MINUS)) Serial.print(F("\r\nMinus")); - if(Wii.getButtonClick(ONE)) + if (Wii.getButtonClick(ONE)) Serial.print(F("\r\nOne")); - if(Wii.getButtonClick(TWO)) + if (Wii.getButtonClick(TWO)) Serial.print(F("\r\nTwo")); - if(Wii.getButtonClick(A)) { + if (Wii.getButtonClick(A)) { printAngle = !printAngle; Serial.print(F("\r\nA")); - } - if(Wii.getButtonClick(B)) { + } + if (Wii.getButtonClick(B)) { Wii.setRumbleToggle(); Serial.print(F("\r\nB")); } } - if(printAngle) { + if (printAngle) { Serial.print(F("\r\nPitch: ")); Serial.print(Wii.getPitch()); Serial.print(F("\tRoll: ")); Serial.print(Wii.getRoll()); - if(Wii.motionPlusConnected) { + if (Wii.motionPlusConnected) { Serial.print(F("\tYaw: ")); Serial.print(Wii.getYaw()); - } - if(Wii.nunchuckConnected) { + } + if (Wii.nunchuckConnected) { Serial.print(F("\tNunchuck Pitch: ")); Serial.print(Wii.getNunchuckPitch()); Serial.print(F("\tNunchuck Roll: ")); @@ -90,12 +90,12 @@ void loop() { } } } - if(Wii.nunchuckConnected) { - if(Wii.getButtonClick(Z)) + if (Wii.nunchuckConnected) { + if (Wii.getButtonClick(Z)) Serial.print(F("\r\nZ")); - if(Wii.getButtonClick(C)) + if (Wii.getButtonClick(C)) Serial.print(F("\r\nC")); - if(Wii.getAnalogHat(HatX) > 137 || Wii.getAnalogHat(HatX) < 117 || Wii.getAnalogHat(HatY) > 137 || Wii.getAnalogHat(HatY) < 117) { + if (Wii.getAnalogHat(HatX) > 137 || Wii.getAnalogHat(HatX) < 117 || Wii.getAnalogHat(HatY) > 137 || Wii.getAnalogHat(HatY) < 117) { Serial.print(F("\r\nHatX: ")); Serial.print(Wii.getAnalogHat(HatX)); Serial.print(F("\tHatY: ")); diff --git a/examples/Bluetooth/WiiIRCamera/WiiIRCamera.ino b/examples/Bluetooth/WiiIRCamera/WiiIRCamera.ino index 08aed4e0..ba701661 100644 --- a/examples/Bluetooth/WiiIRCamera/WiiIRCamera.ino +++ b/examples/Bluetooth/WiiIRCamera/WiiIRCamera.ino @@ -1,12 +1,12 @@ /* Example sketch for the Wii libary showing the IR camera functionality. This example is for the Bluetooth Wii library developed for the USB shield from Circuits@Home - + Created by Allan Glover and Kristian Lauszus. Contact Kristian: http://blog.tkjelectronics.dk/ or send an email at kristianl@tkjelectronics.com. Contact Allan at adglover9.81@gmail.com - -To test the Wiimote IR camera, you will need access to an IR source. Sunlight will work but is not ideal. + +To test the Wiimote IR camera, you will need access to an IR source. Sunlight will work but is not ideal. The simpleist solution is to use the Wii sensor bar, i.e. emitter bar, supplied by the Wii system. Otherwise, wire up a IR LED yourself. */ @@ -22,7 +22,7 @@ USB Usb; USBHub Hub1(&Usb); // Some dongles have a hub inside BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so /* You can create the instance of the class in two ways */ -WII Wii(&Btd,PAIR); // This will start an inquiry and then pair with your Wiimote - you only have to do this once +WII Wii(&Btd, PAIR); // This will start an inquiry and then pair with your Wiimote - you only have to do this once //WII Wii(&Btd); // After the Wiimote pairs once with the line of code above, you can simply create the instance like so and re upload and then press any button on the Wiimote bool printAngle; @@ -33,31 +33,31 @@ void setup() { while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection if (Usb.Init() == -1) { Serial.print(F("\r\nOSC did not start")); - while(1); //halt + while (1); //halt } Serial.print(F("\r\nWiimote Bluetooth Library Started")); } void loop() { Usb.Task(); - if(Wii.wiimoteConnected) { - if(Wii.getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down + if (Wii.wiimoteConnected) { + if (Wii.getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down Serial.print(F("\r\nHOME")); Wii.disconnect(); } else { - if(Wii.getButtonClick(ONE)) + if (Wii.getButtonClick(ONE)) Wii.IRinitialize(); // Run the initialisation sequence - if(Wii.getButtonClick(MINUS) || Wii.getButtonClick(PLUS)) { - if(!Wii.isIRCameraEnabled()) + if (Wii.getButtonClick(MINUS) || Wii.getButtonClick(PLUS)) { + if (!Wii.isIRCameraEnabled()) Serial.print(F("\r\nEnable IR camera first")); else { - if(Wii.getButtonPress(MINUS)) { // getButtonClick will only return true once - if(printObjects > 0) - printObjects--; + if (Wii.getButtonPress(MINUS)) { // getButtonClick will only return true once + if (printObjects > 0) + printObjects--; } else { - if(printObjects < 4) + if (printObjects < 4) printObjects++; } Serial.print(F("\r\nTracking ")); @@ -65,56 +65,56 @@ void loop() { Serial.print(F(" objects")); } } - if(Wii.getButtonClick(A)) { + if (Wii.getButtonClick(A)) { printAngle = !printAngle; Serial.print(F("\r\nA")); } - if(Wii.getButtonClick(B)) { + if (Wii.getButtonClick(B)) { Serial.print(F("\r\nBattery level: ")); Serial.print(Wii.getBatteryLevel()); // You can get the battery level as well } } - if(printObjects > 0) { - if(Wii.getIRx1() != 0x3FF || Wii.getIRy1() != 0x3FF || Wii.getIRs1() != 0) { // Only print if the IR camera is actually seeing something + if (printObjects > 0) { + if (Wii.getIRx1() != 0x3FF || Wii.getIRy1() != 0x3FF || Wii.getIRs1() != 0) { // Only print if the IR camera is actually seeing something Serial.print(F("\r\nx1: ")); - Serial.print(Wii.getIRx1()); + Serial.print(Wii.getIRx1()); Serial.print(F("\ty1: ")); - Serial.print(Wii.getIRy1()); + Serial.print(Wii.getIRy1()); Serial.print(F("\ts1:")); Serial.print(Wii.getIRs1()); } - if(printObjects > 1) { - if(Wii.getIRx2() != 0x3FF || Wii.getIRy2() != 0x3FF || Wii.getIRs2() != 0) { + if (printObjects > 1) { + if (Wii.getIRx2() != 0x3FF || Wii.getIRy2() != 0x3FF || Wii.getIRs2() != 0) { Serial.print(F("\r\nx2: ")); - Serial.print(Wii.getIRx2()); + Serial.print(Wii.getIRx2()); Serial.print(F("\ty2: ")); - Serial.print(Wii.getIRy2()); + Serial.print(Wii.getIRy2()); Serial.print(F("\ts2:")); Serial.print(Wii.getIRs2()); } - if(printObjects > 2) { - if(Wii.getIRx3() != 0x3FF || Wii.getIRy3() != 0x3FF || Wii.getIRs3() != 0) { + if (printObjects > 2) { + if (Wii.getIRx3() != 0x3FF || Wii.getIRy3() != 0x3FF || Wii.getIRs3() != 0) { Serial.print(F("\r\nx3: ")); - Serial.print(Wii.getIRx3()); + Serial.print(Wii.getIRx3()); Serial.print(F("\ty3: ")); - Serial.print(Wii.getIRy3()); + Serial.print(Wii.getIRy3()); Serial.print(F("\ts3:")); Serial.print(Wii.getIRs3()); } - if(printObjects > 3) { - if(Wii.getIRx4() != 0x3FF || Wii.getIRy4() != 0x3FF || Wii.getIRs4() != 0) { + if (printObjects > 3) { + if (Wii.getIRx4() != 0x3FF || Wii.getIRy4() != 0x3FF || Wii.getIRs4() != 0) { Serial.print(F("\r\nx4: ")); - Serial.print(Wii.getIRx4()); + Serial.print(Wii.getIRx4()); Serial.print(F("\ty4: ")); - Serial.print(Wii.getIRy4()); + Serial.print(Wii.getIRy4()); Serial.print(F("\ts4:")); Serial.print(Wii.getIRs4()); } } } } - } - if(printAngle) { // There is no extension bytes available, so the MotionPlus or Nunchuck can't be read + } + if (printAngle) { // There is no extension bytes available, so the MotionPlus or Nunchuck can't be read Serial.print(F("\r\nPitch: ")); Serial.print(Wii.getPitch()); Serial.print(F("\tRoll: ")); diff --git a/examples/Bluetooth/WiiMulti/WiiMulti.ino b/examples/Bluetooth/WiiMulti/WiiMulti.ino index 0eae4d9a..518d9859 100644 --- a/examples/Bluetooth/WiiMulti/WiiMulti.ino +++ b/examples/Bluetooth/WiiMulti/WiiMulti.ino @@ -1,7 +1,7 @@ /* Example sketch for the Wiimote Bluetooth library - developed by Kristian Lauszus This example show how one can use multiple controllers with the library - For more information visit my blog: http://blog.tkjelectronics.dk/ or + For more information visit my blog: http://blog.tkjelectronics.dk/ or send me an e-mail: kristianl@tkjelectronics.com */ @@ -12,85 +12,85 @@ USB Usb; USBHub Hub1(&Usb); // Some dongles have a hub inside 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! -const uint8_t length = sizeof(Wii)/sizeof(Wii[0]); // Get the lenght of the array +const uint8_t length = sizeof(Wii) / sizeof(Wii[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); while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection if (Usb.Init() == -1) { Serial.print(F("\r\nOSC did not start")); - while(1); //halt + while (1); //halt } Serial.print(F("\r\nWiimote Bluetooth Library Started")); } void loop() { Usb.Task(); - for(uint8_t i=0;iwiimoteConnected) { - if(Wii[i]->getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down + for (uint8_t i = 0; i < length; i++) { + if (Wii[i]->wiimoteConnected) { + 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 - } + } else { - if(Wii[i]->getButtonClick(LEFT)) { + if (Wii[i]->getButtonClick(LEFT)) { Wii[i]->setAllOff(); Wii[i]->setLedOn(LED1); Serial.print(F("\r\nLeft")); } - if(Wii[i]->getButtonClick(RIGHT)) { + if (Wii[i]->getButtonClick(RIGHT)) { Wii[i]->setAllOff(); Wii[i]->setLedOn(LED3); Serial.print(F("\r\nRight")); } - if(Wii[i]->getButtonClick(DOWN)) { + if (Wii[i]->getButtonClick(DOWN)) { Wii[i]->setAllOff(); Wii[i]->setLedOn(LED4); Serial.print(F("\r\nDown")); - } - if(Wii[i]->getButtonClick(UP)) { + } + if (Wii[i]->getButtonClick(UP)) { Wii[i]->setAllOff(); - Wii[i]->setLedOn(LED2); + Wii[i]->setLedOn(LED2); Serial.print(F("\r\nUp")); } - if(Wii[i]->getButtonClick(PLUS)) + if (Wii[i]->getButtonClick(PLUS)) Serial.print(F("\r\nPlus")); - if(Wii[i]->getButtonClick(MINUS)) + if (Wii[i]->getButtonClick(MINUS)) Serial.print(F("\r\nMinus")); - if(Wii[i]->getButtonClick(ONE)) + if (Wii[i]->getButtonClick(ONE)) Serial.print(F("\r\nOne")); - if(Wii[i]->getButtonClick(TWO)) + if (Wii[i]->getButtonClick(TWO)) Serial.print(F("\r\nTwo")); - if(Wii[i]->getButtonClick(A)) { + if (Wii[i]->getButtonClick(A)) { printAngle[i] = !printAngle[i]; Serial.print(F("\r\nA")); - } - if(Wii[i]->getButtonClick(B)) { + } + if (Wii[i]->getButtonClick(B)) { Wii[i]->setRumbleToggle(); Serial.print(F("\r\nB")); } } - if(printAngle[i]) { + if (printAngle[i]) { Serial.print(F("\r\nPitch: ")); Serial.print(Wii[i]->getPitch()); Serial.print(F("\tRoll: ")); Serial.print(Wii[i]->getRoll()); - if(Wii[i]->motionPlusConnected) { + if (Wii[i]->motionPlusConnected) { Serial.print(F("\tYaw: ")); Serial.print(Wii[i]->getYaw()); - } - if(Wii[i]->nunchuckConnected) { + } + if (Wii[i]->nunchuckConnected) { Serial.print(F("\tNunchuck Pitch: ")); Serial.print(Wii[i]->getNunchuckPitch()); Serial.print(F("\tNunchuck Roll: ")); @@ -98,12 +98,12 @@ void loop() { } } } - if(Wii[i]->nunchuckConnected) { - if(Wii[i]->getButtonClick(Z)) + if (Wii[i]->nunchuckConnected) { + if (Wii[i]->getButtonClick(Z)) Serial.print(F("\r\nZ")); - if(Wii[i]->getButtonClick(C)) + if (Wii[i]->getButtonClick(C)) Serial.print(F("\r\nC")); - if(Wii[i]->getAnalogHat(HatX) > 137 || Wii[i]->getAnalogHat(HatX) < 117 || Wii[i]->getAnalogHat(HatY) > 137 || Wii[i]->getAnalogHat(HatY) < 117) { + if (Wii[i]->getAnalogHat(HatX) > 137 || Wii[i]->getAnalogHat(HatX) < 117 || Wii[i]->getAnalogHat(HatY) > 137 || Wii[i]->getAnalogHat(HatY) < 117) { Serial.print(F("\r\nHatX: ")); Serial.print(Wii[i]->getAnalogHat(HatX)); Serial.print(F("\tHatY: ")); @@ -114,7 +114,7 @@ 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/examples/Bluetooth/WiiUProController/WiiUProController.ino b/examples/Bluetooth/WiiUProController/WiiUProController.ino index 6ba5618b..608a7688 100644 --- a/examples/Bluetooth/WiiUProController/WiiUProController.ino +++ b/examples/Bluetooth/WiiUProController/WiiUProController.ino @@ -1,6 +1,6 @@ /* Example sketch for the Wiimote Bluetooth library - developed by Kristian Lauszus - For more information visit my blog: http://blog.tkjelectronics.dk/ or + For more information visit my blog: http://blog.tkjelectronics.dk/ or send me an e-mail: kristianl@tkjelectronics.com */ @@ -11,7 +11,7 @@ USB Usb; USBHub Hub1(&Usb); // Some dongles have a hub inside BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so /* You can create the instance of the class in two ways */ -WII Wii(&Btd,PAIR); // This will start an inquiry and then pair with your Wiimote - you only have to do this once +WII Wii(&Btd, PAIR); // This will start an inquiry and then pair with your Wiimote - you only have to do this once //WII Wii(&Btd); // After that you can simply create the instance like so and then press any button on the Wiimote void setup() { @@ -19,69 +19,69 @@ void setup() { while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection if (Usb.Init() == -1) { Serial.print(F("\r\nOSC did not start")); - while(1); //halt + while (1); //halt } Serial.print(F("\r\nWiimote Bluetooth Library Started")); } void loop() { Usb.Task(); - if(Wii.wiiUProControllerConnected) { - if(Wii.getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down + if (Wii.wiiUProControllerConnected) { + if (Wii.getButtonClick(HOME)) { // You can use getButtonPress to see if the button is held down Serial.print(F("\r\nHome")); Wii.disconnect(); - } + } else { - if(Wii.getButtonClick(LEFT)) { + if (Wii.getButtonClick(LEFT)) { Wii.setAllOff(); Wii.setLedOn(LED1); Serial.print(F("\r\nLeft")); } - if(Wii.getButtonClick(RIGHT)) { + if (Wii.getButtonClick(RIGHT)) { Wii.setAllOff(); Wii.setLedOn(LED3); Serial.print(F("\r\nRight")); } - if(Wii.getButtonClick(DOWN)) { + if (Wii.getButtonClick(DOWN)) { Wii.setAllOff(); Wii.setLedOn(LED4); Serial.print(F("\r\nDown")); - } - if(Wii.getButtonClick(UP)) { + } + if (Wii.getButtonClick(UP)) { Wii.setAllOff(); - Wii.setLedOn(LED2); + Wii.setLedOn(LED2); Serial.print(F("\r\nUp")); } - if(Wii.getButtonClick(PLUS)) + if (Wii.getButtonClick(PLUS)) Serial.print(F("\r\nPlus")); - if(Wii.getButtonClick(MINUS)) + if (Wii.getButtonClick(MINUS)) Serial.print(F("\r\nMinus")); - if(Wii.getButtonClick(A)) + if (Wii.getButtonClick(A)) Serial.print(F("\r\nA")); - if(Wii.getButtonClick(B)) { + if (Wii.getButtonClick(B)) { Wii.setRumbleToggle(); Serial.print(F("\r\nB")); } - if(Wii.getButtonClick(X)) + if (Wii.getButtonClick(X)) Serial.print(F("\r\nX")); - if(Wii.getButtonClick(Y)) + if (Wii.getButtonClick(Y)) Serial.print(F("\r\nY")); - - if(Wii.getButtonClick(L)) + + if (Wii.getButtonClick(L)) Serial.print(F("\r\nL")); - if(Wii.getButtonClick(R)) + if (Wii.getButtonClick(R)) Serial.print(F("\r\nR")); - if(Wii.getButtonClick(ZL)) + if (Wii.getButtonClick(ZL)) Serial.print(F("\r\nZL")); - if(Wii.getButtonClick(ZR)) + if (Wii.getButtonClick(ZR)) Serial.print(F("\r\nZR")); - if(Wii.getButtonClick(L3)) + if (Wii.getButtonClick(L3)) Serial.print(F("\r\nL3")); - if(Wii.getButtonClick(R3)) - Serial.print(F("\r\nR3")); + if (Wii.getButtonClick(R3)) + Serial.print(F("\r\nR3")); } - if(Wii.getAnalogHat(LeftHatX) > 2200 || Wii.getAnalogHat(LeftHatX) < 1800 || Wii.getAnalogHat(LeftHatY) > 2200 || Wii.getAnalogHat(LeftHatY) < 1800 || Wii.getAnalogHat(RightHatX) > 2200 || Wii.getAnalogHat(RightHatX) < 1800 || Wii.getAnalogHat(RightHatY) > 2200 || Wii.getAnalogHat(RightHatY) < 1800) { + if (Wii.getAnalogHat(LeftHatX) > 2200 || Wii.getAnalogHat(LeftHatX) < 1800 || Wii.getAnalogHat(LeftHatY) > 2200 || Wii.getAnalogHat(LeftHatY) < 1800 || Wii.getAnalogHat(RightHatX) > 2200 || Wii.getAnalogHat(RightHatX) < 1800 || Wii.getAnalogHat(RightHatY) > 2200 || Wii.getAnalogHat(RightHatY) < 1800) { Serial.print(F("\r\nLeftHatX: ")); Serial.print(Wii.getAnalogHat(LeftHatX)); Serial.print(F("\tLeftHatY: ")); diff --git a/examples/Xbox/XBOXOLD/XBOXOLD.ino b/examples/Xbox/XBOXOLD/XBOXOLD.ino index 22675172..9e2034d6 100644 --- a/examples/Xbox/XBOXOLD/XBOXOLD.ino +++ b/examples/Xbox/XBOXOLD/XBOXOLD.ino @@ -1,6 +1,6 @@ /* Example sketch for the original Xbox library - developed by Kristian Lauszus - For more information visit my blog: http://blog.tkjelectronics.dk/ or + For more information visit my blog: http://blog.tkjelectronics.dk/ or send me an e-mail: kristianl@tkjelectronics.com */ @@ -16,83 +16,83 @@ void setup() { while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection if (Usb.Init() == -1) { Serial.print(F("\r\nOSC did not start")); - while(1); // halt - } + while (1); // halt + } Serial.print(F("\r\nXBOX Library Started")); } void loop() { Usb.Task(); - if(Xbox.XboxConnected) { - if(Xbox.getButtonPress(BLACK) || Xbox.getButtonPress(WHITE)) { + if (Xbox.XboxConnected) { + if (Xbox.getButtonPress(BLACK) || Xbox.getButtonPress(WHITE)) { Serial.print("BLACK: "); Serial.print(Xbox.getButtonPress(BLACK)); Serial.print("\tWHITE: "); Serial.println(Xbox.getButtonPress(WHITE)); - Xbox.setRumbleOn(Xbox.getButtonPress(BLACK),Xbox.getButtonPress(WHITE)); + Xbox.setRumbleOn(Xbox.getButtonPress(BLACK), Xbox.getButtonPress(WHITE)); } else - Xbox.setRumbleOn(0,0); - 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: ")); + Xbox.setRumbleOn(0, 0); + 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: ")); + } + 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: ")); + } + 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.print("\t"); + } + if (Xbox.getAnalogHat(RightHatY) > 7500 || Xbox.getAnalogHat(RightHatY) < -7500) { + Serial.print(F("RightHatY: ")); + Serial.print(Xbox.getAnalogHat(RightHatY)); } Serial.println(); } - - if(Xbox.getButtonClick(UP)) + + if (Xbox.getButtonClick(UP)) Serial.println(F("Up")); - if(Xbox.getButtonClick(DOWN)) + if (Xbox.getButtonClick(DOWN)) Serial.println(F("Down")); - if(Xbox.getButtonClick(LEFT)) + if (Xbox.getButtonClick(LEFT)) Serial.println(F("Left")); - if(Xbox.getButtonClick(RIGHT)) + if (Xbox.getButtonClick(RIGHT)) Serial.println(F("Right")); - if(Xbox.getButtonClick(START)) + if (Xbox.getButtonClick(START)) Serial.println(F("Start")); - if(Xbox.getButtonClick(BACK)) + if (Xbox.getButtonClick(BACK)) Serial.println(F("Back")); - if(Xbox.getButtonClick(L3)) + if (Xbox.getButtonClick(L3)) Serial.println(F("L3")); - if(Xbox.getButtonClick(R3)) + if (Xbox.getButtonClick(R3)) Serial.println(F("R3")); - if(Xbox.getButtonPress(A)) { + if (Xbox.getButtonPress(A)) { Serial.print(F("A: ")); Serial.println(Xbox.getButtonPress(A)); } - if(Xbox.getButtonPress(B)) { + if (Xbox.getButtonPress(B)) { Serial.print(F("B: ")); Serial.println(Xbox.getButtonPress(B)); } - if(Xbox.getButtonPress(X)) { + if (Xbox.getButtonPress(X)) { Serial.print(F("X: ")); Serial.println(Xbox.getButtonPress(X)); } - if(Xbox.getButtonPress(Y)) { + if (Xbox.getButtonPress(Y)) { Serial.print(F("Y: ")); Serial.println(Xbox.getButtonPress(Y)); } - if(Xbox.getButtonPress(L1)) { + if (Xbox.getButtonPress(L1)) { Serial.print(F("L1: ")); Serial.println(Xbox.getButtonPress(L1)); } - if(Xbox.getButtonPress(R1)) { + if (Xbox.getButtonPress(R1)) { Serial.print(F("R1: ")); Serial.println(Xbox.getButtonPress(R1)); } diff --git a/examples/Xbox/XBOXUSB/XBOXUSB.ino b/examples/Xbox/XBOXUSB/XBOXUSB.ino index a26b4110..2d1c6008 100644 --- a/examples/Xbox/XBOXUSB/XBOXUSB.ino +++ b/examples/Xbox/XBOXUSB/XBOXUSB.ino @@ -1,6 +1,6 @@ /* Example sketch for the Xbox 360 USB library - developed by Kristian Lauszus - For more information visit my blog: http://blog.tkjelectronics.dk/ or + For more information visit my blog: http://blog.tkjelectronics.dk/ or send me an e-mail: kristianl@tkjelectronics.com */ @@ -14,90 +14,90 @@ void setup() { while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection if (Usb.Init() == -1) { Serial.print(F("\r\nOSC did not start")); - while(1); //halt - } + while (1); //halt + } Serial.print(F("\r\nXBOX USB Library Started")); } void loop() { Usb.Task(); - if(Xbox.Xbox360Connected) { - if(Xbox.getButtonPress(L2) || Xbox.getButtonPress(R2)) { + if (Xbox.Xbox360Connected) { + if (Xbox.getButtonPress(L2) || Xbox.getButtonPress(R2)) { Serial.print("L2: "); Serial.print(Xbox.getButtonPress(L2)); Serial.print("\tR2: "); Serial.println(Xbox.getButtonPress(R2)); - Xbox.setRumbleOn(Xbox.getButtonPress(L2),Xbox.getButtonPress(R2)); + Xbox.setRumbleOn(Xbox.getButtonPress(L2), Xbox.getButtonPress(R2)); } else - Xbox.setRumbleOn(0,0); - 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: ")); + Xbox.setRumbleOn(0, 0); + 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: ")); + } + 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: ")); + } + 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.print("\t"); + } + if (Xbox.getAnalogHat(RightHatY) > 7500 || Xbox.getAnalogHat(RightHatY) < -7500) { + Serial.print(F("RightHatY: ")); + Serial.print(Xbox.getAnalogHat(RightHatY)); } Serial.println(); } - - if(Xbox.getButtonClick(UP)) { + + if (Xbox.getButtonClick(UP)) { Xbox.setLedOn(LED1); Serial.println(F("Up")); - } - if(Xbox.getButtonClick(DOWN)) { + } + if (Xbox.getButtonClick(DOWN)) { Xbox.setLedOn(LED4); Serial.println(F("Down")); } - if(Xbox.getButtonClick(LEFT)) { + if (Xbox.getButtonClick(LEFT)) { Xbox.setLedOn(LED3); Serial.println(F("Left")); } - if(Xbox.getButtonClick(RIGHT)) { + if (Xbox.getButtonClick(RIGHT)) { Xbox.setLedOn(LED2); Serial.println(F("Right")); } - if(Xbox.getButtonClick(START)) { + if (Xbox.getButtonClick(START)) { Xbox.setLedMode(ALTERNATING); Serial.println(F("Start")); } - if(Xbox.getButtonClick(BACK)) { + if (Xbox.getButtonClick(BACK)) { Xbox.setLedBlink(ALL); Serial.println(F("Back")); } - if(Xbox.getButtonClick(L3)) + if (Xbox.getButtonClick(L3)) Serial.println(F("L3")); - if(Xbox.getButtonClick(R3)) + if (Xbox.getButtonClick(R3)) Serial.println(F("R3")); - if(Xbox.getButtonClick(L1)) + if (Xbox.getButtonClick(L1)) Serial.println(F("L1")); - if(Xbox.getButtonClick(R1)) + if (Xbox.getButtonClick(R1)) Serial.println(F("R1")); - if(Xbox.getButtonClick(XBOX)) { + if (Xbox.getButtonClick(XBOX)) { Xbox.setLedMode(ROTATING); - Serial.println(F("Xbox")); + Serial.println(F("Xbox")); } - if(Xbox.getButtonClick(A)) + if (Xbox.getButtonClick(A)) Serial.println(F("A")); - if(Xbox.getButtonClick(B)) + if (Xbox.getButtonClick(B)) Serial.println(F("B")); - if(Xbox.getButtonClick(X)) + if (Xbox.getButtonClick(X)) Serial.println(F("X")); - if(Xbox.getButtonClick(Y)) + if (Xbox.getButtonClick(Y)) Serial.println(F("Y")); } delay(1); From 5b793db3e3123753c4f691ad8efeb97252b87287 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Fri, 15 Nov 2013 23:19:10 +0100 Subject: [PATCH 13/53] Can now call setLedOff without any argument, to turn all LEDs off --- PS3BT.cpp | 23 +++++++++++-------- PS3BT.h | 4 ++++ PS3USB.h | 4 ++++ Wii.h | 6 +++-- examples/Bluetooth/PS3BT/PS3BT.ino | 8 +++---- examples/Bluetooth/PS3Multi/PS3Multi.ino | 8 +++---- examples/Bluetooth/PS3SPP/PS3SPP.ino | 8 +++---- examples/Bluetooth/Wii/Wii.ino | 8 +++---- examples/Bluetooth/WiiMulti/WiiMulti.ino | 8 +++---- .../WiiUProController/WiiUProController.ino | 8 +++---- examples/PS3USB/PS3USB.ino | 8 +++---- 11 files changed, 54 insertions(+), 39 deletions(-) diff --git a/PS3BT.cpp b/PS3BT.cpp index 7fb6b8b4..72c257d0 100644 --- a/PS3BT.cpp +++ b/PS3BT.cpp @@ -36,7 +36,7 @@ pBtd(p) // pointer to USB class instance - mandatory HIDBuffer[0] = 0x52; // HID BT Set_report (0x50) | Report Type (Output 0x02) HIDBuffer[1] = 0x01; // Report ID - //Needed for PS3 Move Controller commands to work via bluetooth + // Needed for PS3 Move Controller commands to work via bluetooth HIDMoveBuffer[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02) HIDMoveBuffer[1] = 0x02; // Report ID @@ -529,16 +529,16 @@ void PS3BT::Run() { ButtonState = 0; // Clear all values OldButtonState = 0; ButtonClickState = 0; - + onInit(); // Turn on the LED on the controller l2cap_state = L2CAP_DONE; } break; case L2CAP_DONE: - if (PS3MoveConnected) { //The Bulb and rumble values, has to be send at aproximatly every 5th second for it to stay on - 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 + if (PS3MoveConnected) { // The Bulb and rumble values, has to be send at aproximatly every 5th second for it to stay on + 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(); } } @@ -560,8 +560,12 @@ void PS3BT::HID_Command(uint8_t* data, uint8_t nbytes) { } void PS3BT::setAllOff() { - for (uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) - HIDBuffer[i + 2] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); // First two bytes reserved for report type and ID + HIDBuffer[3] = 0x00; // Rumble bytes + HIDBuffer[4] = 0x00; + HIDBuffer[5] = 0x00; + HIDBuffer[6] = 0x00; + + HIDBuffer[11] = 0x00; // LED byte HID_Command(HIDBuffer, HID_BUFFERSIZE); } @@ -596,6 +600,7 @@ void PS3BT::setLedRaw(uint8_t value) { HIDBuffer[11] = value << 1; HID_Command(HIDBuffer, HID_BUFFERSIZE); } + void PS3BT::setLedOff(LED a) { HIDBuffer[11] &= ~((uint8_t)((pgm_read_byte(&LEDS[(uint8_t)a]) & 0x0f) << 1)); HID_Command(HIDBuffer, HID_BUFFERSIZE); @@ -633,7 +638,7 @@ void PS3BT::HIDMove_Command(uint8_t* data, uint8_t nbytes) { } void PS3BT::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 + // Set the Bulb's values into the write buffer HIDMoveBuffer[3] = r; HIDMoveBuffer[4] = g; HIDMoveBuffer[5] = b; @@ -650,7 +655,7 @@ void PS3BT::moveSetRumble(uint8_t rumble) { 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%"), 0x80); #endif - //set the rumble value into the write buffer + // Set the rumble value into the write buffer HIDMoveBuffer[7] = rumble; HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE); diff --git a/PS3BT.h b/PS3BT.h index 5b00232f..6b901402 100644 --- a/PS3BT.h +++ b/PS3BT.h @@ -176,6 +176,10 @@ public: * @param value See: ::LED enum. */ void setLedRaw(uint8_t value); + /** Turn all LEDs off. */ + void setLedOff() { + setLedRaw(0); + } /** * Turn the specific ::LED off. * @param a The ::LED to turn off. diff --git a/PS3USB.h b/PS3USB.h index 2fac0fbe..ae5314f4 100644 --- a/PS3USB.h +++ b/PS3USB.h @@ -220,6 +220,10 @@ public: * @param value See: ::LED enum. */ void setLedRaw(uint8_t value); + /** Turn all LEDs off. */ + void setLedOff() { + setLedRaw(0); + } /** * Turn the specific ::LED off. * @param a The ::LED to turn off. diff --git a/Wii.h b/Wii.h index f1ba6a90..f8d206ef 100755 --- a/Wii.h +++ b/Wii.h @@ -191,6 +191,10 @@ public: * @param value See: ::LED enum. */ void setLedRaw(uint8_t value); + /** Turn all LEDs off. */ + void setLedOff() { + setLedRaw(0); + } /** * Turn the specific ::LED off. * @param a The ::LED to turn off. @@ -210,9 +214,7 @@ public: * This will set the LEDs, so the user can see which connections are active. * * The first ::LED indicate that the Wiimote is connected, - * * the second ::LED indicate indicate that a Motion Plus is also connected - * * the third ::LED will indicate that a Nunchuck controller is also connected. */ void setLedStatus(); diff --git a/examples/Bluetooth/PS3BT/PS3BT.ino b/examples/Bluetooth/PS3BT/PS3BT.ino index 253f17b9..e98d5b73 100644 --- a/examples/Bluetooth/PS3BT/PS3BT.ino +++ b/examples/Bluetooth/PS3BT/PS3BT.ino @@ -69,28 +69,28 @@ void loop() { if (PS3.getButtonClick(UP)) { Serial.print(F("\r\nUp")); if (PS3.PS3Connected) { - PS3.setAllOff(); + PS3.setLedOff(); PS3.setLedOn(LED4); } } if (PS3.getButtonClick(RIGHT)) { Serial.print(F("\r\nRight")); if (PS3.PS3Connected) { - PS3.setAllOff(); + PS3.setLedOff(); PS3.setLedOn(LED1); } } if (PS3.getButtonClick(DOWN)) { Serial.print(F("\r\nDown")); if (PS3.PS3Connected) { - PS3.setAllOff(); + PS3.setLedOff(); PS3.setLedOn(LED2); } } if (PS3.getButtonClick(LEFT)) { Serial.print(F("\r\nLeft")); if (PS3.PS3Connected) { - PS3.setAllOff(); + PS3.setLedOff(); PS3.setLedOn(LED3); } } diff --git a/examples/Bluetooth/PS3Multi/PS3Multi.ino b/examples/Bluetooth/PS3Multi/PS3Multi.ino index 56f8da94..2471cfcc 100644 --- a/examples/Bluetooth/PS3Multi/PS3Multi.ino +++ b/examples/Bluetooth/PS3Multi/PS3Multi.ino @@ -74,28 +74,28 @@ void loop() { if (PS3[i]->getButtonClick(UP)) { Serial.print(F("\r\nUp")); if (PS3[i]->PS3Connected) { - PS3[i]->setAllOff(); + PS3[i]->setLedOff(); PS3[i]->setLedOn(LED4); } } if (PS3[i]->getButtonClick(RIGHT)) { Serial.print(F("\r\nRight")); if (PS3[i]->PS3Connected) { - PS3[i]->setAllOff(); + PS3[i]->setLedOff(); PS3[i]->setLedOn(LED1); } } if (PS3[i]->getButtonClick(DOWN)) { Serial.print(F("\r\nDown")); if (PS3[i]->PS3Connected) { - PS3[i]->setAllOff(); + PS3[i]->setLedOff(); PS3[i]->setLedOn(LED2); } } if (PS3[i]->getButtonClick(LEFT)) { Serial.print(F("\r\nLeft")); if (PS3[i]->PS3Connected) { - PS3[i]->setAllOff(); + PS3[i]->setLedOff(); PS3[i]->setLedOn(LED3); } } diff --git a/examples/Bluetooth/PS3SPP/PS3SPP.ino b/examples/Bluetooth/PS3SPP/PS3SPP.ino index 734de065..0263c10a 100644 --- a/examples/Bluetooth/PS3SPP/PS3SPP.ino +++ b/examples/Bluetooth/PS3SPP/PS3SPP.ino @@ -100,28 +100,28 @@ void loop() { if (PS3.getButtonClick(UP)) { output += " - Up"; if (PS3.PS3Connected) { - PS3.setAllOff(); + PS3.setLedOff(); PS3.setLedOn(LED4); } } if (PS3.getButtonClick(RIGHT)) { output += " - Right"; if (PS3.PS3Connected) { - PS3.setAllOff(); + PS3.setLedOff(); PS3.setLedOn(LED1); } } if (PS3.getButtonClick(DOWN)) { output += " - Down"; if (PS3.PS3Connected) { - PS3.setAllOff(); + PS3.setLedOff(); PS3.setLedOn(LED2); } } if (PS3.getButtonClick(LEFT)) { output += " - Left"; if (PS3.PS3Connected) { - PS3.setAllOff(); + PS3.setLedOff(); PS3.setLedOn(LED3); } } diff --git a/examples/Bluetooth/Wii/Wii.ino b/examples/Bluetooth/Wii/Wii.ino index e377ad24..d56b4252 100644 --- a/examples/Bluetooth/Wii/Wii.ino +++ b/examples/Bluetooth/Wii/Wii.ino @@ -34,22 +34,22 @@ void loop() { } else { if (Wii.getButtonClick(LEFT)) { - Wii.setAllOff(); + Wii.setLedOff(); Wii.setLedOn(LED1); Serial.print(F("\r\nLeft")); } if (Wii.getButtonClick(RIGHT)) { - Wii.setAllOff(); + Wii.setLedOff(); Wii.setLedOn(LED3); Serial.print(F("\r\nRight")); } if (Wii.getButtonClick(DOWN)) { - Wii.setAllOff(); + Wii.setLedOff(); Wii.setLedOn(LED4); Serial.print(F("\r\nDown")); } if (Wii.getButtonClick(UP)) { - Wii.setAllOff(); + Wii.setLedOff(); Wii.setLedOn(LED2); Serial.print(F("\r\nUp")); } diff --git a/examples/Bluetooth/WiiMulti/WiiMulti.ino b/examples/Bluetooth/WiiMulti/WiiMulti.ino index 518d9859..3036b908 100644 --- a/examples/Bluetooth/WiiMulti/WiiMulti.ino +++ b/examples/Bluetooth/WiiMulti/WiiMulti.ino @@ -42,22 +42,22 @@ void loop() { } else { if (Wii[i]->getButtonClick(LEFT)) { - Wii[i]->setAllOff(); + Wii[i]->setLedOff(); Wii[i]->setLedOn(LED1); Serial.print(F("\r\nLeft")); } if (Wii[i]->getButtonClick(RIGHT)) { - Wii[i]->setAllOff(); + Wii[i]->setLedOff(); Wii[i]->setLedOn(LED3); Serial.print(F("\r\nRight")); } if (Wii[i]->getButtonClick(DOWN)) { - Wii[i]->setAllOff(); + Wii[i]->setLedOff(); Wii[i]->setLedOn(LED4); Serial.print(F("\r\nDown")); } if (Wii[i]->getButtonClick(UP)) { - Wii[i]->setAllOff(); + Wii[i]->setLedOff(); Wii[i]->setLedOn(LED2); Serial.print(F("\r\nUp")); } diff --git a/examples/Bluetooth/WiiUProController/WiiUProController.ino b/examples/Bluetooth/WiiUProController/WiiUProController.ino index 608a7688..582eeae3 100644 --- a/examples/Bluetooth/WiiUProController/WiiUProController.ino +++ b/examples/Bluetooth/WiiUProController/WiiUProController.ino @@ -32,22 +32,22 @@ void loop() { } else { if (Wii.getButtonClick(LEFT)) { - Wii.setAllOff(); + Wii.setLedOff(); Wii.setLedOn(LED1); Serial.print(F("\r\nLeft")); } if (Wii.getButtonClick(RIGHT)) { - Wii.setAllOff(); + Wii.setLedOff(); Wii.setLedOn(LED3); Serial.print(F("\r\nRight")); } if (Wii.getButtonClick(DOWN)) { - Wii.setAllOff(); + Wii.setLedOff(); Wii.setLedOn(LED4); Serial.print(F("\r\nDown")); } if (Wii.getButtonClick(UP)) { - Wii.setAllOff(); + Wii.setLedOff(); Wii.setLedOn(LED2); Serial.print(F("\r\nUp")); } diff --git a/examples/PS3USB/PS3USB.ino b/examples/PS3USB/PS3USB.ino index 6e6943a9..50a020c0 100644 --- a/examples/PS3USB/PS3USB.ino +++ b/examples/PS3USB/PS3USB.ino @@ -62,22 +62,22 @@ void loop() { if (PS3.getButtonClick(UP)) { Serial.print(F("\r\nUp")); - PS3.setAllOff(); + PS3.setLedOff(); PS3.setLedOn(LED4); } if (PS3.getButtonClick(RIGHT)) { Serial.print(F("\r\nRight")); - PS3.setAllOff(); + PS3.setLedOff(); PS3.setLedOn(LED1); } if (PS3.getButtonClick(DOWN)) { Serial.print(F("\r\nDown")); - PS3.setAllOff(); + PS3.setLedOff(); PS3.setLedOn(LED2); } if (PS3.getButtonClick(LEFT)) { Serial.print(F("\r\nLeft")); - PS3.setAllOff(); + PS3.setLedOff(); PS3.setLedOn(LED3); } From 99d2e4cb0d8f6c4bdfb3d5fc86d05b72dc16b863 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Fri, 15 Nov 2013 23:20:15 +0100 Subject: [PATCH 14/53] Updated comment --- examples/adk/ArduinoBlinkLED/ArduinoBlinkLED.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/adk/ArduinoBlinkLED/ArduinoBlinkLED.ino b/examples/adk/ArduinoBlinkLED/ArduinoBlinkLED.ino index 6f35c494..f26be384 100644 --- a/examples/adk/ArduinoBlinkLED/ArduinoBlinkLED.ino +++ b/examples/adk/ArduinoBlinkLED/ArduinoBlinkLED.ino @@ -10,7 +10,7 @@ ADK adk(&Usb, "TKJElectronics", // Manufacturer Name "http://www.tkjelectronics.dk/uploads/ArduinoBlinkLED.apk", // URL (web page to visit if no installed apps support the accessory) "123456789"); // Serial Number (optional) -#define LED LED_BUILTIN // Pin 13 is occupied by the SCK pin on a normal Arduino (Uno, Duemilanove etc.), so use a different pin +#define LED LED_BUILTIN // Use built in LED - note that pin 13 is occupied by the SCK pin on a normal Arduino (Uno, Duemilanove etc.), so use a different pin void setup() { Serial.begin(115200); From dd39e62a693101f4147ec3e47579aedceb4bbabd Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Fri, 15 Nov 2013 23:30:16 +0100 Subject: [PATCH 15/53] Added new line --- examples/Xbox/XBOXOLD/XBOXOLD.ino | 1 + examples/Xbox/XBOXRECV/XBOXRECV.ino | 1 + examples/Xbox/XBOXUSB/XBOXUSB.ino | 1 + 3 files changed, 3 insertions(+) diff --git a/examples/Xbox/XBOXOLD/XBOXOLD.ino b/examples/Xbox/XBOXOLD/XBOXOLD.ino index 9e2034d6..1bdfc9f9 100644 --- a/examples/Xbox/XBOXOLD/XBOXOLD.ino +++ b/examples/Xbox/XBOXOLD/XBOXOLD.ino @@ -31,6 +31,7 @@ void loop() { Xbox.setRumbleOn(Xbox.getButtonPress(BLACK), Xbox.getButtonPress(WHITE)); } else Xbox.setRumbleOn(0, 0); + 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: ")); diff --git a/examples/Xbox/XBOXRECV/XBOXRECV.ino b/examples/Xbox/XBOXRECV/XBOXRECV.ino index 512e176e..5896b9dc 100644 --- a/examples/Xbox/XBOXRECV/XBOXRECV.ino +++ b/examples/Xbox/XBOXRECV/XBOXRECV.ino @@ -31,6 +31,7 @@ void loop() { Serial.println(Xbox.getButtonPress(R2, i)); Xbox.setRumbleOn(Xbox.getButtonPress(L2, i), Xbox.getButtonPress(R2, i), i); } + if (Xbox.getAnalogHat(LeftHatX, i) > 7500 || Xbox.getAnalogHat(LeftHatX, i) < -7500 || Xbox.getAnalogHat(LeftHatY, i) > 7500 || Xbox.getAnalogHat(LeftHatY, i) < -7500 || Xbox.getAnalogHat(RightHatX, i) > 7500 || Xbox.getAnalogHat(RightHatX, i) < -7500 || Xbox.getAnalogHat(RightHatY, i) > 7500 || Xbox.getAnalogHat(RightHatY, i) < -7500) { if (Xbox.getAnalogHat(LeftHatX, i) > 7500 || Xbox.getAnalogHat(LeftHatX, i) < -7500) { Serial.print(F("LeftHatX: ")); diff --git a/examples/Xbox/XBOXUSB/XBOXUSB.ino b/examples/Xbox/XBOXUSB/XBOXUSB.ino index 2d1c6008..b7d5a625 100644 --- a/examples/Xbox/XBOXUSB/XBOXUSB.ino +++ b/examples/Xbox/XBOXUSB/XBOXUSB.ino @@ -29,6 +29,7 @@ void loop() { Xbox.setRumbleOn(Xbox.getButtonPress(L2), Xbox.getButtonPress(R2)); } else Xbox.setRumbleOn(0, 0); + 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: ")); From 16f9c97cd69ce8d11d4f3ff566dc996711a4cf2d Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Fri, 15 Nov 2013 23:31:05 +0100 Subject: [PATCH 16/53] Added more debugging when connection is established --- BTD.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/BTD.cpp b/BTD.cpp index d6ccc5b6..95c2cf81 100755 --- a/BTD.cpp +++ b/BTD.cpp @@ -461,6 +461,9 @@ void BTD::HCI_event_task() { case EV_CONNECT_COMPLETE: hci_event_flag |= HCI_FLAG_CONNECT_EVENT; if (!hcibuf[2]) { // check if connected OK +#ifdef EXTRADEBUG + Notify(PSTR("\r\nConnection established"), 0x80); +#endif hci_handle = hcibuf[3] | ((hcibuf[4] & 0x0F) << 8); // store the handle for the ACL connection hci_event_flag |= HCI_FLAG_CONN_COMPLETE; // set connection complete flag } else { From 0de2c0e48b1cef722e72bea449fd075d3d885e38 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 17 Nov 2013 18:57:03 +0100 Subject: [PATCH 17/53] Arduino can now write data to the Android phone as well --- .../adk/ArduinoBlinkLED/ArduinoBlinkLED.ino | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/examples/adk/ArduinoBlinkLED/ArduinoBlinkLED.ino b/examples/adk/ArduinoBlinkLED/ArduinoBlinkLED.ino index f26be384..bc0cb95a 100644 --- a/examples/adk/ArduinoBlinkLED/ArduinoBlinkLED.ino +++ b/examples/adk/ArduinoBlinkLED/ArduinoBlinkLED.ino @@ -12,6 +12,8 @@ ADK adk(&Usb, "TKJElectronics", // Manufacturer Name #define LED LED_BUILTIN // Use built in LED - note that pin 13 is occupied by the SCK pin on a normal Arduino (Uno, Duemilanove etc.), so use a different pin +uint32_t timer; + void setup() { Serial.begin(115200); while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection @@ -29,13 +31,26 @@ void loop() { uint8_t msg[1]; uint16_t len = sizeof(msg); uint8_t rcode = adk.RcvData(&len, msg); - if (rcode && rcode != hrNAK) - USBTRACE2("Data rcv. :", rcode); - else if (len > 0) { + if (rcode && rcode != hrNAK) { + Serial.print(F("\r\nData rcv: ")); + Serial.print(rcode, HEX); + } else if (len > 0) { Serial.print(F("\r\nData Packet: ")); Serial.print(msg[0]); digitalWrite(LED, msg[0] ? HIGH : LOW); } + + if (millis() - timer >= 1000) { // Send data every 1s + timer = millis(); + rcode = adk.SndData(sizeof(timer), (uint8_t*)&timer); + if (rcode && rcode != hrNAK) { + Serial.print(F("\r\nData send: ")); + Serial.print(rcode, HEX); + } else if (rcode != hrNAK) { + Serial.print(F("\r\nTimer: ")); + Serial.print(timer); + } + } } else digitalWrite(LED, LOW); From 0ce8575603def7503a5905ddf357c190617ef598 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 17 Nov 2013 20:13:33 +0100 Subject: [PATCH 18/53] Cleanup --- PS3BT.cpp | 50 ++++++++++++++++---------------------------------- 1 file changed, 16 insertions(+), 34 deletions(-) diff --git a/PS3BT.cpp b/PS3BT.cpp index 72c257d0..976b21b5 100644 --- a/PS3BT.cpp +++ b/PS3BT.cpp @@ -41,9 +41,9 @@ pBtd(p) // pointer to USB class instance - mandatory HIDMoveBuffer[1] = 0x02; // Report ID /* Set device cid for the control and intterrupt channelse - LSB */ - control_dcid[0] = 0x40; //0x0040 + control_dcid[0] = 0x40; // 0x0040 control_dcid[1] = 0x00; - interrupt_dcid[0] = 0x41; //0x0041 + interrupt_dcid[0] = 0x41; // 0x0041 interrupt_dcid[1] = 0x00; Reset(); @@ -56,25 +56,19 @@ bool PS3BT::getButtonPress(Button b) { bool PS3BT::getButtonClick(Button b) { uint32_t button = pgm_read_dword(&BUTTONS[(uint8_t)b]); bool click = (ButtonClickState & button); - ButtonClickState &= ~button; // clear "click" event + ButtonClickState &= ~button; // Clear "click" event return click; } uint8_t PS3BT::getAnalogButton(Button a) { - if (l2capinbuf == NULL) - return 0; return (uint8_t)(l2capinbuf[pgm_read_byte(&ANALOGBUTTONS[(uint8_t)a])]); } uint8_t PS3BT::getAnalogHat(AnalogHat a) { - if (l2capinbuf == NULL) - return 0; return (uint8_t)(l2capinbuf[(uint8_t)a + 15]); } int16_t PS3BT::getSensor(Sensor a) { - if (l2capinbuf == NULL) - return 0; if (PS3Connected) { if (a == aX || a == aY || a == aZ || a == gZ) return ((l2capinbuf[(uint16_t)a] << 8) | l2capinbuf[(uint16_t)a + 1]); @@ -92,13 +86,11 @@ int16_t PS3BT::getSensor(Sensor a) { } double PS3BT::getAngle(Angle a) { - double accXval; - double accYval; - double accZval; + double accXval, accYval, accZval; if (PS3Connected) { // Data for the Kionix KXPC4 used in the DualShock 3 - const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V) + 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); @@ -114,13 +106,10 @@ double PS3BT::getAngle(Angle a) { // 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; - } + if (a == Pitch) + return (atan2(accYval, accZval) + PI) * RAD_TO_DEG; + else + return (atan2(accXval, accZval) + PI) * RAD_TO_DEG; } double PS3BT::get9DOFValues(Sensor a) { // Thanks to Manfred Piendl @@ -168,11 +157,7 @@ String PS3BT::getTemperature() { } bool PS3BT::getStatus(Status c) { - if (l2capinbuf == NULL) - return false; - if (l2capinbuf[(uint16_t)c >> 8] == ((uint8_t)c & 0xff)) - return true; - return false; + return (l2capinbuf[(uint16_t)c >> 8] == ((uint8_t)c & 0xff)); } String PS3BT::getStatusString() { @@ -266,8 +251,7 @@ void PS3BT::ACLData(uint8_t* ACLData) { } } if (((ACLData[0] | (ACLData[1] << 8)) == (hci_handle | 0x2000))) { //acl_handle_ok - for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++) - l2capinbuf[i] = ACLData[i]; + memcpy(l2capinbuf, ACLData, BULK_MAXPKTSIZE); if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) { //l2cap_control - Channel ID for ACL-U if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) { #ifdef DEBUG_USB_HOST @@ -457,8 +441,7 @@ void PS3BT::L2CAP_task() { Notify(PSTR("\r\nHID Interrupt Successfully Configured"), 0x80); #endif if (remote_name[0] == 'M') { // First letter in Motion Controller ('M') - for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++) // Reset l2cap in buffer as it sometimes read it as a button has been pressed - l2capinbuf[i] = 0; + memset(l2capinbuf, 0, BULK_MAXPKTSIZE); // Reset l2cap in buffer as it sometimes read it as a button has been pressed l2cap_state = L2CAP_HID_PS3_LED; } else l2cap_state = L2CAP_HID_ENABLE_SIXAXIS; @@ -497,8 +480,7 @@ void PS3BT::Run() { switch (l2cap_state) { case L2CAP_HID_ENABLE_SIXAXIS: if (millis() - timer > 1000) { // loop 1 second before sending the command - for (uint8_t i = 0; i < BULK_MAXPKTSIZE; i++) // Reset l2cap in buffer as it sometimes read it as a button has been pressed - l2capinbuf[i] = 0; + memset(l2capinbuf, 0, BULK_MAXPKTSIZE); // Reset l2cap in buffer as it sometimes read it as a button has been pressed for (uint8_t i = 15; i < 19; i++) l2capinbuf[i] = 0x7F; // Set the analog joystick values to center position enable_sixaxis(); @@ -550,11 +532,11 @@ void PS3BT::Run() { /* HID Commands */ /************************************************************/ -//Playstation Sixaxis Dualshock and Navigation Controller commands +// Playstation Sixaxis Dualshock and Navigation Controller commands void PS3BT::HID_Command(uint8_t* data, uint8_t nbytes) { - 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 + 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 pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]); // Both the Navigation and Dualshock controller sends data via the control channel timerHID = millis(); } From 4a3c903322a9155776ba563e14adfc69c338aa32 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 18 Nov 2013 21:34:48 +0100 Subject: [PATCH 19/53] Updated link --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 09557cb0..361caf1a 100644 --- a/README.md +++ b/README.md @@ -98,7 +98,7 @@ More information can be found at these blog posts: * * -To implement the SPP protocol I used a Bluetooth sniffing tool called [PacketLogger](http://www.tkjelectronics.com/uploads/PacketLogger.zip) developed by Apple. +To implement the SPP protocol I used a Bluetooth sniffing tool called [PacketLogger](http://www.tkjelectronics.com/uploads/PacketLogger.zip) developed by Apple. It enables me to see the Bluetooth communication between my Mac and any device. ### PS3 Library @@ -107,7 +107,7 @@ These libraries consist of the [PS3BT](PS3BT.cpp) and [PS3USB](PS3USB.cpp). Thes In order to use your Playstation controller via Bluetooth you have to set the Bluetooth address of the dongle internally to your PS3 Controller. This can be achieved by plugging the controller in via USB and letting the library set it automatically. -__Note:__ To obtain the address you have to plug in the Bluetooth dongle before connecting the controller, or alternatively you could set it in code like so: . +__Note:__ To obtain the address you have to plug in the Bluetooth dongle before connecting the controller, or alternatively you could set it in code like so: . For more information about the PS3 protocol see the official wiki: . From 82696f08c783b8fc507ae9d04a058fa8a714ef39 Mon Sep 17 00:00:00 2001 From: "Andrew J. Kroll" Date: Sun, 24 Nov 2013 08:56:27 -0500 Subject: [PATCH 20/53] Clean up type puns, and reordering warnings --- UsbCore.h | 2 +- masstorage.h | 16 ++++++++++------ 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/UsbCore.h b/UsbCore.h index 85b0402e..bbcbfa0e 100644 --- a/UsbCore.h +++ b/UsbCore.h @@ -138,7 +138,7 @@ typedef struct { } wVal_u; uint16_t wIndex; // 4 Depends on bRequest uint16_t wLength; // 6 Depends on bRequest -} SETUP_PKT, *PSETUP_PKT __attribute__((packed)); +}__attribute__((packed)) SETUP_PKT, *PSETUP_PKT; diff --git a/masstorage.h b/masstorage.h index 9f7b43db..12a61ec9 100644 --- a/masstorage.h +++ b/masstorage.h @@ -190,12 +190,12 @@ struct CDB6 { public: CDB6(uint8_t _Opcode, uint8_t _LUN, uint32_t LBA, uint8_t _AllocationLength, uint8_t _Control) : - Opcode(_Opcode), LUN(_LUN), LBAMSB(BGRAB2(LBA) & 0x1f), LBAHB(BGRAB1(LBA)), LBALB(BGRAB0(LBA)), + Opcode(_Opcode), LBAMSB(BGRAB2(LBA) & 0x1f), LUN(_LUN), LBAHB(BGRAB1(LBA)), LBALB(BGRAB0(LBA)), AllocationLength(_AllocationLength), Control(_Control) { } CDB6(uint8_t _Opcode, uint8_t _LUN, uint8_t _AllocationLength, uint8_t _Control) : - Opcode(_Opcode), LUN(_LUN), LBAMSB(0), LBAHB(0), LBALB(0), + Opcode(_Opcode), LBAMSB(0), LUN(_LUN), LBAHB(0), LBALB(0), AllocationLength(_AllocationLength), Control(_Control) { } } __attribute__((packed)); @@ -391,23 +391,27 @@ public: CommandBlockWrapper(uint32_t tag, uint32_t xflen, uint8_t flgs, uint8_t lu, uint8_t cmdlen, uint8_t cmd) : CommandBlockWrapperBase(tag, xflen, flgs), - bmReserved1(0), bmReserved2(0), bmCBWLUN(lu), bmCBWCBLength(cmdlen) { + bmCBWLUN(lu), bmReserved1(0), bmCBWCBLength(cmdlen), bmReserved2(0) { for(int i = 0; i < 16; i++) CBWCB[i] = 0; - ((BASICCDB_t *) CBWCB)->LUN = cmd; + // Type punning can cause optimization problems and bugs. + // Using reinterpret_cast to a different object is the proper way to do this. + //(((BASICCDB_t *) CBWCB)->LUN) = cmd; + BASICCDB_t *x = reinterpret_cast (CBWCB); + x->LUN = cmd; } // Wrap for CDB of 6 CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB6_t *cdb, uint8_t dir) : CommandBlockWrapperBase(tag, xflen, dir), - bmReserved1(0), bmReserved2(0), bmCBWLUN(cdb->LUN), bmCBWCBLength(6) { + bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(6), bmReserved2(0) { memcpy(&CBWCB, cdb, 6); } // Wrap for CDB of 10 CommandBlockWrapper(uint32_t tag, uint32_t xflen, CDB10_t *cdb, uint8_t dir) : CommandBlockWrapperBase(tag, xflen, dir), - bmReserved1(0), bmReserved2(0), bmCBWLUN(cdb->LUN), bmCBWCBLength(10) { + bmCBWLUN(cdb->LUN), bmReserved1(0), bmCBWCBLength(10), bmReserved2(0) { memcpy(&CBWCB, cdb, 10); } } __attribute__((packed)); From 8715cbde679ef377d64ead545ebbd80c70e098a8 Mon Sep 17 00:00:00 2001 From: "Andrew J. Kroll" Date: Sun, 24 Nov 2013 08:56:34 -0500 Subject: [PATCH 21/53] Add spi4teensy3 library support --- settings.h | 16 +++++++++++++++- usbhost.h | 46 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/settings.h b/settings.h index add3ee03..bd64ff3f 100644 --- a/settings.h +++ b/settings.h @@ -6,7 +6,7 @@ */ #ifndef USB_HOST_SHIELD_SETTINGS_H -#define USB_HOST_SHIELD_SETTINGS_H +#define USB_HOST_SHIELD_SETTINGS_H #include "macros.h" //////////////////////////////////////////////////////////////////////////////// @@ -47,6 +47,14 @@ #define MASS_MAX_SUPPORTED_LUN 8 #endif + +//////////////////////////////////////////////////////////////////////////////// +// Set to 1 to use the faster spi4teensy3 driver. +//////////////////////////////////////////////////////////////////////////////// +#ifndef USE_SPI4TEENSY3 +#define USE_SPI4TEENSY3 1 +#endif + //////////////////////////////////////////////////////////////////////////////// // AUTOMATIC Settings //////////////////////////////////////////////////////////////////////////////// @@ -76,4 +84,10 @@ #define XMEM_RELEASE_SPI() (void(0)) #endif +#ifdef __MK20DX128__ +#define USING_SPI4TEENSY3 USE_SPI4TEENSY3 +#else +#define USING_SPI4TEENSY3 0 +#endif + #endif /* SETTINGS_H */ diff --git a/usbhost.h b/usbhost.h index 5a8ca4bb..bc65e106 100644 --- a/usbhost.h +++ b/usbhost.h @@ -22,8 +22,26 @@ e-mail : support@circuitsathome.com #else #define _USBHOST_H_ +#if USING_SPI4TEENSY3 +#include +#include +#endif + /* SPI initialization */ template< typename CLK, typename MOSI, typename MISO, typename SPI_SS > class SPi { +#if USING_SPI4TEENSY3 +public: + + static void init() { + // spi4teensy3 inits everything for us, except /SS + // CLK, MOSI and MISO are hard coded for now. + // spi4teensy3::init(0,0,0); // full speed, cpol 0, cpha 0 + spi4teensy3::init(); // full speed, cpol 0, cpha 0 + SPI_SS::SetDirWrite(); + SPI_SS::Set(); + } + +#else public: static void init() { @@ -39,6 +57,7 @@ public: //tmp = SPSR; //tmp = SPDR; } +#endif }; /* SPI pin definitions. see avrpins.h */ @@ -93,7 +112,7 @@ template< typename SS, typename INTR > /* constructor */ template< typename SS, typename INTR > MAX3421e< SS, INTR >::MAX3421e() { -// Leaving ADK hardware setup in here, for now. This really belongs with the other parts. + // Leaving ADK hardware setup in here, for now. This really belongs with the other parts. #ifdef BOARD_MEGA_ADK // For Mega ADK, which has a Max3421e on-board, set MAX_RESET to output mode, and then set it to HIGH P55::SetDirWrite(); @@ -106,10 +125,17 @@ template< typename SS, typename INTR > void MAX3421e< SS, INTR >::regWr(uint8_t reg, uint8_t data) { XMEM_ACQUIRE_SPI(); SS::Clear(); +#if USING_SPI4TEENSY3 + uint8_t c[2]; + c[0] = reg | 0x02; + c[1] = data; + spi4teensy3::send(c, 2); +#else SPDR = (reg | 0x02); while(!(SPSR & (1 << SPIF))); SPDR = data; while(!(SPSR & (1 << SPIF))); +#endif SS::Set(); XMEM_RELEASE_SPI(); return; @@ -121,6 +147,11 @@ template< typename SS, typename INTR > uint8_t* MAX3421e< SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* data_p) { XMEM_ACQUIRE_SPI(); SS::Clear(); +#if USING_SPI4TEENSY3 + spi4teensy3::send(reg | 0x02); + spi4teensy3::send(data_p, nbytes); + data_p += nbytes; +#else SPDR = (reg | 0x02); //set WR bit and send register number while(nbytes--) { while(!(SPSR & (1 << SPIF))); //check if previous byte was sent @@ -128,6 +159,7 @@ uint8_t* MAX3421e< SS, INTR >::bytesWr(uint8_t reg, uint8_t nbytes, uint8_t* dat data_p++; // advance data pointer } while(!(SPSR & (1 << SPIF))); +#endif SS::Set(); XMEM_RELEASE_SPI(); return( data_p); @@ -149,12 +181,18 @@ template< typename SS, typename INTR > uint8_t MAX3421e< SS, INTR >::regRd(uint8_t reg) { XMEM_ACQUIRE_SPI(); SS::Clear(); +#if USING_SPI4TEENSY3 + spi4teensy3::send(reg); + uint8_t rv = spi4teensy3::receive(); + SS::Set(); +#else SPDR = reg; while(!(SPSR & (1 << SPIF))); SPDR = 0; //send empty byte while(!(SPSR & (1 << SPIF))); SS::Set(); uint8_t rv = SPDR; +#endif XMEM_RELEASE_SPI(); return(rv); } @@ -165,6 +203,11 @@ template< typename SS, typename INTR > uint8_t* MAX3421e< SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* data_p) { XMEM_ACQUIRE_SPI(); SS::Clear(); +#if USING_SPI4TEENSY3 + spi4teensy3::send(reg); + spi4teensy3::receive(data_p, nbytes); + data_p += nbytes; +#else SPDR = reg; while(!(SPSR & (1 << SPIF))); //wait while(nbytes) { @@ -182,6 +225,7 @@ uint8_t* MAX3421e< SS, INTR >::bytesRd(uint8_t reg, uint8_t nbytes, uint8_t* dat #else *data_p++ = SPDR; } +#endif #endif SS::Set(); XMEM_RELEASE_SPI(); From b22f52895cc703601d60ed3f41ef5ff985d18a12 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 24 Nov 2013 15:15:46 +0100 Subject: [PATCH 22/53] Check if PS3Connected is true instead --- examples/Bluetooth/PS3BT/PS3BT.ino | 2 +- examples/Bluetooth/PS3Multi/PS3Multi.ino | 2 +- examples/Bluetooth/PS3SPP/PS3SPP.ino | 2 +- examples/PS3USB/PS3USB.ino | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/Bluetooth/PS3BT/PS3BT.ino b/examples/Bluetooth/PS3BT/PS3BT.ino index e98d5b73..c63fbdcd 100644 --- a/examples/Bluetooth/PS3BT/PS3BT.ino +++ b/examples/Bluetooth/PS3BT/PS3BT.ino @@ -35,7 +35,7 @@ void loop() { Serial.print(PS3.getAnalogHat(LeftHatX)); Serial.print(F("\tLeftHatY: ")); Serial.print(PS3.getAnalogHat(LeftHatY)); - if (!PS3.PS3NavigationConnected) { + if (PS3.PS3Connected) { // The Navigation controller only have one joystick Serial.print(F("\tRightHatX: ")); Serial.print(PS3.getAnalogHat(RightHatX)); Serial.print(F("\tRightHatY: ")); diff --git a/examples/Bluetooth/PS3Multi/PS3Multi.ino b/examples/Bluetooth/PS3Multi/PS3Multi.ino index 2471cfcc..dcb0b8e7 100644 --- a/examples/Bluetooth/PS3Multi/PS3Multi.ino +++ b/examples/Bluetooth/PS3Multi/PS3Multi.ino @@ -40,7 +40,7 @@ void loop() { Serial.print(PS3[i]->getAnalogHat(LeftHatX)); Serial.print(F("\tLeftHatY: ")); Serial.print(PS3[i]->getAnalogHat(LeftHatY)); - if (!PS3[i]->PS3NavigationConnected) { // The Navigation controller only have one joystick + if (PS3[i]->PS3Connected) { // The Navigation controller only have one joystick Serial.print(F("\tRightHatX: ")); Serial.print(PS3[i]->getAnalogHat(RightHatX)); Serial.print(F("\tRightHatY: ")); diff --git a/examples/Bluetooth/PS3SPP/PS3SPP.ino b/examples/Bluetooth/PS3SPP/PS3SPP.ino index 0263c10a..edebdc61 100644 --- a/examples/Bluetooth/PS3SPP/PS3SPP.ino +++ b/examples/Bluetooth/PS3SPP/PS3SPP.ino @@ -59,7 +59,7 @@ void loop() { output += PS3.getAnalogHat(LeftHatX); output += "\tLeftHatY: "; output += PS3.getAnalogHat(LeftHatY); - if (!PS3.PS3NavigationConnected) { + if (PS3.PS3Connected) { // The Navigation controller only have one joystick output += "\tRightHatX: "; output += PS3.getAnalogHat(RightHatX); output += "\tRightHatY: "; diff --git a/examples/PS3USB/PS3USB.ino b/examples/PS3USB/PS3USB.ino index 50a020c0..b3e6e2c4 100644 --- a/examples/PS3USB/PS3USB.ino +++ b/examples/PS3USB/PS3USB.ino @@ -32,7 +32,7 @@ void loop() { Serial.print(PS3.getAnalogHat(LeftHatX)); Serial.print(F("\tLeftHatY: ")); Serial.print(PS3.getAnalogHat(LeftHatY)); - if (!PS3.PS3NavigationConnected) { + if (PS3.PS3Connected) { // The Navigation controller only have one joystick Serial.print(F("\tRightHatX: ")); Serial.print(PS3.getAnalogHat(RightHatX)); Serial.print(F("\tRightHatY: ")); From a340b811006ac144f0e08817c75193bab0f22b79 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 24 Nov 2013 15:17:19 +0100 Subject: [PATCH 23/53] Commented out hub instance by default --- examples/Bluetooth/PS3BT/PS3BT.ino | 3 ++- examples/Bluetooth/PS3Multi/PS3Multi.ino | 3 ++- examples/Bluetooth/PS3SPP/PS3SPP.ino | 3 ++- examples/Bluetooth/SPP/SPP.ino | 3 ++- examples/Bluetooth/SPPMulti/SPPMulti.ino | 3 ++- examples/Bluetooth/Wii/Wii.ino | 3 ++- examples/Bluetooth/WiiIRCamera/WiiIRCamera.ino | 3 ++- examples/Bluetooth/WiiMulti/WiiMulti.ino | 3 ++- examples/Bluetooth/WiiUProController/WiiUProController.ino | 3 ++- 9 files changed, 18 insertions(+), 9 deletions(-) diff --git a/examples/Bluetooth/PS3BT/PS3BT.ino b/examples/Bluetooth/PS3BT/PS3BT.ino index c63fbdcd..f8b13ad7 100644 --- a/examples/Bluetooth/PS3BT/PS3BT.ino +++ b/examples/Bluetooth/PS3BT/PS3BT.ino @@ -8,7 +8,8 @@ #include USB Usb; -USBHub Hub1(&Usb); // Some dongles have a hub inside +//USBHub Hub1(&Usb); // Some dongles have a hub inside + BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so /* You can create the instance of the class in two ways */ PS3BT PS3(&Btd); // This will just create the instance diff --git a/examples/Bluetooth/PS3Multi/PS3Multi.ino b/examples/Bluetooth/PS3Multi/PS3Multi.ino index dcb0b8e7..d7ec631c 100644 --- a/examples/Bluetooth/PS3Multi/PS3Multi.ino +++ b/examples/Bluetooth/PS3Multi/PS3Multi.ino @@ -9,7 +9,8 @@ #include USB Usb; -USBHub Hub1(&Usb); // Some dongles have a hub inside +//USBHub Hub1(&Usb); // Some dongles have a hub inside + 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! const uint8_t length = sizeof(PS3) / sizeof(PS3[0]); // Get the lenght of the array diff --git a/examples/Bluetooth/PS3SPP/PS3SPP.ino b/examples/Bluetooth/PS3SPP/PS3SPP.ino index edebdc61..214ce26a 100644 --- a/examples/Bluetooth/PS3SPP/PS3SPP.ino +++ b/examples/Bluetooth/PS3SPP/PS3SPP.ino @@ -14,7 +14,8 @@ #include USB Usb; -USBHub Hub1(&Usb); // Some dongles have a hub inside +//USBHub Hub1(&Usb); // Some dongles have a hub inside + BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so /* You can create the instances of the bluetooth services in two ways */ diff --git a/examples/Bluetooth/SPP/SPP.ino b/examples/Bluetooth/SPP/SPP.ino index 8ac79a45..e5b92089 100644 --- a/examples/Bluetooth/SPP/SPP.ino +++ b/examples/Bluetooth/SPP/SPP.ino @@ -8,7 +8,8 @@ #include USB Usb; -USBHub Hub1(&Usb); // Some dongles have a hub inside +//USBHub Hub1(&Usb); // Some dongles have a hub inside + BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so /* You can create the instance of the class in two ways */ SPP SerialBT(&Btd); // This will set the name to the defaults: "Arduino" and the pin to "1234" diff --git a/examples/Bluetooth/SPPMulti/SPPMulti.ino b/examples/Bluetooth/SPPMulti/SPPMulti.ino index c846b1a1..af32fd85 100644 --- a/examples/Bluetooth/SPPMulti/SPPMulti.ino +++ b/examples/Bluetooth/SPPMulti/SPPMulti.ino @@ -8,7 +8,8 @@ #include USB Usb; -USBHub Hub1(&Usb); // Some dongles have a hub inside +//USBHub Hub1(&Usb); // Some dongles have a hub inside + BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so SPP *SerialBT[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(SerialBT) / sizeof(SerialBT[0]); // Get the lenght of the array diff --git a/examples/Bluetooth/Wii/Wii.ino b/examples/Bluetooth/Wii/Wii.ino index d56b4252..214625c5 100644 --- a/examples/Bluetooth/Wii/Wii.ino +++ b/examples/Bluetooth/Wii/Wii.ino @@ -8,7 +8,8 @@ #include USB Usb; -USBHub Hub1(&Usb); // Some dongles have a hub inside +//USBHub Hub1(&Usb); // Some dongles have a hub inside + BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so /* You can create the instance of the class in two ways */ WII Wii(&Btd, PAIR); // This will start an inquiry and then pair with your Wiimote - you only have to do this once diff --git a/examples/Bluetooth/WiiIRCamera/WiiIRCamera.ino b/examples/Bluetooth/WiiIRCamera/WiiIRCamera.ino index ba701661..5d0fa91b 100644 --- a/examples/Bluetooth/WiiIRCamera/WiiIRCamera.ino +++ b/examples/Bluetooth/WiiIRCamera/WiiIRCamera.ino @@ -19,7 +19,8 @@ Otherwise, wire up a IR LED yourself. #endif USB Usb; -USBHub Hub1(&Usb); // Some dongles have a hub inside +//USBHub Hub1(&Usb); // Some dongles have a hub inside + BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so /* You can create the instance of the class in two ways */ WII Wii(&Btd, PAIR); // This will start an inquiry and then pair with your Wiimote - you only have to do this once diff --git a/examples/Bluetooth/WiiMulti/WiiMulti.ino b/examples/Bluetooth/WiiMulti/WiiMulti.ino index 3036b908..51c9160b 100644 --- a/examples/Bluetooth/WiiMulti/WiiMulti.ino +++ b/examples/Bluetooth/WiiMulti/WiiMulti.ino @@ -9,7 +9,8 @@ #include USB Usb; -USBHub Hub1(&Usb); // Some dongles have a hub inside +//USBHub Hub1(&Usb); // Some dongles have a hub inside + 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! const uint8_t length = sizeof(Wii) / sizeof(Wii[0]); // Get the lenght of the array diff --git a/examples/Bluetooth/WiiUProController/WiiUProController.ino b/examples/Bluetooth/WiiUProController/WiiUProController.ino index 582eeae3..eb686879 100644 --- a/examples/Bluetooth/WiiUProController/WiiUProController.ino +++ b/examples/Bluetooth/WiiUProController/WiiUProController.ino @@ -8,7 +8,8 @@ #include USB Usb; -USBHub Hub1(&Usb); // Some dongles have a hub inside +//USBHub Hub1(&Usb); // Some dongles have a hub inside + BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so /* You can create the instance of the class in two ways */ WII Wii(&Btd, PAIR); // This will start an inquiry and then pair with your Wiimote - you only have to do this once From c58f93dd8397a36552fde99781c22e8aeeeb2121 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 24 Nov 2013 15:23:41 +0100 Subject: [PATCH 24/53] Check if Bluetooth address is set before returning true to a PS3 controller --- BTD.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/BTD.h b/BTD.h index a2e3d62d..4bfed08a 100755 --- a/BTD.h +++ b/BTD.h @@ -219,7 +219,13 @@ public: * @return Returns true if the device's VID and PID matches this driver. */ virtual boolean VIDPIDOK(uint16_t vid, uint16_t pid) { - return ((vid == PS3_VID || vid == IOGEAR_GBU521_VID) && (pid == PS3_PID || pid == PS3NAVIGATION_PID || pid == PS3MOVE_PID || pid == IOGEAR_GBU521_PID)); + if (vid == IOGEAR_GBU521_VID && pid == IOGEAR_GBU521_PID) + return true; + 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) { // Check if Bluetooth address is set + if (vid == PS3_VID && (pid == PS3_PID || pid == PS3NAVIGATION_PID || pid == PS3MOVE_PID)) + return true; + } + return false; }; /**@}*/ From bcc51279d9995be0ee230e3dbfebe4bf691da32c Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 24 Nov 2013 15:31:12 +0100 Subject: [PATCH 25/53] Added function, so one can connect to any Bluetooth device by setting the Bluetooth address as an argument --- BTD.cpp | 16 ++++++++++------ BTD.h | 7 ++++++- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/BTD.cpp b/BTD.cpp index 95c2cf81..0b5715c2 100755 --- a/BTD.cpp +++ b/BTD.cpp @@ -969,16 +969,20 @@ void BTD::hci_inquiry_cancel() { } void BTD::hci_connect() { + hci_connect(disc_bdaddr); // Use last discovered device +} + +void BTD::hci_connect(uint8_t *bdaddr) { hci_event_flag &= ~(HCI_FLAG_CONN_COMPLETE | HCI_FLAG_CONNECT_EVENT); hcibuf[0] = 0x05; hcibuf[1] = 0x01 << 2; // HCI OGF = 1 hcibuf[2] = 0x0D; // parameter Total Length = 13 - hcibuf[3] = disc_bdaddr[0]; // 6 octet bdaddr - hcibuf[4] = disc_bdaddr[1]; - hcibuf[5] = disc_bdaddr[2]; - hcibuf[6] = disc_bdaddr[3]; - hcibuf[7] = disc_bdaddr[4]; - hcibuf[8] = disc_bdaddr[5]; + hcibuf[3] = bdaddr[0]; // 6 octet bdaddr (LSB) + hcibuf[4] = bdaddr[1]; + hcibuf[5] = bdaddr[2]; + hcibuf[6] = bdaddr[3]; + hcibuf[7] = bdaddr[4]; + hcibuf[8] = bdaddr[5]; hcibuf[9] = 0x18; // DM1 or DH1 may be used hcibuf[10] = 0xCC; // DM3, DH3, DM5, DH5 may be used hcibuf[11] = 0x01; // Page repetition mode R1 diff --git a/BTD.h b/BTD.h index 4bfed08a..efaf8376 100755 --- a/BTD.h +++ b/BTD.h @@ -313,8 +313,13 @@ public: void hci_inquiry(); /** Cancel a HCI inquiry. */ void hci_inquiry_cancel(); - /** Connect to a device. */ + /** Connect to last device communicated with. */ void hci_connect(); + /** + * Connect to device. + * @param bdaddr Bluetooth address of the device. + */ + void hci_connect(uint8_t *bdaddr); /** Used to a set the class of the device. */ void hci_write_class_of_device(); /**@}*/ From 191cdf9e2c3a8293e5a47f1f83fc432b702dc70f Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 24 Nov 2013 16:03:28 +0100 Subject: [PATCH 26/53] Updated testusbhostFAT example and submodules --- .../testusbhostFAT/Arduino_Makefile_master | 2 +- examples/testusbhostFAT/RTClib | 2 +- examples/testusbhostFAT/generic_storage | 2 +- examples/testusbhostFAT/testusbhostFAT.ino | 176 ++++++++++++++---- examples/testusbhostFAT/xmem2 | 2 +- 5 files changed, 148 insertions(+), 36 deletions(-) diff --git a/examples/testusbhostFAT/Arduino_Makefile_master b/examples/testusbhostFAT/Arduino_Makefile_master index 7f1fe2f8..139b9c8b 160000 --- a/examples/testusbhostFAT/Arduino_Makefile_master +++ b/examples/testusbhostFAT/Arduino_Makefile_master @@ -1 +1 @@ -Subproject commit 7f1fe2f8ec3db4d1bd0a5c516dd379e2539d1303 +Subproject commit 139b9c8be59a62e8fb1e8f983ac9bac2b9b9d582 diff --git a/examples/testusbhostFAT/RTClib b/examples/testusbhostFAT/RTClib index cb8b5690..a4bd6f50 160000 --- a/examples/testusbhostFAT/RTClib +++ b/examples/testusbhostFAT/RTClib @@ -1 +1 @@ -Subproject commit cb8b5690c7d683e0c24e6894ff05552f83240714 +Subproject commit a4bd6f500f70599847de60973371ee973d094a34 diff --git a/examples/testusbhostFAT/generic_storage b/examples/testusbhostFAT/generic_storage index db5de2fe..1d481775 160000 --- a/examples/testusbhostFAT/generic_storage +++ b/examples/testusbhostFAT/generic_storage @@ -1 +1 @@ -Subproject commit db5de2fe3c2e0d2d96de98864b1b6e00e172f727 +Subproject commit 1d481775b5096a172edf607062278a86e9618a15 diff --git a/examples/testusbhostFAT/testusbhostFAT.ino b/examples/testusbhostFAT/testusbhostFAT.ino index c462fa92..49713d36 100644 --- a/examples/testusbhostFAT/testusbhostFAT.ino +++ b/examples/testusbhostFAT/testusbhostFAT.ino @@ -47,8 +47,11 @@ ///////////////////////////////////////////////////////////// // End of Arduino IDE specific hacks // ///////////////////////////////////////////////////////////// - +#if defined(AVR) #include +#else +#include +#endif #if WANT_HUB_TEST #include #endif @@ -59,22 +62,23 @@ #include #include #include - +#include +#if defined(AVR) static FILE tty_stdio; static FILE tty_stderr; -USB Usb; - -#define LED 13 // the pin that the LED is attached to - +volatile uint32_t LEDnext_time; // fade timeout +volatile uint32_t HEAPnext_time; // when to print out next heap report volatile int brightness = 0; // how bright the LED is volatile int fadeAmount = 80; // how many points to fade the LED by +#endif + +USB Usb; + volatile uint8_t current_state = 1; -volatile uint32_t LEDnext_time; // fade timeout volatile uint8_t last_state = 0; volatile boolean fatready = false; volatile boolean partsready = false; volatile boolean notified = false; -volatile uint32_t HEAPnext_time; // when to print out next heap report volatile boolean runtest = false; volatile boolean usbon = false; volatile uint32_t usbon_time; @@ -96,6 +100,7 @@ static storage_t sto[_VOLUMES]; #define mbxs 128 static uint8_t My_Buff_x[mbxs]; /* File read buffer */ +#if defined(AVR) #define prescale1 ((1 << WGM12) | (1 << CS10)) #define prescale8 ((1 << WGM12) | (1 << CS11)) @@ -110,6 +115,11 @@ static int tty_stderr_putc(char c, FILE *t) { return 0; } +static int tty_stderr_flush(FILE *t) { + USB_HOST_SERIAL.flush(); + return 0; +} + static int tty_std_putc(char c, FILE *t) { Serial.write(c); return 0; @@ -120,6 +130,49 @@ static int tty_std_getc(FILE *t) { return Serial.read(); } +static int tty_std_flush(FILE *t) { + Serial.flush(); + return 0; +} + +#else +extern "C" { + + int _write(int fd, const char *ptr, int len) { + int j; + for (j = 0; j < len; j++) { + if (fd == 1) + Serial.write(*ptr++); + else if (fd == 2) + USB_HOST_SERIAL.write(*ptr++); + } + return len; + } + + int _read(int fd, char *ptr, int len) { + if (len > 0 && fd == 0) { + while (!Serial.available()); + *ptr = Serial.read(); + return 1; + } + return 0; + } + +#include + + int _fstat(int fd, struct stat *st) { + memset(st, 0, sizeof (*st)); + st->st_mode = S_IFCHR; + st->st_blksize = 1024; + return 0; + } + + int _isatty(int fd) { + return (fd < 3) ? 1 : 0; + } +} +#endif + void setup() { boolean serr = false; for (int i = 0; i < _VOLUMES; i++) { @@ -130,8 +183,10 @@ void setup() { // Set this to higher values to enable more debug information // minimum 0x00, maximum 0xff UsbDEBUGlvl = 0x51; + +#if defined(AVR) // make LED pin as an output: - pinMode(LED, OUTPUT); + pinMode(LED_BUILTIN, OUTPUT); pinMode(2, OUTPUT); // Ensure TX is off _SFR_BYTE(UCSR0B) &= ~_BV(TXEN0); @@ -148,21 +203,26 @@ void setup() { tty_stdio.get = tty_std_getc; tty_stdio.flags = _FDEV_SETUP_RW; tty_stdio.udata = 0; - stdout = &tty_stdio; - stdin = &tty_stdio; tty_stderr.put = tty_stderr_putc; tty_stderr.get = NULL; tty_stderr.flags = _FDEV_SETUP_WRITE; tty_stderr.udata = 0; + + stdout = &tty_stdio; + stdin = &tty_stdio; stderr = &tty_stderr; // Blink LED delay(500); - analogWrite(LED, 255); + analogWrite(LED_BUILTIN, 255); delay(500); - analogWrite(LED, 0); + analogWrite(LED_BUILTIN, 0); delay(500); +#else + while (!Serial); +#endif + printf_P(PSTR("\r\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nStart\r\n")); printf_P(PSTR("Current UsbDEBUGlvl %02x\r\n"), UsbDEBUGlvl); printf_P(PSTR("'+' and '-' increase/decrease by 0x01\r\n")); @@ -187,17 +247,19 @@ void setup() { #endif "\r\n")); } - analogWrite(LED, 255); +#if defined(AVR) + + analogWrite(LED_BUILTIN, 255); delay(500); - analogWrite(LED, 0); + analogWrite(LED_BUILTIN, 0); delay(500); - analogWrite(LED, 255); + analogWrite(LED_BUILTIN, 255); delay(500); - analogWrite(LED, 0); + analogWrite(LED_BUILTIN, 0); delay(500); - analogWrite(LED, 255); + analogWrite(LED_BUILTIN, 255); delay(500); - analogWrite(LED, 0); + analogWrite(LED_BUILTIN, 0); delay(500); LEDnext_time = millis() + 1; @@ -206,6 +268,7 @@ void setup() { #endif printf_P(PSTR("Available heap: %u Bytes\r\n"), freeHeap()); printf_P(PSTR("SP %x\r\n"), (uint8_t *)(SP)); +#endif // Even though I'm not going to actually be deleting, // I want to be able to have slightly more control. @@ -213,7 +276,9 @@ void setup() { #if WANT_HUB_TEST for (int i = 0; i < MAX_HUBS; i++) { Hubs[i] = new USBHub(&Usb); +#if defined(AVR) printf_P(PSTR("Available heap: %u Bytes\r\n"), freeHeap()); +#endif } #endif // Initialize generic storage. This must be done before USB starts. @@ -223,10 +288,8 @@ void setup() { printf_P(PSTR("No USB HOST Shield?\r\n")); Notify(PSTR("OSC did not start."), 0x40); } - // usb VBUS _OFF_ - //Usb.gpioWr(0x00); - //digitalWrite(2, 0); - //usbon_time = millis() + 2000; + +#if defined(AVR) cli(); TCCR3A = 0; TCCR3B = 0; @@ -237,6 +300,32 @@ void setup() { sei(); HEAPnext_time = millis() + 10000; +#else +#if 0 + // + // On the teensy 3 we can raise the speed of SPI here. + // + // Default seen is 0xB8011001. + // + + uint32_t ctar = SPI0_CTAR0; + //printf("SPI_CTAR0 = %8.8X\r\n", ctar); + ctar &= 0x7FFCFFF0; // 1/4 fSYS, 12.5Mhz + //printf("SPI_CTAR0 = %8.8X\r\n", ctar); + ctar |= 0x80000000; // 1/2 fSYS 25Mhz + //printf("SPI_CTAR0 = %8.8X\r\n", ctar); + + uint32_t mcr = SPI0_MCR; + if (mcr & SPI_MCR_MDIS) { + SPI0_CTAR0 = ctar; + } else { + SPI0_MCR = mcr | SPI_MCR_MDIS | SPI_MCR_HALT; + SPI0_CTAR0 = ctar; + SPI0_MCR = mcr; + } +#endif +#endif + } void serialEvent() { @@ -278,12 +367,14 @@ void serialEvent() { } } +#if defined(AVR) + ISR(TIMER3_COMPA_vect) { if (millis() >= LEDnext_time) { LEDnext_time = millis() + 30; // set the brightness of LED - analogWrite(LED, brightness); + analogWrite(LED_BUILTIN, brightness); // change the brightness for next time through the loop: brightness = brightness + fadeAmount; @@ -299,6 +390,7 @@ ISR(TIMER3_COMPA_vect) { } } } +#endif bool isfat(uint8_t t) { return (t == 0x01 || t == 0x04 || t == 0x06 || t == 0x0b || t == 0x0c || t == 0x0e || t == 0x1); @@ -312,6 +404,7 @@ void die(FRESULT rc) { void loop() { FIL My_File_Object_x; /* File object */ +#if defined(AVR) // Print a heap status report about every 10 seconds. if (millis() >= HEAPnext_time) { if (UsbDEBUGlvl > 0x50) { @@ -319,7 +412,11 @@ void loop() { } HEAPnext_time = millis() + 10000; } - + TCCR3B = 0; +#else + // Arm suffers here, oh well... + serialEvent(); +#endif // Horrid! This sort of thing really belongs in an ISR, not here! // We also will be needing to test each hub port, we don't do this yet! if (!change && !usbon && millis() >= usbon_time) { @@ -342,11 +439,15 @@ void loop() { if (current_state != last_state) { if (UsbDEBUGlvl > 0x50) printf_P(PSTR("USB state = %x\r\n"), current_state); +#if defined(AVR) if (current_state == USB_STATE_RUNNING) { fadeAmount = 30; } +#endif if (current_state == USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE) { +#if defined(AVR) fadeAmount = 80; +#endif partsready = false; for (int i = 0; i < cpart; i++) { if (Fats[i] != NULL) @@ -365,10 +466,10 @@ void loop() { if (partsready && !fatready) { if (cpart > 0) fatready = true; } - // This is horrible, and needs to be moved elsewhere! for (int B = 0; B < MAX_USB_MS_DRIVERS; B++) { - if (!partsready && Bulk[B]->GetAddress() != NULL) { + if (!partsready && (Bulk[B]->GetAddress() != NULL)) { + // Build a list. int ML = Bulk[B]->GetbMaxLUN(); //printf("MAXLUN = %i\r\n", ML); @@ -376,8 +477,8 @@ void loop() { for (int i = 0; i < ML; i++) { if (Bulk[B]->LUNIsGood(i)) { partsready = true; - ((pvt_t *)sto[i].private_data)->lun = i; - ((pvt_t *)sto[i].private_data)->B = B; + ((pvt_t *)(sto[i].private_data))->lun = i; + ((pvt_t *)(sto[i].private_data))->B = B; sto[i].Read = *PRead; sto[i].Write = *PWrite; sto[i].Reads = *PReads; @@ -440,7 +541,9 @@ void loop() { p = ((struct Pvt *)(Fats[0]->storage->private_data)); if (!Bulk[p->B]->LUNIsGood(p->lun)) { // media change +#if defined(AVR) fadeAmount = 80; +#endif partsready = false; for (int i = 0; i < cpart; i++) { if (Fats[i] != NULL) @@ -459,11 +562,13 @@ void loop() { UINT bw, br, i; if (!notified) { +#if defined(AVR) fadeAmount = 5; +#endif notified = true; printf_P(PSTR("\r\nOpen an existing file (message.txt).\r\n")); rc = f_open(&My_File_Object_x, "0:/MESSAGE.TXT", FA_READ); - if (rc) printf_P(PSTR("Error %i, message.txt not found.\r\n")); + if (rc) printf_P(PSTR("Error %i, message.txt not found.\r\n"), rc); else { printf_P(PSTR("\r\nType the file content.\r\n")); for (;;) { @@ -522,7 +627,9 @@ outdir: } printf_P(PSTR("\r\nDirectory listing...\r\n")); +#if defined(AVR) printf_P(PSTR("Available heap: %u Bytes\r\n"), freeHeap()); +#endif for (;;) { #if _USE_LFN My_File_Info_Object_x.lfsize = _MAX_LFN; @@ -583,7 +690,9 @@ out: rc = f_open(&My_File_Object_x, "0:/10MB.bin", FA_WRITE | FA_CREATE_ALWAYS); if (rc) goto failed; for (bw = 0; bw < mbxs; bw++) My_Buff_x[bw] = bw & 0xff; + fflush(stdout); start = millis(); + while (start == millis()); for (ii = 10485760LU / mbxs; ii > 0LU; ii--) { rc = f_write(&My_File_Object_x, My_Buff_x, mbxs, &bw); if (rc || !bw) goto failed; @@ -591,10 +700,12 @@ out: rc = f_close(&My_File_Object_x); if (rc) goto failed; end = millis(); - wt = end - start; + wt = (end - start) - 1; printf_P(PSTR("Time to write 10485760 bytes: %lu ms (%lu sec) \r\n"), wt, (500 + wt) / 1000UL); rc = f_open(&My_File_Object_x, "0:/10MB.bin", FA_READ); + fflush(stdout); start = millis(); + while (start == millis()); if (rc) goto failed; for (;;) { rc = f_read(&My_File_Object_x, My_Buff_x, mbxs, &bw); /* Read a chunk of file */ @@ -604,7 +715,7 @@ out: if (rc) goto failed; rc = f_close(&My_File_Object_x); if (rc) goto failed; - rt = end - start; + rt = (end - start) - 1; printf_P(PSTR("Time to read 10485760 bytes: %lu ms (%lu sec)\r\nDelete test file\r\n"), rt, (500 + rt) / 1000UL); failed: if (rc) die(rc); @@ -613,3 +724,4 @@ failed: } } } + diff --git a/examples/testusbhostFAT/xmem2 b/examples/testusbhostFAT/xmem2 index 16374f68..9fe733d3 160000 --- a/examples/testusbhostFAT/xmem2 +++ b/examples/testusbhostFAT/xmem2 @@ -1 +1 @@ -Subproject commit 16374f681b31d411661b7bd9ff5e578b2dff6843 +Subproject commit 9fe733d35304dec1ebe750f5f13f868def2fcfe4 From 0e0b48b3c8d811a8e618d7dddcf6c7e896efdcdb Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 24 Nov 2013 16:03:52 +0100 Subject: [PATCH 27/53] Use the submodules in the makefile --- examples/testusbhostFAT/Makefile | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/testusbhostFAT/Makefile b/examples/testusbhostFAT/Makefile index 191238a0..7e5ebaec 100644 --- a/examples/testusbhostFAT/Makefile +++ b/examples/testusbhostFAT/Makefile @@ -43,12 +43,12 @@ EXTRA_FLAGS += -D USB_HOST_SERIAL=Serial3 #EXTRA_FLAGS += -D DEBUG_USB_HOST # The following are the libraries used. -LIB_DIRS = -LIB_DIRS += ../libraries/xmem -LIB_DIRS += ../libraries/USB_Host_Shield_2_0 -LIB_DIRS += ../libraries/generic_storage -LIB_DIRS += ../libraries/RTClib +LIB_DIRS += ../../ +LIB_DIRS += ../testusbhostFAT/xmem2 +LIB_DIRS += ../testusbhostFAT/generic_storage +LIB_DIRS += ../testusbhostFAT/RTClib LIB_DIRS += $(ARD_HOME)/libraries/Wire LIB_DIRS += $(ARD_HOME)/libraries/Wire/utility + # And finally, the part that brings everything together for you. -include ../Arduino_Makefile_master/_Makefile.master +include Arduino_Makefile_master/_Makefile.master From 31951e85ff33fec64baf07514dbe66e27eb40aa0 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 24 Nov 2013 16:54:42 +0100 Subject: [PATCH 28/53] Decreased delay between commands --- PS3BT.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PS3BT.cpp b/PS3BT.cpp index 976b21b5..9ed5da75 100644 --- a/PS3BT.cpp +++ b/PS3BT.cpp @@ -535,8 +535,8 @@ void PS3BT::Run() { // Playstation Sixaxis Dualshock and Navigation Controller commands void PS3BT::HID_Command(uint8_t* data, uint8_t nbytes) { - 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 + if (millis() - timerHID <= 150) // Check if is has been more than 150ms since last command + delay((uint32_t)(150 - (millis() - timerHID))); // There have to be a delay between commands pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]); // Both the Navigation and Dualshock controller sends data via the control channel timerHID = millis(); } @@ -613,8 +613,8 @@ void PS3BT::enable_sixaxis() { // Command used to enable the Dualshock 3 and Nav // Playstation Move Controller commands void PS3BT::HIDMove_Command(uint8_t* data, uint8_t nbytes) { - 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 + if (millis() - timerHID <= 150)// Check if is has been less than 150ms since last command + delay((uint32_t)(150 - (millis() - timerHID))); // There have to be a delay between commands pBtd->L2CAP_Command(hci_handle, data, nbytes, interrupt_scid[0], interrupt_scid[1]); // The Move controller sends it's data via the intterrupt channel timerHID = millis(); } From 4512f0ee0c15e78bea8e898773f632ef33520ccc Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 24 Nov 2013 16:55:03 +0100 Subject: [PATCH 29/53] Whitespace --- XBOXOLD.cpp | 6 +++--- XBOXUSB.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/XBOXOLD.cpp b/XBOXOLD.cpp index b08f857b..31d2fb6e 100644 --- a/XBOXOLD.cpp +++ b/XBOXOLD.cpp @@ -42,7 +42,7 @@ const uint8_t XBOXOLDBUTTONS[] PROGMEM = { 0, // A 2, // X 3, // Y -}; +}; XBOXOLD::XBOXOLD(USB *p) : pUsb(p), // pointer to USB class instance - mandatory @@ -118,7 +118,7 @@ uint8_t XBOXOLD::Init(uint8_t parent, uint8_t port, bool lowspeed) { if ((VID != XBOX_VID && VID != MADCATZ_VID && VID != JOYTECH_VID) || (PID != XBOX_OLD_PID1 && PID != XBOX_OLD_PID2 && PID != XBOX_OLD_PID3 && PID != XBOX_OLD_PID4)) // Check if VID and PID match goto FailUnknownDevice; - + // Allocate new address according to device class bAddress = addrPool.AllocAddress(parent, false, port); @@ -145,7 +145,7 @@ uint8_t XBOXOLD::Init(uint8_t parent, uint8_t port, bool lowspeed) { D_PrintHex (bAddress, 0x80); #endif delay(300); // Spec says you should wait at least 200ms - + p->lowspeed = false; //get pointer to assigned address record diff --git a/XBOXUSB.cpp b/XBOXUSB.cpp index 4b635f43..1e460347 100644 --- a/XBOXUSB.cpp +++ b/XBOXUSB.cpp @@ -133,7 +133,7 @@ uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) { D_PrintHex (bAddress, 0x80); #endif delay(300); // Spec says you should wait at least 200ms - + p->lowspeed = false; //get pointer to assigned address record From f783b97cb923baab4903e7856f4f3f2c5503d652 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 24 Nov 2013 21:55:15 +0100 Subject: [PATCH 30/53] Initial commit for BTHID library To see incoming data uncomment PRINTREPORT in BTHID.cpp --- BTD.cpp | 142 +++++++--- BTD.h | 56 ++-- BTHID.cpp | 410 +++++++++++++++++++++++++++++ BTHID.h | 162 ++++++++++++ Wii.h | 2 - controllerEnums.h | 2 + examples/Bluetooth/BTHID/BTHID.ino | 37 +++ keywords.txt | 1 + 8 files changed, 749 insertions(+), 63 deletions(-) create mode 100644 BTHID.cpp create mode 100644 BTHID.h create mode 100644 examples/Bluetooth/BTHID/BTHID.ino diff --git a/BTD.cpp b/BTD.cpp index 0b5715c2..ab858d46 100755 --- a/BTD.cpp +++ b/BTD.cpp @@ -27,6 +27,8 @@ const uint8_t BTD::BTD_DATAOUT_PIPE = 3; BTD::BTD(USB *p) : connectToWii(false), pairWithWii(false), +connectToHIDDevice(false), +pairWithHIDDevice(false), pUsb(p), // Pointer to USB class instance - mandatory bAddress(0), // Device address - mandatory bNumEP(1), // If config descriptor needs to be parsed @@ -303,6 +305,8 @@ void BTD::clearAllVariables() { connectToWii = false; incomingWii = false; + connectToHIDDevice = false; + incomingHIDDevice = false; bAddress = 0; // Clear device address bNumEP = 1; // Must have to be reset to 1 qNextPollTime = 0; // Reset next poll time @@ -411,13 +415,18 @@ void BTD::HCI_event_task() { break; case EV_INQUIRY_COMPLETE: - if (inquiry_counter >= 5 && pairWithWii) { + if (inquiry_counter >= 5 && (pairWithWii || pairWithHIDDevice)) { inquiry_counter = 0; #ifdef DEBUG_USB_HOST - Notify(PSTR("\r\nCouldn't find Wiimote"), 0x80); + if (pairWithWii) + Notify(PSTR("\r\nCouldn't find Wiimote"), 0x80); + else + Notify(PSTR("\r\nCouldn't find HID device"), 0x80); #endif connectToWii = false; pairWithWii = false; + connectToHIDDevice = false; + pairWithHIDDevice = false; hci_state = HCI_SCANNING_STATE; } inquiry_counter++; @@ -430,28 +439,44 @@ void BTD::HCI_event_task() { Notify(hcibuf[2], 0x80); #endif for (uint8_t i = 0; i < hcibuf[2]; i++) { - if ((hcibuf[4 + 8 * hcibuf[2] + 3 * i] == 0x04 && hcibuf[5 + 8 * hcibuf[2] + 3 * i] == 0x25 && hcibuf[6 + 8 * hcibuf[2] + 3 * i] == 0x00) || (hcibuf[4 + 8 * hcibuf[2] + 3 * i] == 0x08 && hcibuf[5 + 8 * hcibuf[2] + 3 * i] == 0x05 && hcibuf[6 + 8 * hcibuf[2] + 3 * i] == 0x00)) { // See http://bluetooth-pentest.narod.ru/software/bluetooth_class_of_device-service_generator.html and http://wiibrew.org/wiki/Wiimote#SDP_information - if (hcibuf[4 + 8 * hcibuf[2] + 3 * i] == 0x08) // Check if it's the new Wiimote with motion plus inside that was detected + uint8_t offset = 8 * hcibuf[2] + 3 * i; + uint8_t classOfDevice[3]; + + for (uint8_t j = 0; j < 3; j++) + classOfDevice[j] = hcibuf[j + 4 + offset]; + + if (pairWithWii && classOfDevice[2] == 0x00 && (classOfDevice[1] & 0x05) && (classOfDevice[0] & 0x0C)) { // See http://bluetooth-pentest.narod.ru/software/bluetooth_class_of_device-service_generator.html and http://wiibrew.org/wiki/Wiimote#SDP_information + if (classOfDevice[0] & 0x08) // Check if it's the new Wiimote with motion plus inside that was detected motionPlusInside = true; else motionPlusInside = false; - disc_bdaddr[0] = hcibuf[3 + 6 * i]; - disc_bdaddr[1] = hcibuf[4 + 6 * i]; - disc_bdaddr[2] = hcibuf[5 + 6 * i]; - disc_bdaddr[3] = hcibuf[6 + 6 * i]; - disc_bdaddr[4] = hcibuf[7 + 6 * i]; - disc_bdaddr[5] = hcibuf[8 + 6 * i]; - hci_event_flag |= HCI_FLAG_WII_FOUND; + + for (uint8_t j = 0; j < 6; j++) + disc_bdaddr[j] = hcibuf[j + 3 + 6 * i]; + + hci_event_flag |= HCI_FLAG_DEVICE_FOUND; break; + } else if (pairWithHIDDevice && (classOfDevice[1] & 0x05) && (classOfDevice[0] & 0xC0)) { // Check if it is a mouse or keyboard +#ifdef DEBUG_USB_HOST + if (classOfDevice[0] & 0x80) + Notify(PSTR("\r\nMouse found"), 0x80); + if (classOfDevice[0] & 0x40) + Notify(PSTR("\r\nKeyboard found"), 0x80); +#endif + + for (uint8_t j = 0; j < 6; j++) + disc_bdaddr[j] = hcibuf[j + 3 + 6 * i]; + + hci_event_flag |= HCI_FLAG_DEVICE_FOUND; } #ifdef EXTRADEBUG else { Notify(PSTR("\r\nClass of device: "), 0x80); - D_PrintHex (hcibuf[6 + 8 * hcibuf[2] + 3 * i], 0x80); + D_PrintHex (classOfDevice[2], 0x80); Notify(PSTR(" "), 0x80); - D_PrintHex (hcibuf[5 + 8 * hcibuf[2] + 3 * i], 0x80); + D_PrintHex (classOfDevice[1], 0x80); Notify(PSTR(" "), 0x80); - D_PrintHex (hcibuf[4 + 8 * hcibuf[2] + 3 * i], 0x80); + D_PrintHex (classOfDevice[0], 0x80); } #endif } @@ -467,7 +492,7 @@ void BTD::HCI_event_task() { hci_handle = hcibuf[3] | ((hcibuf[4] & 0x0F) << 8); // store the handle for the ACL connection hci_event_flag |= HCI_FLAG_CONN_COMPLETE; // set connection complete flag } else { - hci_state = HCI_CHECK_WII_SERVICE; + hci_state = HCI_CHECK_DEVICE_SERVICE; #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nConnection Failed: "), 0x80); D_PrintHex (hcibuf[2], 0x80); @@ -491,12 +516,19 @@ void BTD::HCI_event_task() { break; case EV_INCOMING_CONNECT: - disc_bdaddr[0] = hcibuf[2]; - disc_bdaddr[1] = hcibuf[3]; - disc_bdaddr[2] = hcibuf[4]; - disc_bdaddr[3] = hcibuf[5]; - disc_bdaddr[4] = hcibuf[6]; - disc_bdaddr[5] = hcibuf[7]; + for (uint8_t i = 0; i < 6; i++) + disc_bdaddr[i] = hcibuf[i + 2]; + + if ((hcibuf[9] & 0x05) && (hcibuf[8] & 0xC0)) { // Check if it is a mouse or keyboard +#ifdef DEBUG_USB_HOST + if (hcibuf[8] & 0x80) + Notify(PSTR("\r\nMouse is connecting"), 0x80); + if (hcibuf[8] & 0x40) + Notify(PSTR("\r\nKeyboard is connecting"), 0x80); +#endif + incomingHIDDevice = true; + } + #ifdef EXTRADEBUG Notify(PSTR("\r\nClass of device: "), 0x80); D_PrintHex (hcibuf[10], 0x80); @@ -538,9 +570,14 @@ void BTD::HCI_event_task() { case EV_AUTHENTICATION_COMPLETE: if (pairWithWii && !connectToWii) { #ifdef DEBUG_USB_HOST - Notify(PSTR("\r\nPairing successful"), 0x80); + Notify(PSTR("\r\nPairing successful with Wiimote"), 0x80); #endif connectToWii = true; // Only send the ACL data to the Wii service + } else if (pairWithHIDDevice && !connectToHIDDevice) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nPairing successful with HID device"), 0x80); +#endif + connectToHIDDevice = true; // Only send the ACL data to the Wii service } break; /* We will just ignore the following events */ @@ -639,7 +676,7 @@ void BTD::HCI_task() { hci_set_local_name(btdName); hci_state = HCI_SET_NAME_STATE; } else - hci_state = HCI_CHECK_WII_SERVICE; + hci_state = HCI_CHECK_DEVICE_SERVICE; } break; @@ -649,14 +686,17 @@ void BTD::HCI_task() { Notify(PSTR("\r\nThe name is set to: "), 0x80); NotifyStr(btdName, 0x80); #endif - hci_state = HCI_CHECK_WII_SERVICE; + hci_state = HCI_CHECK_DEVICE_SERVICE; } break; - case HCI_CHECK_WII_SERVICE: - if (pairWithWii) { // Check if it should try to connect to a wiimote + case HCI_CHECK_DEVICE_SERVICE: + if (pairWithHIDDevice || pairWithWii) { // Check if it should try to connect to a wiimote #ifdef DEBUG_USB_HOST - Notify(PSTR("\r\nStarting inquiry\r\nPress 1 & 2 on the Wiimote\r\nOr press sync if you are using a Wii U Pro Controller"), 0x80); + if (pairWithWii) + Notify(PSTR("\r\nStarting inquiry\r\nPress 1 & 2 on the Wiimote\r\nOr press sync if you are using a Wii U Pro Controller"), 0x80); + else + Notify(PSTR("\r\nPlease enable discovery of your device"), 0x80); #endif hci_inquiry(); hci_state = HCI_INQUIRY_STATE; @@ -665,37 +705,55 @@ void BTD::HCI_task() { break; case HCI_INQUIRY_STATE: - if (hci_wii_found) { + if (hci_device_found) { hci_inquiry_cancel(); // Stop inquiry #ifdef DEBUG_USB_HOST - Notify(PSTR("\r\nWiimote found"), 0x80); + if (pairWithWii) + Notify(PSTR("\r\nWiimote found"), 0x80); + else + Notify(PSTR("\r\nHID device found"), 0x80); + Notify(PSTR("\r\nNow just create the instance like so:"), 0x80); - Notify(PSTR("\r\nWII Wii(&Btd);"), 0x80); - Notify(PSTR("\r\nAnd then press any button on the Wiimote"), 0x80); + if (pairWithWii) + Notify(PSTR("\r\nWII Wii(&Btd);"), 0x80); + else + Notify(PSTR("\r\nBTHID hid(&Btd);"), 0x80); + + Notify(PSTR("\r\nAnd then press any button on the "), 0x80); + if (pairWithWii) + Notify(PSTR("Wiimote"), 0x80); + else + Notify(PSTR("device"), 0x80); #endif if (motionPlusInside) { hci_remote_name(); // We need to know the name to distinguish between a Wiimote and a Wii U Pro Controller hci_state = HCI_REMOTE_NAME_STATE; } else - hci_state = HCI_CONNECT_WII_STATE; + hci_state = HCI_CONNECT_DEVICE_STATE; } break; - case HCI_CONNECT_WII_STATE: + case HCI_CONNECT_DEVICE_STATE: if (hci_cmd_complete) { #ifdef DEBUG_USB_HOST - Notify(PSTR("\r\nConnecting to Wiimote"), 0x80); + if (pairWithWii) + Notify(PSTR("\r\nConnecting to Wiimote"), 0x80); + else + Notify(PSTR("\r\nConnecting to HID device"), 0x80); #endif hci_connect(); - hci_state = HCI_CONNECTED_WII_STATE; + hci_state = HCI_CONNECTED_DEVICE_STATE; } break; - case HCI_CONNECTED_WII_STATE: + case HCI_CONNECTED_DEVICE_STATE: if (hci_connect_event) { if (hci_connect_complete) { #ifdef DEBUG_USB_HOST - Notify(PSTR("\r\nConnected to Wiimote"), 0x80); + if (pairWithWii) + Notify(PSTR("\r\nConnected to Wiimote"), 0x80); + else + Notify(PSTR("\r\nConnected to HID device"), 0x80); #endif hci_authentication_request(); // This will start the pairing with the wiimote hci_state = HCI_SCANNING_STATE; @@ -709,7 +767,7 @@ void BTD::HCI_task() { break; case HCI_SCANNING_STATE: - if (!connectToWii && !pairWithWii) { + if (!connectToWii && !pairWithWii && !connectToHIDDevice && !pairWithHIDDevice) { #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nWait For Incoming Connection Request"), 0x80); #endif @@ -763,7 +821,7 @@ void BTD::HCI_task() { } } if (pairWithWii && motionPlusInside) - hci_state = HCI_CONNECT_WII_STATE; + hci_state = HCI_CONNECT_DEVICE_STATE; else { hci_accept_connection(); hci_state = HCI_CONNECTED_STATE; @@ -816,6 +874,10 @@ void BTD::HCI_task() { incomingWii = false; pairWithWii = false; + connectToHIDDevice = false; + incomingHIDDevice = false; + pairWithHIDDevice = false; + hci_state = HCI_SCANNING_STATE; } break; @@ -947,7 +1009,7 @@ void BTD::hci_set_local_name(const char* name) { } void BTD::hci_inquiry() { - hci_event_flag &= ~HCI_FLAG_WII_FOUND; + hci_event_flag &= ~HCI_FLAG_DEVICE_FOUND; hcibuf[0] = 0x01; hcibuf[1] = 0x01 << 2; // HCI OGF = 1 hcibuf[2] = 0x05; // Parameter Total Length = 5 diff --git a/BTD.h b/BTD.h index efaf8376..c419a252 100755 --- a/BTD.h +++ b/BTD.h @@ -39,25 +39,25 @@ #define HID_REQUEST_SET_REPORT 0x09 /* Bluetooth HCI states for hci_task() */ -#define HCI_INIT_STATE 0 -#define HCI_RESET_STATE 1 -#define HCI_CLASS_STATE 2 -#define HCI_BDADDR_STATE 3 -#define HCI_LOCAL_VERSION_STATE 4 -#define HCI_SET_NAME_STATE 5 -#define HCI_CHECK_WII_SERVICE 6 +#define HCI_INIT_STATE 0 +#define HCI_RESET_STATE 1 +#define HCI_CLASS_STATE 2 +#define HCI_BDADDR_STATE 3 +#define HCI_LOCAL_VERSION_STATE 4 +#define HCI_SET_NAME_STATE 5 +#define HCI_CHECK_DEVICE_SERVICE 6 -#define HCI_INQUIRY_STATE 7 // These three states are only used if it should pair and connect to a Wii controller -#define HCI_CONNECT_WII_STATE 8 -#define HCI_CONNECTED_WII_STATE 9 +#define HCI_INQUIRY_STATE 7 // These three states are only used if it should pair and connect to a Wii controller +#define HCI_CONNECT_DEVICE_STATE 8 +#define HCI_CONNECTED_DEVICE_STATE 9 -#define HCI_SCANNING_STATE 10 -#define HCI_CONNECT_IN_STATE 11 -#define HCI_REMOTE_NAME_STATE 12 -#define HCI_CONNECTED_STATE 13 -#define HCI_DISABLE_SCAN_STATE 14 -#define HCI_DONE_STATE 15 -#define HCI_DISCONNECT_STATE 16 +#define HCI_SCANNING_STATE 10 +#define HCI_CONNECT_IN_STATE 11 +#define HCI_REMOTE_NAME_STATE 12 +#define HCI_CONNECTED_STATE 13 +#define HCI_DISABLE_SCAN_STATE 14 +#define HCI_DONE_STATE 15 +#define HCI_DISCONNECT_STATE 16 /* HCI event flags*/ #define HCI_FLAG_CMD_COMPLETE 0x01 @@ -67,7 +67,7 @@ #define HCI_FLAG_INCOMING_REQUEST 0x10 #define HCI_FLAG_READ_BDADDR 0x20 #define HCI_FLAG_READ_VERSION 0x40 -#define HCI_FLAG_WII_FOUND 0x80 +#define HCI_FLAG_DEVICE_FOUND 0x80 #define HCI_FLAG_CONNECT_EVENT 0x100 /*Macros for HCI event flag tests */ @@ -78,7 +78,7 @@ #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) -#define hci_wii_found (hci_event_flag & HCI_FLAG_WII_FOUND) +#define hci_device_found (hci_event_flag & HCI_FLAG_DEVICE_FOUND) #define hci_connect_event (hci_event_flag & HCI_FLAG_CONNECT_EVENT) /* HCI Events managed */ @@ -133,6 +133,8 @@ #define BTD_MAX_ENDPOINTS 4 #define BTD_NUMSERVICES 4 // Max number of Bluetooth services - if you need more than four simply increase this number +#define PAIR 1 + /** All Bluetooth services should include this class. */ class BluetoothService { public: @@ -422,19 +424,31 @@ public: /** Call this function to pair with a Wiimote */ void pairWithWiimote() { pairWithWii = true; - hci_state = HCI_CHECK_WII_SERVICE; + hci_state = HCI_CHECK_DEVICE_SERVICE; }; /** Used to only send the ACL data to the wiimote. */ bool connectToWii; /** True if a Wiimote is connecting. */ bool incomingWii; - /** True when it should pair with the incoming Wiimote. */ + /** True when it should pair with a Wiimote. */ bool pairWithWii; /** True if it's the new Wiimote with the Motion Plus Inside or a Wii U Pro Controller. */ bool motionPlusInside; /** True if it's a Wii U Pro Controller. */ bool wiiUProController; + /** Call this function to pair with a Wiimote */ + void pairWithHID() { + pairWithHIDDevice = true; + hci_state = HCI_CHECK_DEVICE_SERVICE; + }; + /** Used to only send the ACL data to the wiimote. */ + bool connectToHIDDevice; + /** True if a Wiimote is connecting. */ + bool incomingHIDDevice; + /** True when it should pair with a device like a mouse or keyboard. */ + bool pairWithHIDDevice; + /** * Read the poll interval taken from the endpoint descriptors. * @return The poll interval in ms. diff --git a/BTHID.cpp b/BTHID.cpp new file mode 100644 index 00000000..848cf12f --- /dev/null +++ b/BTHID.cpp @@ -0,0 +1,410 @@ +/* Copyright (C) 2013 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 "BTHID.h" +// To enable serial debugging see "settings.h" +//#define EXTRADEBUG // Uncomment to get even more debugging data +//#define PRINTREPORT // Uncomment to print the report send by the Wii controllers + +const uint8_t BUTTONS[] PROGMEM = { // Mouse buttons + 0x04, // MIDDLE + 0x02, // RIGHT + 0, // Skip + 0x01, // LEFT +}; + +BTHID::BTHID(BTD *p, bool pair, const char *pin) : +pBtd(p) // pointer to USB class instance - mandatory +{ + if (pBtd) + pBtd->registerServiceClass(this); // Register it as a Bluetooth service + + pBtd->pairWithHIDDevice = pair; + + if (pair) + pBtd->btdPin= pin; + + /* Set device cid for the control and intterrupt channelse - LSB */ + control_dcid[0] = 0x70; // 0x0070 + control_dcid[1] = 0x00; + interrupt_dcid[0] = 0x71; // 0x0071 + interrupt_dcid[1] = 0x00; + + Reset(); +} + +void BTHID::Reset() { + connected = false; + activeConnection = false; + l2cap_event_flag = 0; // Reset flags + l2cap_state = L2CAP_WAIT; +} + +void BTHID::disconnect() { // Use this void to disconnect any of the controllers + // First the HID interrupt channel has to be disconnected, then the HID control channel and finally the HCI connection + pBtd->l2cap_disconnection_request(hci_handle, 0x0A, interrupt_scid, interrupt_dcid); + Reset(); + l2cap_state = L2CAP_INTERRUPT_DISCONNECT; +} + +void BTHID::ACLData(uint8_t* l2capinbuf) { + if (!pBtd->l2capConnectionClaimed && pBtd->incomingHIDDevice && !connected && !activeConnection) { + if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) { + if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) { + pBtd->incomingHIDDevice = false; + pBtd->l2capConnectionClaimed = true; // Claim that the incoming connection belongs to this service + activeConnection = true; + hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection + l2cap_state = L2CAP_WAIT; + } + } + } + if ((l2capinbuf[0] | (l2capinbuf[1] << 8)) == (hci_handle | 0x2000)) { // acl_handle_ok or it's a new connection + if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) { //l2cap_control - Channel ID for ACL-U + if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80); + D_PrintHex (l2capinbuf[13], 0x80); + Notify(PSTR(" "), 0x80); + D_PrintHex (l2capinbuf[12], 0x80); + Notify(PSTR(" "), 0x80); + D_PrintHex (l2capinbuf[17], 0x80); + Notify(PSTR(" "), 0x80); + D_PrintHex (l2capinbuf[16], 0x80); + Notify(PSTR(" "), 0x80); + D_PrintHex (l2capinbuf[15], 0x80); + Notify(PSTR(" "), 0x80); + D_PrintHex (l2capinbuf[14], 0x80); +#endif + } else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_RESPONSE) { + if (((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) == SUCCESSFUL)) { // Success + if (l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) { // Success + //Notify(PSTR("\r\nHID Control Connection Complete"), 0x80); + identifier = l2capinbuf[9]; + control_scid[0] = l2capinbuf[12]; + control_scid[1] = l2capinbuf[13]; + l2cap_event_flag |= L2CAP_FLAG_CONTROL_CONNECTED; + } else if (l2capinbuf[14] == interrupt_dcid[0] && l2capinbuf[15] == interrupt_dcid[1]) { + //Notify(PSTR("\r\nHID Interrupt Connection Complete"), 0x80); + identifier = l2capinbuf[9]; + interrupt_scid[0] = l2capinbuf[12]; + interrupt_scid[1] = l2capinbuf[13]; + l2cap_event_flag |= L2CAP_FLAG_INTERRUPT_CONNECTED; + } + } + } else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) { +#ifdef EXTRADEBUG + Notify(PSTR("\r\nL2CAP Connection Request - PSM: "), 0x80); + D_PrintHex (l2capinbuf[13], 0x80); + Notify(PSTR(" "), 0x80); + D_PrintHex (l2capinbuf[12], 0x80); + Notify(PSTR(" SCID: "), 0x80); + D_PrintHex (l2capinbuf[15], 0x80); + Notify(PSTR(" "), 0x80); + D_PrintHex (l2capinbuf[14], 0x80); + Notify(PSTR(" Identifier: "), 0x80); + D_PrintHex (l2capinbuf[9], 0x80); +#endif + if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) { + identifier = l2capinbuf[9]; + control_scid[0] = l2capinbuf[14]; + control_scid[1] = l2capinbuf[15]; + l2cap_event_flag |= L2CAP_FLAG_CONNECTION_CONTROL_REQUEST; + } else if ((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_INTR_PSM) { + identifier = l2capinbuf[9]; + interrupt_scid[0] = l2capinbuf[14]; + interrupt_scid[1] = l2capinbuf[15]; + l2cap_event_flag |= L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST; + } + } else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) { + if ((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success + if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) { + //Notify(PSTR("\r\nHID Control Configuration Complete"), 0x80); + identifier = l2capinbuf[9]; + l2cap_event_flag |= L2CAP_FLAG_CONFIG_CONTROL_SUCCESS; + } else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) { + //Notify(PSTR("\r\nHID Interrupt Configuration Complete"), 0x80); + identifier = l2capinbuf[9]; + l2cap_event_flag |= L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS; + } + } + } else if (l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) { + if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) { + //Notify(PSTR("\r\nHID Control Configuration Request"), 0x80); + pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], control_scid); + } else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) { + //Notify(PSTR("\r\nHID Interrupt Configuration Request"), 0x80); + pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], interrupt_scid); + } + } else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) { + if (l2capinbuf[12] == control_dcid[0] && l2capinbuf[13] == control_dcid[1]) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nDisconnect Request: Control Channel"), 0x80); +#endif + identifier = l2capinbuf[9]; + pBtd->l2cap_disconnection_response(hci_handle, identifier, control_dcid, control_scid); + Reset(); + } else if (l2capinbuf[12] == interrupt_dcid[0] && l2capinbuf[13] == interrupt_dcid[1]) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nDisconnect Request: Interrupt Channel"), 0x80); +#endif + identifier = l2capinbuf[9]; + pBtd->l2cap_disconnection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid); + Reset(); + } + } else if (l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) { + if (l2capinbuf[12] == control_scid[0] && l2capinbuf[13] == control_scid[1]) { + //Notify(PSTR("\r\nDisconnect Response: Control Channel"), 0x80); + identifier = l2capinbuf[9]; + l2cap_event_flag |= L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE; + } else if (l2capinbuf[12] == interrupt_scid[0] && l2capinbuf[13] == interrupt_scid[1]) { + //Notify(PSTR("\r\nDisconnect Response: Interrupt Channel"), 0x80); + identifier = l2capinbuf[9]; + l2cap_event_flag |= L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE; + } + } +#ifdef EXTRADEBUG + else { + identifier = l2capinbuf[9]; + Notify(PSTR("\r\nL2CAP Unknown Signaling Command: "), 0x80); + D_PrintHex (l2capinbuf[8], 0x80); + } +#endif + } else if (l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) { // l2cap_interrupt + //Notify(PSTR("\r\n\r\nL2CAP Interrupt: "), 0x80); +#ifdef PRINTREPORT + Notify(PSTR("\r\n"), 0x80); + for (uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) { + D_PrintHex (l2capinbuf[i + 8], 0x80); + Notifyc(' ', 0x80); + } +#endif + if (l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT + switch (l2capinbuf[9]) { + case 0x01: // Keyboard events + break; + + case 0x02: // Mouse events + case 0x1A: + ButtonState = l2capinbuf[10]; + /*xAxis = l2capinbuf[11] | ((int16_t)l2capinbuf[12] << 8); + yAxis = l2capinbuf[13] | ((int16_t)l2capinbuf[14] << 8); + scroll = l2capinbuf[15] | ((int16_t)l2capinbuf[16] << 8);*/ + + if (ButtonState != OldButtonState) { + ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable + OldButtonState = ButtonState; + } + break; + case 0x03: +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nChange mode event: "), 0x80); + D_PrintHex (l2capinbuf[11], 0x80); +#endif + break; +#ifdef DEBUG_USB_HOST + default: + Notify(PSTR("\r\nUnknown Report type: "), 0x80); + D_PrintHex (l2capinbuf[9], 0x80); + break; +#endif + } + } + } +#ifdef EXTRADEBUG + else { + Notify(PSTR("\r\nUnsupported L2CAP Data - Channel ID: "), 0x80); + D_PrintHex (l2capinbuf[7], 0x80); + Notify(PSTR(" "), 0x80); + D_PrintHex (l2capinbuf[6], 0x80); + + Notify(PSTR("\r\nData: "), 0x80); + Notify(PSTR("\r\n"), 0x80); + for (uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) { + D_PrintHex (l2capinbuf[i + 8], 0x80); + Notifyc(' ', 0x80); + } + } +#endif + L2CAP_task(); + } +} + +void BTHID::L2CAP_task() { + switch (l2cap_state) { + /* These states are used if the Wiimote is the host */ + case L2CAP_CONTROL_SUCCESS: + if (l2cap_config_success_control_flag) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nHID Control Successfully Configured"), 0x80); +#endif + l2cap_state = L2CAP_INTERRUPT_SETUP; + } + break; + + case L2CAP_INTERRUPT_SETUP: + if (l2cap_connection_request_interrupt_flag) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nHID Interrupt Incoming Connection Request"), 0x80); +#endif + pBtd->l2cap_connection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid, PENDING); + delay(1); + pBtd->l2cap_connection_response(hci_handle, identifier, interrupt_dcid, interrupt_scid, SUCCESSFUL); + identifier++; + delay(1); + pBtd->l2cap_config_request(hci_handle, identifier, interrupt_scid); + + l2cap_state = L2CAP_INTERRUPT_CONFIG_REQUEST; + } + break; + + /* These states are used if the Arduino is the host */ + case L2CAP_CONTROL_CONNECT_REQUEST: + if (l2cap_connected_control_flag) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nSend HID Control Config Request"), 0x80); +#endif + identifier++; + pBtd->l2cap_config_request(hci_handle, identifier, control_scid); + l2cap_state = L2CAP_CONTROL_CONFIG_REQUEST; + } + break; + + case L2CAP_CONTROL_CONFIG_REQUEST: + if (l2cap_config_success_control_flag) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nSend HID Interrupt Connection Request"), 0x80); +#endif + identifier++; + pBtd->l2cap_connection_request(hci_handle, identifier, interrupt_dcid, HID_INTR_PSM); + l2cap_state = L2CAP_INTERRUPT_CONNECT_REQUEST; + } + break; + + case L2CAP_INTERRUPT_CONNECT_REQUEST: + if (l2cap_connected_interrupt_flag) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nSend HID Interrupt Config Request"), 0x80); +#endif + identifier++; + pBtd->l2cap_config_request(hci_handle, identifier, interrupt_scid); + l2cap_state = L2CAP_INTERRUPT_CONFIG_REQUEST; + } + break; + + case L2CAP_INTERRUPT_CONFIG_REQUEST: + if (l2cap_config_success_interrupt_flag) { // Now the HID channels is established +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nHID Channels Established"), 0x80); +#endif + pBtd->connectToHIDDevice = false; + pBtd->pairWithHIDDevice = false; + connected = true; + setProtocol(); + onInit(); + l2cap_state = L2CAP_DONE; + } + break; + + case L2CAP_DONE: + break; + + case L2CAP_INTERRUPT_DISCONNECT: + if (l2cap_disconnect_response_interrupt_flag) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nDisconnected Interrupt Channel"), 0x80); +#endif + identifier++; + pBtd->l2cap_disconnection_request(hci_handle, identifier, control_scid, control_dcid); + l2cap_state = L2CAP_CONTROL_DISCONNECT; + } + break; + + case L2CAP_CONTROL_DISCONNECT: + if (l2cap_disconnect_response_control_flag) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nDisconnected Control Channel"), 0x80); +#endif + pBtd->hci_disconnect(hci_handle); + hci_handle = -1; // Reset handle + l2cap_event_flag = 0; // Reset flags + l2cap_state = L2CAP_WAIT; + } + break; + } +} + +void BTHID::Run() { + switch (l2cap_state) { + case L2CAP_WAIT: + if (pBtd->connectToHIDDevice && !pBtd->l2capConnectionClaimed && !connected && !activeConnection) { + pBtd->l2capConnectionClaimed = true; + activeConnection = true; +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nSend HID Control Connection Request"), 0x80); +#endif + hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection + l2cap_event_flag = 0; // Reset flags + identifier = 0; + pBtd->l2cap_connection_request(hci_handle, identifier, control_dcid, HID_CTRL_PSM); + l2cap_state = L2CAP_CONTROL_CONNECT_REQUEST; + } else if (l2cap_connection_request_control_flag) { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nHID Control Incoming Connection Request"), 0x80); +#endif + pBtd->l2cap_connection_response(hci_handle, identifier, control_dcid, control_scid, PENDING); + delay(1); + pBtd->l2cap_connection_response(hci_handle, identifier, control_dcid, control_scid, SUCCESSFUL); + identifier++; + delay(1); + pBtd->l2cap_config_request(hci_handle, identifier, control_scid); + l2cap_state = L2CAP_CONTROL_SUCCESS; + } + break; + } +} + +/************************************************************/ +/* HID Commands */ +/************************************************************/ +void BTHID::setProtocol() { + uint8_t command = 0x71; // Set Protocol to "Report Protocol Mode", see HID specs page 33 + pBtd->L2CAP_Command(hci_handle, &command, 1, control_scid[0], control_scid[1]); +} + +/************************************************************/ +/* BT HID Commands */ +/************************************************************/ + +bool BTHID::getButtonPress(Button b) { // Return true when a button is pressed + return (bool)((ButtonState & pgm_read_byte(&BUTTONS[(uint8_t)b]))); +} + +bool BTHID::getButtonClick(Button b) { // Only return true when a button is clicked + uint8_t button = pgm_read_byte(&BUTTONS[(uint8_t)b]); + bool click = (ButtonClickState & button); + ButtonClickState &= ~button; // Clear "click" event + return click; +} + +void BTHID::onInit() { + if (pFuncOnInit) + pFuncOnInit(); // Call the user function + else { + // Do nothing + } +} \ No newline at end of file diff --git a/BTHID.h b/BTHID.h new file mode 100644 index 00000000..a62193a0 --- /dev/null +++ b/BTHID.h @@ -0,0 +1,162 @@ +/* Copyright (C) 2013 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 _bthid_h_ +#define _bthid_h_ + +#include "BTD.h" +#include "controllerEnums.h" + +/* Bluetooth L2CAP states for L2CAP_task() */ +#define L2CAP_WAIT 0 + +// These states are used if the device is the host +#define L2CAP_CONTROL_SUCCESS 1 +#define L2CAP_INTERRUPT_SETUP 2 + +// These states are used if the Arduino is the host +#define L2CAP_CONTROL_CONNECT_REQUEST 3 +#define L2CAP_CONTROL_CONFIG_REQUEST 4 +#define L2CAP_INTERRUPT_CONNECT_REQUEST 5 + +#define L2CAP_INTERRUPT_CONFIG_REQUEST 6 +#define L2CAP_DONE 7 + +#define L2CAP_INTERRUPT_DISCONNECT 8 +#define L2CAP_CONTROL_DISCONNECT 9 + +/* L2CAP event flags */ +#define L2CAP_FLAG_CONTROL_CONNECTED 0x01 +#define L2CAP_FLAG_INTERRUPT_CONNECTED 0x02 +#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS 0x04 +#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS 0x08 +#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE 0x10 +#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE 0x20 +#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST 0x40 +#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST 0x80 + +/* Macros for L2CAP event flag tests */ +#define l2cap_connected_control_flag (l2cap_event_flag & L2CAP_FLAG_CONTROL_CONNECTED) +#define l2cap_connected_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_INTERRUPT_CONNECTED) +#define l2cap_config_success_control_flag (l2cap_event_flag & L2CAP_FLAG_CONFIG_CONTROL_SUCCESS) +#define l2cap_config_success_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS) +#define l2cap_disconnect_response_control_flag (l2cap_event_flag & L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE) +#define l2cap_disconnect_response_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE) +#define l2cap_connection_request_control_flag (l2cap_event_flag & L2CAP_FLAG_CONNECTION_CONTROL_REQUEST) +#define l2cap_connection_request_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST) + +/** This BluetoothService class implements support for the HID keyboard and mice. */ +class BTHID : public BluetoothService { +public: + /** + * Constructor for the BTHID class. + * @param p Pointer to the BTD class instance. + * @param pair Set this to true in order to pair with the device. If the argument is omitted then it will not pair with it. One can use ::PAIR to set it to true. + * @param pin Write the pin to BTD#btdPin. If argument is omitted, then "1234" will be used. + */ + BTHID(BTD *p, bool pair = false, const char *pin = "1234"); + + /** @name BluetoothService implementation */ + /** + * Used to pass acldata to the services. + * @param ACLData Incoming acldata. + */ + virtual void ACLData(uint8_t* ACLData); + /** Used to run part of the state maschine. */ + virtual void Run(); + /** Use this to reset the service. */ + virtual void Reset(); + /** Used this to disconnect any of the controllers. */ + virtual void disconnect(); + /**@}*/ + + /** True if a device is connected */ + bool connected; + + /** @name HID mouse functions */ + /** + * getButtonPress(Button b) will return true as long as the button is held down. + * + * While getButtonClick(Button b) will only return it once. + * + * So you instance if you need to increase a variable once you would use getButtonClick(Button b), + * but if you need to drive a robot forward you would use getButtonPress(Button b). + */ + bool getButtonPress(Button b); + bool getButtonClick(Button b); + /**@}*/ + /** @name HID mouse functions */ + /*int16_t getXaxis() { + return xAxis; + } + int16_t getYaxis() { + return yAxis; + } + int16_t getScroll() { + return scroll; + }*/ + /**@}*/ + + /** Call this to start the paring sequence with a controller */ + void pair(void) { + if (pBtd) + pBtd->pairWithHID(); + } + + /** + * Used to call your own function when the controller is successfully initialized. + * @param funcOnInit Function to call. + */ + void attachOnInit(void (*funcOnInit)(void)) { + pFuncOnInit = funcOnInit; + }; + +private: + BTD *pBtd; // Pointer to BTD instance + + /** Set report protocol. */ + void setProtocol(); + + /** + * 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 */ + uint16_t hci_handle; + bool activeConnection; // Used to indicate if it's already has established a connection + + /* Variables used by high level L2CAP task */ + uint8_t l2cap_state; + uint8_t l2cap_event_flag; // l2cap flags of received Bluetooth events + + uint8_t ButtonState, OldButtonState, ButtonClickState; + int16_t xAxis, yAxis, scroll; + + /* L2CAP Channels */ + uint8_t control_scid[2]; // L2CAP source CID for HID_Control + uint8_t control_dcid[2]; // 0x0070 + uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt + uint8_t interrupt_dcid[2]; // 0x0071 + uint8_t identifier; // Identifier for connection +}; +#endif \ No newline at end of file diff --git a/Wii.h b/Wii.h index f8d206ef..397b837f 100755 --- a/Wii.h +++ b/Wii.h @@ -76,8 +76,6 @@ #define motion_plus_connected_flag (l2cap_event_flag & WII_FLAG_MOTION_PLUS_CONNECTED) #define nunchuck_connected_flag (l2cap_event_flag & WII_FLAG_NUNCHUCK_CONNECTED) -#define PAIR 1 - /** Enum used to read the joystick on the Nunchuck. */ enum Hat { /** Read the x-axis on the Nunchuck joystick. */ diff --git a/controllerEnums.h b/controllerEnums.h index 5e0d6dc8..504594ef 100644 --- a/controllerEnums.h +++ b/controllerEnums.h @@ -103,6 +103,8 @@ enum Button { BLACK = 8, // Available on the original Xbox controller WHITE = 9, // Available on the original Xbox controller /**@}*/ + + MIDDLE = 0, // Middle mouse button }; /** Joysticks on the PS3 and Xbox controllers. */ diff --git a/examples/Bluetooth/BTHID/BTHID.ino b/examples/Bluetooth/BTHID/BTHID.ino new file mode 100644 index 00000000..b9c3da4b --- /dev/null +++ b/examples/Bluetooth/BTHID/BTHID.ino @@ -0,0 +1,37 @@ +/* + Example sketch for the HID 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 +#include + +USB Usb; +//USBHub Hub1(&Usb); // Some dongles have a hub inside + +BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so +/* You can create the instance of the class in two ways */ +BTHID hid(&Btd, PAIR, "0000"); // This will start an inquiry and then pair with your Wiimote - you only have to do this once +//BTHID hid(&Btd); // After that you can simply create the instance like so and then press any button on the Wiimote + +void setup() { + Serial.begin(115200); + while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection + if (Usb.Init() == -1) { + Serial.print(F("\r\nOSC did not start")); + while (1); //halt + } + Serial.print(F("\r\nHID Bluetooth Library Started")); +} +void loop() { + Usb.Task(); + if (hid.connected) { + if (hid.getButtonClick(LEFT)) // Print mouse buttons + Serial.println(F("Left")); + if (hid.getButtonClick(RIGHT)) + Serial.println(F("Right")); + if (hid.getButtonClick(MIDDLE)) + Serial.println(F("Middle")); + } +} diff --git a/keywords.txt b/keywords.txt index 6847bb09..6ea68e90 100644 --- a/keywords.txt +++ b/keywords.txt @@ -97,6 +97,7 @@ L3 LITERAL1 R3 LITERAL1 START LITERAL1 UP LITERAL1 +MIDDLE LITERAL1 RIGHT LITERAL1 DOWN LITERAL1 LEFT LITERAL1 From aba004b0479a9b03fc88dd3ebe1abf9821455266 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 24 Nov 2013 23:51:45 +0100 Subject: [PATCH 31/53] Use the HIDBoot class to parse the incoming data --- BTHID.cpp | 56 ++++------------ BTHID.h | 52 +++++++-------- examples/Bluetooth/BTHID/BTHID.ino | 34 ++++++---- examples/Bluetooth/BTHID/KeyboardParser.h | 78 +++++++++++++++++++++++ examples/Bluetooth/BTHID/MouseParser.h | 46 +++++++++++++ 5 files changed, 186 insertions(+), 80 deletions(-) create mode 100644 examples/Bluetooth/BTHID/KeyboardParser.h create mode 100644 examples/Bluetooth/BTHID/MouseParser.h diff --git a/BTHID.cpp b/BTHID.cpp index 848cf12f..d6fbb43c 100644 --- a/BTHID.cpp +++ b/BTHID.cpp @@ -18,18 +18,14 @@ #include "BTHID.h" // To enable serial debugging see "settings.h" //#define EXTRADEBUG // Uncomment to get even more debugging data -//#define PRINTREPORT // Uncomment to print the report send by the Wii controllers - -const uint8_t BUTTONS[] PROGMEM = { // Mouse buttons - 0x04, // MIDDLE - 0x02, // RIGHT - 0, // Skip - 0x01, // LEFT -}; +//#define PRINTREPORT // Uncomment to print the report send by the HID device BTHID::BTHID(BTD *p, bool pair, const char *pin) : pBtd(p) // pointer to USB class instance - mandatory { + for(uint8_t i = 0; i < epMUL; i++) + pRptParser[i] = NULL; + if (pBtd) pBtd->registerServiceClass(this); // Register it as a Bluetooth service @@ -196,22 +192,21 @@ void BTHID::ACLData(uint8_t* l2capinbuf) { if (l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT switch (l2capinbuf[9]) { case 0x01: // Keyboard events + if (pRptParser[KEYBOARD_PARSER_ID]) { + uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); + pRptParser[KEYBOARD_PARSER_ID]->Parse((HID*)this, 0, (uint8_t) length, &l2capinbuf[10]); + } break; case 0x02: // Mouse events case 0x1A: - ButtonState = l2capinbuf[10]; - /*xAxis = l2capinbuf[11] | ((int16_t)l2capinbuf[12] << 8); - yAxis = l2capinbuf[13] | ((int16_t)l2capinbuf[14] << 8); - scroll = l2capinbuf[15] | ((int16_t)l2capinbuf[16] << 8);*/ - - if (ButtonState != OldButtonState) { - ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable - OldButtonState = ButtonState; + if (pRptParser[MOUSE_PARSER_ID]) { + uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); + pRptParser[MOUSE_PARSER_ID]->Parse((HID*)this, 0, (uint8_t) length, &l2capinbuf[10]); } break; case 0x03: -#ifdef DEBUG_USB_HOST +#ifdef EXTRADEBUG Notify(PSTR("\r\nChange mode event: "), 0x80); D_PrintHex (l2capinbuf[11], 0x80); #endif @@ -246,7 +241,7 @@ void BTHID::ACLData(uint8_t* l2capinbuf) { void BTHID::L2CAP_task() { switch (l2cap_state) { - /* These states are used if the Wiimote is the host */ + /* These states are used if the HID device is the host */ case L2CAP_CONTROL_SUCCESS: if (l2cap_config_success_control_flag) { #ifdef DEBUG_USB_HOST @@ -382,29 +377,6 @@ void BTHID::Run() { /* HID Commands */ /************************************************************/ void BTHID::setProtocol() { - uint8_t command = 0x71; // Set Protocol to "Report Protocol Mode", see HID specs page 33 + uint8_t command = 0x70 | protocolMode; // Set Protocol, see HID specs page 33 pBtd->L2CAP_Command(hci_handle, &command, 1, control_scid[0], control_scid[1]); -} - -/************************************************************/ -/* BT HID Commands */ -/************************************************************/ - -bool BTHID::getButtonPress(Button b) { // Return true when a button is pressed - return (bool)((ButtonState & pgm_read_byte(&BUTTONS[(uint8_t)b]))); -} - -bool BTHID::getButtonClick(Button b) { // Only return true when a button is clicked - uint8_t button = pgm_read_byte(&BUTTONS[(uint8_t)b]); - bool click = (ButtonClickState & button); - ButtonClickState &= ~button; // Clear "click" event - return click; -} - -void BTHID::onInit() { - if (pFuncOnInit) - pFuncOnInit(); // Call the user function - else { - // Do nothing - } } \ No newline at end of file diff --git a/BTHID.h b/BTHID.h index a62193a0..cd6b58dc 100644 --- a/BTHID.h +++ b/BTHID.h @@ -20,6 +20,7 @@ #include "BTD.h" #include "controllerEnums.h" +#include "hidboot.h" /* Bluetooth L2CAP states for L2CAP_task() */ #define L2CAP_WAIT 0 @@ -59,6 +60,10 @@ #define l2cap_connection_request_control_flag (l2cap_event_flag & L2CAP_FLAG_CONNECTION_CONTROL_REQUEST) #define l2cap_connection_request_interrupt_flag (l2cap_event_flag & L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST) +#define KEYBOARD_PARSER_ID 0 +#define MOUSE_PARSER_ID 1 +#define epMUL 2 + /** This BluetoothService class implements support for the HID keyboard and mice. */ class BTHID : public BluetoothService { public: @@ -84,38 +89,27 @@ public: virtual void disconnect(); /**@}*/ + HIDReportParser *GetReportParser(uint8_t id) { + return pRptParser[id]; + }; + + bool SetReportParser(uint8_t id, HIDReportParser *prs) { + pRptParser[id] = prs; + return true; + }; + + void setProtocolMode(uint8_t mode) { + protocolMode = mode; + }; + /** True if a device is connected */ bool connected; - /** @name HID mouse functions */ - /** - * getButtonPress(Button b) will return true as long as the button is held down. - * - * While getButtonClick(Button b) will only return it once. - * - * So you instance if you need to increase a variable once you would use getButtonClick(Button b), - * but if you need to drive a robot forward you would use getButtonPress(Button b). - */ - bool getButtonPress(Button b); - bool getButtonClick(Button b); - /**@}*/ - /** @name HID mouse functions */ - /*int16_t getXaxis() { - return xAxis; - } - int16_t getYaxis() { - return yAxis; - } - int16_t getScroll() { - return scroll; - }*/ - /**@}*/ - /** Call this to start the paring sequence with a controller */ void pair(void) { if (pBtd) pBtd->pairWithHID(); - } + }; /** * Used to call your own function when the controller is successfully initialized. @@ -128,15 +122,21 @@ public: private: BTD *pBtd; // Pointer to BTD instance + HIDReportParser *pRptParser[epMUL]; + /** Set report protocol. */ void setProtocol(); + uint8_t protocolMode; /** * 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 onInit() { + if (pFuncOnInit) + pFuncOnInit(); // Call the user function + } void (*pFuncOnInit)(void); // Pointer to function called in onInit() void L2CAP_task(); // L2CAP state machine diff --git a/examples/Bluetooth/BTHID/BTHID.ino b/examples/Bluetooth/BTHID/BTHID.ino index b9c3da4b..fecc4b50 100644 --- a/examples/Bluetooth/BTHID/BTHID.ino +++ b/examples/Bluetooth/BTHID/BTHID.ino @@ -6,32 +6,42 @@ #include #include +#include "KeyboardParser.h" +#include "MouseParser.h" USB Usb; //USBHub Hub1(&Usb); // Some dongles have a hub inside - BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so + /* You can create the instance of the class in two ways */ -BTHID hid(&Btd, PAIR, "0000"); // This will start an inquiry and then pair with your Wiimote - you only have to do this once -//BTHID hid(&Btd); // After that you can simply create the instance like so and then press any button on the Wiimote +// This will start an inquiry and then pair with your device - you only have to do this once +// If you are using a Bluetooth keyboard, then you should type in the password on the keypad and then press enter +BTHID hid(&Btd, PAIR, "0000"); + +// After that you can simply create the instance like so and then press any button on the device +//BTHID hid(&Btd); + +KbdRptParser keyboardPrs; +MouseRptParser mousePrs; void setup() { Serial.begin(115200); while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection if (Usb.Init() == -1) { Serial.print(F("\r\nOSC did not start")); - while (1); //halt + while (1); // Halt } + + hid.SetReportParser(KEYBOARD_PARSER_ID, (HIDReportParser*)&keyboardPrs); + hid.SetReportParser(MOUSE_PARSER_ID, (HIDReportParser*)&mousePrs); + + // If "Boot Protocol Mode" does not work, then try "Report Protocol Mode" + // If that does not work either, then uncomment PRINTREPORT in BTHID.cpp to see the raw report + hid.setProtocolMode(HID_BOOT_PROTOCOL); // Boot Protocol Mode + //hid.setProtocolMode(HID_RPT_PROTOCOL); // Report Protocol Mode + Serial.print(F("\r\nHID Bluetooth Library Started")); } void loop() { Usb.Task(); - if (hid.connected) { - if (hid.getButtonClick(LEFT)) // Print mouse buttons - Serial.println(F("Left")); - if (hid.getButtonClick(RIGHT)) - Serial.println(F("Right")); - if (hid.getButtonClick(MIDDLE)) - Serial.println(F("Middle")); - } } diff --git a/examples/Bluetooth/BTHID/KeyboardParser.h b/examples/Bluetooth/BTHID/KeyboardParser.h new file mode 100644 index 00000000..1054cac0 --- /dev/null +++ b/examples/Bluetooth/BTHID/KeyboardParser.h @@ -0,0 +1,78 @@ +#ifndef __kbdrptparser_h_ +#define __kbdrptparser_h_ + +class KbdRptParser : public KeyboardReportParser { + private: + void PrintKey(uint8_t mod, uint8_t key); + + protected: + virtual void OnControlKeysChanged(uint8_t before, uint8_t after); + virtual void OnKeyDown(uint8_t mod, uint8_t key); + virtual void OnKeyUp(uint8_t mod, uint8_t key); + virtual void OnKeyPressed(uint8_t key); +}; + +void KbdRptParser::PrintKey(uint8_t m, uint8_t key) { + MODIFIERKEYS mod; + *((uint8_t*)&mod) = m; + Serial.print((mod.bmLeftCtrl == 1) ? F("C") : F(" ")); + Serial.print((mod.bmLeftShift == 1) ? F("S") : F(" ")); + Serial.print((mod.bmLeftAlt == 1) ? F("A") : F(" ")); + Serial.print((mod.bmLeftGUI == 1) ? F("G") : F(" ")); + + Serial.print(F(" >")); + PrintHex(key, 0x80); + Serial.print(F("< ")); + + Serial.print((mod.bmRightCtrl == 1) ? F("C") : F(" ")); + Serial.print((mod.bmRightShift == 1) ? F("S") : F(" ")); + Serial.print((mod.bmRightAlt == 1) ? F("A") : F(" ")); + Serial.println((mod.bmRightGUI == 1) ? F("G") : F(" ")); +}; + +void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key) { + Serial.print(F("DN ")); + PrintKey(mod, key); + uint8_t c = OemToAscii(mod, key); + + if (c) + OnKeyPressed(c); +} + +void KbdRptParser::OnControlKeysChanged(uint8_t before, uint8_t after) { + MODIFIERKEYS beforeMod; + *((uint8_t*)&beforeMod) = before; + + MODIFIERKEYS afterMod; + *((uint8_t*)&afterMod) = after; + + if (beforeMod.bmLeftCtrl != afterMod.bmLeftCtrl) + Serial.println(F("LeftCtrl changed")); + if (beforeMod.bmLeftShift != afterMod.bmLeftShift) + Serial.println(F("LeftShift changed")); + if (beforeMod.bmLeftAlt != afterMod.bmLeftAlt) + Serial.println(F("LeftAlt changed")); + if (beforeMod.bmLeftGUI != afterMod.bmLeftGUI) + Serial.println(F("LeftGUI changed")); + + if (beforeMod.bmRightCtrl != afterMod.bmRightCtrl) + Serial.println(F("RightCtrl changed")); + if (beforeMod.bmRightShift != afterMod.bmRightShift) + Serial.println(F("RightShift changed")); + if (beforeMod.bmRightAlt != afterMod.bmRightAlt) + Serial.println(F("RightAlt changed")); + if (beforeMod.bmRightGUI != afterMod.bmRightGUI) + Serial.println(F("RightGUI changed")); +} + +void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key) { + Serial.print(F("UP ")); + PrintKey(mod, key); +} + +void KbdRptParser::OnKeyPressed(uint8_t key) { + Serial.print(F("ASCII: ")); + Serial.println((char)key); +}; + +#endif diff --git a/examples/Bluetooth/BTHID/MouseParser.h b/examples/Bluetooth/BTHID/MouseParser.h new file mode 100644 index 00000000..a9245ded --- /dev/null +++ b/examples/Bluetooth/BTHID/MouseParser.h @@ -0,0 +1,46 @@ +#ifndef __mouserptparser_h__ +#define __mouserptparser_h__ + +class MouseRptParser : public MouseReportParser { + protected: + virtual void OnMouseMove(MOUSEINFO *mi); + virtual void OnLeftButtonUp(MOUSEINFO *mi); + virtual void OnLeftButtonDown(MOUSEINFO *mi); + virtual void OnRightButtonUp(MOUSEINFO *mi); + virtual void OnRightButtonDown(MOUSEINFO *mi); + virtual void OnMiddleButtonUp(MOUSEINFO *mi); + virtual void OnMiddleButtonDown(MOUSEINFO *mi); +}; + +void MouseRptParser::OnMouseMove(MOUSEINFO *mi) { + Serial.print(F("dx=")); + Serial.print(mi->dX, DEC); + Serial.print(F(" dy=")); + Serial.println(mi->dY, DEC); +}; + +void MouseRptParser::OnLeftButtonUp(MOUSEINFO *mi) { + Serial.println(F("L Butt Up")); +}; + +void MouseRptParser::OnLeftButtonDown(MOUSEINFO *mi) { + Serial.println(F("L Butt Dn")); +}; + +void MouseRptParser::OnRightButtonUp(MOUSEINFO *mi) { + Serial.println(F("R Butt Up")); +}; + +void MouseRptParser::OnRightButtonDown(MOUSEINFO *mi) { + Serial.println(F("R Butt Dn")); +}; + +void MouseRptParser::OnMiddleButtonUp(MOUSEINFO *mi) { + Serial.println(F("M Butt Up")); +}; + +void MouseRptParser::OnMiddleButtonDown(MOUSEINFO *mi) { + Serial.println(F("M Butt Dn")); +}; + +#endif From 69dbf06beab3bf50d0e40024ace2aea847c8cd34 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 24 Nov 2013 23:54:59 +0100 Subject: [PATCH 32/53] Updated keywords --- controllerEnums.h | 2 -- keywords.txt | 24 ++++++++++++++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/controllerEnums.h b/controllerEnums.h index 504594ef..5e0d6dc8 100644 --- a/controllerEnums.h +++ b/controllerEnums.h @@ -103,8 +103,6 @@ enum Button { BLACK = 8, // Available on the original Xbox controller WHITE = 9, // Available on the original Xbox controller /**@}*/ - - MIDDLE = 0, // Middle mouse button }; /** Joysticks on the PS3 and Xbox controllers. */ diff --git a/keywords.txt b/keywords.txt index 6ea68e90..b3906513 100644 --- a/keywords.txt +++ b/keywords.txt @@ -19,6 +19,11 @@ USBHub KEYWORD1 BTD KEYWORD1 +#################################################### +# Methods and Functions (KEYWORD2) +#################################################### +Task KEYWORD2 + #################################################### # Syntax Coloring Map For PS3 Bluetooth/USB Library #################################################### @@ -97,7 +102,6 @@ L3 LITERAL1 R3 LITERAL1 START LITERAL1 UP LITERAL1 -MIDDLE LITERAL1 RIGHT LITERAL1 DOWN LITERAL1 LEFT LITERAL1 @@ -293,4 +297,20 @@ getIRy3 KEYWORD2 getIRs3 KEYWORD2 getIRx4 KEYWORD2 getIRy4 KEYWORD2 -getIRs4 KEYWORD2 \ No newline at end of file +getIRs4 KEYWORD2 + +#################################################### +# Syntax Coloring Map For RFCOMM/SPP Library +#################################################### + +#################################################### +# Datatypes (KEYWORD1) +#################################################### + +BTHID KEYWORD1 + +#################################################### +# Methods and Functions (KEYWORD2) +#################################################### +SetReportParser KEYWORD2 +setProtocolMode KEYWORD2 \ No newline at end of file From f8c948f132cd480b469af10e093d2f095b616560 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 25 Nov 2013 00:25:25 +0100 Subject: [PATCH 33/53] Added information about BTHID library --- README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 361caf1a..c36fb8e4 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ For more information about the hardware see the [Hardware Manual](http://www.cir * __Alexei Glushchenko, Circuits@Home__ - * Developers of the USB Core, HID, FTDI, ADK, ACM, and PL2303 libraries * __Kristian Lauszus, TKJ Electronics__ - - * Developer of the [BTD](#bluetooth-libraries), [SPP](#spp-library), [PS3](#ps3-library), [Wii](#wii-library), and [Xbox](#xbox-library) libraries + * Developer of the [BTD](#bluetooth-libraries), [BTHID](#bthid-library), [SPP](#spp-library), [PS3](#ps3-library), [Wii](#wii-library), and [Xbox](#xbox-library) libraries * __Andrew Kroll__ - * Major contributor to mass storage code @@ -86,7 +86,15 @@ This library make it easy to add support for different Bluetooth services like a Some different examples can be found in the [example directory](examples/Bluetooth). The BTD library will also make it possible to use multiple services at once, the following example sketch is an example of this: - +. + +### [BTHID library](BTHID.cpp) + +The [Bluetooth HID library](BTHID.cpp) allows you to connect HID devices via Bluetooth to the USB Host Shield. + +Currently HID mice and keyboards are supported. + +It uses the standard BOOT protocol, but it is very easy to modify it for your device, you simply have do edit the parser. See the example: for more information. ### [SPP library](SPP.cpp) From 27b8656f9165cb144ac1bc882ddf14fed5e1d5a4 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 25 Nov 2013 00:31:42 +0100 Subject: [PATCH 34/53] Added information about how to change protocol mode --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c36fb8e4..c96ac1d9 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ The [Bluetooth HID library](BTHID.cpp) allows you to connect HID devices via Blu Currently HID mice and keyboards are supported. -It uses the standard BOOT protocol, but it is very easy to modify it for your device, you simply have do edit the parser. See the example: for more information. +It uses the standard Boot protocol by default, but it able to use the Report protocol as well. You would simply have to call ```setProtocolMode()``` and then parse ```HID_RPT_PROTOCOL``` as an argument. You will then have to modify the parser for your device. See the example: for more information. ### [SPP library](SPP.cpp) From 0735774a4666b73ff7c723b99582d0bfe0010f79 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 25 Nov 2013 00:32:06 +0100 Subject: [PATCH 35/53] Forgot to init protocolMode --- BTHID.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/BTHID.cpp b/BTHID.cpp index d6fbb43c..de7b485d 100644 --- a/BTHID.cpp +++ b/BTHID.cpp @@ -21,7 +21,8 @@ //#define PRINTREPORT // Uncomment to print the report send by the HID device BTHID::BTHID(BTD *p, bool pair, const char *pin) : -pBtd(p) // pointer to USB class instance - mandatory +pBtd(p), // pointer to USB class instance - mandatory +protocolMode(HID_BOOT_PROTOCOL) { for(uint8_t i = 0; i < epMUL; i++) pRptParser[i] = NULL; From 1b9c3952ac838f5391b3f55a9bbaa70fa90dd33e Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 25 Nov 2013 00:33:44 +0100 Subject: [PATCH 36/53] Typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index c96ac1d9..9907d2d3 100644 --- a/README.md +++ b/README.md @@ -94,7 +94,7 @@ The [Bluetooth HID library](BTHID.cpp) allows you to connect HID devices via Blu Currently HID mice and keyboards are supported. -It uses the standard Boot protocol by default, but it able to use the Report protocol as well. You would simply have to call ```setProtocolMode()``` and then parse ```HID_RPT_PROTOCOL``` as an argument. You will then have to modify the parser for your device. See the example: for more information. +It uses the standard Boot protocol by default, but it is also able to use the Report protocol as well. You would simply have to call ```setProtocolMode()``` and then parse ```HID_RPT_PROTOCOL``` as an argument. You will then have to modify the parser for your device. See the example: for more information. ### [SPP library](SPP.cpp) From 45465fa9280635a83bb1ae38735512f6df3e2742 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 25 Nov 2013 00:43:47 +0100 Subject: [PATCH 37/53] Fixed comment --- PS3USB.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PS3USB.h b/PS3USB.h index ae5314f4..82559acd 100644 --- a/PS3USB.h +++ b/PS3USB.h @@ -140,7 +140,7 @@ public: void getMoveBdaddr(uint8_t *bdaddr); /** * Used to get the calibration data inside the Move controller. - * @param bdaddr Buffer to store data in. Must be at least 147 bytes + * @param data Buffer to store data in. Must be at least 147 bytes */ void getMoveCalibration(uint8_t *data); From 40993141004b215fa1b2b8da10e52e1d44505873 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 25 Nov 2013 01:45:24 +0100 Subject: [PATCH 38/53] Can now set the LEDs on a keyboard --- BTHID.cpp | 8 ++++++ BTHID.h | 3 +++ examples/Bluetooth/BTHID/BTHID.ino | 2 +- examples/Bluetooth/BTHID/KeyboardParser.h | 33 +++++++++++++++++++++-- 4 files changed, 43 insertions(+), 3 deletions(-) diff --git a/BTHID.cpp b/BTHID.cpp index de7b485d..2fe77163 100644 --- a/BTHID.cpp +++ b/BTHID.cpp @@ -380,4 +380,12 @@ void BTHID::Run() { void BTHID::setProtocol() { uint8_t command = 0x70 | protocolMode; // Set Protocol, see HID specs page 33 pBtd->L2CAP_Command(hci_handle, &command, 1, control_scid[0], control_scid[1]); +} + +void BTHID::setLeds(uint8_t data) { + uint8_t buf[3]; + buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02) + buf[1] = 0x01; // Report ID + buf[2] = data; + pBtd->L2CAP_Command(hci_handle, buf, 3, interrupt_scid[0], interrupt_scid[1]); } \ No newline at end of file diff --git a/BTHID.h b/BTHID.h index cd6b58dc..c26de15b 100644 --- a/BTHID.h +++ b/BTHID.h @@ -102,6 +102,9 @@ public: protocolMode = mode; }; + /** Used to set the leds on a keyboard */ + void setLeds(uint8_t data); + /** True if a device is connected */ bool connected; diff --git a/examples/Bluetooth/BTHID/BTHID.ino b/examples/Bluetooth/BTHID/BTHID.ino index fecc4b50..444cc8d2 100644 --- a/examples/Bluetooth/BTHID/BTHID.ino +++ b/examples/Bluetooth/BTHID/BTHID.ino @@ -21,7 +21,7 @@ BTHID hid(&Btd, PAIR, "0000"); // After that you can simply create the instance like so and then press any button on the device //BTHID hid(&Btd); -KbdRptParser keyboardPrs; +KbdRptParser keyboardPrs(&hid); MouseRptParser mousePrs; void setup() { diff --git a/examples/Bluetooth/BTHID/KeyboardParser.h b/examples/Bluetooth/BTHID/KeyboardParser.h index 1054cac0..0d8c081d 100644 --- a/examples/Bluetooth/BTHID/KeyboardParser.h +++ b/examples/Bluetooth/BTHID/KeyboardParser.h @@ -2,16 +2,45 @@ #define __kbdrptparser_h_ class KbdRptParser : public KeyboardReportParser { - private: - void PrintKey(uint8_t mod, uint8_t key); + public: + KbdRptParser(BTHID *p) : pBTHID(p) {}; protected: + virtual uint8_t HandleLockingKeys(HID* hid, uint8_t key); virtual void OnControlKeysChanged(uint8_t before, uint8_t after); virtual void OnKeyDown(uint8_t mod, uint8_t key); virtual void OnKeyUp(uint8_t mod, uint8_t key); virtual void OnKeyPressed(uint8_t key); + + private: + void PrintKey(uint8_t mod, uint8_t key); + BTHID *pBTHID; }; +uint8_t KbdRptParser::HandleLockingKeys(HID* hid, uint8_t key) { + uint8_t old_keys = kbdLockingKeys.bLeds; + + switch (key) { + case KEY_NUM_LOCK: + Serial.println(F("Num lock")); + kbdLockingKeys.kbdLeds.bmNumLock = ~kbdLockingKeys.kbdLeds.bmNumLock; + break; + case KEY_CAPS_LOCK: + Serial.println(F("Caps lock")); + kbdLockingKeys.kbdLeds.bmCapsLock = ~kbdLockingKeys.kbdLeds.bmCapsLock; + break; + case KEY_SCROLL_LOCK: + Serial.println(F("Scroll lock")); + kbdLockingKeys.kbdLeds.bmScrollLock = ~kbdLockingKeys.kbdLeds.bmScrollLock; + break; + } + + if (old_keys != kbdLockingKeys.bLeds && pBTHID) + pBTHID->setLeds(kbdLockingKeys.bLeds); + + return 0; +} + void KbdRptParser::PrintKey(uint8_t m, uint8_t key) { MODIFIERKEYS mod; *((uint8_t*)&mod) = m; From 253b43c06fdd87b03165c86828ef0d1b4493fb20 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 25 Nov 2013 02:15:33 +0100 Subject: [PATCH 39/53] Set protocol before establishing interrupt channel --- BTHID.cpp | 23 ++++++++++++++++------- BTHID.h | 13 +++++++------ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/BTHID.cpp b/BTHID.cpp index 2fe77163..7820d2d5 100644 --- a/BTHID.cpp +++ b/BTHID.cpp @@ -248,6 +248,7 @@ void BTHID::L2CAP_task() { #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nHID Control Successfully Configured"), 0x80); #endif + setProtocol(); l2cap_state = L2CAP_INTERRUPT_SETUP; } break; @@ -276,19 +277,24 @@ void BTHID::L2CAP_task() { #endif identifier++; pBtd->l2cap_config_request(hci_handle, identifier, control_scid); + l2cap_state = L2CAP_SET_PROTOCOL; + } + break; + + case L2CAP_SET_PROTOCOL: + if (l2cap_config_success_control_flag) { + setProtocol(); l2cap_state = L2CAP_CONTROL_CONFIG_REQUEST; } break; case L2CAP_CONTROL_CONFIG_REQUEST: - if (l2cap_config_success_control_flag) { #ifdef DEBUG_USB_HOST - Notify(PSTR("\r\nSend HID Interrupt Connection Request"), 0x80); + Notify(PSTR("\r\nSend HID Interrupt Connection Request"), 0x80); #endif - identifier++; - pBtd->l2cap_connection_request(hci_handle, identifier, interrupt_dcid, HID_INTR_PSM); - l2cap_state = L2CAP_INTERRUPT_CONNECT_REQUEST; - } + identifier++; + pBtd->l2cap_connection_request(hci_handle, identifier, interrupt_dcid, HID_INTR_PSM); + l2cap_state = L2CAP_INTERRUPT_CONNECT_REQUEST; break; case L2CAP_INTERRUPT_CONNECT_REQUEST: @@ -310,7 +316,6 @@ void BTHID::L2CAP_task() { pBtd->connectToHIDDevice = false; pBtd->pairWithHIDDevice = false; connected = true; - setProtocol(); onInit(); l2cap_state = L2CAP_DONE; } @@ -378,6 +383,10 @@ void BTHID::Run() { /* HID Commands */ /************************************************************/ void BTHID::setProtocol() { +#ifdef DEBUG_USB_HOST + Notify(PSTR("\r\nSet protocol mode: "), 0x80); + D_PrintHex (protocolMode, 0x80); +#endif uint8_t command = 0x70 | protocolMode; // Set Protocol, see HID specs page 33 pBtd->L2CAP_Command(hci_handle, &command, 1, control_scid[0], control_scid[1]); } diff --git a/BTHID.h b/BTHID.h index c26de15b..e6e168b6 100644 --- a/BTHID.h +++ b/BTHID.h @@ -31,14 +31,15 @@ // These states are used if the Arduino is the host #define L2CAP_CONTROL_CONNECT_REQUEST 3 -#define L2CAP_CONTROL_CONFIG_REQUEST 4 -#define L2CAP_INTERRUPT_CONNECT_REQUEST 5 +#define L2CAP_SET_PROTOCOL 4 +#define L2CAP_CONTROL_CONFIG_REQUEST 5 +#define L2CAP_INTERRUPT_CONNECT_REQUEST 6 -#define L2CAP_INTERRUPT_CONFIG_REQUEST 6 -#define L2CAP_DONE 7 +#define L2CAP_INTERRUPT_CONFIG_REQUEST 7 +#define L2CAP_DONE 8 -#define L2CAP_INTERRUPT_DISCONNECT 8 -#define L2CAP_CONTROL_DISCONNECT 9 +#define L2CAP_INTERRUPT_DISCONNECT 9 +#define L2CAP_CONTROL_DISCONNECT 10 /* L2CAP event flags */ #define L2CAP_FLAG_CONTROL_CONNECTED 0x01 From eed70438be985a529838a2561c223970a90ec829 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 25 Nov 2013 02:20:57 +0100 Subject: [PATCH 40/53] =?UTF-8?q?Set=20default=20pin=20to=20=E2=80=9C0000?= =?UTF-8?q?=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BTHID.h | 4 ++-- SPP.h | 4 ++-- examples/Bluetooth/PS3SPP/PS3SPP.ino | 2 +- examples/Bluetooth/SPPMulti/SPPMulti.ino | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/BTHID.h b/BTHID.h index e6e168b6..21b92720 100644 --- a/BTHID.h +++ b/BTHID.h @@ -72,9 +72,9 @@ public: * Constructor for the BTHID class. * @param p Pointer to the BTD class instance. * @param pair Set this to true in order to pair with the device. If the argument is omitted then it will not pair with it. One can use ::PAIR to set it to true. - * @param pin Write the pin to BTD#btdPin. If argument is omitted, then "1234" will be used. + * @param pin Write the pin to BTD#btdPin. If argument is omitted, then "0000" will be used. */ - BTHID(BTD *p, bool pair = false, const char *pin = "1234"); + BTHID(BTD *p, bool pair = false, const char *pin = "0000"); /** @name BluetoothService implementation */ /** diff --git a/SPP.h b/SPP.h index 558f16bc..a38014f0 100644 --- a/SPP.h +++ b/SPP.h @@ -96,9 +96,9 @@ public: * Constructor for the SPP class. * @param p Pointer to BTD class instance. * @param name Set the name to BTD#btdName. If argument is omitted, then "Arduino" will be used. - * @param pin Write the pin to BTD#btdPin. If argument is omitted, then "1234" will be used. + * @param pin Write the pin to BTD#btdPin. If argument is omitted, then "0000" will be used. */ - SPP(BTD *p, const char* name = "Arduino", const char* pin = "1234"); + SPP(BTD *p, const char *name = "Arduino", const char *pin = "0000"); /** * Used to provide Boolean tests for the class. diff --git a/examples/Bluetooth/PS3SPP/PS3SPP.ino b/examples/Bluetooth/PS3SPP/PS3SPP.ino index 214ce26a..3f9af1f3 100644 --- a/examples/Bluetooth/PS3SPP/PS3SPP.ino +++ b/examples/Bluetooth/PS3SPP/PS3SPP.ino @@ -19,7 +19,7 @@ USB Usb; BTD Btd(&Usb); // You have to create the Bluetooth Dongle instance like so /* You can create the instances of the bluetooth services in two ways */ -SPP SerialBT(&Btd); // This will set the name to the defaults: "Arduino" and the pin to "1234" +SPP SerialBT(&Btd); // This will set the name to the defaults: "Arduino" and the pin to "0000" //SPP SerialBTBT(&Btd,"Lauszus's Arduino","0000"); // You can also set the name and pin like so PS3BT PS3(&Btd); // This will just create the instance //PS3BT PS3(&Btd,0x00,0x15,0x83,0x3D,0x0A,0x57); // This will also store the bluetooth address - this can be obtained from the dongle when running the sketch diff --git a/examples/Bluetooth/SPPMulti/SPPMulti.ino b/examples/Bluetooth/SPPMulti/SPPMulti.ino index af32fd85..3388bd7b 100644 --- a/examples/Bluetooth/SPPMulti/SPPMulti.ino +++ b/examples/Bluetooth/SPPMulti/SPPMulti.ino @@ -18,7 +18,7 @@ uint8_t buffer[50]; void setup() { for (uint8_t i = 0; i < length; i++) - SerialBT[i] = new SPP(&Btd); // This will set the name to the default: "Arduino" and the pin to "1234" for all connections + SerialBT[i] = new SPP(&Btd); // This will set the name to the default: "Arduino" and the pin to "0000" for all connections Serial.begin(115200); while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection From 5f49b321cb71170225e28633c30f065997bd8e2e Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 25 Nov 2013 02:58:33 +0100 Subject: [PATCH 41/53] Print data receiving on the L2CAP control channel for debugging --- BTHID.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/BTHID.cpp b/BTHID.cpp index 7820d2d5..5cd8701d 100644 --- a/BTHID.cpp +++ b/BTHID.cpp @@ -182,9 +182,8 @@ void BTHID::ACLData(uint8_t* l2capinbuf) { } #endif } else if (l2capinbuf[6] == interrupt_dcid[0] && l2capinbuf[7] == interrupt_dcid[1]) { // l2cap_interrupt - //Notify(PSTR("\r\n\r\nL2CAP Interrupt: "), 0x80); #ifdef PRINTREPORT - Notify(PSTR("\r\n"), 0x80); + Notify(PSTR("\r\nL2CAP Interrupt: "), 0x80); for (uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) { D_PrintHex (l2capinbuf[i + 8], 0x80); Notifyc(' ', 0x80); @@ -200,14 +199,13 @@ void BTHID::ACLData(uint8_t* l2capinbuf) { break; case 0x02: // Mouse events - case 0x1A: if (pRptParser[MOUSE_PARSER_ID]) { uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); pRptParser[MOUSE_PARSER_ID]->Parse((HID*)this, 0, (uint8_t) length, &l2capinbuf[10]); } break; case 0x03: -#ifdef EXTRADEBUG +#ifdef DEBUG_USB_HOST Notify(PSTR("\r\nChange mode event: "), 0x80); D_PrintHex (l2capinbuf[11], 0x80); #endif @@ -220,6 +218,14 @@ void BTHID::ACLData(uint8_t* l2capinbuf) { #endif } } + } else if (l2capinbuf[6] == control_dcid[0] && l2capinbuf[7] == control_dcid[1]) { // l2cap_control +#ifdef PRINTREPORT + Notify(PSTR("\r\nL2CAP Control: "), 0x80); + for (uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) { + D_PrintHex (l2capinbuf[i + 8], 0x80); + Notifyc(' ', 0x80); + } +#endif } #ifdef EXTRADEBUG else { From a31cc4258549b4d9d92df4f72bd6f4394fc90274 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 25 Nov 2013 17:39:59 +0100 Subject: [PATCH 42/53] Use reinterpret_cast to cast from BTHID to HID class, so it can be used in the parser --- BTHID.cpp | 6 +++--- examples/Bluetooth/BTHID/BTHID.ino | 2 +- examples/Bluetooth/BTHID/KeyboardParser.h | 14 ++++++-------- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/BTHID.cpp b/BTHID.cpp index 5cd8701d..b1c3c1f4 100644 --- a/BTHID.cpp +++ b/BTHID.cpp @@ -24,7 +24,7 @@ BTHID::BTHID(BTD *p, bool pair, const char *pin) : pBtd(p), // pointer to USB class instance - mandatory protocolMode(HID_BOOT_PROTOCOL) { - for(uint8_t i = 0; i < epMUL; i++) + for (uint8_t i = 0; i < epMUL; i++) pRptParser[i] = NULL; if (pBtd) @@ -194,14 +194,14 @@ void BTHID::ACLData(uint8_t* l2capinbuf) { case 0x01: // Keyboard events if (pRptParser[KEYBOARD_PARSER_ID]) { uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); - pRptParser[KEYBOARD_PARSER_ID]->Parse((HID*)this, 0, (uint8_t) length, &l2capinbuf[10]); + pRptParser[KEYBOARD_PARSER_ID]->Parse(reinterpret_cast (this), 0, (uint8_t) length, &l2capinbuf[10]); // Use reinterpret_cast again to extract the instance } break; case 0x02: // Mouse events if (pRptParser[MOUSE_PARSER_ID]) { uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); - pRptParser[MOUSE_PARSER_ID]->Parse((HID*)this, 0, (uint8_t) length, &l2capinbuf[10]); + pRptParser[MOUSE_PARSER_ID]->Parse(reinterpret_cast (this), 0, (uint8_t) length, &l2capinbuf[10]); // Use reinterpret_cast again to extract the instance } break; case 0x03: diff --git a/examples/Bluetooth/BTHID/BTHID.ino b/examples/Bluetooth/BTHID/BTHID.ino index 444cc8d2..fecc4b50 100644 --- a/examples/Bluetooth/BTHID/BTHID.ino +++ b/examples/Bluetooth/BTHID/BTHID.ino @@ -21,7 +21,7 @@ BTHID hid(&Btd, PAIR, "0000"); // After that you can simply create the instance like so and then press any button on the device //BTHID hid(&Btd); -KbdRptParser keyboardPrs(&hid); +KbdRptParser keyboardPrs; MouseRptParser mousePrs; void setup() { diff --git a/examples/Bluetooth/BTHID/KeyboardParser.h b/examples/Bluetooth/BTHID/KeyboardParser.h index 0d8c081d..ed04b50e 100644 --- a/examples/Bluetooth/BTHID/KeyboardParser.h +++ b/examples/Bluetooth/BTHID/KeyboardParser.h @@ -2,11 +2,8 @@ #define __kbdrptparser_h_ class KbdRptParser : public KeyboardReportParser { - public: - KbdRptParser(BTHID *p) : pBTHID(p) {}; - protected: - virtual uint8_t HandleLockingKeys(HID* hid, uint8_t key); + virtual uint8_t HandleLockingKeys(HID *hid, uint8_t key); virtual void OnControlKeysChanged(uint8_t before, uint8_t after); virtual void OnKeyDown(uint8_t mod, uint8_t key); virtual void OnKeyUp(uint8_t mod, uint8_t key); @@ -14,10 +11,9 @@ class KbdRptParser : public KeyboardReportParser { private: void PrintKey(uint8_t mod, uint8_t key); - BTHID *pBTHID; }; -uint8_t KbdRptParser::HandleLockingKeys(HID* hid, uint8_t key) { +uint8_t KbdRptParser::HandleLockingKeys(HID *hid, uint8_t key) { uint8_t old_keys = kbdLockingKeys.bLeds; switch (key) { @@ -35,8 +31,10 @@ uint8_t KbdRptParser::HandleLockingKeys(HID* hid, uint8_t key) { break; } - if (old_keys != kbdLockingKeys.bLeds && pBTHID) - pBTHID->setLeds(kbdLockingKeys.bLeds); + if (old_keys != kbdLockingKeys.bLeds && hid) { + BTHID *pBTHID = reinterpret_cast (hid); // A cast the other way around is done in BTHID.cpp + pBTHID->setLeds(kbdLockingKeys.bLeds); // Update the LEDs on the keyboard + } return 0; } From 148b67ca2de2fc89c285da7359213895da76d520 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 25 Nov 2013 18:15:10 +0100 Subject: [PATCH 43/53] Fixed flush It behaved like prior Arduino 1.0 --- SPP.cpp | 2 +- SPP.h | 8 ++++++-- keywords.txt | 3 +-- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/SPP.cpp b/SPP.cpp index 24911da9..0c133830 100644 --- a/SPP.cpp +++ b/SPP.cpp @@ -801,7 +801,7 @@ int SPP::available(void) { return rfcommAvailable; }; -void SPP::flush(void) { +void SPP::discard(void) { rfcommAvailable = 0; } diff --git a/SPP.h b/SPP.h index a38014f0..e2904f14 100644 --- a/SPP.h +++ b/SPP.h @@ -130,8 +130,10 @@ public: * @return Return the number of bytes ready to be read. */ virtual int available(void); - /** Discard all the bytes in the buffer. */ - virtual void flush(void); + /** Send out all bytes in the buffer. */ + virtual void flush(void) { + send(); + }; /** * Used to read the next value in the buffer without advancing to the next one. * @return Return the byte. Will return -1 if no bytes are available. @@ -157,6 +159,8 @@ public: virtual size_t write(const uint8_t* data, size_t size); /** Pull in write(const char *str) from Print */ using Print::write; + /** Discard all the bytes in the buffer. */ + void discard(void); /** * This will send all the bytes in the buffer. * This is called whenever Usb.Task() is called, diff --git a/keywords.txt b/keywords.txt index b3906513..c4f5bd87 100644 --- a/keywords.txt +++ b/keywords.txt @@ -228,8 +228,7 @@ SPP KEYWORD1 #################################################### connected KEYWORD2 -printNumber KEYWORD2 -printNumberln KEYWORD2 +discard KEYWORD2 #################################################### # Syntax Coloring Map For Wiimote Library From 2de6238a6ba2b076c55a164a4ef4452407a40915 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 25 Nov 2013 18:20:22 +0100 Subject: [PATCH 44/53] Updated comment about Stream class --- SPP.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/SPP.h b/SPP.h index e2904f14..81b83829 100644 --- a/SPP.h +++ b/SPP.h @@ -89,7 +89,10 @@ #define BT_RFCOMM_NSC_RSP 0x11 */ -/** This BluetoothService class implements the Serial Port Protocol (SPP). */ +/** + * This BluetoothService class implements the Serial Port Protocol (SPP). + * It inherits the Arduino Stream class. This allows it to use all the standard Arduino print functions. + */ class SPP : public BluetoothService, public Stream { public: /** From 627c39019198bbbb6e624af15c338e14fecc690f Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 25 Nov 2013 18:46:10 +0100 Subject: [PATCH 45/53] Minor --- BTHID.cpp | 6 +++--- Wii.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/BTHID.cpp b/BTHID.cpp index b1c3c1f4..ec0535af 100644 --- a/BTHID.cpp +++ b/BTHID.cpp @@ -89,7 +89,7 @@ void BTHID::ACLData(uint8_t* l2capinbuf) { #endif } else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_RESPONSE) { if (((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) == SUCCESSFUL)) { // Success - if (l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) { // Success + if (l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) { //Notify(PSTR("\r\nHID Control Connection Complete"), 0x80); identifier = l2capinbuf[9]; control_scid[0] = l2capinbuf[12]; @@ -186,7 +186,7 @@ void BTHID::ACLData(uint8_t* l2capinbuf) { Notify(PSTR("\r\nL2CAP Interrupt: "), 0x80); for (uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) { D_PrintHex (l2capinbuf[i + 8], 0x80); - Notifyc(' ', 0x80); + Notify(PSTR(" "), 0x80); } #endif if (l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT @@ -223,7 +223,7 @@ void BTHID::ACLData(uint8_t* l2capinbuf) { Notify(PSTR("\r\nL2CAP Control: "), 0x80); for (uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) { D_PrintHex (l2capinbuf[i + 8], 0x80); - Notifyc(' ', 0x80); + Notify(PSTR(" "), 0x80); } #endif } diff --git a/Wii.cpp b/Wii.cpp index 2e8669db..d55d4e79 100755 --- a/Wii.cpp +++ b/Wii.cpp @@ -163,7 +163,7 @@ void WII::ACLData(uint8_t* l2capinbuf) { #endif } else if (l2capinbuf[8] == L2CAP_CMD_CONNECTION_RESPONSE) { if (((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) && ((l2capinbuf[18] | (l2capinbuf[19] << 8)) == SUCCESSFUL)) { // Success - if (l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) { // Success + if (l2capinbuf[14] == control_dcid[0] && l2capinbuf[15] == control_dcid[1]) { //Notify(PSTR("\r\nHID Control Connection Complete"), 0x80); identifier = l2capinbuf[9]; control_scid[0] = l2capinbuf[12]; From bcc4afede59fa8ad106c55d338ffc38ff073e52d Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 25 Nov 2013 19:01:20 +0100 Subject: [PATCH 46/53] =?UTF-8?q?Set=20protocol=20shouldn=E2=80=99t=20have?= =?UTF-8?q?=20it=E2=80=99s=20own=20state,=20as=20it=20will=20then=20someti?= =?UTF-8?q?mes=20not=20call=20the=20other=20states=20afterwards?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BTHID.cpp | 21 +++++++++------------ BTHID.h | 13 ++++++------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/BTHID.cpp b/BTHID.cpp index ec0535af..02b9a884 100644 --- a/BTHID.cpp +++ b/BTHID.cpp @@ -254,7 +254,7 @@ void BTHID::L2CAP_task() { #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nHID Control Successfully Configured"), 0x80); #endif - setProtocol(); + setProtocol(); // Set protocol before establishing HID interrupt channel l2cap_state = L2CAP_INTERRUPT_SETUP; } break; @@ -283,24 +283,21 @@ void BTHID::L2CAP_task() { #endif identifier++; pBtd->l2cap_config_request(hci_handle, identifier, control_scid); - l2cap_state = L2CAP_SET_PROTOCOL; - } - break; - - case L2CAP_SET_PROTOCOL: - if (l2cap_config_success_control_flag) { - setProtocol(); l2cap_state = L2CAP_CONTROL_CONFIG_REQUEST; } break; case L2CAP_CONTROL_CONFIG_REQUEST: + if (l2cap_config_success_control_flag) { + setProtocol(); // Set protocol before establishing HID interrupt channel + delay(1); // Short delay between commands - just to be sure #ifdef DEBUG_USB_HOST - Notify(PSTR("\r\nSend HID Interrupt Connection Request"), 0x80); + Notify(PSTR("\r\nSend HID Interrupt Connection Request"), 0x80); #endif - identifier++; - pBtd->l2cap_connection_request(hci_handle, identifier, interrupt_dcid, HID_INTR_PSM); - l2cap_state = L2CAP_INTERRUPT_CONNECT_REQUEST; + identifier++; + pBtd->l2cap_connection_request(hci_handle, identifier, interrupt_dcid, HID_INTR_PSM); + l2cap_state = L2CAP_INTERRUPT_CONNECT_REQUEST; + } break; case L2CAP_INTERRUPT_CONNECT_REQUEST: diff --git a/BTHID.h b/BTHID.h index 21b92720..ddd26d59 100644 --- a/BTHID.h +++ b/BTHID.h @@ -31,15 +31,14 @@ // These states are used if the Arduino is the host #define L2CAP_CONTROL_CONNECT_REQUEST 3 -#define L2CAP_SET_PROTOCOL 4 -#define L2CAP_CONTROL_CONFIG_REQUEST 5 -#define L2CAP_INTERRUPT_CONNECT_REQUEST 6 +#define L2CAP_CONTROL_CONFIG_REQUEST 4 +#define L2CAP_INTERRUPT_CONNECT_REQUEST 5 -#define L2CAP_INTERRUPT_CONFIG_REQUEST 7 -#define L2CAP_DONE 8 +#define L2CAP_INTERRUPT_CONFIG_REQUEST 6 +#define L2CAP_DONE 7 -#define L2CAP_INTERRUPT_DISCONNECT 9 -#define L2CAP_CONTROL_DISCONNECT 10 +#define L2CAP_INTERRUPT_DISCONNECT 8 +#define L2CAP_CONTROL_DISCONNECT 9 /* L2CAP event flags */ #define L2CAP_FLAG_CONTROL_CONNECTED 0x01 From 5edcc13c6c9b00f4841b614560e7220e2fe64f41 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 25 Nov 2013 23:26:11 +0100 Subject: [PATCH 47/53] Added information about spi4teensy3 library --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9907d2d3..d208c2b8 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ Currently the following boards are supported by the library: * All official Arduino AVR boards (Uno, Duemilanove, Mega, Mega 2560, Mega ADK, Leonardo etc.) * Teensy (Teensy++ 1.0, Teensy 2.0, Teensy++ 2.0, and Teensy 3.0) + * Note if you are using the Teensy 3.0 you should download this SPI library as well: . You should then add ```#include spi4teensy3.h``` to your .ino file. * Balanduino * Sanguino * Black Widdow From b5d997c821a9adb33b5cfbcbd780a3cc4f5bae33 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Mon, 25 Nov 2013 23:27:37 +0100 Subject: [PATCH 48/53] Typo --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d208c2b8..59c98caf 100644 --- a/README.md +++ b/README.md @@ -67,7 +67,7 @@ Currently the following boards are supported by the library: * All official Arduino AVR boards (Uno, Duemilanove, Mega, Mega 2560, Mega ADK, Leonardo etc.) * Teensy (Teensy++ 1.0, Teensy 2.0, Teensy++ 2.0, and Teensy 3.0) - * Note if you are using the Teensy 3.0 you should download this SPI library as well: . You should then add ```#include spi4teensy3.h``` to your .ino file. + * Note if you are using the Teensy 3.0 you should download this SPI library as well: . You should then add ```#include ``` to your .ino file. * Balanduino * Sanguino * Black Widdow From 6004d61de2afb0076c34658bdd1b9e33a4282def Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Wed, 27 Nov 2013 00:07:58 +0100 Subject: [PATCH 49/53] Removed some unused code and cleanup --- BTHID.cpp | 3 ++- BTHID.h | 4 ---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/BTHID.cpp b/BTHID.cpp index 02b9a884..908f5961 100644 --- a/BTHID.cpp +++ b/BTHID.cpp @@ -204,6 +204,7 @@ void BTHID::ACLData(uint8_t* l2capinbuf) { pRptParser[MOUSE_PARSER_ID]->Parse(reinterpret_cast (this), 0, (uint8_t) length, &l2capinbuf[10]); // Use reinterpret_cast again to extract the instance } break; + case 0x03: #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nChange mode event: "), 0x80); @@ -238,7 +239,7 @@ void BTHID::ACLData(uint8_t* l2capinbuf) { Notify(PSTR("\r\n"), 0x80); for (uint16_t i = 0; i < ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]); i++) { D_PrintHex (l2capinbuf[i + 8], 0x80); - Notifyc(' ', 0x80); + Notify(PSTR(" "), 0x80); } } #endif diff --git a/BTHID.h b/BTHID.h index ddd26d59..7eae9494 100644 --- a/BTHID.h +++ b/BTHID.h @@ -19,7 +19,6 @@ #define _bthid_h_ #include "BTD.h" -#include "controllerEnums.h" #include "hidboot.h" /* Bluetooth L2CAP states for L2CAP_task() */ @@ -152,9 +151,6 @@ private: uint8_t l2cap_state; uint8_t l2cap_event_flag; // l2cap flags of received Bluetooth events - uint8_t ButtonState, OldButtonState, ButtonClickState; - int16_t xAxis, yAxis, scroll; - /* L2CAP Channels */ uint8_t control_scid[2]; // L2CAP source CID for HID_Control uint8_t control_dcid[2]; // 0x0070 From c84dce8e006828201ca949deab369259bbbd96c5 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 1 Dec 2013 16:02:23 +0100 Subject: [PATCH 50/53] Renamed clearAllVariables() to Initialize() --- BTD.cpp | 8 ++++---- BTD.h | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/BTD.cpp b/BTD.cpp index ab858d46..cab5f7f8 100755 --- a/BTD.cpp +++ b/BTD.cpp @@ -39,7 +39,7 @@ bPollEnable(false) // Don't start polling before dongle is connected for (uint8_t i = 0; i < BTD_NUMSERVICES; i++) btService[i] = NULL; - clearAllVariables(); // Set all variables, endpoint structs etc. to default values + Initialize(); // Set all variables, endpoint structs etc. to default values if (pUsb) // Register in USB subsystem pUsb->RegisterDeviceClass(this); // Set devConfig[] entry @@ -52,7 +52,7 @@ uint8_t BTD::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) { UsbDevice *p = NULL; EpInfo *oldep_ptr = NULL; - clearAllVariables(); // Set all variables, endpoint structs etc. to default values + Initialize(); // Set all variables, endpoint structs etc. to default values AddressPool &addrPool = pUsb->GetAddressPool(); // Get memory address of USB device address pool #ifdef EXTRADEBUG @@ -290,7 +290,7 @@ Fail: return rcode; } -void BTD::clearAllVariables() { +void BTD::Initialize() { uint8_t i; for (i = 0; i < BTD_MAX_ENDPOINTS; i++) { epInfo[i].epAddr = 0; @@ -367,7 +367,7 @@ void BTD::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr) { /* Performs a cleanup after failed Init() attempt */ uint8_t BTD::Release() { - clearAllVariables(); // Set all variables, endpoint structs etc. to default values + Initialize(); // Set all variables, endpoint structs etc. to default values pUsb->GetAddressPool().FreeAddress(bAddress); return 0; } diff --git a/BTD.h b/BTD.h index c419a252..a048e098 100755 --- a/BTD.h +++ b/BTD.h @@ -488,7 +488,7 @@ protected: void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr); private: - void clearAllVariables(); // Set all variables, endpoint structs etc. to default values + void Initialize(); // Set all variables, endpoint structs etc. to default values BluetoothService* btService[BTD_NUMSERVICES]; uint16_t PID, VID; // PID and VID of device connected From ab9338a55e7422682308c2a3d86d9efa02beb7cb Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 1 Dec 2013 16:03:11 +0100 Subject: [PATCH 51/53] Added missing semicolon Needed for STM32 --- examples/Bluetooth/BTHID/KeyboardParser.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/Bluetooth/BTHID/KeyboardParser.h b/examples/Bluetooth/BTHID/KeyboardParser.h index ed04b50e..b7ab08e9 100644 --- a/examples/Bluetooth/BTHID/KeyboardParser.h +++ b/examples/Bluetooth/BTHID/KeyboardParser.h @@ -37,7 +37,7 @@ uint8_t KbdRptParser::HandleLockingKeys(HID *hid, uint8_t key) { } return 0; -} +}; void KbdRptParser::PrintKey(uint8_t m, uint8_t key) { MODIFIERKEYS mod; @@ -64,7 +64,7 @@ void KbdRptParser::OnKeyDown(uint8_t mod, uint8_t key) { if (c) OnKeyPressed(c); -} +}; void KbdRptParser::OnControlKeysChanged(uint8_t before, uint8_t after) { MODIFIERKEYS beforeMod; @@ -90,12 +90,12 @@ void KbdRptParser::OnControlKeysChanged(uint8_t before, uint8_t after) { Serial.println(F("RightAlt changed")); if (beforeMod.bmRightGUI != afterMod.bmRightGUI) Serial.println(F("RightGUI changed")); -} +}; void KbdRptParser::OnKeyUp(uint8_t mod, uint8_t key) { Serial.print(F("UP ")); PrintKey(mod, key); -} +}; void KbdRptParser::OnKeyPressed(uint8_t key) { Serial.print(F("ASCII: ")); From 315af437ed63cb7976afe1edb0acbbdbfba17d15 Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 1 Dec 2013 17:06:32 +0100 Subject: [PATCH 52/53] Now easier to disable and enable printing of incoming data --- hidboot.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/hidboot.h b/hidboot.h index 826e8e72..42224c68 100644 --- a/hidboot.h +++ b/hidboot.h @@ -495,10 +495,14 @@ uint8_t HIDBoot::Poll() { if(pRptParser[i]) pRptParser[i]->Parse((HID*)this, 0, (uint8_t) read, buf); - //for (uint8_t i=0; i(buf[i]); - //if (read) - // USB_HOST_SERIAL.println(""); +#if 0 // Set this to 1 to print the incoming data + for (uint8_t i=0; i < read; i++) { + PrintHex (buf[i], 0x80); + USB_HOST_SERIAL.write(' '); + } + if (read) + USB_HOST_SERIAL.println(); +#endif } else { if(rcode != hrNAK) { USBTRACE2("Poll:", rcode); From 237a8a58000c5e04ce39a890451e5f773748a9bf Mon Sep 17 00:00:00 2001 From: Kristian Lauszus Date: Sun, 1 Dec 2013 18:36:19 +0100 Subject: [PATCH 53/53] Formatting --- BTHID.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BTHID.cpp b/BTHID.cpp index 908f5961..3e626b18 100644 --- a/BTHID.cpp +++ b/BTHID.cpp @@ -71,7 +71,7 @@ void BTHID::ACLData(uint8_t* l2capinbuf) { } } if ((l2capinbuf[0] | (l2capinbuf[1] << 8)) == (hci_handle | 0x2000)) { // acl_handle_ok or it's a new connection - if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) { //l2cap_control - Channel ID for ACL-U + if ((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001) { // l2cap_control - Channel ID for ACL-U if (l2capinbuf[8] == L2CAP_CMD_COMMAND_REJECT) { #ifdef DEBUG_USB_HOST Notify(PSTR("\r\nL2CAP Command Rejected - Reason: "), 0x80);