diff --git a/.gitmodules b/.gitmodules
index 324ef790d34c..1822bd3a2b31 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -22,3 +22,6 @@
[submodule "lib/printf"]
path = lib/printf
url = https://github.com/qmk/printf
+[submodule "lib/usbhost/USB_Host_Shield_2.0"]
+ path = lib/usbhost/USB_Host_Shield_2.0
+ url = https://github.com/tmk/USB_Host_Shield_2.0.git
diff --git a/keyboards/converter/usb_usb/custom_matrix.cpp b/keyboards/converter/usb_usb/custom_matrix.cpp
index 296f7fcd026b..cef9bdc34e04 100644
--- a/keyboards/converter/usb_usb/custom_matrix.cpp
+++ b/keyboards/converter/usb_usb/custom_matrix.cpp
@@ -21,7 +21,7 @@ along with this program. If not, see .
// USB HID host
#include "Usb.h"
#include "usbhub.h"
-#include "hid.h"
+#include "usbhid.h"
#include "hidboot.h"
#include "parser.h"
@@ -35,6 +35,13 @@ along with this program. If not, see .
#include "host.h"
#include "keyboard.h"
+/* TMK specific includes
+ #include "hook.h"
+ #include "suspend.h"
+ #include "lufa.h"
+*/
+
+
extern "C" {
#include "quantum.h"
}
@@ -74,10 +81,10 @@ static bool matrix_is_mod = false;
* This supports two cascaded hubs and four keyboards
*/
USB usb_host;
-HIDBoot kbd1(&usb_host);
-HIDBoot kbd2(&usb_host);
-HIDBoot kbd3(&usb_host);
-HIDBoot kbd4(&usb_host);
+HIDBoot kbd1(&usb_host);
+HIDBoot kbd2(&usb_host);
+HIDBoot kbd3(&usb_host);
+HIDBoot kbd4(&usb_host);
KBDReportParser kbd_parser1;
KBDReportParser kbd_parser2;
KBDReportParser kbd_parser3;
@@ -259,4 +266,22 @@ extern "C"
led_set_kb(usb_led);
}
+ // We need to keep doing UHS2 USB::Task() to initialize keyboard
+ // even during USB bus is suspended and remote wakeup is not enabled yet on LUFA side.
+ // This situation can happen just after pluging converter into USB port.
+ /*void hook_usb_suspend_loop(void)
+ {
+ #ifndef TMK_LUFA_DEBUG_UART
+ // This corrupts debug print when suspend
+ suspend_power_down();
+ #endif
+ if (USB_Device_RemoteWakeupEnabled) {
+ if (suspend_wakeup_condition()) {
+ USB_Device_SendRemoteWakeup();
+ }
+ } else {
+ matrix_scan();
+ }
+ }
+ */
};
diff --git a/lib/usbhost/USB_Host_Shield_2.0 b/lib/usbhost/USB_Host_Shield_2.0
new file mode 160000
index 000000000000..3e831605d058
--- /dev/null
+++ b/lib/usbhost/USB_Host_Shield_2.0
@@ -0,0 +1 @@
+Subproject commit 3e831605d058c2c7d209167acd804653699fddc9
diff --git a/lib/usbhost/USB_Host_Shield_2.0/.gitattributes b/lib/usbhost/USB_Host_Shield_2.0/.gitattributes
deleted file mode 100644
index 6238b035a36f..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/.gitattributes
+++ /dev/null
@@ -1,23 +0,0 @@
-# Auto detect text files and perform LF normalization
-* text=auto
-* text eol=lf
-
-# Custom for Visual Studio
-*.cs diff=csharp
-*.sln merge=union
-*.csproj merge=union
-*.vbproj merge=union
-*.fsproj merge=union
-*.dbproj merge=union
-
-# Standard to msysgit
-*.doc diff=astextplain
-*.DOC diff=astextplain
-*.docx diff=astextplain
-*.DOCX diff=astextplain
-*.dot diff=astextplain
-*.DOT diff=astextplain
-*.pdf diff=astextplain
-*.PDF diff=astextplain
-*.rtf diff=astextplain
-*.RTF diff=astextplain
diff --git a/lib/usbhost/USB_Host_Shield_2.0/.gitignore b/lib/usbhost/USB_Host_Shield_2.0/.gitignore
deleted file mode 100644
index 7e69f457ba8a..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/.gitignore
+++ /dev/null
@@ -1,4 +0,0 @@
-*.bak
-*.zip
-*.rar
-build/
\ No newline at end of file
diff --git a/lib/usbhost/USB_Host_Shield_2.0/.gitmodules b/lib/usbhost/USB_Host_Shield_2.0/.gitmodules
deleted file mode 100644
index 32a0783a890b..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/.gitmodules
+++ /dev/null
@@ -1,12 +0,0 @@
-[submodule "examples/testusbhostFAT/generic_storage"]
- path = examples/testusbhostFAT/generic_storage
- url = https://github.com/xxxajk/generic_storage
-[submodule "examples/testusbhostFAT/xmem2"]
- path = examples/testusbhostFAT/xmem2
- url = https://github.com/xxxajk/xmem2
-[submodule "examples/testusbhostFAT/Arduino_Makefile_master"]
- path = examples/testusbhostFAT/Arduino_Makefile_master
- url = https://github.com/xxxajk/Arduino_Makefile_master
-[submodule "examples/testusbhostFAT/RTClib"]
- path = examples/testusbhostFAT/RTClib
- url = https://github.com/xxxajk/RTClib
diff --git a/lib/usbhost/USB_Host_Shield_2.0/BTD.cpp b/lib/usbhost/USB_Host_Shield_2.0/BTD.cpp
deleted file mode 100644
index bcfba14b2b09..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/BTD.cpp
+++ /dev/null
@@ -1,1364 +0,0 @@
-/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
-
- This software may be distributed and modified under the terms of the GNU
- General Public License version 2 (GPL2) as published by the Free Software
- Foundation and appearing in the file GPL2.TXT included in the packaging of
- this file. Please note that GPL2 Section 2[b] requires that all works based
- on this software must also be made publicly available under the terms of
- the GPL2 ("Copyleft").
-
- Contact information
- -------------------
-
- Kristian Lauszus, TKJ Electronics
- Web : http://www.tkjelectronics.com
- e-mail : kristianl@tkjelectronics.com
- */
-
-#include "BTD.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;
-const uint8_t BTD::BTD_EVENT_PIPE = 1;
-const uint8_t BTD::BTD_DATAIN_PIPE = 2;
-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
-qNextPollTime(0), // Reset NextPollTime
-pollInterval(0),
-bPollEnable(false) // Don't start polling before dongle is connected
-{
- for(uint8_t i = 0; i < BTD_NUM_SERVICES; i++)
- btService[i] = NULL;
-
- Initialize(); // Set all variables, endpoint structs etc. to default values
-
- if(pUsb) // Register in USB subsystem
- pUsb->RegisterDeviceClass(this); // Set devConfig[] entry
-}
-
-uint8_t BTD::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
- const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);
- uint8_t buf[constBufSize];
- USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf);
- uint8_t rcode;
- UsbDevice *p = NULL;
- EpInfo *oldep_ptr = NULL;
-
- Initialize(); // Set all variables, endpoint structs etc. to default values
-
- AddressPool &addrPool = pUsb->GetAddressPool(); // Get memory address of USB device address pool
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nBTD ConfigureDevice"), 0x80);
-#endif
-
- 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;
- }
-
- p = addrPool.GetUsbDevicePtr(0); // Get pointer to pseudo device with address 0 assigned
- if(!p) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nAddress not found"), 0x80);
-#endif
- return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
- }
-
- if(!p->epinfo) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nepinfo is null"), 0x80);
-#endif
- return USB_ERROR_EPINFO_IS_NULL;
- }
-
- 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;
- 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;
-
- bAddress = addrPool.AllocAddress(parent, false, port); // Allocate new address according to device class
-
- if(!bAddress) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nOut of address space"), 0x80);
-#endif
- return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
- }
-
- epInfo[0].maxPktSize = udd->bMaxPacketSize0; // Extract Max Packet Size from device descriptor
- epInfo[1].epAddr = udd->bNumConfigurations; // Steal and abuse from epInfo structure to save memory
-
- VID = udd->idVendor;
- PID = udd->idProduct;
-
- return USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET;
-
-FailGetDevDescr:
-#ifdef DEBUG_USB_HOST
- NotifyFailGetDevDescr(rcode);
-#endif
- if(rcode != hrJERR)
- rcode = USB_ERROR_FailGetDevDescr;
- Release();
- return rcode;
-};
-
-uint8_t BTD::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) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nsetAddr: "), 0x80);
- D_PrintHex (rcode, 0x80);
-#endif
- p->lowspeed = false;
- goto Fail;
- }
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nAddr: "), 0x80);
- D_PrintHex (bAddress, 0x80);
-#endif
-
- p->lowspeed = false;
-
- 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;
-
- rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); // Assign epInfo to epinfo pointer - only EP0 is known
- if(rcode)
- goto FailSetDevTblEntry;
-
- if(VID == PS3_VID && (PID == PS3_PID || PID == PS3NAVIGATION_PID || PID == PS3MOVE_PID)) {
- delay(100);
- rcode = pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, 1); // We only need the Control endpoint, so we don't have to initialize the other endpoints of device
- if(rcode)
- goto FailSetConfDescr;
-
-#ifdef DEBUG_USB_HOST
- if(PID == PS3_PID || PID == PS3NAVIGATION_PID) {
- if(PID == PS3_PID)
- Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80);
- else // It must be a navigation controller
- Notify(PSTR("\r\nNavigation Controller Connected"), 0x80);
- } else // It must be a Motion controller
- Notify(PSTR("\r\nMotion Controller Connected"), 0x80);
-#endif
-
- 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) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nPlease plug in the dongle before trying to pair with the PS3 Controller\r\nor set the Bluetooth address in the constructor of the PS3BT class"), 0x80);
-#endif
- } else {
- if(PID == PS3_PID || PID == PS3NAVIGATION_PID)
- setBdaddr(my_bdaddr); // Set internal Bluetooth address
- else
- setMoveBdaddr(my_bdaddr); // Set internal Bluetooth address
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80);
- for(int8_t i = 5; i > 0; i--) {
- D_PrintHex (my_bdaddr[i], 0x80);
- Notify(PSTR(":"), 0x80);
- }
- D_PrintHex (my_bdaddr[0], 0x80);
-#endif
- }
-
- pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, 0); // Reset configuration value
- pUsb->setAddr(bAddress, 0, 0); // Reset address
- Release(); // Release device
- return USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; // Return
- } else {
- // Check if attached device is a Bluetooth dongle and fill endpoint data structure
- // First interface in the configuration must have Bluetooth assigned Class/Subclass/Protocol
- // And 3 endpoints - interrupt-IN, bulk-IN, bulk-OUT, not necessarily in this order
- for(uint8_t i = 0; i < num_of_conf; i++) {
- if(VID == IOGEAR_GBU521_VID && PID == IOGEAR_GBU521_PID) {
- ConfigDescParser confDescrParser(this); // Needed for the IOGEAR GBU521
- rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
- } else {
- ConfigDescParser confDescrParser(this);
- rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
- }
- if(rcode) // Check error code
- goto FailGetConfDescr;
- if(bNumEP >= BTD_MAX_ENDPOINTS) // All endpoints extracted
- break;
- }
-
- if(bNumEP < BTD_MAX_ENDPOINTS)
- goto FailUnknownDevice;
-
- // Assign epInfo to epinfo pointer - this time all 3 endpoins
- rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
- if(rcode)
- goto FailSetDevTblEntry;
-
- // Set Configuration Value
- rcode = pUsb->setConf(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, bConfNum);
- if(rcode)
- goto FailSetConfDescr;
-
- hci_num_reset_loops = 100; // only loop 100 times before trying to send the hci reset command
- hci_counter = 0;
- hci_state = HCI_INIT_STATE;
- watingForConnection = false;
- bPollEnable = true;
-
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nBluetooth Dongle Initialized"), 0x80);
-#endif
- }
- return 0; // Successful configuration
-
- /* Diagnostic messages */
-FailSetDevTblEntry:
-#ifdef DEBUG_USB_HOST
- NotifyFailSetDevTblEntry();
- goto Fail;
-#endif
-
-FailGetConfDescr:
-#ifdef DEBUG_USB_HOST
- NotifyFailGetConfDescr();
- goto Fail;
-#endif
-
-FailSetConfDescr:
-#ifdef DEBUG_USB_HOST
- NotifyFailSetConfDescr();
-#endif
- goto Fail;
-
-FailUnknownDevice:
-#ifdef DEBUG_USB_HOST
- NotifyFailUnknownDevice(VID, PID);
-#endif
- pUsb->setAddr(bAddress, 0, 0); // Reset address
- rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
-Fail:
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nBTD Init Failed, error code: "), 0x80);
- NotifyFail(rcode);
-#endif
- Release();
- return rcode;
-}
-
-void BTD::Initialize() {
- uint8_t i;
- for(i = 0; i < BTD_MAX_ENDPOINTS; i++) {
- epInfo[i].epAddr = 0;
- epInfo[i].maxPktSize = (i) ? 0 : 8;
- epInfo[i].epAttribs = 0;
- epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
- }
- for(i = 0; i < BTD_NUM_SERVICES; i++) {
- if(btService[i])
- btService[i]->Reset(); // Reset all Bluetooth services
- }
-
- connectToWii = false;
- incomingWii = false;
- connectToHIDDevice = false;
- incomingHIDDevice = false;
- incomingPS4 = false;
- bAddress = 0; // Clear device address
- bNumEP = 1; // Must have to be reset to 1
- qNextPollTime = 0; // Reset next poll time
- pollInterval = 0;
- bPollEnable = false; // Don't start polling before dongle is connected
-}
-
-/* Extracts interrupt-IN, bulk-IN, bulk-OUT endpoint information from config descriptor */
-void BTD::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) {
- //ErrorMessage(PSTR("Conf.Val"),conf);
- //ErrorMessage(PSTR("Iface Num"),iface);
- //ErrorMessage(PSTR("Alt.Set"),alt);
-
- if(alt) // Wrong interface - by BT spec, no alt setting
- return;
-
- bConfNum = conf;
- uint8_t index;
-
- if((pep->bmAttributes & 0x03) == 3 && (pep->bEndpointAddress & 0x80) == 0x80) { // Interrupt In endpoint found
- index = BTD_EVENT_PIPE;
- epInfo[index].bmNakPower = USB_NAK_NOWAIT;
- } else {
- if((pep->bmAttributes & 0x02) == 2) // Bulk endpoint found
- index = ((pep->bEndpointAddress & 0x80) == 0x80) ? BTD_DATAIN_PIPE : BTD_DATAOUT_PIPE;
- else
- return;
- }
-
- // Fill the rest of endpoint data structure
- epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
- epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
-#ifdef EXTRADEBUG
- PrintEndpointDescriptor(pep);
-#endif
- if(pollInterval < pep->bInterval) // Set the polling interval as the largest polling interval obtained from endpoints
- pollInterval = pep->bInterval;
- bNumEP++;
-}
-
-void BTD::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr) {
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nEndpoint descriptor:"), 0x80);
- Notify(PSTR("\r\nLength:\t\t"), 0x80);
- D_PrintHex (ep_ptr->bLength, 0x80);
- Notify(PSTR("\r\nType:\t\t"), 0x80);
- D_PrintHex (ep_ptr->bDescriptorType, 0x80);
- Notify(PSTR("\r\nAddress:\t"), 0x80);
- D_PrintHex (ep_ptr->bEndpointAddress, 0x80);
- Notify(PSTR("\r\nAttributes:\t"), 0x80);
- D_PrintHex (ep_ptr->bmAttributes, 0x80);
- Notify(PSTR("\r\nMaxPktSize:\t"), 0x80);
- D_PrintHex (ep_ptr->wMaxPacketSize, 0x80);
- Notify(PSTR("\r\nPoll Intrv:\t"), 0x80);
- D_PrintHex (ep_ptr->bInterval, 0x80);
-#endif
-}
-
-/* Performs a cleanup after failed Init() attempt */
-uint8_t BTD::Release() {
- Initialize(); // Set all variables, endpoint structs etc. to default values
- pUsb->GetAddressPool().FreeAddress(bAddress);
- return 0;
-}
-
-uint8_t BTD::Poll() {
- if(!bPollEnable)
- return 0;
- if((long)(millis() - qNextPollTime) >= 0L) { // Don't poll if shorter than polling interval
- qNextPollTime = millis() + pollInterval; // Set new poll time
- HCI_event_task(); // Poll the HCI event pipe
- HCI_task(); // HCI state machine
- ACL_event_task(); // Poll the ACL input pipe too
- }
- return 0;
-}
-
-void BTD::disconnect() {
- for(uint8_t i = 0; i < BTD_NUM_SERVICES; i++)
- if(btService[i])
- btService[i]->disconnect();
-};
-
-void BTD::HCI_event_task() {
- uint16_t length = BULK_MAXPKTSIZE; // Request more than 16 bytes anyway, the inTransfer routine will take care of this
- uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ BTD_EVENT_PIPE ].epAddr, &length, hcibuf); // Input on endpoint 1
-
- if(!rcode || rcode == hrNAK) { // Check for errors
- switch(hcibuf[0]) { // Switch on event type
- case EV_COMMAND_COMPLETE:
- if(!hcibuf[5]) { // Check if command succeeded
- hci_set_flag(HCI_FLAG_CMD_COMPLETE); // Set command complete flag
- if((hcibuf[3] == 0x01) && (hcibuf[4] == 0x10)) { // Parameters from read local version information
- hci_version = hcibuf[6]; // Used to check if it supports 2.0+EDR - see http://www.bluetooth.org/Technical/AssignedNumbers/hci.htm
- hci_set_flag(HCI_FLAG_READ_VERSION);
- } else if((hcibuf[3] == 0x09) && (hcibuf[4] == 0x10)) { // Parameters from read local bluetooth address
- for(uint8_t i = 0; i < 6; i++)
- my_bdaddr[i] = hcibuf[6 + i];
- hci_set_flag(HCI_FLAG_READ_BDADDR);
- }
- }
- break;
-
- case EV_COMMAND_STATUS:
- 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);
-#endif
- }
- break;
-
- case EV_INQUIRY_COMPLETE:
- if(inquiry_counter >= 5 && (pairWithWii || pairWithHIDDevice)) {
- inquiry_counter = 0;
-#ifdef DEBUG_USB_HOST
- 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++;
- break;
-
- case EV_INQUIRY_RESULT:
- if(hcibuf[2]) { // Check that there is more than zero responses
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nNumber of responses: "), 0x80);
- Notify(hcibuf[2], 0x80);
-#endif
- for(uint8_t i = 0; i < hcibuf[2]; i++) {
- uint8_t offset = 8 * hcibuf[2] + 3 * i;
-
- for(uint8_t j = 0; j < 3; j++)
- classOfDevice[j] = hcibuf[j + 4 + offset];
-
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nClass of device: "), 0x80);
- D_PrintHex (classOfDevice[2], 0x80);
- Notify(PSTR(" "), 0x80);
- D_PrintHex (classOfDevice[1], 0x80);
- Notify(PSTR(" "), 0x80);
- D_PrintHex (classOfDevice[0], 0x80);
-#endif
-
- if(pairWithWii && classOfDevice[2] == 0x00 && (classOfDevice[1] & 0x05) && (classOfDevice[0] & 0x0C)) { // See http://wiibrew.org/wiki/Wiimote#SDP_information
- checkRemoteName = true; // Check remote name to distinguish between the different controllers
-
- for(uint8_t j = 0; j < 6; j++)
- disc_bdaddr[j] = hcibuf[j + 3 + 6 * i];
-
- hci_set_flag(HCI_FLAG_DEVICE_FOUND);
- break;
- } else if(pairWithHIDDevice && (classOfDevice[1] & 0x05) && (classOfDevice[0] & 0xC8)) { // Check if it is a mouse, keyboard or a gamepad - see: http://bluetooth-pentest.narod.ru/software/bluetooth_class_of_device-service_generator.html
-#ifdef DEBUG_USB_HOST
- if(classOfDevice[0] & 0x80)
- Notify(PSTR("\r\nMouse found"), 0x80);
- if(classOfDevice[0] & 0x40)
- Notify(PSTR("\r\nKeyboard found"), 0x80);
- if(classOfDevice[0] & 0x08)
- Notify(PSTR("\r\nGamepad found"), 0x80);
-#endif
-
- for(uint8_t j = 0; j < 6; j++)
- disc_bdaddr[j] = hcibuf[j + 3 + 6 * i];
-
- hci_set_flag(HCI_FLAG_DEVICE_FOUND);
- break;
- }
- }
- }
- break;
-
- case EV_CONNECT_COMPLETE:
- hci_set_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_set_flag(HCI_FLAG_CONNECT_COMPLETE); // Set connection complete flag
- } else {
- hci_state = HCI_CHECK_DEVICE_SERVICE;
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nConnection Failed: "), 0x80);
- D_PrintHex (hcibuf[2], 0x80);
-#endif
- }
- break;
-
- case EV_DISCONNECT_COMPLETE:
- if(!hcibuf[2]) { // Check if disconnected OK
- hci_set_flag(HCI_FLAG_DISCONNECT_COMPLETE); // Set disconnect command complete flag
- hci_clear_flag(HCI_FLAG_CONNECT_COMPLETE); // Clear connection complete flag
- }
- break;
-
- case EV_REMOTE_NAME_COMPLETE:
- if(!hcibuf[2]) { // Check if reading is OK
- for(uint8_t i = 0; i < min(sizeof (remote_name), sizeof (hcibuf) - 9); i++) {
- remote_name[i] = hcibuf[9 + i];
- if(remote_name[i] == '\0') // End of string
- break;
- }
- // TODO: Altid sæt '\0' i remote name!
- hci_set_flag(HCI_FLAG_REMOTE_NAME_COMPLETE);
- }
- break;
-
- case EV_INCOMING_CONNECT:
- for(uint8_t i = 0; i < 6; i++)
- disc_bdaddr[i] = hcibuf[i + 2];
-
- for(uint8_t i = 0; i < 3; i++)
- classOfDevice[i] = hcibuf[i + 8];
-
- if((classOfDevice[1] & 0x05) && (classOfDevice[0] & 0xC8)) { // Check if it is a mouse, keyboard or a gamepad
-#ifdef DEBUG_USB_HOST
- if(classOfDevice[0] & 0x80)
- Notify(PSTR("\r\nMouse is connecting"), 0x80);
- if(classOfDevice[0] & 0x40)
- Notify(PSTR("\r\nKeyboard is connecting"), 0x80);
- if(classOfDevice[0] & 0x08)
- Notify(PSTR("\r\nGamepad is connecting"), 0x80);
-#endif
- incomingHIDDevice = true;
- }
-
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nClass of device: "), 0x80);
- D_PrintHex (classOfDevice[2], 0x80);
- Notify(PSTR(" "), 0x80);
- D_PrintHex (classOfDevice[1], 0x80);
- Notify(PSTR(" "), 0x80);
- D_PrintHex (classOfDevice[0], 0x80);
-#endif
- hci_set_flag(HCI_FLAG_INCOMING_REQUEST);
- break;
-
- case EV_PIN_CODE_REQUEST:
- if(pairWithWii) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nPairing with Wiimote"), 0x80);
-#endif
- hci_pin_code_request_reply();
- } else if(btdPin != NULL) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nBluetooth pin is set too: "), 0x80);
- NotifyStr(btdPin, 0x80);
-#endif
- hci_pin_code_request_reply();
- } else {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nNo pin was set"), 0x80);
-#endif
- hci_pin_code_negative_request_reply();
- }
- break;
-
- case EV_LINK_KEY_REQUEST:
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nReceived Key Request"), 0x80);
-#endif
- hci_link_key_request_negative_reply();
- break;
-
- case EV_AUTHENTICATION_COMPLETE:
- if(pairWithWii && !connectToWii) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nPairing successful with Wiimote"), 0x80);
-#endif
- connectToWii = true; // Used to indicate to the Wii service, that it should connect to this device
- } else if(pairWithHIDDevice && !connectToHIDDevice) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nPairing successful with HID device"), 0x80);
-#endif
- connectToHIDDevice = true; // Used to indicate to the BTHID service, that it should connect to this device
- }
- break;
- /* We will just ignore the following events */
- case EV_NUM_COMPLETE_PKT:
- case EV_ROLE_CHANGED:
- case EV_PAGE_SCAN_REP_MODE:
- case EV_LOOPBACK_COMMAND:
- case EV_DATA_BUFFER_OVERFLOW:
- case EV_CHANGE_CONNECTION_LINK:
- case EV_MAX_SLOTS_CHANGE:
- case EV_QOS_SETUP_COMPLETE:
- case EV_LINK_KEY_NOTIFICATION:
- case EV_ENCRYPTION_CHANGE:
- case EV_READ_REMOTE_VERSION_INFORMATION_COMPLETE:
- break;
-#ifdef EXTRADEBUG
- default:
- if(hcibuf[0] != 0x00) {
- Notify(PSTR("\r\nUnmanaged HCI Event: "), 0x80);
- D_PrintHex (hcibuf[0], 0x80);
- }
- break;
-#endif
- } // Switch
- }
-#ifdef EXTRADEBUG
- else {
- Notify(PSTR("\r\nHCI event error: "), 0x80);
- D_PrintHex (rcode, 0x80);
- }
-#endif
-}
-
-/* Poll Bluetooth and print result */
-void BTD::HCI_task() {
- switch(hci_state) {
- case HCI_INIT_STATE:
- hci_counter++;
- if(hci_counter > hci_num_reset_loops) { // wait until we have looped x times to clear any old events
- hci_reset();
- hci_state = HCI_RESET_STATE;
- hci_counter = 0;
- }
- break;
-
- case HCI_RESET_STATE:
- hci_counter++;
- if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
- hci_counter = 0;
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nHCI Reset complete"), 0x80);
-#endif
- hci_state = HCI_CLASS_STATE;
- hci_write_class_of_device();
- } else if(hci_counter > hci_num_reset_loops) {
- hci_num_reset_loops *= 10;
- if(hci_num_reset_loops > 2000)
- hci_num_reset_loops = 2000;
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nNo response to HCI Reset"), 0x80);
-#endif
- hci_state = HCI_INIT_STATE;
- hci_counter = 0;
- }
- break;
-
- case HCI_CLASS_STATE:
- if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nWrite class of device"), 0x80);
-#endif
- hci_state = HCI_BDADDR_STATE;
- hci_read_bdaddr();
- }
- break;
-
- case HCI_BDADDR_STATE:
- if(hci_check_flag(HCI_FLAG_READ_BDADDR)) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nLocal Bluetooth Address: "), 0x80);
- for(int8_t i = 5; i > 0; i--) {
- D_PrintHex (my_bdaddr[i], 0x80);
- Notify(PSTR(":"), 0x80);
- }
- D_PrintHex (my_bdaddr[0], 0x80);
-#endif
- hci_read_local_version_information();
- hci_state = HCI_LOCAL_VERSION_STATE;
- }
- break;
-
- case HCI_LOCAL_VERSION_STATE: // The local version is used by the PS3BT class
- if(hci_check_flag(HCI_FLAG_READ_VERSION)) {
- if(btdName != NULL) {
- hci_set_local_name(btdName);
- hci_state = HCI_SET_NAME_STATE;
- } else
- hci_state = HCI_CHECK_DEVICE_SERVICE;
- }
- break;
-
- case HCI_SET_NAME_STATE:
- if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nThe name is set to: "), 0x80);
- NotifyStr(btdName, 0x80);
-#endif
- hci_state = HCI_CHECK_DEVICE_SERVICE;
- }
- break;
-
- case HCI_CHECK_DEVICE_SERVICE:
- if(pairWithHIDDevice || pairWithWii) { // Check if it should try to connect to a Wiimote
-#ifdef DEBUG_USB_HOST
- if(pairWithWii)
- Notify(PSTR("\r\nStarting inquiry\r\nPress 1 & 2 on the Wiimote\r\nOr press the SYNC button if you are using a Wii U Pro Controller or a Wii Balance Board"), 0x80);
- else
- Notify(PSTR("\r\nPlease enable discovery of your device"), 0x80);
-#endif
- hci_inquiry();
- hci_state = HCI_INQUIRY_STATE;
- } else
- hci_state = HCI_SCANNING_STATE; // Don't try to connect to a Wiimote
- break;
-
- case HCI_INQUIRY_STATE:
- if(hci_check_flag(HCI_FLAG_DEVICE_FOUND)) {
- hci_inquiry_cancel(); // Stop inquiry
-#ifdef DEBUG_USB_HOST
- 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);
- if(pairWithWii)
- Notify(PSTR("\r\nWII Wii(&Btd);"), 0x80);
- else
- Notify(PSTR("\r\nBTHID bthid(&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(checkRemoteName) {
- hci_remote_name(); // We need to know the name to distinguish between the Wiimote, the new Wiimote with Motion Plus inside, a Wii U Pro Controller and a Wii Balance Board
- hci_state = HCI_REMOTE_NAME_STATE;
- } else
- hci_state = HCI_CONNECT_DEVICE_STATE;
- }
- break;
-
- case HCI_CONNECT_DEVICE_STATE:
- if(hci_check_flag(HCI_FLAG_CMD_COMPLETE)) {
-#ifdef DEBUG_USB_HOST
- if(pairWithWii)
- Notify(PSTR("\r\nConnecting to Wiimote"), 0x80);
- else
- Notify(PSTR("\r\nConnecting to HID device"), 0x80);
-#endif
- checkRemoteName = false;
- hci_connect();
- hci_state = HCI_CONNECTED_DEVICE_STATE;
- }
- break;
-
- case HCI_CONNECTED_DEVICE_STATE:
- if(hci_check_flag(HCI_FLAG_CONNECT_EVENT)) {
- if(hci_check_flag(HCI_FLAG_CONNECT_COMPLETE)) {
-#ifdef DEBUG_USB_HOST
- 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;
- } else {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nTrying to connect one more time..."), 0x80);
-#endif
- hci_connect(); // Try to connect one more time
- }
- }
- break;
-
- case HCI_SCANNING_STATE:
- if(!connectToWii && !pairWithWii && !connectToHIDDevice && !pairWithHIDDevice) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nWait For Incoming Connection Request"), 0x80);
-#endif
- hci_write_scan_enable();
- watingForConnection = true;
- hci_state = HCI_CONNECT_IN_STATE;
- }
- break;
-
- case HCI_CONNECT_IN_STATE:
- if(hci_check_flag(HCI_FLAG_INCOMING_REQUEST)) {
- watingForConnection = false;
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nIncoming Connection Request"), 0x80);
-#endif
- hci_remote_name();
- hci_state = HCI_REMOTE_NAME_STATE;
- } else if(hci_check_flag(HCI_FLAG_DISCONNECT_COMPLETE))
- hci_state = HCI_DISCONNECT_STATE;
- break;
-
- case HCI_REMOTE_NAME_STATE:
- if(hci_check_flag(HCI_FLAG_REMOTE_NAME_COMPLETE)) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nRemote Name: "), 0x80);
- for(uint8_t i = 0; i < strlen(remote_name); i++)
- Notifyc(remote_name[i], 0x80);
-#endif
- if(strncmp((const char*)remote_name, "Nintendo", 8) == 0) {
- incomingWii = true;
- motionPlusInside = false;
- wiiUProController = false;
- pairWiiUsingSync = false;
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nWiimote is connecting"), 0x80);
-#endif
- if(strncmp((const char*)remote_name, "Nintendo RVL-CNT-01-TR", 22) == 0) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR(" with Motion Plus Inside"), 0x80);
-#endif
- motionPlusInside = true;
- } else if(strncmp((const char*)remote_name, "Nintendo RVL-CNT-01-UC", 22) == 0) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR(" - Wii U Pro Controller"), 0x80);
-#endif
- wiiUProController = motionPlusInside = pairWiiUsingSync = true;
- } else if(strncmp((const char*)remote_name, "Nintendo RVL-WBC-01", 19) == 0) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR(" - Wii Balance Board"), 0x80);
-#endif
- pairWiiUsingSync = true;
- }
- }
- if(classOfDevice[2] == 0 && classOfDevice[1] == 0x25 && classOfDevice[0] == 0x08 && strncmp((const char*)remote_name, "Wireless Controller", 19) == 0) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nPS4 controller is connecting"), 0x80);
-#endif
- incomingPS4 = true;
- }
- if(pairWithWii && checkRemoteName)
- hci_state = HCI_CONNECT_DEVICE_STATE;
- else {
- hci_accept_connection();
- hci_state = HCI_CONNECTED_STATE;
- }
- }
- break;
-
- case HCI_CONNECTED_STATE:
- if(hci_check_flag(HCI_FLAG_CONNECT_COMPLETE)) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nConnected to Device: "), 0x80);
- for(int8_t i = 5; i > 0; i--) {
- D_PrintHex (disc_bdaddr[i], 0x80);
- Notify(PSTR(":"), 0x80);
- }
- D_PrintHex (disc_bdaddr[0], 0x80);
-#endif
- if(incomingPS4)
- connectToHIDDevice = true; // We should always connect to the PS4 controller
-
- // Clear these flags for a new connection
- l2capConnectionClaimed = false;
- sdpConnectionClaimed = false;
- rfcommConnectionClaimed = false;
-
- hci_event_flag = 0;
- hci_state = HCI_DONE_STATE;
- }
- break;
-
- case HCI_DONE_STATE:
- hci_counter++;
- if(hci_counter > 1000) { // Wait until we have looped 1000 times to make sure that the L2CAP connection has been started
- hci_counter = 0;
- hci_state = HCI_SCANNING_STATE;
- }
- break;
-
- case HCI_DISCONNECT_STATE:
- if(hci_check_flag(HCI_FLAG_DISCONNECT_COMPLETE)) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nHCI Disconnected from Device"), 0x80);
-#endif
- hci_event_flag = 0; // Clear all flags
-
- // Reset all buffers
- memset(hcibuf, 0, BULK_MAXPKTSIZE);
- memset(l2capinbuf, 0, BULK_MAXPKTSIZE);
-
- connectToWii = incomingWii = pairWithWii = false;
- connectToHIDDevice = incomingHIDDevice = pairWithHIDDevice = checkRemoteName = false;
- incomingPS4 = false;
-
- hci_state = HCI_SCANNING_STATE;
- }
- break;
- default:
- break;
- }
-}
-
-void BTD::ACL_event_task() {
- uint16_t length = BULK_MAXPKTSIZE;
- uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ BTD_DATAIN_PIPE ].epAddr, &length, l2capinbuf); // Input on endpoint 2
-
- if(!rcode) { // Check for errors
- if(length > 0) { // Check if any data was read
- for(uint8_t i = 0; i < BTD_NUM_SERVICES; i++) {
- if(btService[i])
- btService[i]->ACLData(l2capinbuf);
- }
- }
- }
-#ifdef EXTRADEBUG
- else if(rcode != hrNAK) {
- Notify(PSTR("\r\nACL data in error: "), 0x80);
- D_PrintHex (rcode, 0x80);
- }
-#endif
- for(uint8_t i = 0; i < BTD_NUM_SERVICES; i++)
- if(btService[i])
- btService[i]->Run();
-}
-
-/************************************************************/
-/* HCI Commands */
-
-/************************************************************/
-void BTD::HCI_Command(uint8_t* data, uint16_t nbytes) {
- hci_clear_flag(HCI_FLAG_CMD_COMPLETE);
- pUsb->ctrlReq(bAddress, epInfo[ BTD_CONTROL_PIPE ].epAddr, bmREQ_HCI_OUT, 0x00, 0x00, 0x00, 0x00, nbytes, nbytes, data, NULL);
-}
-
-void BTD::hci_reset() {
- hci_event_flag = 0; // Clear all the flags
- hcibuf[0] = 0x03; // HCI OCF = 3
- hcibuf[1] = 0x03 << 2; // HCI OGF = 3
- hcibuf[2] = 0x00;
-
- HCI_Command(hcibuf, 3);
-}
-
-void BTD::hci_write_scan_enable() {
- hci_clear_flag(HCI_FLAG_INCOMING_REQUEST);
- hcibuf[0] = 0x1A; // HCI OCF = 1A
- hcibuf[1] = 0x03 << 2; // HCI OGF = 3
- hcibuf[2] = 0x01; // parameter length = 1
- if(btdName != NULL)
- hcibuf[3] = 0x03; // Inquiry Scan enabled. Page Scan enabled.
- else
- hcibuf[3] = 0x02; // Inquiry Scan disabled. Page Scan enabled.
-
- HCI_Command(hcibuf, 4);
-}
-
-void BTD::hci_write_scan_disable() {
- hcibuf[0] = 0x1A; // HCI OCF = 1A
- hcibuf[1] = 0x03 << 2; // HCI OGF = 3
- hcibuf[2] = 0x01; // parameter length = 1
- hcibuf[3] = 0x00; // Inquiry Scan disabled. Page Scan disabled.
-
- HCI_Command(hcibuf, 4);
-}
-
-void BTD::hci_read_bdaddr() {
- hci_clear_flag(HCI_FLAG_READ_BDADDR);
- hcibuf[0] = 0x09; // HCI OCF = 9
- hcibuf[1] = 0x04 << 2; // HCI OGF = 4
- hcibuf[2] = 0x00;
-
- HCI_Command(hcibuf, 3);
-}
-
-void BTD::hci_read_local_version_information() {
- hci_clear_flag(HCI_FLAG_READ_VERSION);
- hcibuf[0] = 0x01; // HCI OCF = 1
- hcibuf[1] = 0x04 << 2; // HCI OGF = 4
- hcibuf[2] = 0x00;
-
- HCI_Command(hcibuf, 3);
-}
-
-void BTD::hci_accept_connection() {
- hci_clear_flag(HCI_FLAG_CONNECT_COMPLETE);
- hcibuf[0] = 0x09; // HCI OCF = 9
- hcibuf[1] = 0x01 << 2; // HCI OGF = 1
- hcibuf[2] = 0x07; // parameter length 7
- 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[9] = 0x00; // Switch role to master
-
- HCI_Command(hcibuf, 10);
-}
-
-void BTD::hci_remote_name() {
- hci_clear_flag(HCI_FLAG_REMOTE_NAME_COMPLETE);
- hcibuf[0] = 0x19; // HCI OCF = 19
- hcibuf[1] = 0x01 << 2; // HCI OGF = 1
- hcibuf[2] = 0x0A; // parameter length = 10
- 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[9] = 0x01; // Page Scan Repetition Mode
- hcibuf[10] = 0x00; // Reserved
- hcibuf[11] = 0x00; // Clock offset - low byte
- hcibuf[12] = 0x00; // Clock offset - high byte
-
- HCI_Command(hcibuf, 13);
-}
-
-void BTD::hci_set_local_name(const char* name) {
- hcibuf[0] = 0x13; // HCI OCF = 13
- hcibuf[1] = 0x03 << 2; // HCI OGF = 3
- hcibuf[2] = strlen(name) + 1; // parameter length = the length of the string + end byte
- uint8_t i;
- for(i = 0; i < strlen(name); i++)
- hcibuf[i + 3] = name[i];
- hcibuf[i + 3] = 0x00; // End of string
-
- HCI_Command(hcibuf, 4 + strlen(name));
-}
-
-void BTD::hci_inquiry() {
- hci_clear_flag(HCI_FLAG_DEVICE_FOUND);
- hcibuf[0] = 0x01;
- hcibuf[1] = 0x01 << 2; // HCI OGF = 1
- hcibuf[2] = 0x05; // Parameter Total Length = 5
- hcibuf[3] = 0x33; // LAP: Genera/Unlimited Inquiry Access Code (GIAC = 0x9E8B33) - see https://www.bluetooth.org/Technical/AssignedNumbers/baseband.htm
- hcibuf[4] = 0x8B;
- hcibuf[5] = 0x9E;
- hcibuf[6] = 0x30; // Inquiry time = 61.44 sec (maximum)
- hcibuf[7] = 0x0A; // 10 number of responses
-
- HCI_Command(hcibuf, 8);
-}
-
-void BTD::hci_inquiry_cancel() {
- hcibuf[0] = 0x02;
- hcibuf[1] = 0x01 << 2; // HCI OGF = 1
- hcibuf[2] = 0x00; // Parameter Total Length = 0
-
- HCI_Command(hcibuf, 3);
-}
-
-void BTD::hci_connect() {
- hci_connect(disc_bdaddr); // Use last discovered device
-}
-
-void BTD::hci_connect(uint8_t *bdaddr) {
- hci_clear_flag(HCI_FLAG_CONNECT_COMPLETE | HCI_FLAG_CONNECT_EVENT);
- hcibuf[0] = 0x05;
- hcibuf[1] = 0x01 << 2; // HCI OGF = 1
- hcibuf[2] = 0x0D; // parameter Total Length = 13
- 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
- hcibuf[12] = 0x00; // Reserved
- hcibuf[13] = 0x00; // Clock offset
- hcibuf[14] = 0x00; // Invalid clock offset
- hcibuf[15] = 0x00; // Do not allow role switch
-
- HCI_Command(hcibuf, 16);
-}
-
-void BTD::hci_pin_code_request_reply() {
- hcibuf[0] = 0x0D; // HCI OCF = 0D
- hcibuf[1] = 0x01 << 2; // HCI OGF = 1
- hcibuf[2] = 0x17; // parameter length 23
- 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];
- if(pairWithWii) {
- hcibuf[9] = 6; // Pin length is the length of the Bluetooth address
- if(pairWiiUsingSync) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nParing with Wii controller via SYNC"), 0x80);
-#endif
- for(uint8_t i = 0; i < 6; i++)
- hcibuf[10 + i] = my_bdaddr[i]; // The pin is the Bluetooth dongles Bluetooth address backwards
- } else {
- for(uint8_t i = 0; i < 6; i++)
- hcibuf[10 + i] = disc_bdaddr[i]; // The pin is the Wiimote's Bluetooth address backwards
- }
- for(uint8_t i = 16; i < 26; i++)
- hcibuf[i] = 0x00; // The rest should be 0
- } else {
- hcibuf[9] = strlen(btdPin); // Length of pin
- uint8_t i;
- for(i = 0; i < strlen(btdPin); i++) // The maximum size of the pin is 16
- hcibuf[i + 10] = btdPin[i];
- for(; i < 16; i++)
- hcibuf[i + 10] = 0x00; // The rest should be 0
- }
-
- HCI_Command(hcibuf, 26);
-}
-
-void BTD::hci_pin_code_negative_request_reply() {
- hcibuf[0] = 0x0E; // HCI OCF = 0E
- hcibuf[1] = 0x01 << 2; // HCI OGF = 1
- hcibuf[2] = 0x06; // parameter length 6
- 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];
-
- HCI_Command(hcibuf, 9);
-}
-
-void BTD::hci_link_key_request_negative_reply() {
- hcibuf[0] = 0x0C; // HCI OCF = 0C
- hcibuf[1] = 0x01 << 2; // HCI OGF = 1
- hcibuf[2] = 0x06; // parameter length 6
- 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];
-
- HCI_Command(hcibuf, 9);
-}
-
-void BTD::hci_authentication_request() {
- hcibuf[0] = 0x11; // HCI OCF = 11
- hcibuf[1] = 0x01 << 2; // HCI OGF = 1
- hcibuf[2] = 0x02; // parameter length = 2
- hcibuf[3] = (uint8_t)(hci_handle & 0xFF); //connection handle - low byte
- hcibuf[4] = (uint8_t)((hci_handle >> 8) & 0x0F); //connection handle - high byte
-
- HCI_Command(hcibuf, 5);
-}
-
-void BTD::hci_disconnect(uint16_t handle) { // This is called by the different services
- hci_clear_flag(HCI_FLAG_DISCONNECT_COMPLETE);
- hcibuf[0] = 0x06; // HCI OCF = 6
- hcibuf[1] = 0x01 << 2; // HCI OGF = 1
- hcibuf[2] = 0x03; // parameter length = 3
- hcibuf[3] = (uint8_t)(handle & 0xFF); //connection handle - low byte
- hcibuf[4] = (uint8_t)((handle >> 8) & 0x0F); //connection handle - high byte
- hcibuf[5] = 0x13; // reason
-
- HCI_Command(hcibuf, 6);
-}
-
-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 = 24
- hcibuf[1] = 0x03 << 2; // HCI OGF = 3
- hcibuf[2] = 0x03; // parameter length = 3
- hcibuf[3] = 0x04; // Robot
- hcibuf[4] = 0x08; // Toy
- hcibuf[5] = 0x00;
-
- HCI_Command(hcibuf, 6);
-}
-/*******************************************************************
- * *
- * HCI ACL Data Packet *
- * *
- * buf[0] buf[1] buf[2] buf[3]
- * 0 4 8 11 12 16 24 31 MSB
- * .-+-+-+-+-+-+-+-|-+-+-+-|-+-|-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-.
- * | HCI Handle |PB |BC | Data Total Length | HCI ACL Data Packet
- * .-+-+-+-+-+-+-+-|-+-+-+-|-+-|-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-.
- *
- * buf[4] buf[5] buf[6] buf[7]
- * 0 8 16 31 MSB
- * .-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-.
- * | Length | Channel ID | Basic L2CAP header
- * .-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-.
- *
- * buf[8] buf[9] buf[10] buf[11]
- * 0 8 16 31 MSB
- * .-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-.
- * | Code | Identifier | Length | Control frame (C-frame)
- * .-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-|-+-+-+-+-+-+-+-. (signaling packet format)
- */
-/************************************************************/
-/* L2CAP Commands */
-
-/************************************************************/
-void BTD::L2CAP_Command(uint16_t handle, uint8_t* data, uint8_t nbytes, uint8_t channelLow, uint8_t channelHigh) {
- uint8_t buf[8 + nbytes];
- buf[0] = (uint8_t)(handle & 0xff); // HCI handle with PB,BC flag
- buf[1] = (uint8_t)(((handle >> 8) & 0x0f) | 0x20);
- buf[2] = (uint8_t)((4 + nbytes) & 0xff); // HCI ACL total data length
- buf[3] = (uint8_t)((4 + nbytes) >> 8);
- buf[4] = (uint8_t)(nbytes & 0xff); // L2CAP header: Length
- buf[5] = (uint8_t)(nbytes >> 8);
- buf[6] = channelLow;
- buf[7] = channelHigh;
-
- for(uint16_t i = 0; i < nbytes; i++) // L2CAP C-frame
- buf[8 + i] = data[i];
-
- uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ BTD_DATAOUT_PIPE ].epAddr, (8 + nbytes), buf);
- if(rcode) {
- delay(100); // This small delay prevents it from overflowing if it fails
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nError sending L2CAP message: 0x"), 0x80);
- D_PrintHex (rcode, 0x80);
- Notify(PSTR(" - Channel ID: "), 0x80);
- D_PrintHex (channelHigh, 0x80);
- Notify(PSTR(" "), 0x80);
- D_PrintHex (channelLow, 0x80);
-#endif
- }
-}
-
-void BTD::l2cap_connection_request(uint16_t handle, uint8_t rxid, uint8_t* scid, uint16_t psm) {
- l2capoutbuf[0] = L2CAP_CMD_CONNECTION_REQUEST; // Code
- l2capoutbuf[1] = rxid; // Identifier
- l2capoutbuf[2] = 0x04; // Length
- l2capoutbuf[3] = 0x00;
- l2capoutbuf[4] = (uint8_t)(psm & 0xff); // PSM
- l2capoutbuf[5] = (uint8_t)(psm >> 8);
- l2capoutbuf[6] = scid[0]; // Source CID
- l2capoutbuf[7] = scid[1];
-
- L2CAP_Command(handle, l2capoutbuf, 8);
-}
-
-void BTD::l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid, uint8_t result) {
- l2capoutbuf[0] = L2CAP_CMD_CONNECTION_RESPONSE; // Code
- l2capoutbuf[1] = rxid; // Identifier
- l2capoutbuf[2] = 0x08; // Length
- l2capoutbuf[3] = 0x00;
- l2capoutbuf[4] = dcid[0]; // Destination CID
- l2capoutbuf[5] = dcid[1];
- l2capoutbuf[6] = scid[0]; // Source CID
- l2capoutbuf[7] = scid[1];
- l2capoutbuf[8] = result; // Result: Pending or Success
- l2capoutbuf[9] = 0x00;
- l2capoutbuf[10] = 0x00; // No further information
- l2capoutbuf[11] = 0x00;
-
- L2CAP_Command(handle, l2capoutbuf, 12);
-}
-
-void BTD::l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t* dcid) {
- l2capoutbuf[0] = L2CAP_CMD_CONFIG_REQUEST; // Code
- l2capoutbuf[1] = rxid; // Identifier
- l2capoutbuf[2] = 0x08; // Length
- l2capoutbuf[3] = 0x00;
- l2capoutbuf[4] = dcid[0]; // Destination CID
- l2capoutbuf[5] = dcid[1];
- l2capoutbuf[6] = 0x00; // Flags
- l2capoutbuf[7] = 0x00;
- l2capoutbuf[8] = 0x01; // Config Opt: type = MTU (Maximum Transmission Unit) - Hint
- l2capoutbuf[9] = 0x02; // Config Opt: length
- l2capoutbuf[10] = 0xFF; // MTU
- l2capoutbuf[11] = 0xFF;
-
- L2CAP_Command(handle, l2capoutbuf, 12);
-}
-
-void BTD::l2cap_config_response(uint16_t handle, uint8_t rxid, uint8_t* scid) {
- l2capoutbuf[0] = L2CAP_CMD_CONFIG_RESPONSE; // Code
- l2capoutbuf[1] = rxid; // Identifier
- l2capoutbuf[2] = 0x0A; // Length
- l2capoutbuf[3] = 0x00;
- l2capoutbuf[4] = scid[0]; // Source CID
- l2capoutbuf[5] = scid[1];
- l2capoutbuf[6] = 0x00; // Flag
- l2capoutbuf[7] = 0x00;
- l2capoutbuf[8] = 0x00; // Result
- l2capoutbuf[9] = 0x00;
- l2capoutbuf[10] = 0x01; // Config
- l2capoutbuf[11] = 0x02;
- l2capoutbuf[12] = 0xA0;
- l2capoutbuf[13] = 0x02;
-
- L2CAP_Command(handle, l2capoutbuf, 14);
-}
-
-void BTD::l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid) {
- l2capoutbuf[0] = L2CAP_CMD_DISCONNECT_REQUEST; // Code
- l2capoutbuf[1] = rxid; // Identifier
- l2capoutbuf[2] = 0x04; // Length
- l2capoutbuf[3] = 0x00;
- l2capoutbuf[4] = dcid[0];
- l2capoutbuf[5] = dcid[1];
- l2capoutbuf[6] = scid[0];
- l2capoutbuf[7] = scid[1];
-
- L2CAP_Command(handle, l2capoutbuf, 8);
-}
-
-void BTD::l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid) {
- l2capoutbuf[0] = L2CAP_CMD_DISCONNECT_RESPONSE; // Code
- l2capoutbuf[1] = rxid; // Identifier
- l2capoutbuf[2] = 0x04; // Length
- l2capoutbuf[3] = 0x00;
- l2capoutbuf[4] = dcid[0];
- l2capoutbuf[5] = dcid[1];
- l2capoutbuf[6] = scid[0];
- l2capoutbuf[7] = scid[1];
-
- L2CAP_Command(handle, l2capoutbuf, 8);
-}
-
-void BTD::l2cap_information_response(uint16_t handle, uint8_t rxid, uint8_t infoTypeLow, uint8_t infoTypeHigh) {
- l2capoutbuf[0] = L2CAP_CMD_INFORMATION_RESPONSE; // Code
- l2capoutbuf[1] = rxid; // Identifier
- l2capoutbuf[2] = 0x08; // Length
- l2capoutbuf[3] = 0x00;
- l2capoutbuf[4] = infoTypeLow;
- l2capoutbuf[5] = infoTypeHigh;
- l2capoutbuf[6] = 0x00; // Result = success
- l2capoutbuf[7] = 0x00; // Result = success
- l2capoutbuf[8] = 0x00;
- l2capoutbuf[9] = 0x00;
- l2capoutbuf[10] = 0x00;
- l2capoutbuf[11] = 0x00;
-
- L2CAP_Command(handle, l2capoutbuf, 12);
-}
-
-/* PS3 Commands - only set Bluetooth address is implemented in this library */
-void BTD::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, 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[BTD_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL);
-}
-
-void BTD::setMoveBdaddr(uint8_t* bdaddr) {
- /* Set the internal Bluetooth address */
- uint8_t buf[11];
- buf[0] = 0x05;
- buf[7] = 0x10;
- buf[8] = 0x01;
- buf[9] = 0x02;
- buf[10] = 0x12;
-
- for(uint8_t i = 0; i < 6; i++)
- buf[i + 1] = bdaddr[i];
-
- // bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x05), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
- pUsb->ctrlReq(bAddress, epInfo[BTD_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00, 11, 11, buf, NULL);
-}
diff --git a/lib/usbhost/USB_Host_Shield_2.0/BTD.h b/lib/usbhost/USB_Host_Shield_2.0/BTD.h
deleted file mode 100644
index 6549c30c9843..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/BTD.h
+++ /dev/null
@@ -1,620 +0,0 @@
-/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
-
- This software may be distributed and modified under the terms of the GNU
- General Public License version 2 (GPL2) as published by the Free Software
- Foundation and appearing in the file GPL2.TXT included in the packaging of
- this file. Please note that GPL2 Section 2[b] requires that all works based
- on this software must also be made publicly available under the terms of
- the GPL2 ("Copyleft").
-
- Contact information
- -------------------
-
- Kristian Lauszus, TKJ Electronics
- Web : http://www.tkjelectronics.com
- e-mail : kristianl@tkjelectronics.com
- */
-
-#ifndef _btd_h_
-#define _btd_h_
-
-#include "Usb.h"
-#include "hid.h"
-
-//PID and VID of the Sony PS3 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 IOGEAR_GBU521_VID 0x0A5C // The IOGEAR GBU521 dongle does not presents itself correctly, so we have to check for it manually
-#define IOGEAR_GBU521_PID 0x21E8
-
-/* Bluetooth dongle data taken from descriptors */
-#define BULK_MAXPKTSIZE 64 // Max size for ACL data
-
-// Used in control endpoint header for HCI Commands
-#define bmREQ_HCI_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_DEVICE
-
-/* 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_DEVICE_SERVICE 6
-
-#define HCI_INQUIRY_STATE 7 // These three states are only used if it should pair and connect to a device
-#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
-
-/* HCI event flags*/
-#define HCI_FLAG_CMD_COMPLETE (1UL << 0)
-#define HCI_FLAG_CONNECT_COMPLETE (1UL << 1)
-#define HCI_FLAG_DISCONNECT_COMPLETE (1UL << 2)
-#define HCI_FLAG_REMOTE_NAME_COMPLETE (1UL << 3)
-#define HCI_FLAG_INCOMING_REQUEST (1UL << 4)
-#define HCI_FLAG_READ_BDADDR (1UL << 5)
-#define HCI_FLAG_READ_VERSION (1UL << 6)
-#define HCI_FLAG_DEVICE_FOUND (1UL << 7)
-#define HCI_FLAG_CONNECT_EVENT (1UL << 8)
-
-/* Macros for HCI event flag tests */
-#define hci_check_flag(flag) (hci_event_flag & (flag))
-#define hci_set_flag(flag) (hci_event_flag |= (flag))
-#define hci_clear_flag(flag) (hci_event_flag &= ~(flag))
-
-/* HCI Events managed */
-#define EV_INQUIRY_COMPLETE 0x01
-#define EV_INQUIRY_RESULT 0x02
-#define EV_CONNECT_COMPLETE 0x03
-#define EV_INCOMING_CONNECT 0x04
-#define EV_DISCONNECT_COMPLETE 0x05
-#define EV_AUTHENTICATION_COMPLETE 0x06
-#define EV_REMOTE_NAME_COMPLETE 0x07
-#define EV_ENCRYPTION_CHANGE 0x08
-#define EV_CHANGE_CONNECTION_LINK 0x09
-#define EV_ROLE_CHANGED 0x12
-#define EV_NUM_COMPLETE_PKT 0x13
-#define EV_PIN_CODE_REQUEST 0x16
-#define EV_LINK_KEY_REQUEST 0x17
-#define EV_LINK_KEY_NOTIFICATION 0x18
-#define EV_DATA_BUFFER_OVERFLOW 0x1A
-#define EV_MAX_SLOTS_CHANGE 0x1B
-#define EV_READ_REMOTE_VERSION_INFORMATION_COMPLETE 0x0C
-#define EV_QOS_SETUP_COMPLETE 0x0D
-#define EV_COMMAND_COMPLETE 0x0E
-#define EV_COMMAND_STATUS 0x0F
-#define EV_LOOPBACK_COMMAND 0x19
-#define EV_PAGE_SCAN_REP_MODE 0x20
-
-/* Bluetooth states for the different Bluetooth drivers */
-#define L2CAP_WAIT 0
-#define L2CAP_DONE 1
-
-/* Used for HID Control channel */
-#define L2CAP_CONTROL_CONNECT_REQUEST 2
-#define L2CAP_CONTROL_CONFIG_REQUEST 3
-#define L2CAP_CONTROL_SUCCESS 4
-#define L2CAP_CONTROL_DISCONNECT 5
-
-/* Used for HID Interrupt channel */
-#define L2CAP_INTERRUPT_SETUP 6
-#define L2CAP_INTERRUPT_CONNECT_REQUEST 7
-#define L2CAP_INTERRUPT_CONFIG_REQUEST 8
-#define L2CAP_INTERRUPT_DISCONNECT 9
-
-/* Used for SDP channel */
-#define L2CAP_SDP_WAIT 10
-#define L2CAP_SDP_SUCCESS 11
-
-/* Used for RFCOMM channel */
-#define L2CAP_RFCOMM_WAIT 12
-#define L2CAP_RFCOMM_SUCCESS 13
-
-#define L2CAP_DISCONNECT_RESPONSE 14 // Used for both SDP and RFCOMM channel
-
-/* Bluetooth states used by some drivers */
-#define TURN_ON_LED 17
-#define PS3_ENABLE_SIXAXIS 18
-#define WII_CHECK_MOTION_PLUS_STATE 19
-#define WII_CHECK_EXTENSION_STATE 20
-#define WII_INIT_MOTION_PLUS_STATE 21
-
-/* L2CAP event flags for HID Control channel */
-#define L2CAP_FLAG_CONNECTION_CONTROL_REQUEST (1UL << 0)
-#define L2CAP_FLAG_CONFIG_CONTROL_SUCCESS (1UL << 1)
-#define L2CAP_FLAG_CONTROL_CONNECTED (1UL << 2)
-#define L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE (1UL << 3)
-
-/* L2CAP event flags for HID Interrupt channel */
-#define L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST (1UL << 4)
-#define L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS (1UL << 5)
-#define L2CAP_FLAG_INTERRUPT_CONNECTED (1UL << 6)
-#define L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE (1UL << 7)
-
-/* L2CAP event flags for SDP channel */
-#define L2CAP_FLAG_CONNECTION_SDP_REQUEST (1UL << 8)
-#define L2CAP_FLAG_CONFIG_SDP_SUCCESS (1UL << 9)
-#define L2CAP_FLAG_DISCONNECT_SDP_REQUEST (1UL << 10)
-
-/* L2CAP event flags for RFCOMM channel */
-#define L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST (1UL << 11)
-#define L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS (1UL << 12)
-#define L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST (1UL << 13)
-
-#define L2CAP_FLAG_DISCONNECT_RESPONSE (1UL << 14)
-
-/* Macros for L2CAP event flag tests */
-#define l2cap_check_flag(flag) (l2cap_event_flag & (flag))
-#define l2cap_set_flag(flag) (l2cap_event_flag |= (flag))
-#define l2cap_clear_flag(flag) (l2cap_event_flag &= ~(flag))
-
-/* L2CAP signaling commands */
-#define L2CAP_CMD_COMMAND_REJECT 0x01
-#define L2CAP_CMD_CONNECTION_REQUEST 0x02
-#define L2CAP_CMD_CONNECTION_RESPONSE 0x03
-#define L2CAP_CMD_CONFIG_REQUEST 0x04
-#define L2CAP_CMD_CONFIG_RESPONSE 0x05
-#define L2CAP_CMD_DISCONNECT_REQUEST 0x06
-#define L2CAP_CMD_DISCONNECT_RESPONSE 0x07
-#define L2CAP_CMD_INFORMATION_REQUEST 0x0A
-#define L2CAP_CMD_INFORMATION_RESPONSE 0x0B
-
-// Used For Connection Response - Remember to Include High Byte
-#define PENDING 0x01
-#define SUCCESSFUL 0x00
-
-/* Bluetooth L2CAP PSM - see http://www.bluetooth.org/Technical/AssignedNumbers/logical_link.htm */
-#define SDP_PSM 0x01 // Service Discovery Protocol PSM Value
-#define RFCOMM_PSM 0x03 // RFCOMM PSM Value
-#define HID_CTRL_PSM 0x11 // HID_Control PSM Value
-#define HID_INTR_PSM 0x13 // HID_Interrupt PSM Value
-
-// Used to determine if it is a Bluetooth dongle
-#define WI_SUBCLASS_RF 0x01 // RF Controller
-#define WI_PROTOCOL_BT 0x01 // Bluetooth Programming Interface
-
-#define BTD_MAX_ENDPOINTS 4
-#define BTD_NUM_SERVICES 4 // Max number of Bluetooth services - if you need more than 4 simply increase this number
-
-#define PAIR 1
-
-class BluetoothService;
-
-/**
- * The Bluetooth Dongle class will take care of all the USB communication
- * and then pass the data to the BluetoothService classes.
- */
-class BTD : public USBDeviceConfig, public UsbConfigXtracter {
-public:
- /**
- * Constructor for the BTD class.
- * @param p Pointer to USB class instance.
- */
- BTD(USB *p);
-
- /** @name USBDeviceConfig implementation */
- /**
- * Address assignment and basic initialization is done here.
- * @param parent Hub number.
- * @param port Port number on the hub.
- * @param lowspeed Speed of the device.
- * @return 0 on success.
- */
- uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed);
- /**
- * Initialize the Bluetooth dongle.
- * @param parent Hub number.
- * @param port Port number on the hub.
- * @param lowspeed Speed of the device.
- * @return 0 on success.
- */
- uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
- /**
- * Release the USB device.
- * @return 0 on success.
- */
- uint8_t Release();
- /**
- * Poll the USB Input endpoints and run the state machines.
- * @return 0 on success.
- */
- uint8_t Poll();
-
- /**
- * Get the device address.
- * @return The device address.
- */
- virtual uint8_t GetAddress() {
- return bAddress;
- };
-
- /**
- * Used to check if the dongle has been initialized.
- * @return True if it's ready.
- */
- virtual bool isReady() {
- return bPollEnable;
- };
-
- /**
- * Used by the USB core to check what this driver support.
- * @param klass The device's USB class.
- * @return Returns true if the device's USB class matches this driver.
- */
- virtual bool DEVCLASSOK(uint8_t klass) {
- return (klass == USB_CLASS_WIRELESS_CTRL);
- };
-
- /**
- * Used by the USB core to check what this driver support.
- * Used to set the Bluetooth address into the PS3 controllers.
- * @param vid The device's VID.
- * @param pid The device's PID.
- * @return Returns true if the device's VID and PID matches this driver.
- */
- virtual bool VIDPIDOK(uint16_t vid, uint16_t 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;
- };
- /**@}*/
-
- /** @name UsbConfigXtracter implementation */
- /**
- * UsbConfigXtracter implementation, used to extract endpoint information.
- * @param conf Configuration value.
- * @param iface Interface number.
- * @param alt Alternate setting.
- * @param proto Interface Protocol.
- * @param ep Endpoint Descriptor.
- */
- void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
- /**@}*/
-
- /** Disconnects both the L2CAP Channel and the HCI Connection for all Bluetooth services. */
- void disconnect();
-
- /**
- * Register Bluetooth dongle members/services.
- * @param pService Pointer to BluetoothService class instance.
- * @return The service ID on success or -1 on fail.
- */
- int8_t registerBluetoothService(BluetoothService *pService) {
- for(uint8_t i = 0; i < BTD_NUM_SERVICES; i++) {
- if(!btService[i]) {
- btService[i] = pService;
- return i; // Return ID
- }
- }
- return -1; // Error registering BluetoothService
- };
-
- /** @name HCI Commands */
- /**
- * Used to send a HCI Command.
- * @param data Data to send.
- * @param nbytes Number of bytes to send.
- */
- void HCI_Command(uint8_t* data, uint16_t nbytes);
- /** Reset the Bluetooth dongle. */
- void hci_reset();
- /** Read the Bluetooth address of the dongle. */
- void hci_read_bdaddr();
- /** Read the HCI Version of the Bluetooth dongle. */
- void hci_read_local_version_information();
- /**
- * Set the local name of the Bluetooth dongle.
- * @param name Desired name.
- */
- void hci_set_local_name(const char* name);
- /** Enable visibility to other Bluetooth devices. */
- void hci_write_scan_enable();
- /** Disable visibility to other Bluetooth devices. */
- void hci_write_scan_disable();
- /** Read the remote devices name. */
- void hci_remote_name();
- /** Accept the connection with the Bluetooth device. */
- void hci_accept_connection();
- /**
- * Disconnect the HCI connection.
- * @param handle The HCI Handle for the connection.
- */
- void hci_disconnect(uint16_t handle);
- /**
- * Respond with the pin for the connection.
- * The pin is automatically set for the Wii library,
- * but can be customized for the SPP library.
- */
- void hci_pin_code_request_reply();
- /** Respons when no pin was set. */
- void hci_pin_code_negative_request_reply();
- /**
- * Command is used to reply to a Link Key Request event from the BR/EDR Controller
- * if the Host does not have a stored Link Key for the connection.
- */
- void hci_link_key_request_negative_reply();
- /** Used to try to authenticate with the remote device. */
- void hci_authentication_request();
- /** Start a HCI inquiry. */
- void hci_inquiry();
- /** Cancel a HCI inquiry. */
- void hci_inquiry_cancel();
- /** 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();
- /**@}*/
-
- /** @name L2CAP Commands */
- /**
- * Used to send L2CAP Commands.
- * @param handle HCI Handle.
- * @param data Data to send.
- * @param nbytes Number of bytes to send.
- * @param channelLow,channelHigh Low and high byte of channel to send to.
- * If argument is omitted then the Standard L2CAP header: Channel ID (0x01) for ACL-U will be used.
- */
- void L2CAP_Command(uint16_t handle, uint8_t* data, uint8_t nbytes, uint8_t channelLow = 0x01, uint8_t channelHigh = 0x00);
- /**
- * L2CAP Connection Request.
- * @param handle HCI handle.
- * @param rxid Identifier.
- * @param scid Source Channel Identifier.
- * @param psm Protocol/Service Multiplexer - see: https://www.bluetooth.org/Technical/AssignedNumbers/logical_link.htm.
- */
- void l2cap_connection_request(uint16_t handle, uint8_t rxid, uint8_t* scid, uint16_t psm);
- /**
- * L2CAP Connection Response.
- * @param handle HCI handle.
- * @param rxid Identifier.
- * @param dcid Destination Channel Identifier.
- * @param scid Source Channel Identifier.
- * @param result Result - First send ::PENDING and then ::SUCCESSFUL.
- */
- void l2cap_connection_response(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid, uint8_t result);
- /**
- * L2CAP Config Request.
- * @param handle HCI Handle.
- * @param rxid Identifier.
- * @param dcid Destination Channel Identifier.
- */
- void l2cap_config_request(uint16_t handle, uint8_t rxid, uint8_t* dcid);
- /**
- * L2CAP Config Response.
- * @param handle HCI Handle.
- * @param rxid Identifier.
- * @param scid Source Channel Identifier.
- */
- void l2cap_config_response(uint16_t handle, uint8_t rxid, uint8_t* scid);
- /**
- * L2CAP Disconnection Request.
- * @param handle HCI Handle.
- * @param rxid Identifier.
- * @param dcid Device Channel Identifier.
- * @param scid Source Channel Identifier.
- */
- void l2cap_disconnection_request(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid);
- /**
- * L2CAP Disconnection Response.
- * @param handle HCI Handle.
- * @param rxid Identifier.
- * @param dcid Device Channel Identifier.
- * @param scid Source Channel Identifier.
- */
- void l2cap_disconnection_response(uint16_t handle, uint8_t rxid, uint8_t* dcid, uint8_t* scid);
- /**
- * L2CAP Information Response.
- * @param handle HCI Handle.
- * @param rxid Identifier.
- * @param infoTypeLow,infoTypeHigh Infotype.
- */
- void l2cap_information_response(uint16_t handle, uint8_t rxid, uint8_t infoTypeLow, uint8_t infoTypeHigh);
- /**@}*/
-
- /** Use this to see if it is waiting for a incoming connection. */
- bool watingForConnection;
- /** This is used by the service to know when to store the device information. */
- bool l2capConnectionClaimed;
- /** This is used by the SPP library to claim the current SDP incoming request. */
- bool sdpConnectionClaimed;
- /** This is used by the SPP library to claim the current RFCOMM incoming request. */
- bool rfcommConnectionClaimed;
-
- /** The name you wish to make the dongle show up as. It is set automatically by the SPP library. */
- const char* btdName;
- /** The pin you wish to make the dongle use for authentication. It is set automatically by the SPP and BTHID library. */
- const char* btdPin;
-
- /** The bluetooth dongles Bluetooth address. */
- uint8_t my_bdaddr[6];
- /** HCI handle for the last connection. */
- uint16_t hci_handle;
- /** Last incoming devices Bluetooth address. */
- uint8_t disc_bdaddr[6];
- /** First 30 chars of last remote name. */
- char remote_name[30];
- /**
- * The supported HCI Version read from the Bluetooth dongle.
- * Used by the PS3BT library to check the HCI Version of the Bluetooth dongle,
- * it should be at least 3 to work properly with the library.
- */
- uint8_t hci_version;
-
- /** Call this function to pair with a Wiimote */
- void pairWithWiimote() {
- pairWithWii = true;
- 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 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.
- */
- uint8_t readPollInterval() {
- return pollInterval;
- };
-
-protected:
- /** Pointer to USB class instance. */
- USB *pUsb;
- /** Device address. */
- uint8_t bAddress;
- /** Endpoint info structure. */
- EpInfo epInfo[BTD_MAX_ENDPOINTS];
-
- /** Configuration number. */
- uint8_t bConfNum;
- /** Total number of endpoints in the configuration. */
- uint8_t bNumEP;
- /** Next poll time based on poll interval taken from the USB descriptor. */
- uint32_t qNextPollTime;
-
- /** Bluetooth dongle control endpoint. */
- static const uint8_t BTD_CONTROL_PIPE;
- /** HCI event endpoint index. */
- static const uint8_t BTD_EVENT_PIPE;
- /** ACL In endpoint index. */
- static const uint8_t BTD_DATAIN_PIPE;
- /** ACL Out endpoint index. */
- static const uint8_t BTD_DATAOUT_PIPE;
-
- /**
- * Used to print the USB Endpoint Descriptor.
- * @param ep_ptr Pointer to USB Endpoint Descriptor.
- */
- void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
-
-private:
- void Initialize(); // Set all variables, endpoint structs etc. to default values
- BluetoothService *btService[BTD_NUM_SERVICES];
-
- uint16_t PID, VID; // PID and VID of device connected
-
- uint8_t pollInterval;
- bool bPollEnable;
-
- bool pairWiiUsingSync; // True if paring was done using the Wii SYNC button.
- bool checkRemoteName; // Used to check remote device's name before connecting.
- bool incomingPS4; // True if a PS4 controller is connecting
- uint8_t classOfDevice[3]; // Class of device of last device
-
- /* Variables used by high level HCI task */
- uint8_t hci_state; // Current state of Bluetooth HCI connection
- uint16_t hci_counter; // Counter used for Bluetooth HCI reset loops
- uint16_t hci_num_reset_loops; // This value indicate how many times it should read before trying to reset
- uint16_t hci_event_flag; // HCI flags of received Bluetooth events
- uint8_t inquiry_counter;
-
- uint8_t hcibuf[BULK_MAXPKTSIZE]; // General purpose buffer for HCI data
- uint8_t l2capinbuf[BULK_MAXPKTSIZE]; // General purpose buffer for L2CAP in data
- uint8_t l2capoutbuf[14]; // General purpose buffer for L2CAP out data
-
- /* State machines */
- void HCI_event_task(); // Poll the HCI event pipe
- void HCI_task(); // HCI state machine
- void ACL_event_task(); // ACL input pipe
-
- /* Used to set the Bluetooth Address internally to the PS3 Controllers */
- void setBdaddr(uint8_t* BDADDR);
- void setMoveBdaddr(uint8_t* BDADDR);
-};
-
-/** All Bluetooth services should inherit this class. */
-class BluetoothService {
-public:
- BluetoothService(BTD *p) : pBtd(p) {
- if(pBtd)
- pBtd->registerBluetoothService(this); // Register it as a Bluetooth service
- };
- /**
- * Used to pass acldata to the Bluetooth service.
- * @param ACLData Pointer to the incoming acldata.
- */
- virtual void ACLData(uint8_t* ACLData) = 0;
- /** Used to run the different state machines in the Bluetooth service. */
- virtual void Run() = 0;
- /** Used to reset the Bluetooth service. */
- virtual void Reset() = 0;
- /** Used to disconnect both the L2CAP Channel and the HCI Connection for the Bluetooth service. */
- virtual void disconnect() = 0;
-
- /**
- * Used to call your own function when the device is successfully initialized.
- * @param funcOnInit Function to call.
- */
- void attachOnInit(void (*funcOnInit)(void)) {
- pFuncOnInit = funcOnInit; // TODO: This really belong in a class of it's own as it is repeated several times
- };
-
-protected:
- /**
- * Called when a device 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.
- */
- virtual void onInit() = 0;
-
- /** Used to check if the incoming L2CAP data matches the HCI Handle */
- bool checkHciHandle(uint8_t *buf, uint16_t handle) {
- return (buf[0] == (handle & 0xFF)) && (buf[1] == ((handle >> 8) | 0x20));
- }
-
- /** Pointer to function called in onInit(). */
- void (*pFuncOnInit)(void);
-
- /** Pointer to BTD instance. */
- BTD *pBtd;
-
- /** The HCI Handle for the connection. */
- uint16_t hci_handle;
-
- /** L2CAP flags of received Bluetooth events. */
- uint32_t l2cap_event_flag;
-
- /** Identifier for L2CAP commands. */
- uint8_t identifier;
-};
-
-#endif
diff --git a/lib/usbhost/USB_Host_Shield_2.0/BTHID.cpp b/lib/usbhost/USB_Host_Shield_2.0/BTHID.cpp
deleted file mode 100644
index bfa9202c39ba..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/BTHID.cpp
+++ /dev/null
@@ -1,399 +0,0 @@
-/* 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 HID device
-
-BTHID::BTHID(BTD *p, bool pair, const char *pin) :
-BluetoothService(p), // Pointer to USB class instance - mandatory
-protocolMode(HID_BOOT_PROTOCOL) {
- for(uint8_t i = 0; i < NUM_PARSERS; i++)
- pRptParser[i] = NULL;
-
- pBtd->pairWithHIDDevice = 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;
- ResetBTHID();
-}
-
-void BTHID::disconnect() { // Use this void to disconnect the device
- // 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, ++identifier, 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(checkHciHandle(l2capinbuf, hci_handle)) { // acl_handle_ok
- if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { // 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]) {
- //Notify(PSTR("\r\nHID Control Connection Complete"), 0x80);
- identifier = l2capinbuf[9];
- control_scid[0] = l2capinbuf[12];
- control_scid[1] = l2capinbuf[13];
- l2cap_set_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_set_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_set_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_set_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_set_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_set_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_set_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_set_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
-#ifdef PRINTREPORT
- 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);
- Notify(PSTR(" "), 0x80);
- }
-#endif
- if(l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT
- uint16_t length = ((uint16_t)l2capinbuf[5] << 8 | l2capinbuf[4]);
- ParseBTHIDData((uint8_t)(length - 1), &l2capinbuf[9]);
-
- switch(l2capinbuf[9]) {
- case 0x01: // Keyboard or Joystick events
- if(pRptParser[KEYBOARD_PARSER_ID])
- pRptParser[KEYBOARD_PARSER_ID]->Parse(reinterpret_cast(this), 0, (uint8_t)(length - 2), &l2capinbuf[10]); // Use reinterpret_cast again to extract the instance
- break;
-
- case 0x02: // Mouse events
- if(pRptParser[MOUSE_PARSER_ID])
- pRptParser[MOUSE_PARSER_ID]->Parse(reinterpret_cast(this), 0, (uint8_t)(length - 2), &l2capinbuf[10]); // Use reinterpret_cast again to extract the instance
- break;
-#ifdef EXTRADEBUG
- default:
- Notify(PSTR("\r\nUnknown Report type: "), 0x80);
- D_PrintHex (l2capinbuf[9], 0x80);
- break;
-#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);
- Notify(PSTR(" "), 0x80);
- }
-#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);
- Notify(PSTR(" "), 0x80);
- }
- }
-#endif
- L2CAP_task();
- }
-}
-
-void BTHID::L2CAP_task() {
- switch(l2cap_state) {
- /* These states are used if the HID device is the host */
- case L2CAP_CONTROL_SUCCESS:
- if(l2cap_check_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nHID Control Successfully Configured"), 0x80);
-#endif
- setProtocol(); // Set protocol before establishing HID interrupt channel
- l2cap_state = L2CAP_INTERRUPT_SETUP;
- }
- break;
-
- case L2CAP_INTERRUPT_SETUP:
- if(l2cap_check_flag(L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST)) {
-#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_check_flag(L2CAP_FLAG_CONTROL_CONNECTED)) {
-#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_check_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)) {
- 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);
-#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_check_flag(L2CAP_FLAG_INTERRUPT_CONNECTED)) {
-#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_check_flag(L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS)) { // 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;
- onInit();
- l2cap_state = L2CAP_DONE;
- }
- break;
-
- case L2CAP_DONE:
- break;
-
- case L2CAP_INTERRUPT_DISCONNECT:
- if(l2cap_check_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE)) {
-#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_check_flag(L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE)) {
-#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_check_flag(L2CAP_FLAG_CONNECTION_CONTROL_REQUEST)) {
-#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() {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nSet protocol mode: "), 0x80);
- D_PrintHex (protocolMode, 0x80);
-#endif
- if (protocolMode != HID_BOOT_PROTOCOL && protocolMode != HID_RPT_PROTOCOL) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nNot a valid protocol mode. Using Boot protocol instead."), 0x80);
-#endif
- protocolMode = HID_BOOT_PROTOCOL; // Use Boot Protocol by default
- }
- uint8_t command = 0x70 | protocolMode; // Set Protocol, see Bluetooth 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]);
-}
diff --git a/lib/usbhost/USB_Host_Shield_2.0/BTHID.h b/lib/usbhost/USB_Host_Shield_2.0/BTHID.h
deleted file mode 100644
index 1a7d8687c7bb..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/BTHID.h
+++ /dev/null
@@ -1,155 +0,0 @@
-/* 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 "hidboot.h"
-
-#define KEYBOARD_PARSER_ID 0
-#define MOUSE_PARSER_ID 1
-#define NUM_PARSERS 2
-
-/** This BluetoothService class implements support for Bluetooth HID devices. */
-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 "0000" will be used.
- */
- BTHID(BTD *p, bool pair = false, const char *pin = "0000");
-
- /** @name BluetoothService implementation */
- /** Used this to disconnect the devices. */
- void disconnect();
- /**@}*/
-
- /**
- * Get HIDReportParser.
- * @param id ID of parser.
- * @return Returns the corresponding HIDReportParser. Returns NULL if id is not valid.
- */
- HIDReportParser *GetReportParser(uint8_t id) {
- if (id >= NUM_PARSERS)
- return NULL;
- return pRptParser[id];
- };
-
- /**
- * Set HIDReportParser to be used.
- * @param id Id of parser.
- * @param prs Pointer to HIDReportParser.
- * @return Returns true if the HIDReportParser is set. False otherwise.
- */
- bool SetReportParser(uint8_t id, HIDReportParser *prs) {
- if (id >= NUM_PARSERS)
- return false;
- pRptParser[id] = prs;
- return true;
- };
-
- /**
- * Set HID protocol mode.
- * @param mode HID protocol to use. Either HID_BOOT_PROTOCOL or HID_RPT_PROTOCOL.
- */
- void setProtocolMode(uint8_t mode) {
- protocolMode = mode;
- };
-
- /**
- * Used to set the leds on a keyboard.
- * @param data See KBDLEDS in hidboot.h
- */
- void setLeds(uint8_t data);
-
- /** True if a device is connected */
- bool connected;
-
- /** Call this to start the paring sequence with a device */
- void pair(void) {
- if(pBtd)
- pBtd->pairWithHID();
- };
-
-protected:
- /** @name BluetoothService implementation */
- /**
- * Used to pass acldata to the services.
- * @param ACLData Incoming acldata.
- */
- void ACLData(uint8_t* ACLData);
- /** Used to run part of the state machine. */
- void Run();
- /** Use this to reset the service. */
- void Reset();
- /**
- * Called when a device 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() {
- if(pFuncOnInit)
- pFuncOnInit(); // Call the user function
- OnInitBTHID();
- };
- /**@}*/
-
- /** @name Overridable functions */
- /**
- * Used to parse Bluetooth HID data to any class that inherits this class.
- * @param len The length of the incoming data.
- * @param buf Pointer to the data buffer.
- */
- virtual void ParseBTHIDData(uint8_t len, uint8_t *buf) {
- return;
- };
- /** Called when a device is connected */
- virtual void OnInitBTHID() {
- return;
- };
- /** Used to reset any buffers in the class that inherits this */
- virtual void ResetBTHID() {
- return;
- }
- /**@}*/
-
- /** L2CAP source CID for HID_Control */
- uint8_t control_scid[2];
-
- /** L2CAP source CID for HID_Interrupt */
- uint8_t interrupt_scid[2];
-
-private:
- HIDReportParser *pRptParser[NUM_PARSERS]; // Pointer to HIDReportParsers.
-
- /** Set report protocol. */
- void setProtocol();
- uint8_t protocolMode;
-
- void L2CAP_task(); // L2CAP state machine
-
- bool activeConnection; // Used to indicate if it already has established a connection
-
- /* Variables used for L2CAP communication */
- uint8_t control_dcid[2]; // L2CAP device CID for HID_Control - Always 0x0070
- uint8_t interrupt_dcid[2]; // L2CAP device CID for HID_Interrupt - Always 0x0071
- uint8_t l2cap_state;
-};
-#endif
diff --git a/lib/usbhost/USB_Host_Shield_2.0/PS3BT.cpp b/lib/usbhost/USB_Host_Shield_2.0/PS3BT.cpp
deleted file mode 100644
index 235092e0acbd..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/PS3BT.cpp
+++ /dev/null
@@ -1,634 +0,0 @@
-/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
-
- This software may be distributed and modified under the terms of the GNU
- General Public License version 2 (GPL2) as published by the Free Software
- Foundation and appearing in the file GPL2.TXT included in the packaging of
- this file. Please note that GPL2 Section 2[b] requires that all works based
- on this software must also be made publicly available under the terms of
- the GPL2 ("Copyleft").
-
- Contact information
- -------------------
-
- Kristian Lauszus, TKJ Electronics
- Web : http://www.tkjelectronics.com
- e-mail : kristianl@tkjelectronics.com
- */
-
-#include "PS3BT.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
-
-PS3BT::PS3BT(BTD *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0) :
-BluetoothService(p) // Pointer to USB class instance - mandatory
-{
- pBtd->my_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead
- pBtd->my_bdaddr[4] = btadr4;
- pBtd->my_bdaddr[3] = btadr3;
- pBtd->my_bdaddr[2] = btadr2;
- pBtd->my_bdaddr[1] = btadr1;
- pBtd->my_bdaddr[0] = btadr0;
-
- 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
- HIDMoveBuffer[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
- HIDMoveBuffer[1] = 0x02; // Report ID
-
- /* Set device cid for the control and intterrupt channelse - LSB */
- control_dcid[0] = 0x40; // 0x0040
- control_dcid[1] = 0x00;
- interrupt_dcid[0] = 0x41; // 0x0041
- interrupt_dcid[1] = 0x00;
-
- Reset();
-}
-
-bool PS3BT::getButtonPress(ButtonEnum b) {
- return (ButtonState & pgm_read_dword(&PS3_BUTTONS[(uint8_t)b]));
-}
-
-bool PS3BT::getButtonClick(ButtonEnum b) {
- uint32_t button = pgm_read_dword(&PS3_BUTTONS[(uint8_t)b]);
- bool click = (ButtonClickState & button);
- ButtonClickState &= ~button; // Clear "click" event
- return click;
-}
-
-uint8_t PS3BT::getAnalogButton(ButtonEnum a) {
- return (uint8_t)(l2capinbuf[pgm_read_byte(&PS3_ANALOG_BUTTONS[(uint8_t)a])]);
-}
-
-uint8_t PS3BT::getAnalogHat(AnalogHatEnum a) {
- return (uint8_t)(l2capinbuf[(uint8_t)a + 15]);
-}
-
-int16_t PS3BT::getSensor(SensorEnum a) {
- if(PS3Connected) {
- if(a == aX || a == aY || a == aZ || a == gZ)
- return ((l2capinbuf[(uint16_t)a] << 8) | l2capinbuf[(uint16_t)a + 1]);
- else
- return 0;
- } else if(PS3MoveConnected) {
- if(a == mXmove || a == mYmove) // These are all 12-bits long
- return (((l2capinbuf[(uint16_t)a] & 0x0F) << 8) | (l2capinbuf[(uint16_t)a + 1]));
- else if(a == mZmove || a == tempMove) // The tempearature is also 12 bits long
- return ((l2capinbuf[(uint16_t)a] << 4) | ((l2capinbuf[(uint16_t)a + 1] & 0xF0) >> 4));
- else // aXmove, aYmove, aZmove, gXmove, gYmove and gZmove
- return (l2capinbuf[(uint16_t)a] | (l2capinbuf[(uint16_t)a + 1] << 8));
- } else
- return 0;
-}
-
-double PS3BT::getAngle(AngleEnum a) {
- 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)
- accXval = -((double)getSensor(aX) - zeroG);
- accYval = -((double)getSensor(aY) - zeroG);
- accZval = -((double)getSensor(aZ) - zeroG);
- } else if(PS3MoveConnected) {
- // It's a Kionix KXSC4 inside the Motion controller
- const uint16_t zeroG = 0x8000;
- accXval = -(int16_t)(getSensor(aXmove) - zeroG);
- accYval = (int16_t)(getSensor(aYmove) - zeroG);
- accZval = (int16_t)(getSensor(aZmove) - zeroG);
- } else
- return 0;
-
- // 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)
- return (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
- else
- return (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
-}
-
-double PS3BT::get9DOFValues(SensorEnum a) { // Thanks to Manfred Piendl
- if(!PS3MoveConnected)
- return 0;
- int16_t value = getSensor(a);
- if(a == mXmove || a == mYmove || a == mZmove) {
- if(value > 2047)
- value -= 0x1000;
- return (double)value / 3.2; // unit: muT = 10^(-6) Tesla
- } else if(a == aXmove || a == aYmove || a == aZmove) {
- if(value < 0)
- value += 0x8000;
- else
- value -= 0x8000;
- return (double)value / 442.0; // unit: m/(s^2)
- } else if(a == gXmove || a == gYmove || a == gZmove) {
- if(value < 0)
- value += 0x8000;
- else
- value -= 0x8000;
- if(a == gXmove)
- return (double)value / 11.6; // unit: deg/s
- else if(a == gYmove)
- return (double)value / 11.2; // unit: deg/s
- else // gZmove
- return (double)value / 9.6; // unit: deg/s
- } else
- return 0;
-}
-
-String PS3BT::getTemperature() {
- if(PS3MoveConnected) {
- int16_t input = getSensor(tempMove);
-
- String output = String(input / 100);
- output += ".";
- if(input % 100 < 10)
- output += "0";
- output += String(input % 100);
-
- return output;
- } else
- return "Error";
-}
-
-bool PS3BT::getStatus(StatusEnum c) {
- return (l2capinbuf[(uint16_t)c >> 8] == ((uint8_t)c & 0xff));
-}
-
-void PS3BT::printStatusString() {
- char statusOutput[100]; // Max string length plus null character
- if(PS3Connected || PS3NavigationConnected) {
- strcpy_P(statusOutput, PSTR("ConnectionStatus: "));
-
- if(getStatus(Plugged)) strcat_P(statusOutput, PSTR("Plugged"));
- else if(getStatus(Unplugged)) strcat_P(statusOutput, PSTR("Unplugged"));
- else strcat_P(statusOutput, PSTR("Error"));
-
- strcat_P(statusOutput, PSTR(" - PowerRating: "));
-
- if(getStatus(Charging)) strcat_P(statusOutput, PSTR("Charging"));
- else if(getStatus(NotCharging)) strcat_P(statusOutput, PSTR("Not Charging"));
- else if(getStatus(Shutdown)) strcat_P(statusOutput, PSTR("Shutdown"));
- else if(getStatus(Dying)) strcat_P(statusOutput, PSTR("Dying"));
- else if(getStatus(Low)) strcat_P(statusOutput, PSTR("Low"));
- else if(getStatus(High)) strcat_P(statusOutput, PSTR("High"));
- else if(getStatus(Full)) strcat_P(statusOutput, PSTR("Full"));
- else strcat_P(statusOutput, PSTR("Error"));
-
- strcat_P(statusOutput, PSTR(" - WirelessStatus: "));
-
- if(getStatus(CableRumble)) strcat_P(statusOutput, PSTR("Cable - Rumble is on"));
- else if(getStatus(Cable)) strcat_P(statusOutput, PSTR("Cable - Rumble is off"));
- else if(getStatus(BluetoothRumble)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is on"));
- else if(getStatus(Bluetooth)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is off"));
- else strcat_P(statusOutput, PSTR("Error"));
- } else if(PS3MoveConnected) {
- strcpy_P(statusOutput, PSTR("PowerRating: "));
-
- if(getStatus(MoveCharging)) strcat_P(statusOutput, PSTR("Charging"));
- else if(getStatus(MoveNotCharging)) strcat_P(statusOutput, PSTR("Not Charging"));
- else if(getStatus(MoveShutdown)) strcat_P(statusOutput, PSTR("Shutdown"));
- else if(getStatus(MoveDying)) strcat_P(statusOutput, PSTR("Dying"));
- else if(getStatus(MoveLow)) strcat_P(statusOutput, PSTR("Low"));
- else if(getStatus(MoveHigh)) strcat_P(statusOutput, PSTR("High"));
- else if(getStatus(MoveFull)) strcat_P(statusOutput, PSTR("Full"));
- else strcat_P(statusOutput, PSTR("Error"));
- } else
- strcpy_P(statusOutput, PSTR("Error"));
-
- USB_HOST_SERIAL.write(statusOutput);
-}
-
-void PS3BT::Reset() {
- PS3Connected = false;
- PS3MoveConnected = false;
- PS3NavigationConnected = false;
- activeConnection = false;
- l2cap_event_flag = 0; // Reset flags
- l2cap_state = L2CAP_WAIT;
-
- // Needed for PS3 Dualshock Controller commands to work via Bluetooth
- 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
-}
-
-void PS3BT::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, ++identifier, interrupt_scid, interrupt_dcid);
- Reset();
- l2cap_state = L2CAP_INTERRUPT_DISCONNECT;
-}
-
-void PS3BT::ACLData(uint8_t* ACLData) {
- if(!pBtd->l2capConnectionClaimed && !PS3Connected && !PS3MoveConnected && !PS3NavigationConnected && !activeConnection && !pBtd->connectToWii && !pBtd->incomingWii && !pBtd->pairWithWii) {
- if(ACLData[8] == L2CAP_CMD_CONNECTION_REQUEST) {
- if((ACLData[12] | (ACLData[13] << 8)) == HID_CTRL_PSM) {
- 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;
- remote_name_first = pBtd->remote_name[0]; // Store the first letter in remote name for the connection
-#ifdef DEBUG_USB_HOST
- if(pBtd->hci_version < 3) { // Check the HCI Version of the Bluetooth dongle
- Notify(PSTR("\r\nYour dongle may not support reading the analog buttons, sensors and status\r\nYour HCI Version is: "), 0x80);
- Notify(pBtd->hci_version, 0x80);
- Notify(PSTR("\r\nBut should be at least 3\r\nThis means that it doesn't support Bluetooth Version 2.0+EDR"), 0x80);
- }
-#endif
- }
- }
- }
-
- if(checkHciHandle(ACLData, hci_handle)) { // acl_handle_ok
- memcpy(l2capinbuf, ACLData, BULK_MAXPKTSIZE);
- if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { // 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(" Data: "), 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_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_set_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_set_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);
- l2cap_set_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);
- l2cap_set_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_set_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_set_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE);
- }
- }
-#ifdef EXTRADEBUG
- else {
- 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\nL2CAP Interrupt"), 0x80);
- if(PS3Connected || PS3MoveConnected || PS3NavigationConnected) {
- /* Read Report */
- if(l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT
- lastMessageTime = millis(); // Store the last message time
-
- if(PS3Connected || PS3NavigationConnected)
- ButtonState = (uint32_t)(l2capinbuf[11] | ((uint16_t)l2capinbuf[12] << 8) | ((uint32_t)l2capinbuf[13] << 16));
- else if(PS3MoveConnected)
- ButtonState = (uint32_t)(l2capinbuf[10] | ((uint16_t)l2capinbuf[11] << 8) | ((uint32_t)l2capinbuf[12] << 16));
-
- //Notify(PSTR("\r\nButtonState", 0x80);
- //PrintHex(ButtonState, 0x80);
-
- if(ButtonState != OldButtonState) {
- ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
- OldButtonState = ButtonState;
- }
-
-#ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
- for(uint8_t i = 10; i < 58; i++) {
- D_PrintHex (l2capinbuf[i], 0x80);
- Notify(PSTR(" "), 0x80);
- }
- Notify(PSTR("\r\n"), 0x80);
-#endif
- }
- }
- }
- L2CAP_task();
- }
-}
-
-void PS3BT::L2CAP_task() {
- switch(l2cap_state) {
- case L2CAP_WAIT:
- if(l2cap_check_flag(L2CAP_FLAG_CONNECTION_CONTROL_REQUEST)) {
-#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;
-
- case L2CAP_CONTROL_SUCCESS:
- if(l2cap_check_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)) {
-#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_check_flag(L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST)) {
-#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;
-
- case L2CAP_INTERRUPT_CONFIG_REQUEST:
- if(l2cap_check_flag(L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS)) { // Now the HID channels is established
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nHID Interrupt Successfully Configured"), 0x80);
-#endif
- if(remote_name_first == 'M') { // First letter in Motion Controller ('M')
- memset(l2capinbuf, 0, BULK_MAXPKTSIZE); // Reset l2cap in buffer as it sometimes read it as a button has been pressed
- l2cap_state = TURN_ON_LED;
- } else
- l2cap_state = PS3_ENABLE_SIXAXIS;
- timer = millis();
- }
- break;
-
- /* These states are handled in Run() */
-
- case L2CAP_INTERRUPT_DISCONNECT:
- if(l2cap_check_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE)) {
-#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_check_flag(L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE)) {
-#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 PS3BT::Run() {
- switch(l2cap_state) {
- case PS3_ENABLE_SIXAXIS:
- if(millis() - timer > 1000) { // loop 1 second before sending the command
- 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();
- l2cap_state = TURN_ON_LED;
- timer = millis();
- }
- break;
-
- case TURN_ON_LED:
- if(millis() - timer > 1000) { // loop 1 second before sending the command
- if(remote_name_first == 'P') { // First letter in PLAYSTATION(R)3 Controller ('P')
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nDualshock 3 Controller Enabled\r\n"), 0x80);
-#endif
- PS3Connected = true;
- } else if(remote_name_first == 'N') { // First letter in Navigation Controller ('N')
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nNavigation Controller Enabled\r\n"), 0x80);
-#endif
- PS3NavigationConnected = true;
- } else if(remote_name_first == 'M') { // First letter in Motion Controller ('M')
- timer = millis();
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nMotion Controller Enabled\r\n"), 0x80);
-#endif
- PS3MoveConnected = true;
- }
- 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 approximately every 5th second for it to stay on
- if(millis() - timer > 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
- timer = millis();
- }
- }
- break;
- }
-}
-
-/************************************************************/
-/* HID Commands */
-/************************************************************/
-
-// Playstation Sixaxis Dualshock and Navigation Controller commands
-
-void PS3BT::HID_Command(uint8_t* data, uint8_t nbytes) {
- 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();
-}
-
-void PS3BT::setAllOff() {
- HIDBuffer[3] = 0x00; // Rumble bytes
- HIDBuffer[4] = 0x00;
- HIDBuffer[5] = 0x00;
- HIDBuffer[6] = 0x00;
-
- HIDBuffer[11] = 0x00; // LED byte
-
- HID_Command(HIDBuffer, HID_BUFFERSIZE);
-}
-
-void PS3BT::setRumbleOff() {
- HIDBuffer[3] = 0x00;
- HIDBuffer[4] = 0x00;
- HIDBuffer[5] = 0x00;
- HIDBuffer[6] = 0x00;
-
- HID_Command(HIDBuffer, HID_BUFFERSIZE);
-}
-
-void PS3BT::setRumbleOn(RumbleEnum mode) {
- uint8_t power[2] = {0xff, 0x00}; // Defaults to RumbleLow
- if(mode == RumbleHigh) {
- power[0] = 0x00;
- power[1] = 0xff;
- }
- setRumbleOn(0xfe, power[0], 0xfe, power[1]);
-}
-
-void PS3BT::setRumbleOn(uint8_t rightDuration, uint8_t rightPower, uint8_t leftDuration, uint8_t leftPower) {
- HIDBuffer[3] = rightDuration;
- HIDBuffer[4] = rightPower;
- HIDBuffer[5] = leftDuration;
- HIDBuffer[6] = leftPower;
- HID_Command(HIDBuffer, HID_BUFFERSIZE);
-}
-
-void PS3BT::setLedRaw(uint8_t value) {
- HIDBuffer[11] = value << 1;
- HID_Command(HIDBuffer, HID_BUFFERSIZE);
-}
-
-void PS3BT::setLedOff(LEDEnum a) {
- HIDBuffer[11] &= ~((uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1));
- HID_Command(HIDBuffer, HID_BUFFERSIZE);
-}
-
-void PS3BT::setLedOn(LEDEnum a) {
- if(a == OFF)
- setLedRaw(0);
- else {
- HIDBuffer[11] |= (uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1);
- HID_Command(HIDBuffer, HID_BUFFERSIZE);
- }
-}
-
-void PS3BT::setLedToggle(LEDEnum a) {
- HIDBuffer[11] ^= (uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1);
- HID_Command(HIDBuffer, HID_BUFFERSIZE);
-}
-
-void PS3BT::enable_sixaxis() { // Command used to enable the Dualshock 3 and Navigation controller to send data via 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
- cmd_buf[2] = 0x42; // Special PS3 Controller enable commands
- cmd_buf[3] = 0x03;
- cmd_buf[4] = 0x00;
- cmd_buf[5] = 0x00;
-
- HID_Command(cmd_buf, 6);
-}
-
-// Playstation Move Controller commands
-
-void PS3BT::HIDMove_Command(uint8_t* data, uint8_t nbytes) {
- 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();
-}
-
-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
- HIDMoveBuffer[3] = r;
- HIDMoveBuffer[4] = g;
- HIDMoveBuffer[5] = b;
-
- HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE);
-}
-
-void PS3BT::moveSetBulb(ColorsEnum color) { // Use this to set the Color using the predefined colors in enum
- moveSetBulb((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
-}
-
-void PS3BT::moveSetRumble(uint8_t rumble) {
-#ifdef DEBUG_USB_HOST
- 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
- HIDMoveBuffer[7] = rumble;
-
- HIDMove_Command(HIDMoveBuffer, HID_BUFFERSIZE);
-}
-
-void PS3BT::onInit() {
- if(pFuncOnInit)
- pFuncOnInit(); // Call the user function
- else {
- if(PS3MoveConnected)
- moveSetBulb(Red);
- else // Dualshock 3 or Navigation controller
- setLedOn(LED1);
- }
-}
diff --git a/lib/usbhost/USB_Host_Shield_2.0/PS3BT.h b/lib/usbhost/USB_Host_Shield_2.0/PS3BT.h
deleted file mode 100644
index c25ac5e59da1..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/PS3BT.h
+++ /dev/null
@@ -1,240 +0,0 @@
-/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
-
- This software may be distributed and modified under the terms of the GNU
- General Public License version 2 (GPL2) as published by the Free Software
- Foundation and appearing in the file GPL2.TXT included in the packaging of
- this file. Please note that GPL2 Section 2[b] requires that all works based
- on this software must also be made publicly available under the terms of
- the GPL2 ("Copyleft").
-
- Contact information
- -------------------
-
- Kristian Lauszus, TKJ Electronics
- Web : http://www.tkjelectronics.com
- e-mail : kristianl@tkjelectronics.com
- */
-
-#ifndef _ps3bt_h_
-#define _ps3bt_h_
-
-#include "BTD.h"
-#include "PS3Enums.h"
-
-#define HID_BUFFERSIZE 50 // Size of the buffer for the Playstation Motion Controller
-
-/**
- * This BluetoothService class implements support for all the official PS3 Controllers:
- * Dualshock 3, Navigation or a Motion controller via Bluetooth.
- *
- * Information about the protocol can be found at the wiki: https://github.com/felis/USB_Host_Shield_2.0/wiki/PS3-Information.
- */
-class PS3BT : public BluetoothService {
-public:
- /**
- * Constructor for the PS3BT class.
- * @param pBtd Pointer to BTD class instance.
- * @param btadr5,btadr4,btadr3,btadr2,btadr1,btadr0
- * Pass your dongles Bluetooth address into the constructor,
- * This will set BTD#my_bdaddr, so you don't have to plug in the dongle before pairing with your controller.
- */
- PS3BT(BTD *pBtd, uint8_t btadr5 = 0, uint8_t btadr4 = 0, uint8_t btadr3 = 0, uint8_t btadr2 = 0, uint8_t btadr1 = 0, uint8_t btadr0 = 0);
-
- /** @name BluetoothService implementation */
- /** Used this to disconnect any of the controllers. */
- void disconnect();
- /**@}*/
-
- /** @name PS3 Controller functions */
- /**
- * getButtonPress(ButtonEnum b) will return true as long as the button is held down.
- *
- * While getButtonClick(ButtonEnum b) will only return it once.
- *
- * So you instance if you need to increase a variable once you would use getButtonClick(ButtonEnum b),
- * but if you need to drive a robot forward you would use getButtonPress(ButtonEnum b).
- * @param b ::ButtonEnum to read.
- * @return getButtonPress(ButtonEnum b) will return a true as long as a button is held down, while getButtonClick(ButtonEnum b) will return true once for each button press.
- */
- bool getButtonPress(ButtonEnum b);
- bool getButtonClick(ButtonEnum b);
- /**@}*/
- /** @name PS3 Controller functions */
- /**
- * Used to get the analog value from button presses.
- * @param a The ::ButtonEnum to read.
- * The supported buttons are:
- * ::UP, ::RIGHT, ::DOWN, ::LEFT, ::L1, ::L2, ::R1, ::R2,
- * ::TRIANGLE, ::CIRCLE, ::CROSS, ::SQUARE, and ::T.
- * @return Analog value in the range of 0-255.
- */
- uint8_t getAnalogButton(ButtonEnum a);
- /**
- * Used to read the analog joystick.
- * @param a ::LeftHatX, ::LeftHatY, ::RightHatX, and ::RightHatY.
- * @return Return the analog value in the range of 0-255.
- */
- uint8_t getAnalogHat(AnalogHatEnum a);
- /**
- * Used to read the sensors inside the Dualshock 3 and Move controller.
- * @param a
- * The Dualshock 3 has a 3-axis accelerometer and a 1-axis gyro inside.
- * The Move controller has a 3-axis accelerometer, a 3-axis gyro, a 3-axis magnetometer
- * and a temperature sensor inside.
- * @return Return the raw sensor value.
- */
- int16_t getSensor(SensorEnum a);
- /**
- * Use this to get ::Pitch and ::Roll calculated using the accelerometer.
- * @param a Either ::Pitch or ::Roll.
- * @return Return the angle in the range of 0-360.
- */
- double getAngle(AngleEnum a);
- /**
- * Read the sensors inside the Move controller.
- * @param a ::aXmove, ::aYmove, ::aZmove, ::gXmove, ::gYmove, ::gZmove, ::mXmove, ::mYmove, and ::mXmove.
- * @return The value in SI units.
- */
- double get9DOFValues(SensorEnum a);
- /**
- * Get the status from the controller.
- * @param c The ::StatusEnum you want to read.
- * @return True if correct and false if not.
- */
- bool getStatus(StatusEnum c);
- /** Read all the available statuses from the controller and prints it as a nice formated string. */
- void printStatusString();
- /**
- * Read the temperature from the Move controller.
- * @return The temperature in degrees Celsius.
- */
- String getTemperature();
-
- /** Used to set all LEDs and rumble off. */
- void setAllOff();
- /** Turn off rumble. */
- void setRumbleOff();
- /**
- * Turn on rumble.
- * @param mode Either ::RumbleHigh or ::RumbleLow.
- */
- void setRumbleOn(RumbleEnum mode);
- /**
- * Turn on rumble using custom duration and power.
- * @param rightDuration The duration of the right/low rumble effect.
- * @param rightPower The intensity of the right/low rumble effect.
- * @param leftDuration The duration of the left/high rumble effect.
- * @param leftPower The intensity of the left/high rumble effect.
- */
- void setRumbleOn(uint8_t rightDuration, uint8_t rightPower, uint8_t leftDuration, uint8_t leftPower);
-
- /**
- * Set LED value without using ::LEDEnum.
- * @param value See: ::LEDEnum.
- */
- void setLedRaw(uint8_t value);
-
- /** Turn all LEDs off. */
- void setLedOff() {
- setLedRaw(0);
- };
- /**
- * Turn the specific LED off.
- * @param a The ::LEDEnum to turn off.
- */
- void setLedOff(LEDEnum a);
- /**
- * Turn the specific LED on.
- * @param a The ::LEDEnum to turn on.
- */
- void setLedOn(LEDEnum a);
- /**
- * Toggle the specific LED.
- * @param a The ::LEDEnum to toggle.
- */
- void setLedToggle(LEDEnum a);
-
- /**
- * Use this to set the Color using RGB values.
- * @param r,g,b RGB value.
- */
- void moveSetBulb(uint8_t r, uint8_t g, uint8_t b);
- /**
- * Use this to set the color using the predefined colors in ::ColorsEnum.
- * @param color The desired color.
- */
- void moveSetBulb(ColorsEnum color);
- /**
- * Set the rumble value inside the Move controller.
- * @param rumble The desired value in the range from 64-255.
- */
- void moveSetRumble(uint8_t rumble);
-
- /** Used to get the millis() of the last message */
- uint32_t getLastMessageTime() {
- return lastMessageTime;
- };
- /**@}*/
-
- /** Variable used to indicate if the normal Playstation controller is successfully connected. */
- bool PS3Connected;
- /** Variable used to indicate if the Move controller is successfully connected. */
- bool PS3MoveConnected;
- /** Variable used to indicate if the Navigation controller is successfully connected. */
- bool PS3NavigationConnected;
-
-protected:
- /** @name BluetoothService implementation */
- /**
- * Used to pass acldata to the services.
- * @param ACLData Incoming acldata.
- */
- void ACLData(uint8_t* ACLData);
- /** Used to run part of the state machine. */
- void Run();
- /** Use this to reset the service. */
- void Reset();
- /**
- * 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();
- /**@}*/
-
-private:
-
- void L2CAP_task(); // L2CAP state machine
-
- /* Variables filled from HCI event management */
- char remote_name_first; // First letter in remote name
- bool activeConnection; // Used to indicate if it's already has established a connection
-
- /* Variables used by high level L2CAP task */
- uint8_t l2cap_state;
-
- uint32_t lastMessageTime; // Variable used to store the millis value of the last message.
-
- uint32_t ButtonState;
- uint32_t OldButtonState;
- uint32_t ButtonClickState;
-
- uint32_t timer; // Timer used to limit time between messages and also used to continuously set PS3 Move controller Bulb and rumble values
- uint32_t timerHID; // Timer used see if there has to be a delay before a new HID command
-
- uint8_t l2capinbuf[BULK_MAXPKTSIZE]; // General purpose buffer for L2CAP in data
- uint8_t HIDBuffer[HID_BUFFERSIZE]; // Used to store HID commands
- uint8_t HIDMoveBuffer[HID_BUFFERSIZE]; // Used to store HID commands for the Move controller
-
- /* L2CAP Channels */
- uint8_t control_scid[2]; // L2CAP source CID for HID_Control
- uint8_t control_dcid[2]; // 0x0040
- uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt
- uint8_t interrupt_dcid[2]; // 0x0041
-
- /* HID Commands */
- void HID_Command(uint8_t* data, uint8_t nbytes);
- void HIDMove_Command(uint8_t* data, uint8_t nbytes);
- void enable_sixaxis(); // Command used to enable the Dualshock 3 and Navigation controller to send data via Bluetooth
-};
-#endif
diff --git a/lib/usbhost/USB_Host_Shield_2.0/PS3Enums.h b/lib/usbhost/USB_Host_Shield_2.0/PS3Enums.h
deleted file mode 100644
index 77801945f276..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/PS3Enums.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
-
- This software may be distributed and modified under the terms of the GNU
- General Public License version 2 (GPL2) as published by the Free Software
- Foundation and appearing in the file GPL2.TXT included in the packaging of
- this file. Please note that GPL2 Section 2[b] requires that all works based
- on this software must also be made publicly available under the terms of
- the GPL2 ("Copyleft").
-
- Contact information
- -------------------
-
- Kristian Lauszus, TKJ Electronics
- Web : http://www.tkjelectronics.com
- e-mail : kristianl@tkjelectronics.com
- */
-
-#ifndef _ps3enums_h
-#define _ps3enums_h
-
-#include "controllerEnums.h"
-
-/** Size of the output report buffer for the Dualshock and Navigation controllers */
-#define PS3_REPORT_BUFFER_SIZE 48
-
-/** Report buffer for all PS3 commands */
-const uint8_t PS3_REPORT_BUFFER[PS3_REPORT_BUFFER_SIZE] PROGMEM = {
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0xff, 0x27, 0x10, 0x00, 0x32,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-/** Size of the output report buffer for the Move Controller */
-#define MOVE_REPORT_BUFFER_SIZE 7
-
-/** Used to set the LEDs on the controllers */
-const uint8_t PS3_LEDS[] PROGMEM = {
- 0x00, // OFF
- 0x01, // LED1
- 0x02, // LED2
- 0x04, // LED3
- 0x08, // LED4
-
- 0x09, // LED5
- 0x0A, // LED6
- 0x0C, // LED7
- 0x0D, // LED8
- 0x0E, // LED9
- 0x0F, // LED10
-};
-
-/**
- * Buttons on the controllers.
- * Note: that the location is shifted 9 when it's connected via USB.
- */
-const uint32_t PS3_BUTTONS[] PROGMEM = {
- 0x10, // UP
- 0x20, // RIGHT
- 0x40, // DOWN
- 0x80, // LEFT
-
- 0x01, // SELECT
- 0x08, // START
- 0x02, // L3
- 0x04, // R3
-
- 0x0100, // L2
- 0x0200, // R2
- 0x0400, // L1
- 0x0800, // R1
-
- 0x1000, // TRIANGLE
- 0x2000, // CIRCLE
- 0x4000, // CROSS
- 0x8000, // SQUARE
-
- 0x010000, // PS
- 0x080000, // MOVE - covers 12 bits - we only need to read the top 8
- 0x100000, // T - covers 12 bits - we only need to read the top 8
-};
-
-/**
- * Analog buttons on the controllers.
- * Note: that the location is shifted 9 when it's connected via USB.
- */
-const uint8_t PS3_ANALOG_BUTTONS[] PROGMEM = {
- 23, // UP_ANALOG
- 24, // RIGHT_ANALOG
- 25, // DOWN_ANALOG
- 26, // LEFT_ANALOG
- 0, 0, 0, 0, // Skip SELECT, L3, R3 and START
-
- 27, // L2_ANALOG
- 28, // R2_ANALOG
- 29, // L1_ANALOG
- 30, // R1_ANALOG
- 31, // TRIANGLE_ANALOG
- 32, // CIRCLE_ANALOG
- 33, // CROSS_ANALOG
- 34, // SQUARE_ANALOG
- 0, 0, // Skip PS and MOVE
-
- // Playstation Move Controller
- 15, // T_ANALOG - Both at byte 14 (last reading) and byte 15 (current reading)
-};
-
-enum StatusEnum {
- // Note that the location is shifted 9 when it's connected via USB
- // Byte location | bit location
- Plugged = (38 << 8) | 0x02,
- Unplugged = (38 << 8) | 0x03,
-
- Charging = (39 << 8) | 0xEE,
- NotCharging = (39 << 8) | 0xF1,
- Shutdown = (39 << 8) | 0x01,
- Dying = (39 << 8) | 0x02,
- Low = (39 << 8) | 0x03,
- High = (39 << 8) | 0x04,
- Full = (39 << 8) | 0x05,
-
- MoveCharging = (21 << 8) | 0xEE,
- MoveNotCharging = (21 << 8) | 0xF1,
- MoveShutdown = (21 << 8) | 0x01,
- MoveDying = (21 << 8) | 0x02,
- MoveLow = (21 << 8) | 0x03,
- MoveHigh = (21 << 8) | 0x04,
- MoveFull = (21 << 8) | 0x05,
-
- CableRumble = (40 << 8) | 0x10, // Operating by USB and rumble is turned on
- Cable = (40 << 8) | 0x12, // Operating by USB and rumble is turned off
- BluetoothRumble = (40 << 8) | 0x14, // Operating by Bluetooth and rumble is turned on
- Bluetooth = (40 << 8) | 0x16, // Operating by Bluetooth and rumble is turned off
-};
-
-#endif
diff --git a/lib/usbhost/USB_Host_Shield_2.0/PS3USB.cpp b/lib/usbhost/USB_Host_Shield_2.0/PS3USB.cpp
deleted file mode 100644
index c32175389c94..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/PS3USB.cpp
+++ /dev/null
@@ -1,572 +0,0 @@
-/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
-
- This software may be distributed and modified under the terms of the GNU
- General Public License version 2 (GPL2) as published by the Free Software
- Foundation and appearing in the file GPL2.TXT included in the packaging of
- this file. Please note that GPL2 Section 2[b] requires that all works based
- on this software must also be made publicly available under the terms of
- the GPL2 ("Copyleft").
-
- Contact information
- -------------------
-
- Kristian Lauszus, TKJ Electronics
- Web : http://www.tkjelectronics.com
- e-mail : kristianl@tkjelectronics.com
- */
-
-#include "PS3USB.h"
-// 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
-
-PS3USB::PS3USB(USB *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0) :
-pUsb(p), // pointer to USB class instance - mandatory
-bAddress(0), // device address - mandatory
-bPollEnable(false) // don't start polling before dongle is connected
-{
- for(uint8_t i = 0; i < PS3_MAX_ENDPOINTS; i++) {
- epInfo[i].epAddr = 0;
- epInfo[i].maxPktSize = (i) ? 0 : 8;
- epInfo[i].epAttribs = 0;
- epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
- }
-
- if(pUsb) // register in USB subsystem
- pUsb->RegisterDeviceClass(this); //set devConfig[] entry
-
- my_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead
- my_bdaddr[4] = btadr4;
- my_bdaddr[3] = btadr3;
- my_bdaddr[2] = btadr2;
- my_bdaddr[1] = btadr1;
- my_bdaddr[0] = btadr0;
-}
-
-uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
- uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
- USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf);
- uint8_t rcode;
- UsbDevice *p = NULL;
- EpInfo *oldep_ptr = NULL;
- uint16_t PID;
- uint16_t VID;
-
- // get memory address of USB device address pool
- AddressPool &addrPool = pUsb->GetAddressPool();
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nPS3USB Init"), 0x80);
-#endif
- // check if address has already been assigned to an instance
- if(bAddress) {
-#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);
-
- if(!p) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nAddress not found"), 0x80);
-#endif
- return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
- }
-
- if(!p->epinfo) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nepinfo is null"), 0x80);
-#endif
- return USB_ERROR_EPINFO_IS_NULL;
- }
-
- // Save old pointer to EP_RECORD of address 0
- oldep_ptr = p->epinfo;
-
- // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
- p->epinfo = epInfo;
-
- p->lowspeed = lowspeed;
-
- // Get device descriptor
- rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
- // Restore p->epinfo
- p->epinfo = oldep_ptr;
-
- if(rcode)
- goto FailGetDevDescr;
-
- VID = udd->idVendor;
- PID = udd->idProduct;
-
- if(VID != PS3_VID || (PID != PS3_PID && PID != PS3NAVIGATION_PID && PID != PS3MOVE_PID))
- goto FailUnknownDevice;
-
- // Allocate new address according to device class
- bAddress = addrPool.AllocAddress(parent, false, port);
-
- if(!bAddress)
- return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
-
- // Extract Max Packet Size from device descriptor
- epInfo[0].maxPktSize = udd->bMaxPacketSize0;
-
- // Assign new address to the device
- rcode = pUsb->setAddr(0, 0, bAddress);
- if(rcode) {
- p->lowspeed = false;
- addrPool.FreeAddress(bAddress);
- bAddress = 0;
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nsetAddr: "), 0x80);
- D_PrintHex (rcode, 0x80);
-#endif
- return rcode;
- }
-#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)
- return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
-
- p->lowspeed = lowspeed;
-
- // Assign epInfo to epinfo pointer - only EP0 is known
- rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
- if(rcode)
- goto FailSetDevTblEntry;
-
-
- /* The application will work in reduced host mode, so we can save program and data
- memory space. After verifying the PID and VID we will use known values for the
- configuration values for device, interface, endpoints and HID for the PS3 Controllers */
-
- /* Initialize data structures for endpoints of device */
- epInfo[ PS3_OUTPUT_PIPE ].epAddr = 0x02; // PS3 output endpoint
- epInfo[ PS3_OUTPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
- epInfo[ PS3_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
- epInfo[ PS3_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
- epInfo[ PS3_OUTPUT_PIPE ].bmSndToggle = 0;
- epInfo[ PS3_OUTPUT_PIPE ].bmRcvToggle = 0;
- epInfo[ PS3_INPUT_PIPE ].epAddr = 0x01; // PS3 report endpoint
- epInfo[ PS3_INPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
- epInfo[ PS3_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
- epInfo[ PS3_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
- epInfo[ PS3_INPUT_PIPE ].bmSndToggle = 0;
- epInfo[ PS3_INPUT_PIPE ].bmRcvToggle = 0;
-
- rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
- if(rcode)
- goto FailSetDevTblEntry;
-
- delay(200); //Give time for address change
-
- rcode = pUsb->setConf(bAddress, epInfo[ PS3_CONTROL_PIPE ].epAddr, 1);
- if(rcode)
- goto FailSetConfDescr;
-
- if(PID == PS3_PID || PID == PS3NAVIGATION_PID) {
- if(PID == PS3_PID) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80);
-#endif
- PS3Connected = true;
- } else { // must be a navigation controller
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nNavigation Controller Connected"), 0x80);
-#endif
- PS3NavigationConnected = true;
- }
- enable_sixaxis(); // The PS3 controller needs a special command before it starts sending data
-
- // Needed for PS3 Dualshock and Navigation commands to work
- for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
- writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]);
-
- for(uint8_t i = 6; i < 10; i++)
- readBuf[i] = 0x7F; // Set the analog joystick values to center position
- } else { // must be a Motion controller
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nMotion Controller Connected"), 0x80);
-#endif
- PS3MoveConnected = true;
- writeBuf[0] = 0x02; // Set report ID, this is needed for Move commands to work
- }
- if(my_bdaddr[0] != 0x00 || my_bdaddr[1] != 0x00 || my_bdaddr[2] != 0x00 || my_bdaddr[3] != 0x00 || my_bdaddr[4] != 0x00 || my_bdaddr[5] != 0x00) {
- if(PS3MoveConnected)
- setMoveBdaddr(my_bdaddr); // Set internal Bluetooth address
- else
- setBdaddr(my_bdaddr); // Set internal Bluetooth address
-
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80);
- for(int8_t i = 5; i > 0; i--) {
- D_PrintHex (my_bdaddr[i], 0x80);
- Notify(PSTR(":"), 0x80);
- }
- D_PrintHex (my_bdaddr[0], 0x80);
-#endif
- }
- onInit();
-
- bPollEnable = true;
- Notify(PSTR("\r\n"), 0x80);
- timer = millis();
- return 0; // Successful configuration
-
- /* Diagnostic messages */
-FailGetDevDescr:
-#ifdef DEBUG_USB_HOST
- NotifyFailGetDevDescr();
- goto Fail;
-#endif
-
-FailSetDevTblEntry:
-#ifdef DEBUG_USB_HOST
- NotifyFailSetDevTblEntry();
- goto Fail;
-#endif
-
-FailSetConfDescr:
-#ifdef DEBUG_USB_HOST
- NotifyFailSetConfDescr();
-#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\nPS3 Init Failed, error code: "), 0x80);
- NotifyFail(rcode);
-#endif
- Release();
- return rcode;
-}
-
-/* Performs a cleanup after failed Init() attempt */
-uint8_t PS3USB::Release() {
- PS3Connected = false;
- PS3MoveConnected = false;
- PS3NavigationConnected = false;
- pUsb->GetAddressPool().FreeAddress(bAddress);
- bAddress = 0;
- bPollEnable = false;
- return 0;
-}
-
-uint8_t PS3USB::Poll() {
- if(!bPollEnable)
- return 0;
-
- if(PS3Connected || PS3NavigationConnected) {
- uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
- pUsb->inTransfer(bAddress, epInfo[ PS3_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
- if(millis() - timer > 100) { // Loop 100ms before processing data
- readReport();
-#ifdef PRINTREPORT
- printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
-#endif
- }
- } else if(PS3MoveConnected) { // One can only set the color of the bulb, set the rumble, set and get the bluetooth address and calibrate the magnetometer via USB
- if(millis() - timer > 4000) { // Send at least every 4th second
- Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE); // The Bulb and rumble values, has to be written again and again, for it to stay turned on
- timer = millis();
- }
- }
- return 0;
-}
-
-void PS3USB::readReport() {
- ButtonState = (uint32_t)(readBuf[2] | ((uint16_t)readBuf[3] << 8) | ((uint32_t)readBuf[4] << 16));
-
- //Notify(PSTR("\r\nButtonState", 0x80);
- //PrintHex(ButtonState, 0x80);
-
- if(ButtonState != OldButtonState) {
- ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
- OldButtonState = ButtonState;
- }
-}
-
-void PS3USB::printReport() { // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
-#ifdef PRINTREPORT
- for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) {
- D_PrintHex (readBuf[i], 0x80);
- Notify(PSTR(" "), 0x80);
- }
- Notify(PSTR("\r\n"), 0x80);
-#endif
-}
-
-bool PS3USB::getButtonPress(ButtonEnum b) {
- return (ButtonState & pgm_read_dword(&PS3_BUTTONS[(uint8_t)b]));
-}
-
-bool PS3USB::getButtonClick(ButtonEnum b) {
- uint32_t button = pgm_read_dword(&PS3_BUTTONS[(uint8_t)b]);
- bool click = (ButtonClickState & button);
- ButtonClickState &= ~button; // Clear "click" event
- return click;
-}
-
-uint8_t PS3USB::getAnalogButton(ButtonEnum a) {
- return (uint8_t)(readBuf[(pgm_read_byte(&PS3_ANALOG_BUTTONS[(uint8_t)a])) - 9]);
-}
-
-uint8_t PS3USB::getAnalogHat(AnalogHatEnum a) {
- return (uint8_t)(readBuf[((uint8_t)a + 6)]);
-}
-
-uint16_t PS3USB::getSensor(SensorEnum a) {
- return ((readBuf[((uint16_t)a) - 9] << 8) | readBuf[((uint16_t)a + 1) - 9]);
-}
-
-double PS3USB::getAngle(AngleEnum a) {
- if(PS3Connected) {
- double accXval;
- double accYval;
- double accZval;
-
- // Data for the Kionix KXPC4 used in the DualShock 3
- const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V)
- accXval = -((double)getSensor(aX) - zeroG);
- accYval = -((double)getSensor(aY) - zeroG);
- accZval = -((double)getSensor(aZ) - zeroG);
-
- // Convert to 360 degrees resolution
- // atan2 outputs the value of -π to π (radians)
- // We are then converting it to 0 to 2π and then to degrees
- if(a == Pitch)
- return (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
- else
- return (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
- } else
- return 0;
-}
-
-bool PS3USB::getStatus(StatusEnum c) {
- return (readBuf[((uint16_t)c >> 8) - 9] == ((uint8_t)c & 0xff));
-}
-
-void PS3USB::printStatusString() {
- char statusOutput[100]; // Max string length plus null character
- if(PS3Connected || PS3NavigationConnected) {
- strcpy_P(statusOutput, PSTR("ConnectionStatus: "));
-
- if(getStatus(Plugged)) strcat_P(statusOutput, PSTR("Plugged"));
- else if(getStatus(Unplugged)) strcat_P(statusOutput, PSTR("Unplugged"));
- else strcat_P(statusOutput, PSTR("Error"));
-
- strcat_P(statusOutput, PSTR(" - PowerRating: "));
-
- if(getStatus(Charging)) strcat_P(statusOutput, PSTR("Charging"));
- else if(getStatus(NotCharging)) strcat_P(statusOutput, PSTR("Not Charging"));
- else if(getStatus(Shutdown)) strcat_P(statusOutput, PSTR("Shutdown"));
- else if(getStatus(Dying)) strcat_P(statusOutput, PSTR("Dying"));
- else if(getStatus(Low)) strcat_P(statusOutput, PSTR("Low"));
- else if(getStatus(High)) strcat_P(statusOutput, PSTR("High"));
- else if(getStatus(Full)) strcat_P(statusOutput, PSTR("Full"));
- else strcat_P(statusOutput, PSTR("Error"));
-
- strcat_P(statusOutput, PSTR(" - WirelessStatus: "));
-
- if(getStatus(CableRumble)) strcat_P(statusOutput, PSTR("Cable - Rumble is on"));
- else if(getStatus(Cable)) strcat_P(statusOutput, PSTR("Cable - Rumble is off"));
- else if(getStatus(BluetoothRumble)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is on"));
- else if(getStatus(Bluetooth)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is off"));
- else strcat_P(statusOutput, PSTR("Error"));
- } else
- strcpy_P(statusOutput, PSTR("Error"));
-
- USB_HOST_SERIAL.write(statusOutput);
-}
-
-/* Playstation Sixaxis Dualshock and Navigation Controller commands */
-void PS3USB::PS3_Command(uint8_t *data, uint16_t nbytes) {
- // bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x01), Report Type (Output 0x02), interface (0x00), datalength, datalength, data)
- pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x01, 0x02, 0x00, nbytes, nbytes, data, NULL);
-}
-
-void PS3USB::setAllOff() {
- for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
- writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); // Reset buffer
-
- PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
-}
-
-void PS3USB::setRumbleOff() {
- writeBuf[1] = 0x00;
- writeBuf[2] = 0x00; // Low mode off
- writeBuf[3] = 0x00;
- writeBuf[4] = 0x00; // High mode off
-
- PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
-}
-
-void PS3USB::setRumbleOn(RumbleEnum mode) {
- if((mode & 0x30) > 0x00) {
- uint8_t power[2] = {0xff, 0x00}; // Defaults to RumbleLow
- if(mode == RumbleHigh) {
- power[0] = 0x00;
- power[1] = 0xff;
- }
- setRumbleOn(0xfe, power[0], 0xfe, power[1]);
- }
-}
-
-void PS3USB::setRumbleOn(uint8_t rightDuration, uint8_t rightPower, uint8_t leftDuration, uint8_t leftPower) {
- writeBuf[1] = rightDuration;
- writeBuf[2] = rightPower;
- writeBuf[3] = leftDuration;
- writeBuf[4] = leftPower;
- PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
-}
-
-void PS3USB::setLedRaw(uint8_t value) {
- writeBuf[9] = value << 1;
- PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
-}
-
-void PS3USB::setLedOff(LEDEnum a) {
- writeBuf[9] &= ~((uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1));
- PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
-}
-
-void PS3USB::setLedOn(LEDEnum a) {
- if(a == OFF)
- setLedRaw(0);
- else {
- writeBuf[9] |= (uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1);
- PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
- }
-}
-
-void PS3USB::setLedToggle(LEDEnum a) {
- writeBuf[9] ^= (uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1);
- PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
-}
-
-void PS3USB::setBdaddr(uint8_t *bdaddr) {
- /* Set the internal Bluetooth address */
- uint8_t buf[8];
- buf[0] = 0x01;
- buf[1] = 0x00;
-
- for(uint8_t i = 0; i < 6; i++)
- buf[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed, 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::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)
- pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF4, 0x03, 0x00, 4, 4, cmd_buf, NULL);
-}
-
-/* Playstation Move Controller commands */
-void PS3USB::Move_Command(uint8_t *data, uint16_t nbytes) {
- pUsb->outTransfer(bAddress, epInfo[ PS3_OUTPUT_PIPE ].epAddr, nbytes, data);
-}
-
-void PS3USB::moveSetBulb(uint8_t r, uint8_t g, uint8_t b) { // Use this to set the Color using RGB values
- // Set the Bulb's values into the write buffer
- writeBuf[2] = r;
- writeBuf[3] = g;
- writeBuf[4] = b;
-
- Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
-}
-
-void PS3USB::moveSetBulb(ColorsEnum color) { // Use this to set the Color using the predefined colors in "enums.h"
- moveSetBulb((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
-}
-
-void PS3USB::moveSetRumble(uint8_t rumble) {
-#ifdef DEBUG_USB_HOST
- 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
- 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 */
- uint8_t buf[11];
- buf[0] = 0x05;
- buf[7] = 0x10;
- buf[8] = 0x01;
- buf[9] = 0x02;
- buf[10] = 0x12;
-
- for(uint8_t i = 0; i < 6; i++)
- buf[i + 1] = bdaddr[i];
-
- // bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x05), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
- pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00, 11, 11, buf, NULL);
-}
-
-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
- else {
- if(PS3MoveConnected)
- moveSetBulb(Red);
- else // Dualshock 3 or Navigation controller
- setLedOn(LED1);
- }
-}
diff --git a/lib/usbhost/USB_Host_Shield_2.0/PS3USB.h b/lib/usbhost/USB_Host_Shield_2.0/PS3USB.h
deleted file mode 100644
index 2eba9258cfa5..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/PS3USB.h
+++ /dev/null
@@ -1,303 +0,0 @@
-/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
-
- This software may be distributed and modified under the terms of the GNU
- General Public License version 2 (GPL2) as published by the Free Software
- Foundation and appearing in the file GPL2.TXT included in the packaging of
- this file. Please note that GPL2 Section 2[b] requires that all works based
- on this software must also be made publicly available under the terms of
- the GPL2 ("Copyleft").
-
- Contact information
- -------------------
-
- Kristian Lauszus, TKJ Electronics
- Web : http://www.tkjelectronics.com
- e-mail : kristianl@tkjelectronics.com
- */
-
-#ifndef _ps3usb_h_
-#define _ps3usb_h_
-
-#include "Usb.h"
-#include "hid.h"
-#include "PS3Enums.h"
-
-/* PS3 data taken from descriptors */
-#define EP_MAXPKTSIZE 64 // max size for data via USB
-
-/* Names we give to the 3 ps3 pipes - this is only used for setting the bluetooth address into the ps3 controllers */
-#define PS3_CONTROL_PIPE 0
-#define PS3_OUTPUT_PIPE 1
-#define PS3_INPUT_PIPE 2
-
-//PID and VID of the different devices
-#define PS3_VID 0x054C // Sony Corporation
-#define PS3_PID 0x0268 // PS3 Controller DualShock 3
-#define PS3NAVIGATION_PID 0x042F // Navigation controller
-#define PS3MOVE_PID 0x03D5 // Motion controller
-
-#define PS3_MAX_ENDPOINTS 3
-
-/**
- * This class implements support for all the official PS3 Controllers:
- * Dualshock 3, Navigation or a Motion controller via USB.
- *
- * One can only set the color of the bulb, set the rumble, set and get the bluetooth address and calibrate the magnetometer via USB on the Move controller.
- *
- * Information about the protocol can be found at the wiki: https://github.com/felis/USB_Host_Shield_2.0/wiki/PS3-Information.
- */
-class PS3USB : public USBDeviceConfig {
-public:
- /**
- * Constructor for the PS3USB class.
- * @param pUsb Pointer to USB class instance.
- * @param btadr5,btadr4,btadr3,btadr2,btadr1,btadr0
- * Pass your dongles Bluetooth address into the constructor,
- * so you are able to pair the controller with a Bluetooth dongle.
- */
- PS3USB(USB *pUsb, uint8_t btadr5 = 0, uint8_t btadr4 = 0, uint8_t btadr3 = 0, uint8_t btadr2 = 0, uint8_t btadr1 = 0, uint8_t btadr0 = 0);
-
- /** @name USBDeviceConfig implementation */
- /**
- * Initialize the PS3 Controller.
- * @param parent Hub number.
- * @param port Port number on the hub.
- * @param lowspeed Speed of the device.
- * @return 0 on success.
- */
- uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
- /**
- * Release the USB device.
- * @return 0 on success.
- */
- uint8_t Release();
- /**
- * Poll the USB Input endpoins and run the state machines.
- * @return 0 on success.
- */
- uint8_t Poll();
-
- /**
- * Get the device address.
- * @return The device address.
- */
- virtual uint8_t GetAddress() {
- return bAddress;
- };
-
- /**
- * Used to check if the controller has been initialized.
- * @return True if it's ready.
- */
- virtual bool isReady() {
- return bPollEnable;
- };
-
- /**
- * Used by the USB core to check what this driver support.
- * @param vid The device's VID.
- * @param pid The device's PID.
- * @return Returns true if the device's VID and PID matches this driver.
- */
- virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) {
- return (vid == PS3_VID && (pid == PS3_PID || pid == PS3NAVIGATION_PID || pid == PS3MOVE_PID));
- };
- /**@}*/
-
- /**
- * Used to set the Bluetooth address inside the Dualshock 3 and Navigation controller.
- * Set using LSB first.
- * @param bdaddr Your dongles Bluetooth address.
- */
- 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.
- * Set using LSB first.
- * @param bdaddr Your dongles Bluetooth address.
- */
- 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 data Buffer to store data in. Must be at least 147 bytes
- */
- void getMoveCalibration(uint8_t *data);
-
- /** @name PS3 Controller functions */
- /**
- * getButtonPress(ButtonEnum b) will return true as long as the button is held down.
- *
- * While getButtonClick(ButtonEnum b) will only return it once.
- *
- * So you instance if you need to increase a variable once you would use getButtonClick(ButtonEnum b),
- * but if you need to drive a robot forward you would use getButtonPress(ButtonEnum b).
- * @param b ::ButtonEnum to read.
- * @return getButtonPress(ButtonEnum b) will return a true as long as a button is held down, while getButtonClick(ButtonEnum b) will return true once for each button press.
- */
- bool getButtonPress(ButtonEnum b);
- bool getButtonClick(ButtonEnum b);
- /**@}*/
- /** @name PS3 Controller functions */
- /**
- * Used to get the analog value from button presses.
- * @param a The ::ButtonEnum to read.
- * The supported buttons are:
- * ::UP, ::RIGHT, ::DOWN, ::LEFT, ::L1, ::L2, ::R1, ::R2,
- * ::TRIANGLE, ::CIRCLE, ::CROSS, ::SQUARE, and ::T.
- * @return Analog value in the range of 0-255.
- */
- uint8_t getAnalogButton(ButtonEnum a);
- /**
- * Used to read the analog joystick.
- * @param a ::LeftHatX, ::LeftHatY, ::RightHatX, and ::RightHatY.
- * @return Return the analog value in the range of 0-255.
- */
- uint8_t getAnalogHat(AnalogHatEnum a);
- /**
- * Used to read the sensors inside the Dualshock 3 controller.
- * @param a
- * The Dualshock 3 has a 3-axis accelerometer and a 1-axis gyro inside.
- * @return Return the raw sensor value.
- */
- uint16_t getSensor(SensorEnum a);
- /**
- * Use this to get ::Pitch and ::Roll calculated using the accelerometer.
- * @param a Either ::Pitch or ::Roll.
- * @return Return the angle in the range of 0-360.
- */
- double getAngle(AngleEnum a);
- /**
- * Get the ::StatusEnum from the controller.
- * @param c The ::StatusEnum you want to read.
- * @return True if correct and false if not.
- */
- bool getStatus(StatusEnum c);
- /** Read all the available statuses from the controller and prints it as a nice formated string. */
- void printStatusString();
-
- /** Used to set all LEDs and rumble off. */
- void setAllOff();
- /** Turn off rumble. */
- void setRumbleOff();
- /**
- * Turn on rumble.
- * @param mode Either ::RumbleHigh or ::RumbleLow.
- */
- void setRumbleOn(RumbleEnum mode);
- /**
- * Turn on rumble using custom duration and power.
- * @param rightDuration The duration of the right/low rumble effect.
- * @param rightPower The intensity of the right/low rumble effect.
- * @param leftDuration The duration of the left/high rumble effect.
- * @param leftPower The intensity of the left/high rumble effect.
- */
- void setRumbleOn(uint8_t rightDuration, uint8_t rightPower, uint8_t leftDuration, uint8_t leftPower);
-
- /**
- * Set LED value without using the ::LEDEnum.
- * @param value See: ::LEDEnum.
- */
- void setLedRaw(uint8_t value);
-
- /** Turn all LEDs off. */
- void setLedOff() {
- setLedRaw(0);
- }
- /**
- * Turn the specific ::LEDEnum off.
- * @param a The ::LEDEnum to turn off.
- */
- void setLedOff(LEDEnum a);
- /**
- * Turn the specific ::LEDEnum on.
- * @param a The ::LEDEnum to turn on.
- */
- void setLedOn(LEDEnum a);
- /**
- * Toggle the specific ::LEDEnum.
- * @param a The ::LEDEnum to toggle.
- */
- void setLedToggle(LEDEnum a);
-
- /**
- * Use this to set the Color using RGB values.
- * @param r,g,b RGB value.
- */
- void moveSetBulb(uint8_t r, uint8_t g, uint8_t b);
- /**
- * Use this to set the color using the predefined colors in ::ColorsEnum.
- * @param color The desired color.
- */
- void moveSetBulb(ColorsEnum color);
- /**
- * Set the rumble value inside the Move controller.
- * @param rumble The desired value in the range from 64-255.
- */
- void moveSetRumble(uint8_t rumble);
-
- /**
- * Used to call your own function when the controller is successfully initialized.
- * @param funcOnInit Function to call.
- */
- void attachOnInit(void (*funcOnInit)(void)) {
- pFuncOnInit = funcOnInit;
- };
- /**@}*/
-
- /** Variable used to indicate if the normal playstation controller is successfully connected. */
- bool PS3Connected;
- /** Variable used to indicate if the move controller is successfully connected. */
- bool PS3MoveConnected;
- /** Variable used to indicate if the navigation controller is successfully connected. */
- bool PS3NavigationConnected;
-
-protected:
- /** Pointer to USB class instance. */
- USB *pUsb;
- /** Device address. */
- uint8_t bAddress;
- /** Endpoint info structure. */
- EpInfo epInfo[PS3_MAX_ENDPOINTS];
-
-private:
- /**
- * Called when the controller is successfully initialized.
- * Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
- * This is useful for instance if you want to set the LEDs in a specific way.
- */
- void onInit();
- void (*pFuncOnInit)(void); // Pointer to function called in onInit()
-
- bool bPollEnable;
-
- uint32_t timer; // used to continuously set PS3 Move controller Bulb and rumble values
-
- uint32_t ButtonState;
- uint32_t OldButtonState;
- uint32_t ButtonClickState;
-
- uint8_t my_bdaddr[6]; // Change to your dongles Bluetooth address in the constructor
- uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data
- uint8_t writeBuf[EP_MAXPKTSIZE]; // General purpose buffer for output data
-
- void readReport(); // read incoming data
- void printReport(); // print incoming date - Uncomment for debugging
-
- /* Private commands */
- void PS3_Command(uint8_t *data, uint16_t nbytes);
- void enable_sixaxis(); // Command used to enable the Dualshock 3 and Navigation controller to send data via USB
- void Move_Command(uint8_t *data, uint16_t nbytes);
-};
-#endif
diff --git a/lib/usbhost/USB_Host_Shield_2.0/PS4BT.h b/lib/usbhost/USB_Host_Shield_2.0/PS4BT.h
deleted file mode 100644
index b7eb4b5a9135..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/PS4BT.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/* Copyright (C) 2014 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 _ps4bt_h_
-#define _ps4bt_h_
-
-#include "BTHID.h"
-#include "PS4Parser.h"
-
-/**
- * This class implements support for the PS4 controller via Bluetooth.
- * It uses the BTHID class for all the Bluetooth communication.
- */
-class PS4BT : public BTHID, public PS4Parser {
-public:
- /**
- * Constructor for the PS4BT 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 "0000" will be used.
- */
- PS4BT(BTD *p, bool pair = false, const char *pin = "0000") :
- BTHID(p, pair, pin) {
- PS4Parser::Reset();
- };
-
- /**
- * Used to check if a PS4 controller is connected.
- * @return Returns true if it is connected.
- */
- bool connected() {
- return BTHID::connected;
- };
-
-protected:
- /** @name BTHID implementation */
- /**
- * Used to parse Bluetooth HID data.
- * @param len The length of the incoming data.
- * @param buf Pointer to the data buffer.
- */
- virtual void ParseBTHIDData(uint8_t len, uint8_t *buf) {
- PS4Parser::Parse(len, buf);
- };
-
- /**
- * Called when a device 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.
- */
- virtual void OnInitBTHID() {
- PS4Parser::Reset();
- enable_sixaxis(); // Make the controller send out the entire output report
- if (pFuncOnInit)
- pFuncOnInit(); // Call the user function
- else
- setLed(Blue);
- };
-
- /** Used to reset the different buffers to there default values */
- virtual void ResetBTHID() {
- PS4Parser::Reset();
- };
- /**@}*/
-
- /** @name PS4Parser implementation */
- virtual void sendOutputReport(PS4Output *output) { // Source: https://github.com/chrippa/ds4drv
- uint8_t buf[79];
- memset(buf, 0, sizeof(buf));
-
- buf[0] = 0x52; // HID BT Set_report (0x50) | Report Type (Output 0x02)
- buf[1] = 0x11; // Report ID
- buf[2] = 0x80;
- buf[4]= 0xFF;
-
- buf[7] = output->smallRumble; // Small Rumble
- buf[8] = output->bigRumble; // Big rumble
-
- buf[9] = output->r; // Red
- buf[10] = output->g; // Green
- buf[11] = output->b; // Blue
-
- buf[12] = output->flashOn; // Time to flash bright (255 = 2.5 seconds)
- buf[13] = output->flashOff; // Time to flash dark (255 = 2.5 seconds)
-
- output->reportChanged = false;
-
- // The PS4 console actually set the four last bytes to a CRC32 checksum, but it seems like it is actually not needed
-
- HID_Command(buf, sizeof(buf));
- };
- /**@}*/
-
-private:
- void enable_sixaxis() { // Command used to make the PS4 controller send out the entire output report
- uint8_t buf[2];
- buf[0] = 0x43; // HID BT Get_report (0x40) | Report Type (Feature 0x03)
- buf[1] = 0x02; // Report ID
-
- HID_Command(buf, 2);
- };
-
- void HID_Command(uint8_t *data, uint8_t nbytes) {
- pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]);
- };
-};
-#endif
diff --git a/lib/usbhost/USB_Host_Shield_2.0/PS4Parser.cpp b/lib/usbhost/USB_Host_Shield_2.0/PS4Parser.cpp
deleted file mode 100644
index ca6adce403e9..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/PS4Parser.cpp
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Copyright (C) 2014 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 "PS4Parser.h"
-
-// To enable serial debugging see "settings.h"
-//#define PRINTREPORT // Uncomment to print the report send by the PS4 Controller
-
-bool PS4Parser::checkDpad(ButtonEnum b) {
- switch (b) {
- case UP:
- return ps4Data.btn.dpad == DPAD_LEFT_UP || ps4Data.btn.dpad == DPAD_UP || ps4Data.btn.dpad == DPAD_UP_RIGHT;
- case RIGHT:
- return ps4Data.btn.dpad == DPAD_UP_RIGHT || ps4Data.btn.dpad == DPAD_RIGHT || ps4Data.btn.dpad == DPAD_RIGHT_DOWN;
- case DOWN:
- return ps4Data.btn.dpad == DPAD_RIGHT_DOWN || ps4Data.btn.dpad == DPAD_DOWN || ps4Data.btn.dpad == DPAD_DOWN_LEFT;
- case LEFT:
- return ps4Data.btn.dpad == DPAD_DOWN_LEFT || ps4Data.btn.dpad == DPAD_LEFT || ps4Data.btn.dpad == DPAD_LEFT_UP;
- default:
- return false;
- }
-}
-
-bool PS4Parser::getButtonPress(ButtonEnum b) {
- if (b <= LEFT) // Dpad
- return checkDpad(b);
- else
- return ps4Data.btn.val & (1UL << pgm_read_byte(&PS4_BUTTONS[(uint8_t)b]));
-}
-
-bool PS4Parser::getButtonClick(ButtonEnum b) {
- uint32_t mask = 1UL << pgm_read_byte(&PS4_BUTTONS[(uint8_t)b]);
- bool click = buttonClickState.val & mask;
- buttonClickState.val &= ~mask; // Clear "click" event
- return click;
-}
-
-uint8_t PS4Parser::getAnalogButton(ButtonEnum b) {
- if (b == L2) // These are the only analog buttons on the controller
- return ps4Data.trigger[0];
- else if (b == R2)
- return ps4Data.trigger[1];
- return 0;
-}
-
-uint8_t PS4Parser::getAnalogHat(AnalogHatEnum a) {
- return ps4Data.hatValue[(uint8_t)a];
-}
-
-void PS4Parser::Parse(uint8_t len, uint8_t *buf) {
- if (len > 1 && buf) {
-#ifdef PRINTREPORT
- Notify(PSTR("\r\n"), 0x80);
- for (uint8_t i = 0; i < len; i++) {
- D_PrintHex (buf[i], 0x80);
- Notify(PSTR(" "), 0x80);
- }
-#endif
-
- if (buf[0] == 0x01) // Check report ID
- memcpy(&ps4Data, buf + 1, min((uint8_t)(len - 1), sizeof(ps4Data)));
- else if (buf[0] == 0x11) { // This report is send via Bluetooth, it has an offset of 2 compared to the USB data
- if (len < 4) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nReport is too short: "), 0x80);
- D_PrintHex (len, 0x80);
-#endif
- return;
- }
- memcpy(&ps4Data, buf + 3, min((uint8_t)(len - 3), sizeof(ps4Data)));
- } else {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nUnknown report id: "), 0x80);
- D_PrintHex (buf[0], 0x80);
-#endif
- return;
- }
-
- if (ps4Data.btn.val != oldButtonState.val) { // Check if anything has changed
- buttonClickState.val = ps4Data.btn.val & ~oldButtonState.val; // Update click state variable
- oldButtonState.val = ps4Data.btn.val;
-
- // The DPAD buttons does not set the different bits, but set a value corresponding to the buttons pressed, we will simply set the bits ourself
- uint8_t newDpad = 0;
- if (checkDpad(UP))
- newDpad |= 1 << UP;
- if (checkDpad(RIGHT))
- newDpad |= 1 << RIGHT;
- if (checkDpad(DOWN))
- newDpad |= 1 << DOWN;
- if (checkDpad(LEFT))
- newDpad |= 1 << LEFT;
- if (newDpad != oldDpad) {
- buttonClickState.dpad = newDpad & ~oldDpad; // Override values
- oldDpad = newDpad;
- }
- }
- }
-
- if (ps4Output.reportChanged)
- sendOutputReport(&ps4Output); // Send output report
-}
diff --git a/lib/usbhost/USB_Host_Shield_2.0/PS4Parser.h b/lib/usbhost/USB_Host_Shield_2.0/PS4Parser.h
deleted file mode 100644
index 51f0806361cd..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/PS4Parser.h
+++ /dev/null
@@ -1,407 +0,0 @@
-/* Copyright (C) 2014 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 _ps4parser_h_
-#define _ps4parser_h_
-
-#include "Usb.h"
-#include "controllerEnums.h"
-
-/** Buttons on the controller */
-const uint8_t PS4_BUTTONS[] PROGMEM = {
- UP, // UP
- RIGHT, // RIGHT
- DOWN, // DOWN
- LEFT, // LEFT
-
- 0x0C, // SHARE
- 0x0D, // OPTIONS
- 0x0E, // L3
- 0x0F, // R3
-
- 0x0A, // L2
- 0x0B, // R2
- 0x08, // L1
- 0x09, // R1
-
- 0x07, // TRIANGLE
- 0x06, // CIRCLE
- 0x05, // CROSS
- 0x04, // SQUARE
-
- 0x10, // PS
- 0x11, // TOUCHPAD
-};
-
-union PS4Buttons {
- struct {
- uint8_t dpad : 4;
- uint8_t square : 1;
- uint8_t cross : 1;
- uint8_t circle : 1;
- uint8_t triangle : 1;
-
- uint8_t l1 : 1;
- uint8_t r1 : 1;
- uint8_t l2 : 1;
- uint8_t r2 : 1;
- uint8_t share : 1;
- uint8_t options : 1;
- uint8_t l3 : 1;
- uint8_t r3 : 1;
-
- uint8_t ps : 1;
- uint8_t touchpad : 1;
- uint8_t reportCounter : 6;
- } __attribute__((packed));
- uint32_t val : 24;
-} __attribute__((packed));
-
-struct touchpadXY {
- uint8_t dummy; // I can not figure out what this data is for, it seems to change randomly, maybe a timestamp?
- struct {
- uint8_t counter : 7; // Increments every time a finger is touching the touchpad
- uint8_t touching : 1; // The top bit is cleared if the finger is touching the touchpad
- uint16_t x : 12;
- uint16_t y : 12;
- } __attribute__((packed)) finger[2]; // 0 = first finger, 1 = second finger
-} __attribute__((packed));
-
-struct PS4Status {
- uint8_t battery : 4;
- uint8_t usb : 1;
- uint8_t audio : 1;
- uint8_t mic : 1;
- uint8_t unknown : 1; // Extension port?
-} __attribute__((packed));
-
-struct PS4Data {
- /* Button and joystick values */
- uint8_t hatValue[4];
- PS4Buttons btn;
- uint8_t trigger[2];
-
- /* Gyro and accelerometer values */
- uint8_t dummy[3]; // First two looks random, while the third one might be some kind of status - it increments once in a while
- int16_t gyroY, gyroZ, gyroX;
- int16_t accX, accZ, accY;
-
- uint8_t dummy2[5];
- PS4Status status;
- uint8_t dummy3[3];
-
- /* The rest is data for the touchpad */
- touchpadXY xy[3]; // It looks like it sends out three coordinates each time, this might be because the microcontroller inside the PS4 controller is much faster than the Bluetooth connection.
- // The last data is read from the last position in the array while the oldest measurement is from the first position.
- // The first position will also keep it's value after the finger is released, while the other two will set them to zero.
- // Note that if you read fast enough from the device, then only the first one will contain any data.
-
- // The last three bytes are always: 0x00, 0x80, 0x00
-} __attribute__((packed));
-
-struct PS4Output {
- uint8_t bigRumble, smallRumble; // Rumble
- uint8_t r, g, b; // RGB
- uint8_t flashOn, flashOff; // Time to flash bright/dark (255 = 2.5 seconds)
- bool reportChanged; // The data is send when data is received from the controller
-} __attribute__((packed));
-
-enum DPADEnum {
- DPAD_UP = 0x0,
- DPAD_UP_RIGHT = 0x1,
- DPAD_RIGHT = 0x2,
- DPAD_RIGHT_DOWN = 0x3,
- DPAD_DOWN = 0x4,
- DPAD_DOWN_LEFT = 0x5,
- DPAD_LEFT = 0x6,
- DPAD_LEFT_UP = 0x7,
- DPAD_OFF = 0x8,
-};
-
-/** This class parses all the data sent by the PS4 controller */
-class PS4Parser {
-public:
- /** Constructor for the PS4Parser class. */
- PS4Parser() {
- Reset();
- };
-
- /** @name PS4 Controller functions */
- /**
- * getButtonPress(ButtonEnum b) will return true as long as the button is held down.
- *
- * While getButtonClick(ButtonEnum b) will only return it once.
- *
- * So you instance if you need to increase a variable once you would use getButtonClick(ButtonEnum b),
- * but if you need to drive a robot forward you would use getButtonPress(ButtonEnum b).
- * @param b ::ButtonEnum to read.
- * @return getButtonPress(ButtonEnum b) will return a true as long as a button is held down, while getButtonClick(ButtonEnum b) will return true once for each button press.
- */
- bool getButtonPress(ButtonEnum b);
- bool getButtonClick(ButtonEnum b);
- /**@}*/
- /** @name PS4 Controller functions */
- /**
- * Used to get the analog value from button presses.
- * @param b The ::ButtonEnum to read.
- * The supported buttons are:
- * ::UP, ::RIGHT, ::DOWN, ::LEFT, ::L1, ::L2, ::R1, ::R2,
- * ::TRIANGLE, ::CIRCLE, ::CROSS, ::SQUARE, and ::T.
- * @return Analog value in the range of 0-255.
- */
- uint8_t getAnalogButton(ButtonEnum b);
-
- /**
- * Used to read the analog joystick.
- * @param a ::LeftHatX, ::LeftHatY, ::RightHatX, and ::RightHatY.
- * @return Return the analog value in the range of 0-255.
- */
- uint8_t getAnalogHat(AnalogHatEnum a);
-
- /**
- * Get the x-coordinate of the touchpad. Position 0 is in the top left.
- * @param finger 0 = first finger, 1 = second finger. If omitted, then 0 will be used.
- * @param xyId The controller sends out three packets with the same structure.
- * The third one will contain the last measure, but if you read from the controller then there is only be data in the first one.
- * For that reason it will be set to 0 if the argument is omitted.
- * @return Returns the x-coordinate of the finger.
- */
- uint16_t getX(uint8_t finger = 0, uint8_t xyId = 0) {
- return ps4Data.xy[xyId].finger[finger].x;
- };
-
- /**
- * Get the y-coordinate of the touchpad. Position 0 is in the top left.
- * @param finger 0 = first finger, 1 = second finger. If omitted, then 0 will be used.
- * @param xyId The controller sends out three packets with the same structure.
- * The third one will contain the last measure, but if you read from the controller then there is only be data in the first one.
- * For that reason it will be set to 0 if the argument is omitted.
- * @return Returns the y-coordinate of the finger.
- */
- uint16_t getY(uint8_t finger = 0, uint8_t xyId = 0) {
- return ps4Data.xy[xyId].finger[finger].y;
- };
-
- /**
- * Returns whenever the user is toucing the touchpad.
- * @param finger 0 = first finger, 1 = second finger. If omitted, then 0 will be used.
- * @param xyId The controller sends out three packets with the same structure.
- * The third one will contain the last measure, but if you read from the controller then there is only be data in the first one.
- * For that reason it will be set to 0 if the argument is omitted.
- * @return Returns true if the specific finger is touching the touchpad.
- */
- bool isTouching(uint8_t finger = 0, uint8_t xyId = 0) {
- return !(ps4Data.xy[xyId].finger[finger].touching); // The bit is cleared when a finger is touching the touchpad
- };
-
- /**
- * This counter increments every time a finger touches the touchpad.
- * @param finger 0 = first finger, 1 = second finger. If omitted, then 0 will be used.
- * @param xyId The controller sends out three packets with the same structure.
- * The third one will contain the last measure, but if you read from the controller then there is only be data in the first one.
- * For that reason it will be set to 0 if the argument is omitted.
- * @return Return the value of the counter, note that it is only a 7-bit value.
- */
- uint8_t getTouchCounter(uint8_t finger = 0, uint8_t xyId = 0) {
- return ps4Data.xy[xyId].finger[finger].counter;
- };
-
- /**
- * Get the angle of the controller calculated using the accelerometer.
- * @param a Either ::Pitch or ::Roll.
- * @return Return the angle in the range of 0-360.
- */
- double getAngle(AngleEnum a) {
- if (a == Pitch)
- return (atan2(ps4Data.accY, ps4Data.accZ) + PI) * RAD_TO_DEG;
- else
- return (atan2(ps4Data.accX, ps4Data.accZ) + PI) * RAD_TO_DEG;
- };
-
- /**
- * Used to get the raw values from the 3-axis gyroscope and 3-axis accelerometer inside the PS4 controller.
- * @param s The sensor to read.
- * @return Returns the raw sensor reading.
- */
- int16_t getSensor(SensorEnum s) {
- switch(s) {
- case gX:
- return ps4Data.gyroX;
- case gY:
- return ps4Data.gyroY;
- case gZ:
- return ps4Data.gyroZ;
- case aX:
- return ps4Data.accX;
- case aY:
- return ps4Data.accY;
- case aZ:
- return ps4Data.accZ;
- default:
- return 0;
- }
- };
-
- /**
- * Return the battery level of the PS4 controller.
- * @return The battery level in the range 0-15.
- */
- uint8_t getBatteryLevel() {
- return ps4Data.status.battery;
- };
-
- /**
- * Use this to check if an USB cable is connected to the PS4 controller.
- * @return Returns true if an USB cable is connected.
- */
- bool getUsbStatus() {
- return ps4Data.status.usb;
- };
-
- /**
- * Use this to check if an audio jack cable is connected to the PS4 controller.
- * @return Returns true if an audio jack cable is connected.
- */
- bool getAudioStatus() {
- return ps4Data.status.audio;
- };
-
- /**
- * Use this to check if a microphone is connected to the PS4 controller.
- * @return Returns true if a microphone is connected.
- */
- bool getMicStatus() {
- return ps4Data.status.mic;
- };
-
- /** Turn both rumble and the LEDs off. */
- void setAllOff() {
- setRumbleOff();
- setLedOff();
- };
-
- /** Set rumble off. */
- void setRumbleOff() {
- setRumbleOn(0, 0);
- };
-
- /**
- * Turn on rumble.
- * @param mode Either ::RumbleHigh or ::RumbleLow.
- */
- void setRumbleOn(RumbleEnum mode) {
- if (mode == RumbleLow)
- setRumbleOn(0x00, 0xFF);
- else
- setRumbleOn(0xFF, 0x00);
- };
-
- /**
- * Turn on rumble.
- * @param bigRumble Value for big motor.
- * @param smallRumble Value for small motor.
- */
- void setRumbleOn(uint8_t bigRumble, uint8_t smallRumble) {
- ps4Output.bigRumble = bigRumble;
- ps4Output.smallRumble = smallRumble;
- ps4Output.reportChanged = true;
- };
-
- /** Turn all LEDs off. */
- void setLedOff() {
- setLed(0, 0, 0);
- };
-
- /**
- * Use this to set the color using RGB values.
- * @param r,g,b RGB value.
- */
- void setLed(uint8_t r, uint8_t g, uint8_t b) {
- ps4Output.r = r;
- ps4Output.g = g;
- ps4Output.b = b;
- ps4Output.reportChanged = true;
- };
-
- /**
- * Use this to set the color using the predefined colors in ::ColorsEnum.
- * @param color The desired color.
- */
- void setLed(ColorsEnum color) {
- setLed((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
- };
-
- /**
- * Set the LEDs flash time.
- * @param flashOn Time to flash bright (255 = 2.5 seconds).
- * @param flashOff Time to flash dark (255 = 2.5 seconds).
- */
- void setLedFlash(uint8_t flashOn, uint8_t flashOff) {
- ps4Output.flashOn = flashOn;
- ps4Output.flashOff = flashOff;
- ps4Output.reportChanged = true;
- };
- /**@}*/
-
-protected:
- /**
- * Used to parse data sent from the PS4 controller.
- * @param len Length of the data.
- * @param buf Pointer to the data buffer.
- */
- void Parse(uint8_t len, uint8_t *buf);
-
- /** Used to reset the different buffers to their default values */
- void Reset() {
- uint8_t i;
- for (i = 0; i < sizeof(ps4Data.hatValue); i++)
- ps4Data.hatValue[i] = 127; // Center value
- ps4Data.btn.val = 0;
- oldButtonState.val = 0;
- for (i = 0; i < sizeof(ps4Data.trigger); i++)
- ps4Data.trigger[i] = 0;
- for (i = 0; i < sizeof(ps4Data.xy)/sizeof(ps4Data.xy[0]); i++) {
- for (uint8_t j = 0; j < sizeof(ps4Data.xy[0].finger)/sizeof(ps4Data.xy[0].finger[0]); j++)
- ps4Data.xy[i].finger[j].touching = 1; // The bit is cleared if the finger is touching the touchpad
- }
-
- ps4Data.btn.dpad = DPAD_OFF;
- oldButtonState.dpad = DPAD_OFF;
- buttonClickState.dpad = 0;
- oldDpad = 0;
-
- ps4Output.bigRumble = ps4Output.smallRumble = 0;
- ps4Output.r = ps4Output.g = ps4Output.b = 0;
- ps4Output.flashOn = ps4Output.flashOff = 0;
- ps4Output.reportChanged = false;
- };
-
- /**
- * Send the output to the PS4 controller. This is implemented in PS4BT.h and PS4USB.h.
- * @param output Pointer to PS4Output buffer;
- */
- virtual void sendOutputReport(PS4Output *output) = 0;
-
-private:
- bool checkDpad(ButtonEnum b); // Used to check PS4 DPAD buttons
-
- PS4Data ps4Data;
- PS4Buttons oldButtonState, buttonClickState;
- PS4Output ps4Output;
- uint8_t oldDpad;
-};
-#endif
diff --git a/lib/usbhost/USB_Host_Shield_2.0/PS4USB.h b/lib/usbhost/USB_Host_Shield_2.0/PS4USB.h
deleted file mode 100644
index b43079a6e902..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/PS4USB.h
+++ /dev/null
@@ -1,130 +0,0 @@
-/* Copyright (C) 2014 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 _ps4usb_h_
-#define _ps4usb_h_
-
-#include "hiduniversal.h"
-#include "PS4Parser.h"
-
-#define PS4_VID 0x054C // Sony Corporation
-#define PS4_PID 0x05C4 // PS4 Controller
-
-/**
- * This class implements support for the PS4 controller via USB.
- * It uses the HIDUniversal class for all the USB communication.
- */
-class PS4USB : public HIDUniversal, public PS4Parser {
-public:
- /**
- * Constructor for the PS4USB class.
- * @param p Pointer to the USB class instance.
- */
- PS4USB(USB *p) :
- HIDUniversal(p) {
- PS4Parser::Reset();
- };
-
- /**
- * Used to check if a PS4 controller is connected.
- * @return Returns true if it is connected.
- */
- bool connected() {
- return HIDUniversal::isReady() && HIDUniversal::VID == PS4_VID && HIDUniversal::PID == PS4_PID;
- };
-
- /**
- * Used to call your own function when the device is successfully initialized.
- * @param funcOnInit Function to call.
- */
- void attachOnInit(void (*funcOnInit)(void)) {
- pFuncOnInit = funcOnInit;
- };
-
-protected:
- /** @name HIDUniversal implementation */
- /**
- * Used to parse USB HID data.
- * @param hid Pointer to the HID class.
- * @param is_rpt_id Only used for Hubs.
- * @param len The length of the incoming data.
- * @param buf Pointer to the data buffer.
- */
- virtual void ParseHIDData(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) {
- if (HIDUniversal::VID == PS4_VID && HIDUniversal::PID == PS4_PID)
- PS4Parser::Parse(len, buf);
- };
-
- /**
- * Called when a device 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.
- */
- virtual uint8_t OnInitSuccessful() {
- if (HIDUniversal::VID == PS4_VID && HIDUniversal::PID == PS4_PID) {
- PS4Parser::Reset();
- if (pFuncOnInit)
- pFuncOnInit(); // Call the user function
- else
- setLed(Blue);
- };
- return 0;
- };
- /**@}*/
-
- /** @name PS4Parser implementation */
- virtual void sendOutputReport(PS4Output *output) { // Source: https://github.com/chrippa/ds4drv
- uint8_t buf[32];
- memset(buf, 0, sizeof(buf));
-
- buf[0] = 0x05; // Report ID
- buf[1]= 0xFF;
-
- buf[4] = output->smallRumble; // Small Rumble
- buf[5] = output->bigRumble; // Big rumble
-
- buf[6] = output->r; // Red
- buf[7] = output->g; // Green
- buf[8] = output->b; // Blue
-
- buf[9] = output->flashOn; // Time to flash bright (255 = 2.5 seconds)
- buf[10] = output->flashOff; // Time to flash dark (255 = 2.5 seconds)
-
- output->reportChanged = false;
-
- // The PS4 console actually set the four last bytes to a CRC32 checksum, but it seems like it is actually not needed
-
- pUsb->outTransfer(bAddress, epInfo[ hidInterfaces[0].epIndex[epInterruptOutIndex] ].epAddr, sizeof(buf), buf);
- };
- /**@}*/
-
- /** @name USBDeviceConfig implementation */
- /**
- * Used by the USB core to check what this driver support.
- * @param vid The device's VID.
- * @param pid The device's PID.
- * @return Returns true if the device's VID and PID matches this driver.
- */
- virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) {
- return (vid == PS4_VID && pid == PS4_PID);
- };
- /**@}*/
-
-private:
- void (*pFuncOnInit)(void); // Pointer to function called in onInit()
-};
-#endif
diff --git a/lib/usbhost/USB_Host_Shield_2.0/PSBuzz.cpp b/lib/usbhost/USB_Host_Shield_2.0/PSBuzz.cpp
deleted file mode 100644
index 498164d5a695..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/PSBuzz.cpp
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Copyright (C) 2014 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 "PSBuzz.h"
-
-// To enable serial debugging see "settings.h"
-//#define PRINTREPORT // Uncomment to print the report send by the PS Buzz Controllers
-
-void PSBuzz::ParseHIDData(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf) {
- if (HIDUniversal::VID == PSBUZZ_VID && HIDUniversal::PID == PSBUZZ_PID && len > 2 && buf) {
-#ifdef PRINTREPORT
- Notify(PSTR("\r\n"), 0x80);
- for (uint8_t i = 0; i < len; i++) {
- D_PrintHex (buf[i], 0x80);
- Notify(PSTR(" "), 0x80);
- }
-#endif
- memcpy(&psbuzzButtons, buf + 2, min((uint8_t)(len - 2), sizeof(psbuzzButtons)));
-
- if (psbuzzButtons.val != oldButtonState.val) { // Check if anything has changed
- buttonClickState.val = psbuzzButtons.val & ~oldButtonState.val; // Update click state variable
- oldButtonState.val = psbuzzButtons.val;
- }
- }
-};
-
-uint8_t PSBuzz::OnInitSuccessful() {
- if (HIDUniversal::VID == PSBUZZ_VID && HIDUniversal::PID == PSBUZZ_PID) {
- Reset();
- if (pFuncOnInit)
- pFuncOnInit(); // Call the user function
- else
- setLedOnAll(); // Turn the LED on, on all four controllers
- };
- return 0;
-};
-
-bool PSBuzz::getButtonPress(ButtonEnum b, uint8_t controller) {
- return psbuzzButtons.val & (1UL << (b + 5 * controller)); // Each controller uses 5 bits, so the value is shifted 5 for each controller
-};
-
-bool PSBuzz::getButtonClick(ButtonEnum b, uint8_t controller) {
- uint32_t mask = (1UL << (b + 5 * controller)); // Each controller uses 5 bits, so the value is shifted 5 for each controller
- bool click = buttonClickState.val & mask;
- buttonClickState.val &= ~mask; // Clear "click" event
- return click;
-};
-
-// Source: http://www.developerfusion.com/article/84338/making-usb-c-friendly/ and https://github.com/torvalds/linux/blob/master/drivers/hid/hid-sony.c
-void PSBuzz::setLedRaw(bool value, uint8_t controller) {
- ledState[controller] = value; // Save value for next time it is called
-
- uint8_t buf[7];
- buf[0] = 0x00;
- buf[1] = ledState[0] ? 0xFF : 0x00;
- buf[2] = ledState[1] ? 0xFF : 0x00;
- buf[3] = ledState[2] ? 0xFF : 0x00;
- buf[4] = ledState[3] ? 0xFF : 0x00;
- buf[5] = 0x00;
- buf[6] = 0x00;
-
- PSBuzz_Command(buf, sizeof(buf));
-};
-
-void PSBuzz::PSBuzz_Command(uint8_t *data, uint16_t nbytes) {
- // bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x00), Report Type (Output 0x02), interface (0x00), datalength, datalength, data)
- pUsb->ctrlReq(bAddress, epInfo[0].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x00, 0x02, 0x00, nbytes, nbytes, data, NULL);
-};
diff --git a/lib/usbhost/USB_Host_Shield_2.0/PSBuzz.h b/lib/usbhost/USB_Host_Shield_2.0/PSBuzz.h
deleted file mode 100644
index 8880d9e50a08..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/PSBuzz.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* Copyright (C) 2014 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 _psbuzz_h_
-#define _psbuzz_h_
-
-#include "hiduniversal.h"
-#include "controllerEnums.h"
-
-#define PSBUZZ_VID 0x054C // Sony Corporation
-#define PSBUZZ_PID 0x1000 // PS Buzz Controller
-
-/** Struct used to easily read the different buttons on the controllers */
-union PSBUZZButtons {
- struct {
- uint8_t red : 1;
- uint8_t yellow : 1;
- uint8_t green : 1;
- uint8_t orange : 1;
- uint8_t blue : 1;
- } __attribute__((packed)) btn[4];
- uint32_t val : 20;
-} __attribute__((packed));
-
-/**
- * This class implements support for the PS Buzz controllers via USB.
- * It uses the HIDUniversal class for all the USB communication.
- */
-class PSBuzz : public HIDUniversal {
-public:
- /**
- * Constructor for the PSBuzz class.
- * @param p Pointer to the USB class instance.
- */
- PSBuzz(USB *p) :
- HIDUniversal(p) {
- Reset();
- };
-
- /**
- * Used to check if a PS Buzz controller is connected.
- * @return Returns true if it is connected.
- */
- bool connected() {
- return HIDUniversal::isReady() && HIDUniversal::VID == PSBUZZ_VID && HIDUniversal::PID == PSBUZZ_PID;
- };
-
- /**
- * Used to call your own function when the device is successfully initialized.
- * @param funcOnInit Function to call.
- */
- void attachOnInit(void (*funcOnInit)(void)) {
- pFuncOnInit = funcOnInit;
- };
-
- /** @name PS Buzzer Controller functions */
- /**
- * getButtonPress(ButtonEnum b) will return true as long as the button is held down.
- *
- * While getButtonClick(ButtonEnum b) will only return it once.
- *
- * So you instance if you need to increase a variable once you would use getButtonClick(ButtonEnum b),
- * but if you need to drive a robot forward you would use getButtonPress(ButtonEnum b).
- * @param b ::ButtonEnum to read.
- * @param controller The controller to read from. Default to 0.
- * @return getButtonPress(ButtonEnum b) will return a true as long as a button is held down, while getButtonClick(ButtonEnum b) will return true once for each button press.
- */
- bool getButtonPress(ButtonEnum b, uint8_t controller = 0);
- bool getButtonClick(ButtonEnum b, uint8_t controller = 0);
- /**@}*/
- /** @name PS Buzzer Controller functions */
- /**
- * Set LED value without using ::LEDEnum.
- * @param value See: ::LEDEnum.
- */
- /**
- * Set LED values directly.
- * @param value Used to set whenever the LED should be on or off
- * @param controller The controller to control. Defaults to 0.
- */
- void setLedRaw(bool value, uint8_t controller = 0);
-
- /** Turn all LEDs off. */
- void setLedOffAll() {
- for (uint8_t i = 1; i < 4; i++) // Skip first as it will be set in setLedRaw
- ledState[i] = false; // Just an easy way to set all four off at the same time
- setLedRaw(false); // Turn the LED off, on all four controllers
- };
-
- /**
- * Turn the LED off on a specific controller.
- * @param controller The controller to turn off. Defaults to 0.
- */
- void setLedOff(uint8_t controller = 0) {
- setLedRaw(false, controller);
- };
-
-
- /** Turn all LEDs on. */
- void setLedOnAll() {
- for (uint8_t i = 1; i < 4; i++) // Skip first as it will be set in setLedRaw
- ledState[i] = true; // Just an easy way to set all four off at the same time
- setLedRaw(true); // Turn the LED on, on all four controllers
- };
-
- /**
- * Turn the LED on on a specific controller.
- * @param controller The controller to turn off. Defaults to 0.
- */
- void setLedOn(uint8_t controller = 0) {
- setLedRaw(true, controller);
- };
-
- /**
- * Toggle the LED on a specific controller.
- * @param controller The controller to turn off. Defaults to 0.
- */
- void setLedToggle(uint8_t controller = 0) {
- setLedRaw(!ledState[controller], controller);
- };
- /**@}*/
-
-protected:
- /** @name HIDUniversal implementation */
- /**
- * Used to parse USB HID data.
- * @param hid Pointer to the HID class.
- * @param is_rpt_id Only used for Hubs.
- * @param len The length of the incoming data.
- * @param buf Pointer to the data buffer.
- */
- void ParseHIDData(HID *hid, bool is_rpt_id, uint8_t len, uint8_t *buf);
-
- /**
- * Called when a device 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.
- */
- uint8_t OnInitSuccessful();
- /**@}*/
-
- /** Used to reset the different buffers to their default values */
- void Reset() {
- psbuzzButtons.val = 0;
- oldButtonState.val = 0;
- buttonClickState.val = 0;
- for (uint8_t i = 0; i < sizeof(ledState); i++)
- ledState[i] = 0;
- };
-
- /** @name USBDeviceConfig implementation */
- /**
- * Used by the USB core to check what this driver support.
- * @param vid The device's VID.
- * @param pid The device's PID.
- * @return Returns true if the device's VID and PID matches this driver.
- */
- virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) {
- return (vid == PSBUZZ_VID && pid == PSBUZZ_PID);
- };
- /**@}*/
-
-private:
- void (*pFuncOnInit)(void); // Pointer to function called in onInit()
-
- void PSBuzz_Command(uint8_t *data, uint16_t nbytes);
-
- PSBUZZButtons psbuzzButtons, oldButtonState, buttonClickState;
- bool ledState[4];
-};
-#endif
diff --git a/lib/usbhost/USB_Host_Shield_2.0/README.md b/lib/usbhost/USB_Host_Shield_2.0/README.md
deleted file mode 100644
index 1eecb78ef2a5..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/README.md
+++ /dev/null
@@ -1,351 +0,0 @@
-# USB Host Library Rev.2.0
-
-The code is released under the GNU General Public License.
-__________
-
-# Summary
-This is Revision 2.0 of MAX3421E-based USB Host Shield Library for AVR's.
-
-Project main web site is: .
-
-Some information can also be found at: .
-
-The shield can be purchased at the main site: or from [TKJ Electronics](http://tkjelectronics.com/): .
-
-
-
-For more information about the hardware see the [Hardware Manual](http://www.circuitsathome.com/usb-host-shield-hardware-manual).
-
-# Developed By
-
-* __Oleg Mazurov, Circuits@Home__ -
-* __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), [BTHID](#bthid-library), [SPP](#spp-library), [PS4](#ps4-library), [PS3](#ps3-library), [Wii](#wii-library), [Xbox](#xbox-library), and [PSBuzz](#ps-buzz-library) libraries
-* __Andrew Kroll__ -
- * Major contributor to mass storage code
-* __guruthree__
- * [Xbox ONE](#xbox-one-library) controller support
-
-# Donate
-
-Help yourself by helping us support you! Many thousands of hours have been spent developing the USB Host Shield library. Since you find it useful, please consider donating via the button below. Donations will allow us to support you by ensuring hardware that you have can be acquired in order to add support for your microcontroller board.
-
-
-
-# Table of Contents
-
-* [How to include the library](#how-to-include-the-library)
- * [Arduino Library Manager](#arduino-library-manager)
- * [Manual installation](#manual-installation)
-* [How to use the library](#how-to-use-the-library)
- * [Documentation](#documentation)
- * [Enable debugging](#enable-debugging)
- * [Boards](#boards)
- * [Bluetooth libraries](#bluetooth-libraries)
- * [BTHID library](#bthid-library)
- * [SPP library](#spp-library)
- * [PS4 Library](#ps4-library)
- * [PS3 Library](#ps3-library)
- * [Xbox Libraries](#xbox-libraries)
- * [Xbox library](#xbox-library)
- * [Xbox 360 Library](#xbox-360-library)
- * [Xbox ONE Library](#xbox-one-library)
- * [Wii library](#wii-library)
- * [PS Buzz Library](#ps-buzz-library)
-* [Interface modifications](#interface-modifications)
-* [FAQ](#faq)
-
-# How to include the library
-
-### Arduino Library Manager
-
-First install Arduino IDE version 1.6.2 or newer, then simply use the Arduino Library Manager to install the library.
-
-Please see the following page for instructions: .
-
-### Manual installation
-
-First download the library by clicking on the following link: .
-
-Then uncompress the zip folder and rename the directory to "USB\_Host\_Shield\_20", as any special characters are not supported by the Arduino IDE.
-
-Now open up the Arduino IDE and open "File>Preferences". There you will see the location of your sketchbook. Open that directory and create a directory called "libraries" inside that directory.
-Now move the "USB\_Host\_Shield\_20" directory to the "libraries" directory.
-
-The final structure should look like this:
-
-* Arduino/
- * libraries/
- * USB\_Host\_Shield\_20/
-
-Now quit the Arduino IDE and reopen it.
-
-Now you should be able to go open all the examples codes by navigating to "File>Examples>USB\_Host\_Shield\_20" and then select the example you will like to open.
-
-For more information visit the following sites: and .
-
-# How to use the library
-
-### Documentation
-
-Documentation for the library can be found at the following link: .
-
-### Enable debugging
-
-By default serial debugging is disabled. To turn it on simply change ```ENABLE_UHS_DEBUGGING``` to 1 in [settings.h](settings.h) like so:
-
-```C++
-#define ENABLE_UHS_DEBUGGING 1
-```
-
-### Boards
-
-Currently the following boards are supported by the library:
-
-* All official Arduino AVR boards (Uno, Duemilanove, Mega, Mega 2560, Mega ADK, Leonardo etc.)
-* Arduino Due, Intel Galileo, Intel Galileo 2, and Intel Edison
- * Note that the Intel Galileo uses pin 2 and 3 as INT and SS pin respectively by default, so some modifications to the shield are needed. See the "Interface modifications" section in the [hardware manual](https://www.circuitsathome.com/usb-host-shield-hardware-manual) for more information.
-* Teensy (Teensy++ 1.0, Teensy 2.0, Teensy++ 2.0, and Teensy 3.x)
- * Note if you are using the Teensy 3.x you should download this SPI library as well: . You should then add ```#include ``` to your .ino file.
-* Balanduino
-* Sanguino
-* Black Widdow
-* RedBearLab nRF51822
-* Digilent chipKIT
- * Please see: .
-
-The following boards need to be activated manually in [settings.h](settings.h):
-
-* Arduino Mega ADK
- * If you are using Arduino 1.5.5 or newer there is no need to activate the Arduino Mega ADK manually
-* Black Widdow
-
-Simply set the corresponding value to 1 instead of 0.
-
-### [Bluetooth libraries](BTD.cpp)
-
-The [BTD library](BTD.cpp) is a general purpose library for an ordinary Bluetooth dongle.
-This library make it easy to add support for different Bluetooth services like a PS3 or a Wii controller or SPP which is a virtual serial port via Bluetooth.
-Some different examples can be found in the [example directory](examples/Bluetooth).
-
-The BTD library also makes it possible to use multiple services at once, the following example sketch is an example of this:
-[PS3SPP.ino](examples/Bluetooth/PS3SPP/PS3SPP.ino).
-
-### [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 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: [BTHID.ino](examples/Bluetooth/BTHID/BTHID.ino) for more information.
-
-The [PS4 library](#ps4-library) also uses this class to handle all Bluetooth communication.
-
-For information see the following blog post: .
-
-### [SPP library](SPP.cpp)
-
-SPP stands for "Serial Port Profile" and is a Bluetooth protocol that implements a virtual comport which allows you to send data back and forth from your computer/phone to your Arduino via Bluetooth.
-It has been tested successfully on Windows, Mac OS X, Linux, and Android.
-
-Take a look at the [SPP.ino](examples/Bluetooth/SPP/SPP.ino) example for more information.
-
-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.
-It enables me to see the Bluetooth communication between my Mac and any device.
-
-### PS4 Library
-
-The PS4BT library is split up into the [PS4BT](PS4BT.h) and the [PS4USB](PS4USB.h) library. These allow you to use the Sony PS4 controller via Bluetooth and USB.
-
-The [PS4BT.ino](examples/Bluetooth/PS4BT/PS4BT.ino) and [PS4USB.ino](examples/PS4USB/PS4USB.ino) examples shows how to easily read the buttons, joysticks, touchpad and IMU on the controller via Bluetooth and USB respectively. It is also possible to control the rumble and light on the controller and get the battery level.
-
-Before you can use the PS4 controller via Bluetooth you will need to pair with it.
-
-Simply create the PS4BT instance like so: ```PS4BT PS4(&Btd, PAIR);``` and then hold down the Share button and then hold down the PS without releasing the Share button. The PS4 controller will then start to blink rapidly indicating that it is in paring mode.
-
-It should then automatically pair the dongle with your controller. This only have to be done once.
-
-For information see the following blog post: .
-
-Also check out this excellent Wiki by Frank Zhao about the PS4 controller: and this Linux driver: .
-
-### PS3 Library
-
-These libraries consist of the [PS3BT](PS3BT.cpp) and [PS3USB](PS3USB.cpp). These libraries allows you to use a Dualshock 3, Navigation or a Motion controller with the USB Host Shield both via Bluetooth and USB.
-
-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 first plugging in the Bluetooth dongle and wait a few seconds. Now plug in the controller via USB and wait until the LEDs start to flash. The library has now written the Bluetooth address of the dongle to the PS3 controller.
-
-Finally simply plug in the Bluetooth dongle again and press PS on the PS3 controller. After a few seconds it should be connected to the dongle and ready to use.
-
-__Note:__ You will have to plug in the Bluetooth dongle before connecting the controller, as the library needs to read the address of the dongle. Alternatively you could set it in code like so: [PS3BT.ino#L20](examples/Bluetooth/PS3BT/PS3BT.ino#L20).
-
-For more information about the PS3 protocol see the official wiki: .
-
-Also take a look at the blog posts:
-
-*
-*
-*
-
-A special thanks go to the following people:
-
-1. _Richard Ibbotson_ who made this excellent guide:
-2. _Tomoyuki Tanaka_ for releasing his code for the Arduino USB Host shield connected to the wiimote:
-
-Also a big thanks all the people behind these sites about the Motion controller:
-
-*
-*
-*
-*
-
-### Xbox Libraries
-
-The library supports both the original Xbox controller via USB and the Xbox 360 controller both via USB and wirelessly.
-
-#### Xbox library
-
-The [XBOXOLD](XBOXOLD.cpp) class implements support for the original Xbox controller via USB.
-
-All the information are from the following sites:
-
-*
-*
-*
-*
-
-#### Xbox 360 Library
-
-The library support one Xbox 360 via USB or up to four Xbox 360 controllers wirelessly by using a [Xbox 360 wireless receiver](http://blog.tkjelectronics.dk/wp-content/uploads/xbox360-wireless-receiver.jpg).
-
-To use it via USB use the [XBOXUSB](XBOXUSB.cpp) library or to use it wirelessly use the [XBOXRECV](XBOXRECV.cpp) library.
-
-__Note that a Wireless controller can NOT be used via USB!__
-
-Examples code can be found in the [examples directory](examples/Xbox).
-
-Also see the following blog posts:
-
-*
-*
-*
-
-All the information regarding the Xbox 360 controller protocol are form these sites:
-
-*
-*
-*
-
-#### Xbox ONE Library
-
-An Xbox ONE controller is supported via USB in the [XBOXONE](XBOXONE.cpp) class. It is heavily based on the 360 library above. In addition to cross referencing the above, information on the protocol was found at:
-
-*
-*
-*
-
-### [Wii library](Wii.cpp)
-
-The [Wii](Wii.cpp) library support the Wiimote, but also the Nunchuch and Motion Plus extensions via Bluetooth. The Wii U Pro Controller and Wii Balance Board are also supported via Bluetooth.
-
-First you have to pair with the controller, this is done automatically by the library if you create the instance like so:
-
-```C++
-WII Wii(&Btd, PAIR);
-```
-
-And then press 1 & 2 at once on the Wiimote or the SYNC buttons if you are using a Wii U Pro Controller or a Wii Balance Board.
-
-After that you can simply create the instance like so:
-
-```C++
-WII Wii(&Btd);
-```
-
-Then just press any button on the Wiimote and it will then connect to the dongle.
-
-Take a look at the example for more information: [Wii.ino](examples/Bluetooth/Wii/Wii.ino).
-
-Also take a look at the blog post:
-
-*
-
-The Wii IR camera can also be used, but you will have to activate the code for it manually as it is quite large. Simply set ```ENABLE_WII_IR_CAMERA``` to 1 in [settings.h](settings.h).
-
-The [WiiIRCamera.ino](examples/Bluetooth/WiiIRCamera/WiiIRCamera.ino) example shows how it can be used.
-
-All the information about the Wii controllers are from these sites:
-
-*
-*
-*
-*
-*
-* The old library created by _Tomoyuki Tanaka_: also helped a lot.
-
-### [PS Buzz Library](PSBuzz.cpp)
-
-This library implements support for the Playstation Buzz controllers via USB.
-
-It is essentially just a wrapper around the [HIDUniversal](hiduniversal.cpp) which takes care of the initializing and reading of the controllers. The [PSBuzz](PSBuzz.cpp) class simply inherits this and parses the data, so it is easy for users to read the buttons and turn the big red button on the controllers on and off.
-
-The example [PSBuzz.ino](examples/PSBuzz/PSBuzz.ino) shows how one can do this with just a few lines of code.
-
-More information about the controller can be found at the following sites:
-
-* http://www.developerfusion.com/article/84338/making-usb-c-friendly/
-* https://github.com/torvalds/linux/blob/master/drivers/hid/hid-sony.c
-
-# Interface modifications
-
-The shield is using SPI for communicating with the MAX3421E USB host controller. It uses the SCK, MISO and MOSI pins via the ICSP on your board.
-
-Note this means that it uses pin 13, 12, 11 on an Arduino Uno, so these pins can not be used for anything else than SPI communication!
-
-Furthermore it uses one pin as SS and one INT pin. These are by default located on pin 10 and 9 respectively. They can easily be reconfigured in case you need to use them for something else by cutting the jumper on the shield and then solder a wire from the pad to the new pin.
-
-After that you need modify the following entry in [UsbCore.h](UsbCore.h):
-
-```C++
-typedef MAX3421e MAX3421E;
-```
-
-For instance if you have rerouted SS to pin 7 it should read:
-
-```C++
-typedef MAX3421e MAX3421E;
-```
-
-See the "Interface modifications" section in the [hardware manual](https://www.circuitsathome.com/usb-host-shield-hardware-manual) for more information.
-
-# FAQ
-
-> When I plug my device into the USB connector nothing happens?
-
-* Try to connect a external power supply to the Arduino - this solves the problem in most cases.
-* You can also use a powered hub between the device and the USB Host Shield. You should then include the USB hub library: ```#include ``` and create the instance like so: ```USBHub Hub1(&Usb);```.
-
-> When I connecting my PS3 controller I get a output like this:
-
-```
-Dualshock 3 Controller Enabled
-
-LeftHatX: 0 LeftHatY: 0 RightHatX: 0 RightHatY: 0
-LeftHatX: 0 LeftHatY: 0 RightHatX: 0 RightHatY: 0
-LeftHatX: 0 LeftHatY: 0 RightHatX: 0 RightHatY: 0
-LeftHatX: 0 LeftHatY: 0 RightHatX: 0 RightHatY: 0
-LeftHatX: 0 LeftHatY: 0 RightHatX: 0 RightHatY: 0
-```
-
-* This means that your dongle does not support 2.0+EDR, so you will need another dongle. Please see the following [list](https://github.com/felis/USB_Host_Shield_2.0/wiki/Bluetooth-dongles) for tested working dongles.
-
-> When compiling I am getting the following error: "fatal error: SPI.h: No such file or directory".
-
-* Please make sure to include the SPI library like so: ```#include ``` in your .ino file.
diff --git a/lib/usbhost/USB_Host_Shield_2.0/SPP.cpp b/lib/usbhost/USB_Host_Shield_2.0/SPP.cpp
deleted file mode 100644
index 0f4ee5e98106..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/SPP.cpp
+++ /dev/null
@@ -1,829 +0,0 @@
-/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
-
- This software may be distributed and modified under the terms of the GNU
- General Public License version 2 (GPL2) as published by the Free Software
- Foundation and appearing in the file GPL2.TXT included in the packaging of
- this file. Please note that GPL2 Section 2[b] requires that all works based
- on this software must also be made publicly available under the terms of
- the GPL2 ("Copyleft").
-
- Contact information
- -------------------
-
- Kristian Lauszus, TKJ Electronics
- Web : http://www.tkjelectronics.com
- e-mail : kristianl@tkjelectronics.com
- */
-
-#include "SPP.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
-
-/*
- * CRC (reversed crc) lookup table as calculated by the table generator in ETSI TS 101 369 V6.3.0.
- */
-const uint8_t rfcomm_crc_table[256] PROGMEM = {/* reversed, 8-bit, poly=0x07 */
- 0x00, 0x91, 0xE3, 0x72, 0x07, 0x96, 0xE4, 0x75, 0x0E, 0x9F, 0xED, 0x7C, 0x09, 0x98, 0xEA, 0x7B,
- 0x1C, 0x8D, 0xFF, 0x6E, 0x1B, 0x8A, 0xF8, 0x69, 0x12, 0x83, 0xF1, 0x60, 0x15, 0x84, 0xF6, 0x67,
- 0x38, 0xA9, 0xDB, 0x4A, 0x3F, 0xAE, 0xDC, 0x4D, 0x36, 0xA7, 0xD5, 0x44, 0x31, 0xA0, 0xD2, 0x43,
- 0x24, 0xB5, 0xC7, 0x56, 0x23, 0xB2, 0xC0, 0x51, 0x2A, 0xBB, 0xC9, 0x58, 0x2D, 0xBC, 0xCE, 0x5F,
- 0x70, 0xE1, 0x93, 0x02, 0x77, 0xE6, 0x94, 0x05, 0x7E, 0xEF, 0x9D, 0x0C, 0x79, 0xE8, 0x9A, 0x0B,
- 0x6C, 0xFD, 0x8F, 0x1E, 0x6B, 0xFA, 0x88, 0x19, 0x62, 0xF3, 0x81, 0x10, 0x65, 0xF4, 0x86, 0x17,
- 0x48, 0xD9, 0xAB, 0x3A, 0x4F, 0xDE, 0xAC, 0x3D, 0x46, 0xD7, 0xA5, 0x34, 0x41, 0xD0, 0xA2, 0x33,
- 0x54, 0xC5, 0xB7, 0x26, 0x53, 0xC2, 0xB0, 0x21, 0x5A, 0xCB, 0xB9, 0x28, 0x5D, 0xCC, 0xBE, 0x2F,
- 0xE0, 0x71, 0x03, 0x92, 0xE7, 0x76, 0x04, 0x95, 0xEE, 0x7F, 0x0D, 0x9C, 0xE9, 0x78, 0x0A, 0x9B,
- 0xFC, 0x6D, 0x1F, 0x8E, 0xFB, 0x6A, 0x18, 0x89, 0xF2, 0x63, 0x11, 0x80, 0xF5, 0x64, 0x16, 0x87,
- 0xD8, 0x49, 0x3B, 0xAA, 0xDF, 0x4E, 0x3C, 0xAD, 0xD6, 0x47, 0x35, 0xA4, 0xD1, 0x40, 0x32, 0xA3,
- 0xC4, 0x55, 0x27, 0xB6, 0xC3, 0x52, 0x20, 0xB1, 0xCA, 0x5B, 0x29, 0xB8, 0xCD, 0x5C, 0x2E, 0xBF,
- 0x90, 0x01, 0x73, 0xE2, 0x97, 0x06, 0x74, 0xE5, 0x9E, 0x0F, 0x7D, 0xEC, 0x99, 0x08, 0x7A, 0xEB,
- 0x8C, 0x1D, 0x6F, 0xFE, 0x8B, 0x1A, 0x68, 0xF9, 0x82, 0x13, 0x61, 0xF0, 0x85, 0x14, 0x66, 0xF7,
- 0xA8, 0x39, 0x4B, 0xDA, 0xAF, 0x3E, 0x4C, 0xDD, 0xA6, 0x37, 0x45, 0xD4, 0xA1, 0x30, 0x42, 0xD3,
- 0xB4, 0x25, 0x57, 0xC6, 0xB3, 0x22, 0x50, 0xC1, 0xBA, 0x2B, 0x59, 0xC8, 0xBD, 0x2C, 0x5E, 0xCF
-};
-
-SPP::SPP(BTD *p, const char* name, const char* pin) :
-BluetoothService(p) // Pointer to BTD class instance - mandatory
-{
- pBtd->btdName = name;
- pBtd->btdPin = pin;
-
- /* Set device cid for the SDP and RFCOMM channelse */
- sdp_dcid[0] = 0x50; // 0x0050
- sdp_dcid[1] = 0x00;
- rfcomm_dcid[0] = 0x51; // 0x0051
- rfcomm_dcid[1] = 0x00;
-
- Reset();
-}
-
-void SPP::Reset() {
- connected = false;
- RFCOMMConnected = false;
- SDPConnected = false;
- waitForLastCommand = false;
- l2cap_sdp_state = L2CAP_SDP_WAIT;
- l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT;
- l2cap_event_flag = 0;
- sppIndex = 0;
- creditSent = false;
-}
-
-void SPP::disconnect() {
- connected = false;
- // First the two L2CAP channels has to be disconnected and then the HCI connection
- if(RFCOMMConnected)
- pBtd->l2cap_disconnection_request(hci_handle, ++identifier, rfcomm_scid, rfcomm_dcid);
- if(RFCOMMConnected && SDPConnected)
- delay(1); // Add delay between commands
- if(SDPConnected)
- pBtd->l2cap_disconnection_request(hci_handle, ++identifier, sdp_scid, sdp_dcid);
- l2cap_sdp_state = L2CAP_DISCONNECT_RESPONSE;
-}
-
-void SPP::ACLData(uint8_t* l2capinbuf) {
- if(!connected) {
- if(l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
- if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == SDP_PSM && !pBtd->sdpConnectionClaimed) {
- pBtd->sdpConnectionClaimed = true;
- hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
- l2cap_sdp_state = L2CAP_SDP_WAIT; // Reset state
- } else if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == RFCOMM_PSM && !pBtd->rfcommConnectionClaimed) {
- pBtd->rfcommConnectionClaimed = true;
- hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
- l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT; // Reset state
- }
- }
- }
-
- if(checkHciHandle(l2capinbuf, hci_handle)) { // acl_handle_ok
- if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { // 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(" Data: "), 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_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)) == SDP_PSM) { // It doesn't matter if it receives another reqeust, since it waits for the channel to disconnect in the L2CAP_SDP_DONE state, and the l2cap_event_flag will be cleared if so
- identifier = l2capinbuf[9];
- sdp_scid[0] = l2capinbuf[14];
- sdp_scid[1] = l2capinbuf[15];
- l2cap_set_flag(L2CAP_FLAG_CONNECTION_SDP_REQUEST);
- } else if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == RFCOMM_PSM) { // ----- || -----
- identifier = l2capinbuf[9];
- rfcomm_scid[0] = l2capinbuf[14];
- rfcomm_scid[1] = l2capinbuf[15];
- l2cap_set_flag(L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST);
- }
- } else if(l2capinbuf[8] == L2CAP_CMD_CONFIG_RESPONSE) {
- if((l2capinbuf[16] | (l2capinbuf[17] << 8)) == 0x0000) { // Success
- if(l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
- //Notify(PSTR("\r\nSDP Configuration Complete"), 0x80);
- l2cap_set_flag(L2CAP_FLAG_CONFIG_SDP_SUCCESS);
- } else if(l2capinbuf[12] == rfcomm_dcid[0] && l2capinbuf[13] == rfcomm_dcid[1]) {
- //Notify(PSTR("\r\nRFCOMM Configuration Complete"), 0x80);
- l2cap_set_flag(L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS);
- }
- }
- } else if(l2capinbuf[8] == L2CAP_CMD_CONFIG_REQUEST) {
- if(l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
- //Notify(PSTR("\r\nSDP Configuration Request"), 0x80);
- pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], sdp_scid);
- } else if(l2capinbuf[12] == rfcomm_dcid[0] && l2capinbuf[13] == rfcomm_dcid[1]) {
- //Notify(PSTR("\r\nRFCOMM Configuration Request"), 0x80);
- pBtd->l2cap_config_response(hci_handle, l2capinbuf[9], rfcomm_scid);
- }
- } else if(l2capinbuf[8] == L2CAP_CMD_DISCONNECT_REQUEST) {
- if(l2capinbuf[12] == sdp_dcid[0] && l2capinbuf[13] == sdp_dcid[1]) {
- //Notify(PSTR("\r\nDisconnect Request: SDP Channel"), 0x80);
- identifier = l2capinbuf[9];
- l2cap_set_flag(L2CAP_FLAG_DISCONNECT_SDP_REQUEST);
- } else if(l2capinbuf[12] == rfcomm_dcid[0] && l2capinbuf[13] == rfcomm_dcid[1]) {
- //Notify(PSTR("\r\nDisconnect Request: RFCOMM Channel"), 0x80);
- identifier = l2capinbuf[9];
- l2cap_set_flag(L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST);
- }
- } else if(l2capinbuf[8] == L2CAP_CMD_DISCONNECT_RESPONSE) {
- if(l2capinbuf[12] == sdp_scid[0] && l2capinbuf[13] == sdp_scid[1]) {
- //Notify(PSTR("\r\nDisconnect Response: SDP Channel"), 0x80);
- identifier = l2capinbuf[9];
- l2cap_set_flag(L2CAP_FLAG_DISCONNECT_RESPONSE);
- } else if(l2capinbuf[12] == rfcomm_scid[0] && l2capinbuf[13] == rfcomm_scid[1]) {
- //Notify(PSTR("\r\nDisconnect Response: RFCOMM Channel"), 0x80);
- identifier = l2capinbuf[9];
- l2cap_set_flag(L2CAP_FLAG_DISCONNECT_RESPONSE);
- }
- } else if(l2capinbuf[8] == L2CAP_CMD_INFORMATION_REQUEST) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nInformation request"), 0x80);
-#endif
- identifier = l2capinbuf[9];
- pBtd->l2cap_information_response(hci_handle, identifier, l2capinbuf[12], l2capinbuf[13]);
- }
-#ifdef EXTRADEBUG
- else {
- Notify(PSTR("\r\nL2CAP Unknown Signaling Command: "), 0x80);
- D_PrintHex (l2capinbuf[8], 0x80);
- }
-#endif
- } else if(l2capinbuf[6] == sdp_dcid[0] && l2capinbuf[7] == sdp_dcid[1]) { // SDP
- if(l2capinbuf[8] == SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST_PDU) {
- if(((l2capinbuf[16] << 8 | l2capinbuf[17]) == SERIALPORT_UUID) || ((l2capinbuf[16] << 8 | l2capinbuf[17]) == 0x0000 && (l2capinbuf[18] << 8 | l2capinbuf[19]) == SERIALPORT_UUID)) { // Check if it's sending the full UUID, see: https://www.bluetooth.org/Technical/AssignedNumbers/service_discovery.htm, we will just check the first four bytes
- if(firstMessage) {
- serialPortResponse1(l2capinbuf[9], l2capinbuf[10]);
- firstMessage = false;
- } else {
- serialPortResponse2(l2capinbuf[9], l2capinbuf[10]); // Serialport continuation state
- firstMessage = true;
- }
- } else if(((l2capinbuf[16] << 8 | l2capinbuf[17]) == L2CAP_UUID) || ((l2capinbuf[16] << 8 | l2capinbuf[17]) == 0x0000 && (l2capinbuf[18] << 8 | l2capinbuf[19]) == L2CAP_UUID)) {
- if(firstMessage) {
- l2capResponse1(l2capinbuf[9], l2capinbuf[10]);
- firstMessage = false;
- } else {
- l2capResponse2(l2capinbuf[9], l2capinbuf[10]); // L2CAP continuation state
- firstMessage = true;
- }
- } else
- serviceNotSupported(l2capinbuf[9], l2capinbuf[10]); // The service is not supported
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nUUID: "), 0x80);
- uint16_t uuid;
- if((l2capinbuf[16] << 8 | l2capinbuf[17]) == 0x0000) // Check if it's sending the UUID as a 128-bit UUID
- uuid = (l2capinbuf[18] << 8 | l2capinbuf[19]);
- else // Short UUID
- uuid = (l2capinbuf[16] << 8 | l2capinbuf[17]);
- D_PrintHex (uuid, 0x80);
-
- Notify(PSTR("\r\nLength: "), 0x80);
- uint16_t length = l2capinbuf[11] << 8 | l2capinbuf[12];
- D_PrintHex (length, 0x80);
- Notify(PSTR("\r\nData: "), 0x80);
- for(uint8_t i = 0; i < length; i++) {
- D_PrintHex (l2capinbuf[13 + i], 0x80);
- Notify(PSTR(" "), 0x80);
- }
-#endif
- }
-#ifdef EXTRADEBUG
- else {
- Notify(PSTR("\r\nUnknown PDU: "), 0x80);
- D_PrintHex (l2capinbuf[8], 0x80);
- }
-#endif
- } else if(l2capinbuf[6] == rfcomm_dcid[0] && l2capinbuf[7] == rfcomm_dcid[1]) { // RFCOMM
- rfcommChannel = l2capinbuf[8] & 0xF8;
- rfcommDirection = l2capinbuf[8] & 0x04;
- rfcommCommandResponse = l2capinbuf[8] & 0x02;
- rfcommChannelType = l2capinbuf[9] & 0xEF;
- rfcommPfBit = l2capinbuf[9] & 0x10;
-
- if(rfcommChannel >> 3 != 0x00)
- rfcommChannelConnection = rfcommChannel;
-
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nRFCOMM Channel: "), 0x80);
- D_PrintHex (rfcommChannel >> 3, 0x80);
- Notify(PSTR(" Direction: "), 0x80);
- D_PrintHex (rfcommDirection >> 2, 0x80);
- Notify(PSTR(" CommandResponse: "), 0x80);
- D_PrintHex (rfcommCommandResponse >> 1, 0x80);
- Notify(PSTR(" ChannelType: "), 0x80);
- D_PrintHex (rfcommChannelType, 0x80);
- Notify(PSTR(" PF_BIT: "), 0x80);
- D_PrintHex (rfcommPfBit, 0x80);
-#endif
- if(rfcommChannelType == RFCOMM_DISC) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nReceived Disconnect RFCOMM Command on channel: "), 0x80);
- D_PrintHex (rfcommChannel >> 3, 0x80);
-#endif
- connected = false;
- sendRfcomm(rfcommChannel, rfcommDirection, rfcommCommandResponse, RFCOMM_UA, rfcommPfBit, rfcommbuf, 0x00); // UA Command
- }
- if(connected) {
- /* 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; // 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 += 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);
- }
-#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++)
- Notifyc(l2capinbuf[i + 11 + offset], 0x80);
-#endif
- } else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_RPN_CMD) { // UIH Remote Port Negotiation Command
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nReceived UIH Remote Port Negotiation Command"), 0x80);
-#endif
- rfcommbuf[0] = BT_RFCOMM_RPN_RSP; // Command
- rfcommbuf[1] = l2capinbuf[12]; // Length and shiftet like so: length << 1 | 1
- rfcommbuf[2] = l2capinbuf[13]; // Channel: channel << 1 | 1
- rfcommbuf[3] = l2capinbuf[14]; // Pre difined for Bluetooth, see 5.5.3 of TS 07.10 Adaption for RFCOMM
- rfcommbuf[4] = l2capinbuf[15]; // Priority
- rfcommbuf[5] = l2capinbuf[16]; // Timer
- rfcommbuf[6] = l2capinbuf[17]; // Max Fram Size LSB
- rfcommbuf[7] = l2capinbuf[18]; // Max Fram Size MSB
- rfcommbuf[8] = l2capinbuf[19]; // MaxRatransm.
- rfcommbuf[9] = l2capinbuf[20]; // Number of Frames
- sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x0A); // UIH Remote Port Negotiation Response
- } else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_MSC_CMD) { // UIH Modem Status Command
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nSend UIH Modem Status Response"), 0x80);
-#endif
- rfcommbuf[0] = BT_RFCOMM_MSC_RSP; // UIH Modem Status Response
- rfcommbuf[1] = 2 << 1 | 1; // Length and shiftet like so: length << 1 | 1
- rfcommbuf[2] = l2capinbuf[13]; // Channel: (1 << 0) | (1 << 1) | (0 << 2) | (channel << 3)
- rfcommbuf[3] = l2capinbuf[14];
- sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x04);
- }
- } else {
- if(rfcommChannelType == RFCOMM_SABM) { // SABM Command - this is sent twice: once for channel 0 and then for the channel to establish
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nReceived SABM Command"), 0x80);
-#endif
- sendRfcomm(rfcommChannel, rfcommDirection, rfcommCommandResponse, RFCOMM_UA, rfcommPfBit, rfcommbuf, 0x00); // UA Command
- } else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_PN_CMD) { // UIH Parameter Negotiation Command
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nReceived UIH Parameter Negotiation Command"), 0x80);
-#endif
- rfcommbuf[0] = BT_RFCOMM_PN_RSP; // UIH Parameter Negotiation Response
- rfcommbuf[1] = l2capinbuf[12]; // Length and shiftet like so: length << 1 | 1
- rfcommbuf[2] = l2capinbuf[13]; // Channel: channel << 1 | 1
- rfcommbuf[3] = 0xE0; // Pre difined for Bluetooth, see 5.5.3 of TS 07.10 Adaption for RFCOMM
- rfcommbuf[4] = 0x00; // Priority
- rfcommbuf[5] = 0x00; // Timer
- rfcommbuf[6] = BULK_MAXPKTSIZE - 14; // Max Fram Size LSB - set to the size of received data (50)
- rfcommbuf[7] = 0x00; // Max Fram Size MSB
- rfcommbuf[8] = 0x00; // MaxRatransm.
- rfcommbuf[9] = 0x00; // Number of Frames
- sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x0A);
- } else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_MSC_CMD) { // UIH Modem Status Command
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nSend UIH Modem Status Response"), 0x80);
-#endif
- rfcommbuf[0] = BT_RFCOMM_MSC_RSP; // UIH Modem Status Response
- rfcommbuf[1] = 2 << 1 | 1; // Length and shiftet like so: length << 1 | 1
- rfcommbuf[2] = l2capinbuf[13]; // Channel: (1 << 0) | (1 << 1) | (0 << 2) | (channel << 3)
- rfcommbuf[3] = l2capinbuf[14];
- sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x04);
-
- delay(1);
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nSend UIH Modem Status Command"), 0x80);
-#endif
- rfcommbuf[0] = BT_RFCOMM_MSC_CMD; // UIH Modem Status Command
- rfcommbuf[1] = 2 << 1 | 1; // Length and shiftet like so: length << 1 | 1
- rfcommbuf[2] = l2capinbuf[13]; // Channel: (1 << 0) | (1 << 1) | (0 << 2) | (channel << 3)
- rfcommbuf[3] = 0x8D; // Can receive frames (YES), Ready to Communicate (YES), Ready to Receive (YES), Incomig Call (NO), Data is Value (YES)
-
- sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x04);
- } else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_MSC_RSP) { // UIH Modem Status Response
- if(!creditSent) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nSend UIH Command with credit"), 0x80);
-#endif
- sendRfcommCredit(rfcommChannelConnection, rfcommDirection, 0, RFCOMM_UIH, 0x10, sizeof (rfcommDataBuffer)); // Send credit
- creditSent = true;
- timer = millis();
- waitForLastCommand = true;
- }
- } else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[10] == 0x01) { // UIH Command with credit
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nReceived UIH Command with credit"), 0x80);
-#endif
- } else if(rfcommChannelType == RFCOMM_UIH && l2capinbuf[11] == BT_RFCOMM_RPN_CMD) { // UIH Remote Port Negotiation Command
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nReceived UIH Remote Port Negotiation Command"), 0x80);
-#endif
- rfcommbuf[0] = BT_RFCOMM_RPN_RSP; // Command
- rfcommbuf[1] = l2capinbuf[12]; // Length and shiftet like so: length << 1 | 1
- rfcommbuf[2] = l2capinbuf[13]; // Channel: channel << 1 | 1
- rfcommbuf[3] = l2capinbuf[14]; // Pre difined for Bluetooth, see 5.5.3 of TS 07.10 Adaption for RFCOMM
- rfcommbuf[4] = l2capinbuf[15]; // Priority
- rfcommbuf[5] = l2capinbuf[16]; // Timer
- rfcommbuf[6] = l2capinbuf[17]; // Max Fram Size LSB
- rfcommbuf[7] = l2capinbuf[18]; // Max Fram Size MSB
- rfcommbuf[8] = l2capinbuf[19]; // MaxRatransm.
- rfcommbuf[9] = l2capinbuf[20]; // Number of Frames
- sendRfcomm(rfcommChannel, rfcommDirection, 0, RFCOMM_UIH, rfcommPfBit, rfcommbuf, 0x0A); // UIH Remote Port Negotiation Response
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nRFCOMM Connection is now established\r\n"), 0x80);
-#endif
- onInit();
- }
-#ifdef EXTRADEBUG
- else if(rfcommChannelType != RFCOMM_DISC) {
- Notify(PSTR("\r\nUnsupported RFCOMM Data - ChannelType: "), 0x80);
- D_PrintHex (rfcommChannelType, 0x80);
- Notify(PSTR(" Command: "), 0x80);
- D_PrintHex (l2capinbuf[11], 0x80);
- }
-#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);
- }
-#endif
- SDP_task();
- RFCOMM_task();
- }
-}
-
-void SPP::Run() {
- if(waitForLastCommand && (millis() - timer) > 100) { // We will only wait 100ms and see if the UIH Remote Port Negotiation Command is send, as some deviced don't send it
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nRFCOMM Connection is now established - Automatic\r\n"), 0x80);
-#endif
- onInit();
- }
- send(); // Send all bytes currently in the buffer
-}
-
-void SPP::onInit() {
- creditSent = false;
- waitForLastCommand = false;
- connected = true; // The RFCOMM channel is now established
- sppIndex = 0;
- if(pFuncOnInit)
- pFuncOnInit(); // Call the user function
-};
-
-void SPP::SDP_task() {
- switch(l2cap_sdp_state) {
- case L2CAP_SDP_WAIT:
- if(l2cap_check_flag(L2CAP_FLAG_CONNECTION_SDP_REQUEST)) {
- l2cap_clear_flag(L2CAP_FLAG_CONNECTION_SDP_REQUEST); // Clear flag
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nSDP Incoming Connection Request"), 0x80);
-#endif
- pBtd->l2cap_connection_response(hci_handle, identifier, sdp_dcid, sdp_scid, PENDING);
- delay(1);
- pBtd->l2cap_connection_response(hci_handle, identifier, sdp_dcid, sdp_scid, SUCCESSFUL);
- identifier++;
- delay(1);
- pBtd->l2cap_config_request(hci_handle, identifier, sdp_scid);
- l2cap_sdp_state = L2CAP_SDP_SUCCESS;
- } else if(l2cap_check_flag(L2CAP_FLAG_DISCONNECT_SDP_REQUEST)) {
- l2cap_clear_flag(L2CAP_FLAG_DISCONNECT_SDP_REQUEST); // Clear flag
- SDPConnected = false;
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nDisconnected SDP Channel"), 0x80);
-#endif
- pBtd->l2cap_disconnection_response(hci_handle, identifier, sdp_dcid, sdp_scid);
- }
- break;
- case L2CAP_SDP_SUCCESS:
- if(l2cap_check_flag(L2CAP_FLAG_CONFIG_SDP_SUCCESS)) {
- l2cap_clear_flag(L2CAP_FLAG_CONFIG_SDP_SUCCESS); // Clear flag
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nSDP Successfully Configured"), 0x80);
-#endif
- firstMessage = true; // Reset bool
- SDPConnected = true;
- l2cap_sdp_state = L2CAP_SDP_WAIT;
- }
- break;
-
- case L2CAP_DISCONNECT_RESPONSE: // This is for both disconnection response from the RFCOMM and SDP channel if they were connected
- if(l2cap_check_flag(L2CAP_FLAG_DISCONNECT_RESPONSE)) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nDisconnected L2CAP Connection"), 0x80);
-#endif
- pBtd->hci_disconnect(hci_handle);
- hci_handle = -1; // Reset handle
- Reset();
- }
- break;
- }
-}
-
-void SPP::RFCOMM_task() {
- switch(l2cap_rfcomm_state) {
- case L2CAP_RFCOMM_WAIT:
- if(l2cap_check_flag(L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST)) {
- l2cap_clear_flag(L2CAP_FLAG_CONNECTION_RFCOMM_REQUEST); // Clear flag
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nRFCOMM Incoming Connection Request"), 0x80);
-#endif
- pBtd->l2cap_connection_response(hci_handle, identifier, rfcomm_dcid, rfcomm_scid, PENDING);
- delay(1);
- pBtd->l2cap_connection_response(hci_handle, identifier, rfcomm_dcid, rfcomm_scid, SUCCESSFUL);
- identifier++;
- delay(1);
- pBtd->l2cap_config_request(hci_handle, identifier, rfcomm_scid);
- l2cap_rfcomm_state = L2CAP_RFCOMM_SUCCESS;
- } else if(l2cap_check_flag(L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST)) {
- l2cap_clear_flag(L2CAP_FLAG_DISCONNECT_RFCOMM_REQUEST); // Clear flag
- RFCOMMConnected = false;
- connected = false;
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nDisconnected RFCOMM Channel"), 0x80);
-#endif
- pBtd->l2cap_disconnection_response(hci_handle, identifier, rfcomm_dcid, rfcomm_scid);
- }
- break;
- case L2CAP_RFCOMM_SUCCESS:
- if(l2cap_check_flag(L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS)) {
- l2cap_clear_flag(L2CAP_FLAG_CONFIG_RFCOMM_SUCCESS); // Clear flag
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nRFCOMM Successfully Configured"), 0x80);
-#endif
- rfcommAvailable = 0; // Reset number of bytes available
- bytesRead = 0; // Reset number of bytes received
- RFCOMMConnected = true;
- l2cap_rfcomm_state = L2CAP_RFCOMM_WAIT;
- }
- break;
- }
-}
-/************************************************************/
-/* SDP Commands */
-
-/************************************************************/
-void SPP::SDP_Command(uint8_t* data, uint8_t nbytes) { // See page 223 in the Bluetooth specs
- pBtd->L2CAP_Command(hci_handle, data, nbytes, sdp_scid[0], sdp_scid[1]);
-}
-
-void SPP::serviceNotSupported(uint8_t transactionIDHigh, uint8_t transactionIDLow) { // See page 235 in the Bluetooth specs
- l2capoutbuf[0] = SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE_PDU;
- l2capoutbuf[1] = transactionIDHigh;
- l2capoutbuf[2] = transactionIDLow;
- l2capoutbuf[3] = 0x00; // MSB Parameter Length
- l2capoutbuf[4] = 0x05; // LSB Parameter Length = 5
- l2capoutbuf[5] = 0x00; // MSB AttributeListsByteCount
- l2capoutbuf[6] = 0x02; // LSB AttributeListsByteCount = 2
-
- /* Attribute ID/Value Sequence: */
- l2capoutbuf[7] = 0x35; // Data element sequence - length in next byte
- l2capoutbuf[8] = 0x00; // Length = 0
- l2capoutbuf[9] = 0x00; // No continuation state
-
- SDP_Command(l2capoutbuf, 10);
-}
-
-void SPP::serialPortResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
- l2capoutbuf[0] = SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE_PDU;
- l2capoutbuf[1] = transactionIDHigh;
- l2capoutbuf[2] = transactionIDLow;
- l2capoutbuf[3] = 0x00; // MSB Parameter Length
- l2capoutbuf[4] = 0x2B; // LSB Parameter Length = 43
- l2capoutbuf[5] = 0x00; // MSB AttributeListsByteCount
- l2capoutbuf[6] = 0x26; // LSB AttributeListsByteCount = 38
-
- /* Attribute ID/Value Sequence: */
- l2capoutbuf[7] = 0x36; // Data element sequence - length in next two bytes
- l2capoutbuf[8] = 0x00; // MSB Length
- l2capoutbuf[9] = 0x3C; // LSB Length = 60
-
- l2capoutbuf[10] = 0x36; // Data element sequence - length in next two bytes
- l2capoutbuf[11] = 0x00; // MSB Length
- l2capoutbuf[12] = 0x39; // LSB Length = 57
-
- l2capoutbuf[13] = 0x09; // Unsigned Integer - length 2 bytes
- l2capoutbuf[14] = 0x00; // MSB ServiceRecordHandle
- l2capoutbuf[15] = 0x00; // LSB ServiceRecordHandle
- l2capoutbuf[16] = 0x0A; // Unsigned int - length 4 bytes
- l2capoutbuf[17] = 0x00; // ServiceRecordHandle value - TODO: Is this related to HCI_Handle?
- l2capoutbuf[18] = 0x01;
- l2capoutbuf[19] = 0x00;
- l2capoutbuf[20] = 0x06;
-
- l2capoutbuf[21] = 0x09; // Unsigned Integer - length 2 bytes
- l2capoutbuf[22] = 0x00; // MSB ServiceClassIDList
- l2capoutbuf[23] = 0x01; // LSB ServiceClassIDList
- l2capoutbuf[24] = 0x35; // Data element sequence - length in next byte
- l2capoutbuf[25] = 0x03; // Length = 3
- l2capoutbuf[26] = 0x19; // UUID (universally unique identifier) - length = 2 bytes
- l2capoutbuf[27] = 0x11; // MSB SerialPort
- l2capoutbuf[28] = 0x01; // LSB SerialPort
-
- l2capoutbuf[29] = 0x09; // Unsigned Integer - length 2 bytes
- l2capoutbuf[30] = 0x00; // MSB ProtocolDescriptorList
- l2capoutbuf[31] = 0x04; // LSB ProtocolDescriptorList
- l2capoutbuf[32] = 0x35; // Data element sequence - length in next byte
- l2capoutbuf[33] = 0x0C; // Length = 12
-
- l2capoutbuf[34] = 0x35; // Data element sequence - length in next byte
- l2capoutbuf[35] = 0x03; // Length = 3
- l2capoutbuf[36] = 0x19; // UUID (universally unique identifier) - length = 2 bytes
- l2capoutbuf[37] = 0x01; // MSB L2CAP
- l2capoutbuf[38] = 0x00; // LSB L2CAP
-
- l2capoutbuf[39] = 0x35; // Data element sequence - length in next byte
- l2capoutbuf[40] = 0x05; // Length = 5
- l2capoutbuf[41] = 0x19; // UUID (universally unique identifier) - length = 2 bytes
- l2capoutbuf[42] = 0x00; // MSB RFCOMM
- l2capoutbuf[43] = 0x03; // LSB RFCOMM
- l2capoutbuf[44] = 0x08; // Unsigned Integer - length 1 byte
-
- l2capoutbuf[45] = 0x02; // ContinuationState - Two more bytes
- l2capoutbuf[46] = 0x00; // MSB length
- l2capoutbuf[47] = 0x19; // LSB length = 25 more bytes to come
-
- SDP_Command(l2capoutbuf, 48);
-}
-
-void SPP::serialPortResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
- l2capoutbuf[0] = SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE_PDU;
- l2capoutbuf[1] = transactionIDHigh;
- l2capoutbuf[2] = transactionIDLow;
- l2capoutbuf[3] = 0x00; // MSB Parameter Length
- l2capoutbuf[4] = 0x1C; // LSB Parameter Length = 28
- l2capoutbuf[5] = 0x00; // MSB AttributeListsByteCount
- l2capoutbuf[6] = 0x19; // LSB AttributeListsByteCount = 25
-
- /* Attribute ID/Value Sequence: */
- l2capoutbuf[7] = 0x01; // Channel 1 - TODO: Try different values, so multiple servers can be used at once
-
- l2capoutbuf[8] = 0x09; // Unsigned Integer - length 2 bytes
- l2capoutbuf[9] = 0x00; // MSB LanguageBaseAttributeIDList
- l2capoutbuf[10] = 0x06; // LSB LanguageBaseAttributeIDList
- l2capoutbuf[11] = 0x35; // Data element sequence - length in next byte
- l2capoutbuf[12] = 0x09; // Length = 9
-
- // Identifier representing the natural language = en = English - see: "ISO 639:1988"
- l2capoutbuf[13] = 0x09; // Unsigned Integer - length 2 bytes
- l2capoutbuf[14] = 0x65; // 'e'
- l2capoutbuf[15] = 0x6E; // 'n'
-
- // "The second element of each triplet contains an identifier that specifies a character encoding used for the language"
- // Encoding is set to 106 (UTF-8) - see: http://www.iana.org/assignments/character-sets/character-sets.xhtml
- l2capoutbuf[16] = 0x09; // Unsigned Integer - length 2 bytes
- l2capoutbuf[17] = 0x00; // MSB of character encoding
- l2capoutbuf[18] = 0x6A; // LSB of character encoding (106)
-
- // Attribute ID that serves as the base attribute ID for the natural language in the service record
- // "To facilitate the retrieval of human-readable universal attributes in a principal language, the base attribute ID value for the primary language supported by a service record shall be 0x0100"
- l2capoutbuf[19] = 0x09; // Unsigned Integer - length 2 bytes
- l2capoutbuf[20] = 0x01;
- l2capoutbuf[21] = 0x00;
-
- l2capoutbuf[22] = 0x09; // Unsigned Integer - length 2 bytes
- l2capoutbuf[23] = 0x01; // MSB ServiceDescription
- l2capoutbuf[24] = 0x00; // LSB ServiceDescription
-
- l2capoutbuf[25] = 0x25; // Text string - length in next byte
- l2capoutbuf[26] = 0x05; // Name length
- l2capoutbuf[27] = 'T';
- l2capoutbuf[28] = 'K';
- l2capoutbuf[29] = 'J';
- l2capoutbuf[30] = 'S';
- l2capoutbuf[31] = 'P';
- l2capoutbuf[32] = 0x00; // No continuation state
-
- SDP_Command(l2capoutbuf, 33);
-}
-
-void SPP::l2capResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
- serialPortResponse1(transactionIDHigh, transactionIDLow); // These has to send all the supported functions, since it only supports virtual serialport it just sends the message again
-}
-
-void SPP::l2capResponse2(uint8_t transactionIDHigh, uint8_t transactionIDLow) {
- serialPortResponse2(transactionIDHigh, transactionIDLow); // Same data as serialPortResponse2
-}
-/************************************************************/
-/* RFCOMM Commands */
-
-/************************************************************/
-void SPP::RFCOMM_Command(uint8_t* data, uint8_t nbytes) {
- pBtd->L2CAP_Command(hci_handle, data, nbytes, rfcomm_scid[0], rfcomm_scid[1]);
-}
-
-void SPP::sendRfcomm(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t* data, uint8_t length) {
- l2capoutbuf[0] = channel | direction | CR | extendAddress; // RFCOMM Address
- l2capoutbuf[1] = channelType | pfBit; // RFCOMM Control
- l2capoutbuf[2] = length << 1 | 0x01; // Length and format (always 0x01 bytes format)
- uint8_t i = 0;
- for(; i < length; i++)
- l2capoutbuf[i + 3] = data[i];
- l2capoutbuf[i + 3] = calcFcs(l2capoutbuf);
-#ifdef EXTRADEBUG
- Notify(PSTR(" - RFCOMM Data: "), 0x80);
- for(i = 0; i < length + 4; i++) {
- D_PrintHex (l2capoutbuf[i], 0x80);
- Notify(PSTR(" "), 0x80);
- }
-#endif
- RFCOMM_Command(l2capoutbuf, length + 4);
-}
-
-void SPP::sendRfcommCredit(uint8_t channel, uint8_t direction, uint8_t CR, uint8_t channelType, uint8_t pfBit, uint8_t credit) {
- l2capoutbuf[0] = channel | direction | CR | extendAddress; // RFCOMM Address
- l2capoutbuf[1] = channelType | pfBit; // RFCOMM Control
- l2capoutbuf[2] = 0x01; // Length = 0
- l2capoutbuf[3] = credit; // Credit
- l2capoutbuf[4] = calcFcs(l2capoutbuf);
-#ifdef EXTRADEBUG
- Notify(PSTR(" - RFCOMM Credit Data: "), 0x80);
- for(uint8_t i = 0; i < 5; i++) {
- D_PrintHex (l2capoutbuf[i], 0x80);
- Notify(PSTR(" "), 0x80);
- }
-#endif
- RFCOMM_Command(l2capoutbuf, 5);
-}
-
-/* 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]]));
-}
-
-/* Calculate FCS */
-uint8_t SPP::calcFcs(uint8_t *data) {
- uint8_t temp = crc(data);
- if((data[1] & 0xEF) == RFCOMM_UIH)
- return (0xFF - temp); // FCS on 2 bytes
- else
- return (0xFF - pgm_read_byte(&rfcomm_crc_table[temp ^ 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 */
-#if defined(ARDUINO) && ARDUINO >=100
-
-size_t SPP::write(uint8_t data) {
- return write(&data, 1);
-}
-#else
-
-void SPP::write(uint8_t data) {
- write(&data, 1);
-}
-#endif
-
-#if defined(ARDUINO) && ARDUINO >=100
-
-size_t SPP::write(const uint8_t *data, size_t size) {
-#else
-
-void SPP::write(const uint8_t *data, size_t size) {
-#endif
- for(uint8_t i = 0; i < size; i++) {
- if(sppIndex >= sizeof (sppOutputBuffer) / sizeof (sppOutputBuffer[0]))
- send(); // Send the current data in the buffer
- sppOutputBuffer[sppIndex++] = data[i]; // All the bytes are put into a buffer and then send using the send() function
- }
-#if defined(ARDUINO) && ARDUINO >=100
- return size;
-#endif
-}
-
-void SPP::send() {
- if(!connected || !sppIndex)
- return;
- uint8_t length; // This is the length of the string we are sending
- uint8_t offset = 0; // This is used to keep track of where we are in the string
-
- l2capoutbuf[0] = rfcommChannelConnection | 0 | 0 | extendAddress; // RFCOMM Address
- l2capoutbuf[1] = RFCOMM_UIH; // RFCOMM Control
-
- while(sppIndex) { // We will run this while loop until this variable is 0
- if(sppIndex > (sizeof (l2capoutbuf) - 4)) // Check if the string is larger than the outgoing buffer
- length = sizeof (l2capoutbuf) - 4;
- else
- length = sppIndex;
-
- l2capoutbuf[2] = length << 1 | 1; // Length
- uint8_t i = 0;
- for(; i < length; i++)
- l2capoutbuf[i + 3] = sppOutputBuffer[i + offset];
- l2capoutbuf[i + 3] = calcFcs(l2capoutbuf); // Calculate checksum
-
- RFCOMM_Command(l2capoutbuf, length + 4);
-
- sppIndex -= length;
- offset += length; // Increment the offset
- }
-}
-
-int SPP::available(void) {
- return rfcommAvailable;
-};
-
-void SPP::discard(void) {
- rfcommAvailable = 0;
-}
-
-int SPP::peek(void) {
- if(rfcommAvailable == 0) // Don't read if there is nothing in the buffer
- return -1;
- return rfcommDataBuffer[0];
-}
-
-int SPP::read(void) {
- if(rfcommAvailable == 0) // Don't read if there is nothing in the buffer
- return -1;
- uint8_t output = rfcommDataBuffer[0];
- for(uint8_t i = 1; i < rfcommAvailable; i++)
- rfcommDataBuffer[i - 1] = rfcommDataBuffer[i]; // Shift the buffer one left
- rfcommAvailable--;
- bytesRead++;
- if(bytesRead > (sizeof (rfcommDataBuffer) - 5)) { // We will send the command just before it runs out of credit
- bytesRead = 0;
- sendRfcommCredit(rfcommChannelConnection, rfcommDirection, 0, RFCOMM_UIH, 0x10, sizeof (rfcommDataBuffer)); // Send more credit
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nSent "), 0x80);
- Notify((uint8_t)sizeof (rfcommDataBuffer), 0x80);
- Notify(PSTR(" more credit"), 0x80);
-#endif
- }
- return output;
-}
diff --git a/lib/usbhost/USB_Host_Shield_2.0/SPP.h b/lib/usbhost/USB_Host_Shield_2.0/SPP.h
deleted file mode 100644
index 233ac611fd97..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/SPP.h
+++ /dev/null
@@ -1,225 +0,0 @@
-/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
-
- This software may be distributed and modified under the terms of the GNU
- General Public License version 2 (GPL2) as published by the Free Software
- Foundation and appearing in the file GPL2.TXT included in the packaging of
- this file. Please note that GPL2 Section 2[b] requires that all works based
- on this software must also be made publicly available under the terms of
- the GPL2 ("Copyleft").
-
- Contact information
- -------------------
-
- Kristian Lauszus, TKJ Electronics
- Web : http://www.tkjelectronics.com
- e-mail : kristianl@tkjelectronics.com
- */
-
-#ifndef _spp_h_
-#define _spp_h_
-
-#include "BTD.h"
-
-/* Used for SDP */
-#define SDP_SERVICE_SEARCH_ATTRIBUTE_REQUEST_PDU 0x06 // See the RFCOMM specs
-#define SDP_SERVICE_SEARCH_ATTRIBUTE_RESPONSE_PDU 0x07 // See the RFCOMM specs
-#define SERIALPORT_UUID 0x1101 // See http://www.bluetooth.org/Technical/AssignedNumbers/service_discovery.htm
-#define L2CAP_UUID 0x0100
-
-/* Used for RFCOMM */
-#define RFCOMM_SABM 0x2F
-#define RFCOMM_UA 0x63
-#define RFCOMM_UIH 0xEF
-//#define RFCOMM_DM 0x0F
-#define RFCOMM_DISC 0x43
-
-#define extendAddress 0x01 // Always 1
-
-// Multiplexer message types
-#define BT_RFCOMM_PN_CMD 0x83
-#define BT_RFCOMM_PN_RSP 0x81
-#define BT_RFCOMM_MSC_CMD 0xE3
-#define BT_RFCOMM_MSC_RSP 0xE1
-#define BT_RFCOMM_RPN_CMD 0x93
-#define BT_RFCOMM_RPN_RSP 0x91
-/*
-#define BT_RFCOMM_TEST_CMD 0x23
-#define BT_RFCOMM_TEST_RSP 0x21
-#define BT_RFCOMM_FCON_CMD 0xA3
-#define BT_RFCOMM_FCON_RSP 0xA1
-#define BT_RFCOMM_FCOFF_CMD 0x63
-#define BT_RFCOMM_FCOFF_RSP 0x61
-#define BT_RFCOMM_RLS_CMD 0x53
-#define BT_RFCOMM_RLS_RSP 0x51
-#define BT_RFCOMM_NSC_RSP 0x11
- */
-
-/**
- * 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 and stream functions.
- */
-class SPP : public BluetoothService, public Stream {
-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 "0000" will be used.
- */
- SPP(BTD *p, const char *name = "Arduino", const char *pin = "0000");
-
- /** @name BluetoothService implementation */
- /** Used this to disconnect the virtual serial port. */
- void disconnect();
- /**@}*/
-
- /**
- * Used to provide Boolean tests for the class.
- * @return Return true if SPP communication is connected.
- */
- operator bool() {
- return connected;
- }
- /** Variable used to indicate if the connection is established. */
- bool connected;
-
- /** @name Serial port profile (SPP) Print functions */
- /**
- * Get number of bytes waiting to be read.
- * @return Return the number of bytes ready to be read.
- */
- int available(void);
-
- /** Send out all bytes in the buffer. */
- 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.
- */
- int peek(void);
- /**
- * Used to read the buffer.
- * @return Return the byte. Will return -1 if no bytes are available.
- */
- int read(void);
-
-#if defined(ARDUINO) && ARDUINO >=100
- /**
- * Writes the byte to send to a buffer. The message is send when either send() or after Usb.Task() is called.
- * @param data The byte to write.
- * @return Return the number of bytes written.
- */
- size_t write(uint8_t data);
- /**
- * Writes the bytes to send to a buffer. The message is send when either send() or after Usb.Task() is called.
- * @param data The data array to send.
- * @param size Size of the data.
- * @return Return the number of bytes written.
- */
- size_t write(const uint8_t* data, size_t size);
- /** Pull in write(const char *str) from Print */
- using Print::write;
-#else
- /**
- * Writes the byte to send to a buffer. The message is send when either send() or after Usb.Task() is called.
- * @param data The byte to write.
- */
- void write(uint8_t data);
- /**
- * Writes the bytes to send to a buffer. The message is send when either send() or after Usb.Task() is called.
- * @param data The data array to send.
- * @param size Size of the data.
- */
- void write(const uint8_t* data, size_t size);
-#endif
-
- /** 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,
- * but can also be called via this function.
- */
- void send(void);
- /**@}*/
-
-protected:
- /** @name BluetoothService implementation */
- /**
- * Used to pass acldata to the services.
- * @param ACLData Incoming acldata.
- */
- void ACLData(uint8_t* ACLData);
- /** Used to establish the connection automatically. */
- void Run();
- /** Use this to reset the service. */
- void Reset();
- /**
- * Called when a device 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();
- /**@}*/
-
-private:
- /* Set true when a channel is created */
- bool SDPConnected;
- bool RFCOMMConnected;
-
- /* Variables used by L2CAP state machines */
- uint8_t l2cap_sdp_state;
- uint8_t l2cap_rfcomm_state;
-
- uint8_t l2capoutbuf[BULK_MAXPKTSIZE]; // General purpose buffer for l2cap out data
- uint8_t rfcommbuf[10]; // Buffer for RFCOMM Commands
-
- /* L2CAP Channels */
- uint8_t sdp_scid[2]; // L2CAP source CID for SDP
- uint8_t sdp_dcid[2]; // 0x0050
- uint8_t rfcomm_scid[2]; // L2CAP source CID for RFCOMM
- uint8_t rfcomm_dcid[2]; // 0x0051
-
- /* RFCOMM Variables */
- uint8_t rfcommChannel;
- uint8_t rfcommChannelConnection; // This is the channel the SPP channel will be running at
- uint8_t rfcommDirection;
- uint8_t rfcommCommandResponse;
- uint8_t rfcommChannelType;
- uint8_t rfcommPfBit;
-
- uint32_t timer;
- bool waitForLastCommand;
- bool creditSent;
-
- uint8_t rfcommDataBuffer[100]; // Create a 100 sized buffer for incoming data
- uint8_t sppOutputBuffer[100]; // Create a 100 sized buffer for outgoing SPP data
- uint8_t sppIndex;
- uint8_t rfcommAvailable;
-
- bool firstMessage; // Used to see if it's the first SDP request received
- uint8_t bytesRead; // Counter to see when it's time to send more credit
-
- /* State machines */
- void SDP_task(); // SDP state machine
- void RFCOMM_task(); // RFCOMM state machine
-
- /* SDP Commands */
- 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);
- void l2capResponse1(uint8_t transactionIDHigh, uint8_t transactionIDLow);
- 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 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);
- bool checkFcs(uint8_t *data, uint8_t fcs);
- uint8_t crc(uint8_t *data);
-};
-#endif
diff --git a/lib/usbhost/USB_Host_Shield_2.0/Usb.cpp b/lib/usbhost/USB_Host_Shield_2.0/Usb.cpp
deleted file mode 100644
index 14272588a16c..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/Usb.cpp
+++ /dev/null
@@ -1,812 +0,0 @@
-/* Copyright (C) 2011 Circuits At Home, LTD. 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
--------------------
-
-Circuits At Home, LTD
-Web : http://www.circuitsathome.com
-e-mail : support@circuitsathome.com
- */
-/* USB functions */
-
-#include "Usb.h"
-
-static uint8_t usb_error = 0;
-static uint8_t usb_task_state;
-
-/* constructor */
-USB::USB() : bmHubPre(0) {
- usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE; //set up state machine
- init();
-}
-
-/* Initialize data structures */
-void USB::init() {
- //devConfigIndex = 0;
- bmHubPre = 0;
-}
-
-uint8_t USB::getUsbTaskState(void) {
- return ( usb_task_state);
-}
-
-void USB::setUsbTaskState(uint8_t state) {
- usb_task_state = state;
-}
-
-EpInfo* USB::getEpInfoEntry(uint8_t addr, uint8_t ep) {
- UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
-
- if(!p || !p->epinfo)
- return NULL;
-
- EpInfo *pep = p->epinfo;
-
- for(uint8_t i = 0; i < p->epcount; i++) {
- if((pep)->epAddr == ep)
- return pep;
-
- pep++;
- }
- return NULL;
-}
-
-/* set device table entry */
-
-/* each device is different and has different number of endpoints. This function plugs endpoint record structure, defined in application, to devtable */
-uint8_t USB::setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo* eprecord_ptr) {
- if(!eprecord_ptr)
- return USB_ERROR_INVALID_ARGUMENT;
-
- UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
-
- if(!p)
- return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
-
- p->address.devAddress = addr;
- p->epinfo = eprecord_ptr;
- p->epcount = epcount;
-
- return 0;
-}
-
-uint8_t USB::SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t *nak_limit) {
- UsbDevice *p = addrPool.GetUsbDevicePtr(addr);
-
- if(!p)
- return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
-
- if(!p->epinfo)
- return USB_ERROR_EPINFO_IS_NULL;
-
- *ppep = getEpInfoEntry(addr, ep);
-
- if(!*ppep)
- return USB_ERROR_EP_NOT_FOUND_IN_TBL;
-
- *nak_limit = (0x0001UL << (((*ppep)->bmNakPower > USB_NAK_MAX_POWER) ? USB_NAK_MAX_POWER : (*ppep)->bmNakPower));
- (*nak_limit)--;
- /*
- USBTRACE2("\r\nAddress: ", addr);
- USBTRACE2(" EP: ", ep);
- USBTRACE2(" NAK Power: ",(*ppep)->bmNakPower);
- USBTRACE2(" NAK Limit: ", nak_limit);
- USBTRACE("\r\n");
- */
- regWr(rPERADDR, addr); //set peripheral address
-
- uint8_t mode = regRd(rMODE);
-
- //Serial.print("\r\nMode: ");
- //Serial.println( mode, HEX);
- //Serial.print("\r\nLS: ");
- //Serial.println(p->lowspeed, HEX);
-
-
-
- // Set bmLOWSPEED and bmHUBPRE in case of low-speed device, reset them otherwise
- regWr(rMODE, (p->lowspeed) ? mode | bmLOWSPEED | bmHubPre : mode & ~(bmHUBPRE | bmLOWSPEED));
-
- return 0;
-}
-
-/* Control transfer. Sets address, endpoint, fills control packet with necessary data, dispatches control packet, and initiates bulk IN transfer, */
-/* depending on request. Actual requests are defined as inlines */
-/* return codes: */
-/* 00 = success */
-
-/* 01-0f = non-zero HRSLT */
-uint8_t USB::ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi,
- uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t* dataptr, USBReadParser *p) {
- bool direction = false; //request direction, IN or OUT
- uint8_t rcode;
- SETUP_PKT setup_pkt;
-
- EpInfo *pep = NULL;
- uint16_t nak_limit = 0;
-
- rcode = SetAddress(addr, ep, &pep, &nak_limit);
-
- if(rcode)
- return rcode;
-
- direction = ((bmReqType & 0x80) > 0);
-
- /* fill in setup packet */
- setup_pkt.ReqType_u.bmRequestType = bmReqType;
- setup_pkt.bRequest = bRequest;
- setup_pkt.wVal_u.wValueLo = wValLo;
- setup_pkt.wVal_u.wValueHi = wValHi;
- setup_pkt.wIndex = wInd;
- setup_pkt.wLength = total;
-
- bytesWr(rSUDFIFO, 8, (uint8_t*) & setup_pkt); //transfer to setup packet FIFO
-
- rcode = dispatchPkt(tokSETUP, ep, nak_limit); //dispatch packet
-
- if(rcode) //return HRSLT if not zero
- return ( rcode);
-
- if(dataptr != NULL) //data stage, if present
- {
- if(direction) //IN transfer
- {
- uint16_t left = total;
-
- pep->bmRcvToggle = 1; //bmRCVTOG1;
-
- while(left) {
- // Bytes read into buffer
- uint16_t read = nbytes;
- //uint16_t read = (leftbmRcvToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
- continue;
- }
-
- if(rcode)
- return rcode;
-
- // Invoke callback function if inTransfer completed successfully and callback function pointer is specified
- if(!rcode && p)
- ((USBReadParser*)p)->Parse(read, dataptr, total - left);
-
- left -= read;
-
- if(read < nbytes)
- break;
- }
- } else //OUT transfer
- {
- pep->bmSndToggle = 1; //bmSNDTOG1;
- rcode = OutTransfer(pep, nak_limit, nbytes, dataptr);
- }
- if(rcode) //return error
- return ( rcode);
- }
- // Status stage
- return dispatchPkt((direction) ? tokOUTHS : tokINHS, ep, nak_limit); //GET if direction
-}
-
-/* IN transfer to arbitrary endpoint. Assumes PERADDR is set. Handles multiple packets if necessary. Transfers 'nbytes' bytes. */
-/* Keep sending INs and writes data to memory area pointed by 'data' */
-
-/* rcode 0 if no errors. rcode 01-0f is relayed from dispatchPkt(). Rcode f0 means RCVDAVIRQ error,
- fe USB xfer timeout */
-uint8_t USB::inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t* data) {
- EpInfo *pep = NULL;
- uint16_t nak_limit = 0;
-
- uint8_t rcode = SetAddress(addr, ep, &pep, &nak_limit);
-
- if(rcode) {
- USBTRACE3("(USB::InTransfer) SetAddress Failed ", rcode, 0x81);
- USBTRACE3("(USB::InTransfer) addr requested ", addr, 0x81);
- USBTRACE3("(USB::InTransfer) ep requested ", ep, 0x81);
- return rcode;
- }
- return InTransfer(pep, nak_limit, nbytesptr, data);
-}
-
-uint8_t USB::InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t* data) {
- uint8_t rcode = 0;
- uint8_t pktsize;
-
- uint16_t nbytes = *nbytesptr;
- //printf("Requesting %i bytes ", nbytes);
- uint8_t maxpktsize = pep->maxPktSize;
-
- *nbytesptr = 0;
- regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value
-
- // use a 'break' to exit this loop
- while(1) {
- rcode = dispatchPkt(tokIN, pep->epAddr, nak_limit); //IN packet to EP-'endpoint'. Function takes care of NAKS.
- if(rcode == hrTOGERR) {
- // yes, we flip it wrong here so that next time it is actually correct!
- pep->bmRcvToggle = (regRd(rHRSL) & bmRCVTOGRD) ? 0 : 1;
- regWr(rHCTL, (pep->bmRcvToggle) ? bmRCVTOG1 : bmRCVTOG0); //set toggle value
- continue;
- }
- if(rcode) {
- //printf(">>>>>>>> Problem! dispatchPkt %2.2x\r\n", rcode);
- break; //should be 0, indicating ACK. Else return error code.
- }
- /* check for RCVDAVIRQ and generate error if not present */
- /* the only case when absence of RCVDAVIRQ makes sense is when toggle error occurred. Need to add handling for that */
- if((regRd(rHIRQ) & bmRCVDAVIRQ) == 0) {
- //printf(">>>>>>>> Problem! NO RCVDAVIRQ!\r\n");
- rcode = 0xf0; //receive error
- break;
- }
- pktsize = regRd(rRCVBC); //number of received bytes
- //printf("Got %i bytes \r\n", pktsize);
- // This would be OK, but...
- //assert(pktsize <= nbytes);
- if(pktsize > nbytes) {
- // This can happen. Use of assert on Arduino locks up the Arduino.
- // So I will trim the value, and hope for the best.
- //printf(">>>>>>>> Problem! Wanted %i bytes but got %i.\r\n", nbytes, pktsize);
- pktsize = nbytes;
- }
-
- int16_t mem_left = (int16_t)nbytes - *((int16_t*)nbytesptr);
-
- if(mem_left < 0)
- mem_left = 0;
-
- data = bytesRd(rRCVFIFO, ((pktsize > mem_left) ? mem_left : pktsize), data);
-
- regWr(rHIRQ, bmRCVDAVIRQ); // Clear the IRQ & free the buffer
- *nbytesptr += pktsize; // add this packet's byte count to total transfer length
-
- /* The transfer is complete under two conditions: */
- /* 1. The device sent a short packet (L.T. maxPacketSize) */
- /* 2. 'nbytes' have been transferred. */
- if((pktsize < maxpktsize) || (*nbytesptr >= nbytes)) // have we transferred 'nbytes' bytes?
- {
- // Save toggle value
- pep->bmRcvToggle = ((regRd(rHRSL) & bmRCVTOGRD)) ? 1 : 0;
- //printf("\r\n");
- rcode = 0;
- break;
- } // if
- } //while( 1 )
- return ( rcode);
-}
-
-/* OUT transfer to arbitrary endpoint. Handles multiple packets if necessary. Transfers 'nbytes' bytes. */
-/* Handles NAK bug per Maxim Application Note 4000 for single buffer transfer */
-
-/* rcode 0 if no errors. rcode 01-0f is relayed from HRSL */
-uint8_t USB::outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* data) {
- EpInfo *pep = NULL;
- uint16_t nak_limit = 0;
-
- uint8_t rcode = SetAddress(addr, ep, &pep, &nak_limit);
-
- if(rcode)
- return rcode;
-
- return OutTransfer(pep, nak_limit, nbytes, data);
-}
-
-uint8_t USB::OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8_t *data) {
- uint8_t rcode = hrSUCCESS, retry_count;
- uint8_t *data_p = data; //local copy of the data pointer
- uint16_t bytes_tosend, nak_count;
- uint16_t bytes_left = nbytes;
-
- uint8_t maxpktsize = pep->maxPktSize;
-
- if(maxpktsize < 1 || maxpktsize > 64)
- return USB_ERROR_INVALID_MAX_PKT_SIZE;
-
- unsigned long timeout = millis() + USB_XFER_TIMEOUT;
-
- regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value
-
- while(bytes_left) {
- retry_count = 0;
- nak_count = 0;
- bytes_tosend = (bytes_left >= maxpktsize) ? maxpktsize : bytes_left;
- bytesWr(rSNDFIFO, bytes_tosend, data_p); //filling output FIFO
- regWr(rSNDBC, bytes_tosend); //set number of bytes
- regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet
- while(!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ
- regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
- rcode = (regRd(rHRSL) & 0x0f);
-
- while(rcode && ((long)(millis() - timeout) < 0L)) {
- switch(rcode) {
- case hrNAK:
- nak_count++;
- if(nak_limit && (nak_count == nak_limit))
- goto breakout;
- //return ( rcode);
- break;
- case hrTIMEOUT:
- retry_count++;
- if(retry_count == USB_RETRY_LIMIT)
- goto breakout;
- //return ( rcode);
- break;
- case hrTOGERR:
- // yes, we flip it wrong here so that next time it is actually correct!
- pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 0 : 1;
- regWr(rHCTL, (pep->bmSndToggle) ? bmSNDTOG1 : bmSNDTOG0); //set toggle value
- break;
- default:
- goto breakout;
- }//switch( rcode
-
- /* process NAK according to Host out NAK bug */
- regWr(rSNDBC, 0);
- regWr(rSNDFIFO, *data_p);
- regWr(rSNDBC, bytes_tosend);
- regWr(rHXFR, (tokOUT | pep->epAddr)); //dispatch packet
- while(!(regRd(rHIRQ) & bmHXFRDNIRQ)); //wait for the completion IRQ
- regWr(rHIRQ, bmHXFRDNIRQ); //clear IRQ
- rcode = (regRd(rHRSL) & 0x0f);
- }//while( rcode && ....
- bytes_left -= bytes_tosend;
- data_p += bytes_tosend;
- }//while( bytes_left...
-breakout:
-
- pep->bmSndToggle = (regRd(rHRSL) & bmSNDTOGRD) ? 1 : 0; //bmSNDTOG1 : bmSNDTOG0; //update toggle
- return ( rcode); //should be 0 in all cases
-}
-/* dispatch USB packet. Assumes peripheral address is set and relevant buffer is loaded/empty */
-/* If NAK, tries to re-send up to nak_limit times */
-/* If nak_limit == 0, do not count NAKs, exit after timeout */
-/* If bus timeout, re-sends up to USB_RETRY_LIMIT times */
-
-/* return codes 0x00-0x0f are HRSLT( 0x00 being success ), 0xff means timeout */
-uint8_t USB::dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit) {
- unsigned long timeout = millis() + USB_XFER_TIMEOUT;
- uint8_t tmpdata;
- uint8_t rcode = hrSUCCESS;
- uint8_t retry_count = 0;
- uint16_t nak_count = 0;
-
- while((long)(millis() - timeout) < 0L) {
- regWr(rHXFR, (token | ep)); //launch the transfer
- rcode = USB_ERROR_TRANSFER_TIMEOUT;
-
- while((long)(millis() - timeout) < 0L) //wait for transfer completion
- {
- tmpdata = regRd(rHIRQ);
-
- if(tmpdata & bmHXFRDNIRQ) {
- regWr(rHIRQ, bmHXFRDNIRQ); //clear the interrupt
- rcode = 0x00;
- break;
- }//if( tmpdata & bmHXFRDNIRQ
-
- }//while ( millis() < timeout
-
- //if (rcode != 0x00) //exit if timeout
- // return ( rcode);
-
- rcode = (regRd(rHRSL) & 0x0f); //analyze transfer result
-
- switch(rcode) {
- case hrNAK:
- nak_count++;
- if(nak_limit && (nak_count == nak_limit))
- return (rcode);
- break;
- case hrTIMEOUT:
- retry_count++;
- if(retry_count == USB_RETRY_LIMIT)
- return (rcode);
- break;
- default:
- return (rcode);
- }//switch( rcode
-
- }//while( timeout > millis()
- return ( rcode);
-}
-
-/* USB main task. Performs enumeration/cleanup */
-void USB::Task(void) //USB state machine
-{
- uint8_t rcode;
- uint8_t tmpdata;
- static unsigned long delay = 0;
- //USB_DEVICE_DESCRIPTOR buf;
- bool lowspeed = false;
-
- MAX3421E::Task();
-
- tmpdata = getVbusState();
-
- /* modify USB task state if Vbus changed */
- switch(tmpdata) {
- case SE1: //illegal state
- usb_task_state = USB_DETACHED_SUBSTATE_ILLEGAL;
- lowspeed = false;
- break;
- case SE0: //disconnected
- if((usb_task_state & USB_STATE_MASK) != USB_STATE_DETACHED)
- usb_task_state = USB_DETACHED_SUBSTATE_INITIALIZE;
- lowspeed = false;
- break;
- case LSHOST:
-
- lowspeed = true;
- //intentional fallthrough
- case FSHOST: //attached
- if((usb_task_state & USB_STATE_MASK) == USB_STATE_DETACHED) {
- delay = millis() + USB_SETTLE_DELAY;
- usb_task_state = USB_ATTACHED_SUBSTATE_SETTLE;
- }
- break;
- }// switch( tmpdata
-
- for(uint8_t i = 0; i < USB_NUMDEVICES; i++)
- if(devConfig[i])
- rcode = devConfig[i]->Poll();
-
- switch(usb_task_state) {
- case USB_DETACHED_SUBSTATE_INITIALIZE:
- init();
-
- for(uint8_t i = 0; i < USB_NUMDEVICES; i++)
- if(devConfig[i])
- rcode = devConfig[i]->Release();
-
- usb_task_state = USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE;
- break;
- case USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE: //just sit here
- break;
- case USB_DETACHED_SUBSTATE_ILLEGAL: //just sit here
- break;
- case USB_ATTACHED_SUBSTATE_SETTLE: //settle time for just attached device
- if((long)(millis() - delay) >= 0L)
- usb_task_state = USB_ATTACHED_SUBSTATE_RESET_DEVICE;
- else break; // don't fall through
- case USB_ATTACHED_SUBSTATE_RESET_DEVICE:
- regWr(rHCTL, bmBUSRST); //issue bus reset
- usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE;
- break;
- case USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE:
- if((regRd(rHCTL) & bmBUSRST) == 0) {
- tmpdata = regRd(rMODE) | bmSOFKAENAB; //start SOF generation
- regWr(rMODE, tmpdata);
- usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_SOF;
- //delay = millis() + 20; //20ms wait after reset per USB spec
- }
- break;
- case USB_ATTACHED_SUBSTATE_WAIT_SOF: //todo: change check order
- if(regRd(rHIRQ) & bmFRAMEIRQ) {
- //when first SOF received _and_ 20ms has passed we can continue
- /*
- if (delay < millis()) //20ms passed
- usb_task_state = USB_STATE_CONFIGURING;
- */
- usb_task_state = USB_ATTACHED_SUBSTATE_WAIT_RESET;
- delay = millis() + 20;
- }
- break;
- case USB_ATTACHED_SUBSTATE_WAIT_RESET:
- if((long)(millis() - delay) >= 0L) usb_task_state = USB_STATE_CONFIGURING;
- else break; // don't fall through
- case USB_STATE_CONFIGURING:
-
- //Serial.print("\r\nConf.LS: ");
- //Serial.println(lowspeed, HEX);
-
- rcode = Configuring(0, 0, lowspeed);
-
- if(rcode) {
- if(rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE) {
- usb_error = rcode;
- usb_task_state = USB_STATE_ERROR;
- }
- } else
- usb_task_state = USB_STATE_RUNNING;
- break;
- case USB_STATE_RUNNING:
- break;
- case USB_STATE_ERROR:
- //MAX3421E::Init();
- break;
- } // switch( usb_task_state )
-}
-
-uint8_t USB::DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed) {
- //uint8_t buf[12];
- uint8_t rcode;
- UsbDevice *p0 = NULL, *p = NULL;
-
- // Get pointer to pseudo device with address 0 assigned
- p0 = addrPool.GetUsbDevicePtr(0);
-
- if(!p0)
- return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
-
- if(!p0->epinfo)
- return USB_ERROR_EPINFO_IS_NULL;
-
- p0->lowspeed = (lowspeed) ? true : false;
-
- // Allocate new address according to device class
- uint8_t bAddress = addrPool.AllocAddress(parent, false, port);
-
- if(!bAddress)
- return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
-
- p = addrPool.GetUsbDevicePtr(bAddress);
-
- if(!p)
- return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
-
- p->lowspeed = lowspeed;
-
- // Assign new address to the device
- rcode = setAddr(0, 0, bAddress);
-
- if(rcode) {
- addrPool.FreeAddress(bAddress);
- bAddress = 0;
- return rcode;
- }
- return 0;
-};
-
-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);
- if(rcode == USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET) {
- if(parent == 0) {
- // Send a bus reset on the root interface.
- regWr(rHCTL, bmBUSRST); //issue bus reset
- delay(102); // delay 102ms, compensate for clock inaccuracy.
- } else {
- // reset parent port
- devConfig[parent]->ResetHubPort(port);
- }
- } 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 && retries < 3) { // Some devices returns this when plugged in - trying to initialize the device again usually works
- delay(100);
- retries++;
- goto again;
- }
- if(rcode) {
- // Issue a bus reset, because the device may be in a limbo state
- if(parent == 0) {
- // Send a bus reset on the root interface.
- regWr(rHCTL, bmBUSRST); //issue bus reset
- delay(102); // delay 102ms, compensate for clock inaccuracy.
- } else {
- // reset parent port
- devConfig[parent]->ResetHubPort(port);
- }
- }
- return rcode;
-}
-
-/*
- * This is broken. We need to enumerate differently.
- * It causes major problems with several devices if detected in an unexpected order.
- *
- *
- * Oleg - I wouldn't do anything before the newly connected device is considered sane.
- * i.e.(delays are not indicated for brevity):
- * 1. reset
- * 2. GetDevDescr();
- * 3a. If ACK, continue with allocating address, addressing, etc.
- * 3b. Else reset again, count resets, stop at some number (5?).
- * 4. When max.number of resets is reached, toggle power/fail
- * If desired, this could be modified by performing two resets with GetDevDescr() in the middle - however, from my experience, if a device answers to GDD()
- * it doesn't need to be reset again
- * New steps proposal:
- * 1: get address pool instance. exit on fail
- * 2: pUsb->getDevDescr(0, 0, constBufSize, (uint8_t*)buf). exit on fail.
- * 3: bus reset, 100ms delay
- * 4: set address
- * 5: pUsb->setEpInfoEntry(bAddress, 1, epInfo), exit on fail
- * 6: while (configurations) {
- * for(each configuration) {
- * for (each driver) {
- * 6a: Ask device if it likes configuration. Returns 0 on OK.
- * If successful, the driver configured device.
- * The driver now owns the endpoints, and takes over managing them.
- * The following will need codes:
- * Everything went well, instance consumed, exit with success.
- * Instance already in use, ignore it, try next driver.
- * Not a supported device, ignore it, try next driver.
- * Not a supported configuration for this device, ignore it, try next driver.
- * Could not configure device, fatal, exit with fail.
- * }
- * }
- * }
- * 7: for(each driver) {
- * 7a: Ask device if it knows this VID/PID. Acts exactly like 6a, but using VID/PID
- * 8: if we get here, no driver likes the device plugged in, so exit failure.
- *
- */
-uint8_t USB::Configuring(uint8_t parent, uint8_t port, bool lowspeed) {
- //uint8_t bAddress = 0;
- //printf("Configuring: parent = %i, port = %i\r\n", parent, port);
- uint8_t devConfigIndex;
- uint8_t rcode = 0;
- uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
- USB_DEVICE_DESCRIPTOR *udd = reinterpret_cast(buf);
- UsbDevice *p = NULL;
- EpInfo *oldep_ptr = NULL;
- EpInfo epInfo;
-
- epInfo.epAddr = 0;
- epInfo.maxPktSize = 8;
- epInfo.epAttribs = 0;
- epInfo.bmNakPower = USB_NAK_MAX_POWER;
-
- //delay(2000);
- AddressPool &addrPool = GetAddressPool();
- // Get pointer to pseudo device with address 0 assigned
- p = addrPool.GetUsbDevicePtr(0);
- if(!p) {
- //printf("Configuring error: USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL\r\n");
- return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
- }
-
- // Save old pointer to EP_RECORD of address 0
- oldep_ptr = p->epinfo;
-
- // Temporary assign new pointer to epInfo to p->epinfo in order to
- // avoid toggle inconsistence
-
- p->epinfo = &epInfo;
-
- p->lowspeed = lowspeed;
- // Get device descriptor
- rcode = getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);
-
- // Restore p->epinfo
- p->epinfo = oldep_ptr;
-
- if(rcode) {
- //printf("Configuring error: Can't get USB_DEVICE_DESCRIPTOR\r\n");
- return rcode;
- }
-
- // to-do?
- // Allocate new address according to device class
- //bAddress = addrPool.AllocAddress(parent, false, port);
-
- uint16_t vid = udd->idVendor;
- uint16_t pid = udd->idProduct;
- uint8_t klass = udd->bDeviceClass;
- uint8_t subklass = udd->bDeviceSubClass;
- // Attempt to configure if VID/PID or device class matches with a driver
- // Qualify with subclass too.
- //
- // VID/PID & class tests default to false for drivers not yet ported
- // subclass defaults to true, so you don't have to define it if you don't have to.
- //
- for(devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
- if(!devConfig[devConfigIndex]) continue; // no driver
- if(devConfig[devConfigIndex]->GetAddress()) continue; // consumed
- if(devConfig[devConfigIndex]->DEVSUBCLASSOK(subklass) && (devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass))) {
- rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed);
- if(rcode != USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED)
- break;
- }
- }
-
- if(devConfigIndex < USB_NUMDEVICES) {
- return rcode;
- }
-
-
- // blindly attempt to configure
- for(devConfigIndex = 0; devConfigIndex < USB_NUMDEVICES; devConfigIndex++) {
- if(!devConfig[devConfigIndex]) continue;
- if(devConfig[devConfigIndex]->GetAddress()) continue; // consumed
- if(devConfig[devConfigIndex]->DEVSUBCLASSOK(subklass) && (devConfig[devConfigIndex]->VIDPIDOK(vid, pid) || devConfig[devConfigIndex]->DEVCLASSOK(klass))) continue; // If this is true it means it must have returned USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED above
- rcode = AttemptConfig(devConfigIndex, parent, port, lowspeed);
-
- //printf("ERROR ENUMERATING %2.2x\r\n", rcode);
- if(!(rcode == USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED || rcode == USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE)) {
- // in case of an error dev_index should be reset to 0
- // in order to start from the very beginning the
- // next time the program gets here
- //if (rcode != USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE)
- // devConfigIndex = 0;
- return rcode;
- }
- }
- // if we get here that means that the device class is not supported by any of registered classes
- rcode = DefaultAddressing(parent, port, lowspeed);
-
- return rcode;
-}
-
-uint8_t USB::ReleaseDevice(uint8_t addr) {
- if(!addr)
- return 0;
-
- for(uint8_t i = 0; i < USB_NUMDEVICES; i++) {
- if(!devConfig[i]) continue;
- if(devConfig[i]->GetAddress() == addr)
- return devConfig[i]->Release();
- }
- return 0;
-}
-
-#if 1 //!defined(USB_METHODS_INLINE)
-//get device descriptor
-
-uint8_t USB::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr) {
- return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, nbytes, dataptr, NULL));
-}
-//get configuration descriptor
-
-uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr) {
- return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, nbytes, dataptr, NULL));
-}
-
-/* Requests Configuration Descriptor. Sends two Get Conf Descr requests. The first one gets the total length of all descriptors, then the second one requests this
- total length. The length of the first request can be shorter ( 4 bytes ), however, there are devices which won't work unless this length is set to 9 */
-uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser *p) {
- const uint8_t bufSize = 64;
- uint8_t buf[bufSize];
- USB_CONFIGURATION_DESCRIPTOR *ucd = reinterpret_cast(buf);
-
- uint8_t ret = getConfDescr(addr, ep, 9, conf, buf);
-
- if(ret)
- return ret;
-
- uint16_t total = ucd->wTotalLength;
-
- //USBTRACE2("\r\ntotal conf.size:", total);
-
- return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, total, bufSize, buf, p));
-}
-
-//get string descriptor
-
-uint8_t USB::getStrDescr(uint8_t addr, uint8_t ep, uint16_t ns, uint8_t index, uint16_t langid, uint8_t* dataptr) {
- return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, ns, ns, dataptr, NULL));
-}
-//set address
-
-uint8_t USB::setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr) {
- uint8_t rcode = ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL);
- //delay(2); //per USB 2.0 sect.9.2.6.3
- delay(300); // Older spec says you should wait at least 200ms
- return rcode;
- //return ( ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL));
-}
-//set configuration
-
-uint8_t USB::setConf(uint8_t addr, uint8_t ep, uint8_t conf_value) {
- return ( ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, 0x0000, NULL, NULL));
-}
-
-#endif // defined(USB_METHODS_INLINE)
diff --git a/lib/usbhost/USB_Host_Shield_2.0/Usb.h b/lib/usbhost/USB_Host_Shield_2.0/Usb.h
deleted file mode 100644
index 47bd626cce53..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/Usb.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (C) 2011 Circuits At Home, LTD. 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
--------------------
-
-Circuits At Home, LTD
-Web : http://www.circuitsathome.com
-e-mail : support@circuitsathome.com
- */
-/* USB functions */
-#ifndef _usb_h_
-#define _usb_h_
-
-// WARNING: Do not change the order of includes, or stuff will break!
-#include
-#include
-#include
-
-// None of these should ever be included by a driver, or a user's sketch.
-#include "settings.h"
-#include "printhex.h"
-#include "message.h"
-#include "hexdump.h"
-#include "sink_parser.h"
-#include "max3421e.h"
-#include "address.h"
-#include "avrpins.h"
-#include "usb_ch9.h"
-#include "usbhost.h"
-#include "UsbCore.h"
-#include "parsetools.h"
-#include "confdescparser.h"
-
-#endif //_usb_h_
diff --git a/lib/usbhost/USB_Host_Shield_2.0/UsbCore.h b/lib/usbhost/USB_Host_Shield_2.0/UsbCore.h
deleted file mode 100644
index 5c6c77101725..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/UsbCore.h
+++ /dev/null
@@ -1,298 +0,0 @@
-/* Copyright (C) 2011 Circuits At Home, LTD. 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
--------------------
-
-Circuits At Home, LTD
-Web : http://www.circuitsathome.com
-e-mail : support@circuitsathome.com
- */
-
-#if !defined(_usb_h_) || defined(USBCORE_H)
-#error "Never include UsbCore.h directly; include Usb.h instead"
-#else
-#define USBCORE_H
-
-// Not used anymore? If anyone uses this, please let us know so that this may be
-// moved to the proper place, settings.h.
-//#define USB_METHODS_INLINE
-
-/* shield pins. First parameter - SS pin, second parameter - INT pin */
-#ifdef BOARD_BLACK_WIDDOW
-typedef MAX3421e MAX3421E; // Black Widow
-#elif defined(CORE_TEENSY) && (defined(__AVR_AT90USB646__) || defined(__AVR_AT90USB1286__))
-#if EXT_RAM
-typedef MAX3421e MAX3421E; // Teensy++ 2.0 with XMEM2
-#else
-typedef MAX3421e MAX3421E; // Teensy++ 1.0 and 2.0
-#endif
-#elif defined(BOARD_MEGA_ADK)
-typedef MAX3421e MAX3421E; // Arduino Mega ADK
-#elif defined(ARDUINO_AVR_BALANDUINO)
-typedef MAX3421e MAX3421E; // Balanduino
-#elif defined(__ARDUINO_X86__) && PLATFORM_ID == 0x06
-typedef MAX3421e MAX3421E; // The Intel Galileo supports much faster read and write speed at pin 2 and 3
-#else
-typedef MAX3421e MAX3421E; // Official Arduinos (UNO, Duemilanove, Mega, 2560, Leonardo, Due etc.), Intel Edison, Intel Galileo 2 or Teensy 2.0 and 3.0
-#endif
-
-/* Common setup data constant combinations */
-#define bmREQ_GET_DESCR USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE //get descriptor request type
-#define bmREQ_SET USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_STANDARD|USB_SETUP_RECIPIENT_DEVICE //set request type for all but 'set feature' and 'set interface'
-#define bmREQ_CL_GET_INTF USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE //get interface request type
-
-// D7 data transfer direction (0 - host-to-device, 1 - device-to-host)
-// D6-5 Type (0- standard, 1 - class, 2 - vendor, 3 - reserved)
-// D4-0 Recipient (0 - device, 1 - interface, 2 - endpoint, 3 - other, 4..31 - reserved)
-
-// USB Device Classes
-#define USB_CLASS_USE_CLASS_INFO 0x00 // Use Class Info in the Interface Descriptors
-#define USB_CLASS_AUDIO 0x01 // Audio
-#define USB_CLASS_COM_AND_CDC_CTRL 0x02 // Communications and CDC Control
-#define USB_CLASS_HID 0x03 // HID
-#define USB_CLASS_PHYSICAL 0x05 // Physical
-#define USB_CLASS_IMAGE 0x06 // Image
-#define USB_CLASS_PRINTER 0x07 // Printer
-#define USB_CLASS_MASS_STORAGE 0x08 // Mass Storage
-#define USB_CLASS_HUB 0x09 // Hub
-#define USB_CLASS_CDC_DATA 0x0a // CDC-Data
-#define USB_CLASS_SMART_CARD 0x0b // Smart-Card
-#define USB_CLASS_CONTENT_SECURITY 0x0d // Content Security
-#define USB_CLASS_VIDEO 0x0e // Video
-#define USB_CLASS_PERSONAL_HEALTH 0x0f // Personal Healthcare
-#define USB_CLASS_DIAGNOSTIC_DEVICE 0xdc // Diagnostic Device
-#define USB_CLASS_WIRELESS_CTRL 0xe0 // Wireless Controller
-#define USB_CLASS_MISC 0xef // Miscellaneous
-#define USB_CLASS_APP_SPECIFIC 0xfe // Application Specific
-#define USB_CLASS_VENDOR_SPECIFIC 0xff // Vendor Specific
-
-// Additional Error Codes
-#define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED 0xD1
-#define USB_DEV_CONFIG_ERROR_DEVICE_INIT_INCOMPLETE 0xD2
-#define USB_ERROR_UNABLE_TO_REGISTER_DEVICE_CLASS 0xD3
-#define USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL 0xD4
-#define USB_ERROR_HUB_ADDRESS_OVERFLOW 0xD5
-#define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL 0xD6
-#define USB_ERROR_EPINFO_IS_NULL 0xD7
-#define USB_ERROR_INVALID_ARGUMENT 0xD8
-#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE 0xD9
-#define USB_ERROR_INVALID_MAX_PKT_SIZE 0xDA
-#define USB_ERROR_EP_NOT_FOUND_IN_TBL 0xDB
-#define USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET 0xE0
-#define USB_ERROR_FailGetDevDescr 0xE1
-#define USB_ERROR_FailSetDevTblEntry 0xE2
-#define USB_ERROR_FailGetConfDescr 0xE3
-#define USB_ERROR_TRANSFER_TIMEOUT 0xFF
-
-#define USB_XFER_TIMEOUT 5000 // (5000) USB transfer timeout in milliseconds, per section 9.2.6.1 of USB 2.0 spec
-//#define USB_NAK_LIMIT 32000 // NAK limit for a transfer. 0 means NAKs are not counted
-#define USB_RETRY_LIMIT 3 // 3 retry limit for a transfer
-#define USB_SETTLE_DELAY 200 // settle delay in milliseconds
-
-#define USB_NUMDEVICES 16 //number of USB devices
-//#define HUB_MAX_HUBS 7 // maximum number of hubs that can be attached to the host controller
-#define HUB_PORT_RESET_DELAY 20 // hub port reset delay 10 ms recomended, can be up to 20 ms
-
-/* USB state machine states */
-#define USB_STATE_MASK 0xf0
-
-#define USB_STATE_DETACHED 0x10
-#define USB_DETACHED_SUBSTATE_INITIALIZE 0x11
-#define USB_DETACHED_SUBSTATE_WAIT_FOR_DEVICE 0x12
-#define USB_DETACHED_SUBSTATE_ILLEGAL 0x13
-#define USB_ATTACHED_SUBSTATE_SETTLE 0x20
-#define USB_ATTACHED_SUBSTATE_RESET_DEVICE 0x30
-#define USB_ATTACHED_SUBSTATE_WAIT_RESET_COMPLETE 0x40
-#define USB_ATTACHED_SUBSTATE_WAIT_SOF 0x50
-#define USB_ATTACHED_SUBSTATE_WAIT_RESET 0x51
-#define USB_ATTACHED_SUBSTATE_GET_DEVICE_DESCRIPTOR_SIZE 0x60
-#define USB_STATE_ADDRESSING 0x70
-#define USB_STATE_CONFIGURING 0x80
-#define USB_STATE_RUNNING 0x90
-#define USB_STATE_ERROR 0xa0
-
-class USBDeviceConfig {
-public:
-
- virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed) {
- return 0;
- }
-
- virtual uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
- return 0;
- }
-
- virtual uint8_t Release() {
- return 0;
- }
-
- virtual uint8_t Poll() {
- return 0;
- }
-
- virtual uint8_t GetAddress() {
- return 0;
- }
-
- virtual void ResetHubPort(uint8_t port) {
- return;
- } // Note used for hubs only!
-
- virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) {
- return false;
- }
-
- virtual bool DEVCLASSOK(uint8_t klass) {
- return false;
- }
-
- virtual bool DEVSUBCLASSOK(uint8_t subklass) {
- return true;
- }
-
-};
-
-/* USB Setup Packet Structure */
-typedef struct {
-
- union { // offset description
- uint8_t bmRequestType; // 0 Bit-map of request type
-
- struct {
- uint8_t recipient : 5; // Recipient of the request
- uint8_t type : 2; // Type of request
- uint8_t direction : 1; // Direction of data X-fer
- } __attribute__((packed));
- } ReqType_u;
- uint8_t bRequest; // 1 Request
-
- union {
- uint16_t wValue; // 2 Depends on bRequest
-
- struct {
- uint8_t wValueLo;
- uint8_t wValueHi;
- } __attribute__((packed));
- } wVal_u;
- uint16_t wIndex; // 4 Depends on bRequest
- uint16_t wLength; // 6 Depends on bRequest
-} __attribute__((packed)) SETUP_PKT, *PSETUP_PKT;
-
-
-
-// Base class for incoming data parser
-
-class USBReadParser {
-public:
- virtual void Parse(const uint16_t len, const uint8_t *pbuf, const uint16_t &offset) = 0;
-};
-
-class USB : public MAX3421E {
- AddressPoolImpl addrPool;
- USBDeviceConfig* devConfig[USB_NUMDEVICES];
- uint8_t bmHubPre;
-
-public:
- USB(void);
-
- void SetHubPreMask() {
- bmHubPre |= bmHUBPRE;
- };
-
- void ResetHubPreMask() {
- bmHubPre &= (~bmHUBPRE);
- };
-
- AddressPool& GetAddressPool() {
- return (AddressPool&)addrPool;
- };
-
- uint8_t RegisterDeviceClass(USBDeviceConfig *pdev) {
- for(uint8_t i = 0; i < USB_NUMDEVICES; i++) {
- if(!devConfig[i]) {
- devConfig[i] = pdev;
- return 0;
- }
- }
- return USB_ERROR_UNABLE_TO_REGISTER_DEVICE_CLASS;
- };
-
- void ForEachUsbDevice(UsbDeviceHandleFunc pfunc) {
- addrPool.ForEachUsbDevice(pfunc);
- };
- uint8_t getUsbTaskState(void);
- void setUsbTaskState(uint8_t state);
-
- EpInfo* getEpInfoEntry(uint8_t addr, uint8_t ep);
- uint8_t setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo* eprecord_ptr);
-
- /* Control requests */
- uint8_t getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr);
- uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr);
-
- uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint8_t conf, USBReadParser *p);
-
- uint8_t getStrDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t index, uint16_t langid, uint8_t* dataptr);
- uint8_t setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr);
- uint8_t setConf(uint8_t addr, uint8_t ep, uint8_t conf_value);
- /**/
- uint8_t ctrlData(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr, bool direction);
- uint8_t ctrlStatus(uint8_t ep, bool direction, uint16_t nak_limit);
- uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t* data);
- uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* data);
- uint8_t dispatchPkt(uint8_t token, uint8_t ep, uint16_t nak_limit);
-
- void Task(void);
-
- uint8_t DefaultAddressing(uint8_t parent, uint8_t port, bool lowspeed);
- uint8_t Configuring(uint8_t parent, uint8_t port, bool lowspeed);
- uint8_t ReleaseDevice(uint8_t addr);
-
- uint8_t ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi,
- uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t* dataptr, USBReadParser *p);
-
-private:
- void init();
- uint8_t SetAddress(uint8_t addr, uint8_t ep, EpInfo **ppep, uint16_t *nak_limit);
- uint8_t OutTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t nbytes, uint8_t *data);
- uint8_t InTransfer(EpInfo *pep, uint16_t nak_limit, uint16_t *nbytesptr, uint8_t *data);
- uint8_t AttemptConfig(uint8_t driver, uint8_t parent, uint8_t port, bool lowspeed);
-};
-
-#if 0 //defined(USB_METHODS_INLINE)
-//get device descriptor
-
-inline uint8_t USB::getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t* dataptr) {
- return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, 0x00, USB_DESCRIPTOR_DEVICE, 0x0000, nbytes, dataptr));
-}
-//get configuration descriptor
-
-inline uint8_t USB::getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t* dataptr) {
- return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, conf, USB_DESCRIPTOR_CONFIGURATION, 0x0000, nbytes, dataptr));
-}
-//get string descriptor
-
-inline uint8_t USB::getStrDescr(uint8_t addr, uint8_t ep, uint16_t nuint8_ts, uint8_t index, uint16_t langid, uint8_t* dataptr) {
- return ( ctrlReq(addr, ep, bmREQ_GET_DESCR, USB_REQUEST_GET_DESCRIPTOR, index, USB_DESCRIPTOR_STRING, langid, nuint8_ts, dataptr));
-}
-//set address
-
-inline uint8_t USB::setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr) {
- return ( ctrlReq(oldaddr, ep, bmREQ_SET, USB_REQUEST_SET_ADDRESS, newaddr, 0x00, 0x0000, 0x0000, NULL));
-}
-//set configuration
-
-inline uint8_t USB::setConf(uint8_t addr, uint8_t ep, uint8_t conf_value) {
- return ( ctrlReq(addr, ep, bmREQ_SET, USB_REQUEST_SET_CONFIGURATION, conf_value, 0x00, 0x0000, 0x0000, NULL));
-}
-
-#endif // defined(USB_METHODS_INLINE)
-
-#endif /* USBCORE_H */
diff --git a/lib/usbhost/USB_Host_Shield_2.0/Wii.cpp b/lib/usbhost/USB_Host_Shield_2.0/Wii.cpp
deleted file mode 100644
index 4bbf4c91cb45..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/Wii.cpp
+++ /dev/null
@@ -1,1268 +0,0 @@
-/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
-
- This software may be distributed and modified under the terms of the GNU
- General Public License version 2 (GPL2) as published by the Free Software
- Foundation and appearing in the file GPL2.TXT included in the packaging of
- this file. Please note that GPL2 Section 2[b] requires that all works based
- on this software must also be made publicly available under the terms of
- the GPL2 ("Copyleft").
-
- Contact information
- -------------------
-
- Kristian Lauszus, TKJ Electronics
- Web : http://www.tkjelectronics.com
- e-mail : kristianl@tkjelectronics.com
-
- IR camera support added by Allan Glover (adglover9.81@gmail.com) and Kristian Lauszus
- */
-
-#include "Wii.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 WII_LEDS[] PROGMEM = {
- 0x00, // OFF
- 0x10, // LED1
- 0x20, // LED2
- 0x40, // LED3
- 0x80, // LED4
-
- 0x90, // LED5
- 0xA0, // LED6
- 0xC0, // LED7
- 0xD0, // LED8
- 0xE0, // LED9
- 0xF0, // LED10
-};
-
-const uint32_t WII_BUTTONS[] PROGMEM = {
- 0x00008, // UP
- 0x00002, // RIGHT
- 0x00004, // DOWN
- 0x00001, // LEFT
-
- 0, // Skip
- 0x00010, // PLUS
- 0x00100, // TWO
- 0x00200, // ONE
-
- 0x01000, // MINUS
- 0x08000, // HOME
- 0x10000, // Z
- 0x20000, // C
-
- 0x00400, // B
- 0x00800, // A
-};
-const uint32_t WII_PROCONTROLLER_BUTTONS[] PROGMEM = {
- 0x00100, // UP
- 0x00080, // RIGHT
- 0x00040, // DOWN
- 0x00200, // LEFT
-
- 0, // Skip
- 0x00004, // PLUS
- 0x20000, // L3
- 0x10000, // R3
-
- 0x00010, // MINUS
- 0x00008, // HOME
- 0, 0, // Skip
-
- 0x04000, // B
- 0x01000, // A
- 0x00800, // X
- 0x02000, // Y
-
- 0x00020, // L
- 0x00002, // R
- 0x08000, // ZL
- 0x00400, // ZR
-};
-
-WII::WII(BTD *p, bool pair) :
-BluetoothService(p) // Pointer to USB class instance - mandatory
-{
- pBtd->pairWithWii = pair;
-
- HIDBuffer[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
-
- /* Set device cid for the control and intterrupt channelse - LSB */
- control_dcid[0] = 0x60; // 0x0060
- control_dcid[1] = 0x00;
- interrupt_dcid[0] = 0x61; // 0x0061
- interrupt_dcid[1] = 0x00;
-
- Reset();
-}
-
-void WII::Reset() {
- wiimoteConnected = false;
- nunchuckConnected = false;
- motionPlusConnected = false;
- activateNunchuck = false;
- motionValuesReset = false;
- activeConnection = false;
- motionPlusInside = false;
- pBtd->wiiUProController = false;
- wiiUProControllerConnected = false;
- wiiBalanceBoardConnected = false;
- l2cap_event_flag = 0; // Reset flags
- l2cap_state = L2CAP_WAIT;
-}
-
-void WII::disconnect() { // Use this void to disconnect any of the controllers
- if(!motionPlusInside) { // The old Wiimote needs a delay after the first command or it will automatically reconnect
- if(motionPlusConnected) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nDeactivating Motion Plus"), 0x80);
-#endif
- initExtension1(); // This will disable the Motion Plus extension
- }
- timer = millis() + 1000; // We have to wait for the message before the rest of the channels can be deactivated
- } else
- timer = millis(); // Don't wait
- // 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, ++identifier, interrupt_scid, interrupt_dcid);
- Reset();
- l2cap_state = L2CAP_INTERRUPT_DISCONNECT;
-}
-
-void WII::ACLData(uint8_t* l2capinbuf) {
- if(!pBtd->l2capConnectionClaimed && pBtd->incomingWii && !wiimoteConnected && !activeConnection) {
- if(l2capinbuf[8] == L2CAP_CMD_CONNECTION_REQUEST) {
- if((l2capinbuf[12] | (l2capinbuf[13] << 8)) == HID_CTRL_PSM) {
- motionPlusInside = pBtd->motionPlusInside;
- pBtd->incomingWii = false;
- pBtd->l2capConnectionClaimed = true; // Claim that the incoming connection belongs to this service
- activeConnection = true;
- hci_handle = pBtd->hci_handle; // Store the HCI Handle for the connection
- l2cap_state = L2CAP_WAIT;
- }
- }
- }
-
- if(checkHciHandle(l2capinbuf, hci_handle)) { // acl_handle_ok
- if((l2capinbuf[6] | (l2capinbuf[7] << 8)) == 0x0001U) { // 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]) {
- //Notify(PSTR("\r\nHID Control Connection Complete"), 0x80);
- identifier = l2capinbuf[9];
- control_scid[0] = l2capinbuf[12];
- control_scid[1] = l2capinbuf[13];
- l2cap_set_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_set_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_set_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_set_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_set_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_set_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_set_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_set_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\nL2CAP Interrupt"), 0x80);
- if(l2capinbuf[8] == 0xA1) { // HID_THDR_DATA_INPUT
- if((l2capinbuf[9] >= 0x20 && l2capinbuf[9] <= 0x22) || (l2capinbuf[9] >= 0x30 && l2capinbuf[9] <= 0x37) || l2capinbuf[9] == 0x3e || l2capinbuf[9] == 0x3f) { // These reports include the buttons
- if((l2capinbuf[9] >= 0x20 && l2capinbuf[9] <= 0x22) || l2capinbuf[9] == 0x31 || l2capinbuf[9] == 0x33) // These reports have no extensions bytes
- ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8));
- else if(wiiUProControllerConnected)
- ButtonState = (uint32_t)(((~l2capinbuf[23]) & 0xFE) | ((uint16_t)(~l2capinbuf[24]) << 8) | ((uint32_t)((~l2capinbuf[25]) & 0x03) << 16));
- else if(motionPlusConnected) {
- if(l2capinbuf[20] & 0x02) // Only update the Wiimote buttons, since the extension bytes are from the Motion Plus
- ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((uint32_t)(ButtonState & 0xFFFF0000)));
- else if(nunchuckConnected) // Update if it's a report from the Nunchuck
- ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((uint32_t)((~l2capinbuf[20]) & 0x0C) << 14));
- //else if(classicControllerConnected) // Update if it's a report from the Classic Controller
- } else if(nunchuckConnected) // The Nunchuck is directly connected
- ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8) | ((uint32_t)((~l2capinbuf[20]) & 0x03) << 16));
- //else if(classicControllerConnected) // The Classic Controller is directly connected
- else if(!unknownExtensionConnected)
- ButtonState = (uint32_t)((l2capinbuf[10] & 0x1F) | ((uint16_t)(l2capinbuf[11] & 0x9F) << 8));
-#ifdef PRINTREPORT
- Notify(PSTR("ButtonState: "), 0x80);
- D_PrintHex (ButtonState, 0x80);
- Notify(PSTR("\r\n"), 0x80);
-#endif
- if(ButtonState != OldButtonState) {
- ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
- OldButtonState = ButtonState;
- }
- }
- if(l2capinbuf[9] == 0x31 || l2capinbuf[9] == 0x33 || l2capinbuf[9] == 0x35 || l2capinbuf[9] == 0x37) { // Read the accelerometer
- accXwiimote = ((l2capinbuf[12] << 2) | (l2capinbuf[10] & 0x60 >> 5)) - 500;
- accYwiimote = ((l2capinbuf[13] << 2) | (l2capinbuf[11] & 0x20 >> 4)) - 500;
- accZwiimote = ((l2capinbuf[14] << 2) | (l2capinbuf[11] & 0x40 >> 5)) - 500;
- }
- switch(l2capinbuf[9]) {
- case 0x20: // Status Information - (a1) 20 BB BB LF 00 00 VV
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nStatus report was received"), 0x80);
-#endif
- wiiState = l2capinbuf[12]; // (0x01: Battery is nearly empty), (0x02: An Extension Controller is connected), (0x04: Speaker enabled), (0x08: IR enabled), (0x10: LED1, 0x20: LED2, 0x40: LED3, 0x80: LED4)
- batteryLevel = l2capinbuf[15]; // Update battery level
-
- if(!checkBatteryLevel) { // If this is true it means that the user must have called getBatteryLevel()
- if(l2capinbuf[12] & 0x02) { // Check if a extension is connected
-#ifdef DEBUG_USB_HOST
- if(!unknownExtensionConnected)
- Notify(PSTR("\r\nExtension connected"), 0x80);
-#endif
- unknownExtensionConnected = true;
-#ifdef WIICAMERA
- if(!isIRCameraEnabled()) // Don't activate the Motion Plus if we are trying to initialize the IR camera
-#endif
- setReportMode(false, 0x35); // Also read the extension
- } else {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nExtension disconnected"), 0x80);
-#endif
- if(motionPlusConnected) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR(" - from Motion Plus"), 0x80);
-#endif
- wii_clear_flag(WII_FLAG_NUNCHUCK_CONNECTED);
- if(!activateNunchuck) // If it's already trying to initialize the Nunchuck don't set it to false
- nunchuckConnected = false;
- //else if(classicControllerConnected)
- } else if(nunchuckConnected) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR(" - Nunchuck"), 0x80);
-#endif
- nunchuckConnected = false; // It must be the Nunchuck controller then
- wii_clear_flag(WII_FLAG_NUNCHUCK_CONNECTED);
- onInit();
- setReportMode(false, 0x31); // If there is no extension connected we will read the buttons and accelerometer
- } else
- setReportMode(false, 0x31); // If there is no extension connected we will read the buttons and accelerometer
- }
- }
- else {
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nChecking battery level"), 0x80);
-#endif
- checkBatteryLevel = false; // Check for extensions by default
- }
-#ifdef DEBUG_USB_HOST
- if(l2capinbuf[12] & 0x01)
- Notify(PSTR("\r\nWARNING: Battery is nearly empty"), 0x80);
-#endif
-
- break;
- case 0x21: // Read Memory Data
- if((l2capinbuf[12] & 0x0F) == 0) { // No error
- uint8_t reportLength = (l2capinbuf[12] >> 4) + 1; // // Bit 4-7 is the length - 1
- // See: http://wiibrew.org/wiki/Wiimote/Extension_Controllers
- if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x00 && l2capinbuf[20] == 0x00) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nNunchuck connected"), 0x80);
-#endif
- wii_set_flag(WII_FLAG_NUNCHUCK_CONNECTED);
- } else if(l2capinbuf[16] == 0x00 && (l2capinbuf[17] == 0xA6 || l2capinbuf[17] == 0xA4) && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x00 && l2capinbuf[20] == 0x05) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nMotion Plus connected"), 0x80);
-#endif
- wii_set_flag(WII_FLAG_MOTION_PLUS_CONNECTED);
- } else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x04 && l2capinbuf[20] == 0x05) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nMotion Plus activated in normal mode"), 0x80);
-#endif
- motionPlusConnected = true;
-#ifdef WIICAMERA
- if(!isIRCameraEnabled()) // Don't activate the Motion Plus if we are trying to initialize the IR camera
-#endif
- setReportMode(false, 0x35); // Also read the extension
- } else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x05 && l2capinbuf[20] == 0x05) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nMotion Plus activated in Nunchuck pass-through mode"), 0x80);
-#endif
- activateNunchuck = false;
- motionPlusConnected = true;
- nunchuckConnected = true;
-#ifdef WIICAMERA
- if(!isIRCameraEnabled()) // Don't activate the Motion Plus if we are trying to initialize the IR camera
-#endif
- setReportMode(false, 0x35); // Also read the extension
- } else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA6 && l2capinbuf[18] == 0x20 && (l2capinbuf[19] == 0x00 || l2capinbuf[19] == 0x04 || l2capinbuf[19] == 0x05 || l2capinbuf[19] == 0x07) && l2capinbuf[20] == 0x05) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nInactive Wii Motion Plus"), 0x80);
- Notify(PSTR("\r\nPlease unplug the Motion Plus, disconnect the Wiimote and then replug the Motion Plus Extension"), 0x80);
-#endif
- stateCounter = 300; // Skip the rest in "WII_CHECK_MOTION_PLUS_STATE"
- } else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x01 && l2capinbuf[20] == 0x20) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nWii U Pro Controller connected"), 0x80);
-#endif
- wiiUProControllerConnected = true;
- } else if(l2capinbuf[16] == 0x00 && l2capinbuf[17] == 0xA4 && l2capinbuf[18] == 0x20 && l2capinbuf[19] == 0x04 && l2capinbuf[20] == 0x02) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nWii Balance Board connected"), 0x80);
-#endif
- setReportMode(false, 0x32); // Read the Wii Balance Board extension
- wii_set_flag(WII_FLAG_CALIBRATE_BALANCE_BOARD);
- }
- // Wii Balance Board calibration reports (24 bits in total)
- else if(l2capinbuf[13] == 0x00 && l2capinbuf[14] == 0x24 && reportLength == 16) { // First 16-bit
- for(uint8_t i = 0; i < 2; i++) {
- for(uint8_t j = 0; j < 4; j++)
- wiiBalanceBoardCal[i][j] = l2capinbuf[16 + 8 * i + 2 * j] | l2capinbuf[15 + 8 * i + 2 * j] << 8;
- }
- } else if(l2capinbuf[13] == 0x00 && l2capinbuf[14] == 0x34 && reportLength == 8) { // Last 8-bit
- for(uint8_t j = 0; j < 4; j++)
- wiiBalanceBoardCal[2][j] = l2capinbuf[16 + 2 * j] | l2capinbuf[15 + 2 * j] << 8;
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nWii Balance Board calibration values read successfully"), 0x80);
-#endif
- wii_clear_flag(WII_FLAG_CALIBRATE_BALANCE_BOARD);
- wiiBalanceBoardConnected = true;
- }
-#ifdef DEBUG_USB_HOST
- else {
- Notify(PSTR("\r\nUnknown Device: "), 0x80);
- D_PrintHex (l2capinbuf[13], 0x80);
- D_PrintHex (l2capinbuf[14], 0x80);
- Notify(PSTR("\r\nData: "), 0x80);
- for(uint8_t i = 0; i < reportLength; i++) {
- D_PrintHex (l2capinbuf[15 + i], 0x80);
- Notify(PSTR(" "), 0x80);
- }
- }
-#endif
- }
-#ifdef EXTRADEBUG
- else {
- Notify(PSTR("\r\nReport Error: "), 0x80);
- D_PrintHex (l2capinbuf[13], 0x80);
- D_PrintHex (l2capinbuf[14], 0x80);
- }
-#endif
- break;
- case 0x22: // Acknowledge output report, return function result
-#ifdef DEBUG_USB_HOST
- if(l2capinbuf[13] != 0x00) { // Check if there is an error
- Notify(PSTR("\r\nCommand failed: "), 0x80);
- D_PrintHex (l2capinbuf[12], 0x80);
- }
-#endif
- break;
- case 0x30: // Core buttons - (a1) 30 BB BB
- break;
- case 0x31: // Core Buttons and Accelerometer - (a1) 31 BB BB AA AA AA
- break;
- case 0x32: // Core Buttons with 8 Extension bytes - (a1) 32 BB BB EE EE EE EE EE EE EE EE
- // See: http://wiibrew.org/wiki/Wii_Balance_Board#Data_Format
- wiiBalanceBoardRaw[TopRight] = l2capinbuf[13] | l2capinbuf[12] << 8; // Top right
- wiiBalanceBoardRaw[BotRight] = l2capinbuf[15] | l2capinbuf[14] << 8; // Bottom right
- wiiBalanceBoardRaw[TopLeft] = l2capinbuf[17] | l2capinbuf[16] << 8; // Top left
- wiiBalanceBoardRaw[BotLeft] = l2capinbuf[19] | l2capinbuf[18] << 8; // Bottom left
- break;
- case 0x33: // Core Buttons with Accelerometer and 12 IR bytes - (a1) 33 BB BB AA AA AA II II II II II II II II II II II II
-#ifdef WIICAMERA
- // Read the IR data
- IR_object_x1 = (l2capinbuf[15] | ((uint16_t)(l2capinbuf[17] & 0x30) << 4)); // x position
- IR_object_y1 = (l2capinbuf[16] | ((uint16_t)(l2capinbuf[17] & 0xC0) << 2)); // y position
- IR_object_s1 = (l2capinbuf[17] & 0x0F); // Size value, 0-15
-
- IR_object_x2 = (l2capinbuf[18] | ((uint16_t)(l2capinbuf[20] & 0x30) << 4));
- IR_object_y2 = (l2capinbuf[19] | ((uint16_t)(l2capinbuf[20] & 0xC0) << 2));
- IR_object_s2 = (l2capinbuf[20] & 0x0F);
-
- IR_object_x3 = (l2capinbuf[21] | ((uint16_t)(l2capinbuf[23] & 0x30) << 4));
- IR_object_y3 = (l2capinbuf[22] | ((uint16_t)(l2capinbuf[23] & 0xC0) << 2));
- IR_object_s3 = (l2capinbuf[23] & 0x0F);
-
- IR_object_x4 = (l2capinbuf[24] | ((uint16_t)(l2capinbuf[26] & 0x30) << 4));
- IR_object_y4 = (l2capinbuf[25] | ((uint16_t)(l2capinbuf[26] & 0xC0) << 2));
- IR_object_s4 = (l2capinbuf[26] & 0x0F);
-#endif
- break;
- case 0x34: // Core Buttons with 19 Extension bytes - (a1) 34 BB BB EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
- break;
- /* 0x3e and 0x3f both give unknown report types when report mode is 0x3e or 0x3f with mode number 0x05 */
- case 0x3E: // Core Buttons with Accelerometer and 32 IR bytes
- // (a1) 31 BB BB AA AA AA II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II II
- // corresponds to output report mode 0x3e
-
- /**** for reading in full mode: DOES NOT WORK YET ****/
- /* When it works it will also have intensity and bounding box data */
- /*
- IR_object_x1 = (l2capinbuf[13] | ((uint16_t)(l2capinbuf[15] & 0x30) << 4));
- IR_object_y1 = (l2capinbuf[14] | ((uint16_t)(l2capinbuf[15] & 0xC0) << 2));
- IR_object_s1 = (l2capinbuf[15] & 0x0F);
- */
- break;
- case 0x3F:
- /*
- IR_object_x1 = (l2capinbuf[13] | ((uint16_t)(l2capinbuf[15] & 0x30) << 4));
- IR_object_y1 = (l2capinbuf[14] | ((uint16_t)(l2capinbuf[15] & 0xC0) << 2));
- IR_object_s1 = (l2capinbuf[15] & 0x0F);
- */
- break;
- case 0x35: // Core Buttons and Accelerometer with 16 Extension Bytes
- // (a1) 35 BB BB AA AA AA EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE EE
-#if 1 // Set this to 0 if you don't want to use an extension, this reduceds the size of the library a lot!
- if(motionPlusConnected) {
- if(l2capinbuf[20] & 0x02) { // Check if it's a report from the Motion controller or the extension
- if(motionValuesReset) { // We will only use the values when the gyro value has been set
- gyroYawRaw = ((l2capinbuf[15] | ((l2capinbuf[18] & 0xFC) << 6)) - gyroYawZero);
- gyroRollRaw = ((l2capinbuf[16] | ((l2capinbuf[19] & 0xFC) << 6)) - gyroRollZero);
- gyroPitchRaw = ((l2capinbuf[17] | ((l2capinbuf[20] & 0xFC) << 6)) - gyroPitchZero);
-
- yawGyroSpeed = (double)gyroYawRaw / ((double)gyroYawZero / yawGyroScale);
- rollGyroSpeed = -(double)gyroRollRaw / ((double)gyroRollZero / rollGyroScale); // We invert these values so they will fit the acc values
- pitchGyroSpeed = (double)gyroPitchRaw / ((double)gyroPitchZero / pitchGyroScale);
-
- /* The onboard gyro has two ranges for slow and fast mode */
- if(!(l2capinbuf[18] & 0x02)) // Check if fast mode is used
- yawGyroSpeed *= 4.545;
- if(!(l2capinbuf[18] & 0x01)) // Check if fast mode is used
- pitchGyroSpeed *= 4.545;
- 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
- compRoll = (0.93 * (compRoll + (rollGyroSpeed * (double)(micros() - timer) / 1000000)))+(0.07 * getWiimoteRoll());
-
- gyroYaw += (yawGyroSpeed * ((double)(micros() - timer) / 1000000));
- gyroRoll += (rollGyroSpeed * ((double)(micros() - timer) / 1000000));
- gyroPitch += (pitchGyroSpeed * ((double)(micros() - timer) / 1000000));
- timer = micros();
- /*
- // Uncomment these lines to tune the gyro scale variabels
- Notify(PSTR("\r\ngyroYaw: "), 0x80);
- Notify(gyroYaw, 0x80);
- Notify(PSTR("\tgyroRoll: "), 0x80);
- Notify(gyroRoll, 0x80);
- Notify(PSTR("\tgyroPitch: "), 0x80);
- Notify(gyroPitch, 0x80);
- */
- /*
- Notify(PSTR("\twiimoteRoll: "), 0x80);
- Notify(wiimoteRoll, 0x80);
- Notify(PSTR("\twiimotePitch: "), 0x80);
- Notify(wiimotePitch, 0x80);
- */
- } else {
- if((micros() - timer) > 1000000) { // Loop for 1 sec before resetting the values
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nThe gyro values has been reset"), 0x80);
-#endif
- gyroYawZero = (l2capinbuf[15] | ((l2capinbuf[18] & 0xFC) << 6));
- gyroRollZero = (l2capinbuf[16] | ((l2capinbuf[19] & 0xFC) << 6));
- gyroPitchZero = (l2capinbuf[17] | ((l2capinbuf[20] & 0xFC) << 6));
-
- rollGyroScale = 500; // You might need to adjust these
- pitchGyroScale = 400;
- yawGyroScale = 415;
-
- gyroYaw = 0;
- gyroRoll = 0;
- gyroPitch = 0;
-
- motionValuesReset = true;
- timer = micros();
- }
- }
- } else {
- if(nunchuckConnected) {
- hatValues[HatX] = l2capinbuf[15];
- hatValues[HatY] = l2capinbuf[16];
- accXnunchuck = ((l2capinbuf[17] << 2) | (l2capinbuf[20] & 0x10 >> 3)) - 416;
- accYnunchuck = ((l2capinbuf[18] << 2) | (l2capinbuf[20] & 0x20 >> 4)) - 416;
- accZnunchuck = (((l2capinbuf[19] & 0xFE) << 2) | (l2capinbuf[20] & 0xC0 >> 5)) - 416;
- }
- //else if(classicControllerConnected) { }
- }
- if(l2capinbuf[19] & 0x01) {
- if(!extensionConnected) {
- extensionConnected = true;
- unknownExtensionConnected = true;
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nExtension connected to Motion Plus"), 0x80);
-#endif
- }
- } else {
- if(extensionConnected && !unknownExtensionConnected) {
- extensionConnected = false;
- unknownExtensionConnected = true;
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nExtension disconnected from Motion Plus"), 0x80);
-#endif
- nunchuckConnected = false; // There is no extension connected to the Motion Plus if this report is sent
- }
- }
-
- } else if(nunchuckConnected) {
- hatValues[HatX] = l2capinbuf[15];
- hatValues[HatY] = l2capinbuf[16];
- accXnunchuck = ((l2capinbuf[17] << 2) | (l2capinbuf[20] & 0x0C >> 2)) - 416;
- accYnunchuck = ((l2capinbuf[18] << 2) | (l2capinbuf[20] & 0x30 >> 4)) - 416;
- accZnunchuck = ((l2capinbuf[19] << 2) | (l2capinbuf[20] & 0xC0 >> 6)) - 416;
- } else if(wiiUProControllerConnected) {
- hatValues[LeftHatX] = (l2capinbuf[15] | l2capinbuf[16] << 8);
- hatValues[RightHatX] = (l2capinbuf[17] | l2capinbuf[18] << 8);
- hatValues[LeftHatY] = (l2capinbuf[19] | l2capinbuf[20] << 8);
- hatValues[RightHatY] = (l2capinbuf[21] | l2capinbuf[22] << 8);
- }
-#endif
- break;
-#ifdef DEBUG_USB_HOST
- default:
- Notify(PSTR("\r\nUnknown Report type: "), 0x80);
- D_PrintHex (l2capinbuf[9], 0x80);
- break;
-#endif
- }
- }
- }
- L2CAP_task();
- }
-}
-
-void WII::L2CAP_task() {
- switch(l2cap_state) {
- /* These states are used if the Wiimote is the host */
- case L2CAP_CONTROL_SUCCESS:
- if(l2cap_check_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)) {
-#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_check_flag(L2CAP_FLAG_CONNECTION_INTERRUPT_REQUEST)) {
-#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_check_flag(L2CAP_FLAG_CONTROL_CONNECTED)) {
-#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_check_flag(L2CAP_FLAG_CONFIG_CONTROL_SUCCESS)) {
-#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_check_flag(L2CAP_FLAG_INTERRUPT_CONNECTED)) {
-#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_check_flag(L2CAP_FLAG_CONFIG_INTERRUPT_SUCCESS)) { // Now the HID channels is established
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nHID Channels Established"), 0x80);
-#endif
- pBtd->connectToWii = false;
- pBtd->pairWithWii = false;
- stateCounter = 0;
- l2cap_state = WII_CHECK_MOTION_PLUS_STATE;
- }
- break;
-
- /* The next states are in run() */
-
- case L2CAP_INTERRUPT_DISCONNECT:
- if(l2cap_check_flag(L2CAP_FLAG_DISCONNECT_INTERRUPT_RESPONSE) && ((long)(millis() - timer) >= 0L)) {
-#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_check_flag(L2CAP_FLAG_DISCONNECT_CONTROL_RESPONSE)) {
-#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 WII::Run() {
- if(l2cap_state == L2CAP_INTERRUPT_DISCONNECT && ((long)(millis() - timer) >= 0L))
- L2CAP_task(); // Call the rest of the disconnection routine after we have waited long enough
-
- switch(l2cap_state) {
- case L2CAP_WAIT:
- if(pBtd->connectToWii && !pBtd->l2capConnectionClaimed && !wiimoteConnected && !activeConnection) {
- pBtd->l2capConnectionClaimed = true;
- activeConnection = true;
- motionPlusInside = pBtd->motionPlusInside;
-#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_check_flag(L2CAP_FLAG_CONNECTION_CONTROL_REQUEST)) {
-#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;
-
- case WII_CHECK_MOTION_PLUS_STATE:
-#ifdef DEBUG_USB_HOST
- if(stateCounter == 0) // Only print onnce
- Notify(PSTR("\r\nChecking if a Motion Plus is connected"), 0x80);
-#endif
- stateCounter++;
- if(stateCounter % 200 == 0)
- checkMotionPresent(); // Check if there is a motion plus connected
- if(wii_check_flag(WII_FLAG_MOTION_PLUS_CONNECTED)) {
- stateCounter = 0;
- l2cap_state = WII_INIT_MOTION_PLUS_STATE;
- timer = micros();
-
- if(unknownExtensionConnected) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nA extension is also connected"), 0x80);
-#endif
- activateNunchuck = true; // For we will just set this to true as this the only extension supported so far
- }
-
- } else if(stateCounter == 601) { // We will try three times to check for the motion plus
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nNo Motion Plus was detected"), 0x80);
-#endif
- stateCounter = 0;
- l2cap_state = WII_CHECK_EXTENSION_STATE;
- }
- break;
-
- case WII_CHECK_EXTENSION_STATE: // This is used to check if there is anything plugged in to the extension port
-#ifdef DEBUG_USB_HOST
- if(stateCounter == 0) // Only print onnce
- Notify(PSTR("\r\nChecking if there is any extension connected"), 0x80);
-#endif
- stateCounter++; // We use this counter as there has to be a short delay between the commands
- if(stateCounter == 1)
- statusRequest(); // See if a new device has connected
- if(stateCounter == 100) {
- if(unknownExtensionConnected) // Check if there is a extension is connected to the port
- initExtension1();
- else
- stateCounter = 499;
- } else if(stateCounter == 200)
- initExtension2();
- else if(stateCounter == 300) {
- readExtensionType();
- unknownExtensionConnected = false;
- } else if(stateCounter == 400) {
- if(wii_check_flag(WII_FLAG_CALIBRATE_BALANCE_BOARD)) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nReading Wii Balance Board calibration values"), 0x80);
-#endif
- readWiiBalanceBoardCalibration();
- } else
- stateCounter = 499;
- } else if(stateCounter == 500) {
- stateCounter = 0;
- l2cap_state = TURN_ON_LED;
- }
- break;
-
- case WII_INIT_MOTION_PLUS_STATE:
- stateCounter++;
- if(stateCounter == 1)
- initMotionPlus();
- else if(stateCounter == 100)
- activateMotionPlus();
- else if(stateCounter == 200)
- readExtensionType(); // Check if it has been activated
- else if(stateCounter == 300) {
- stateCounter = 0;
- unknownExtensionConnected = false; // The motion plus will send a status report when it's activated, we will set this to false so it doesn't reinitialize the Motion Plus
- l2cap_state = TURN_ON_LED;
- }
- break;
-
- case TURN_ON_LED:
- if(wii_check_flag(WII_FLAG_NUNCHUCK_CONNECTED))
- nunchuckConnected = true;
- wiimoteConnected = true;
- onInit();
- l2cap_state = L2CAP_DONE;
- break;
-
- case L2CAP_DONE:
- if(unknownExtensionConnected) {
-#ifdef DEBUG_USB_HOST
- if(stateCounter == 0) // Only print once
- Notify(PSTR("\r\nChecking extension port"), 0x80);
-#endif
- stateCounter++; // We will use this counter as there has to be a short delay between the commands
- if(stateCounter == 50)
- statusRequest();
- else if(stateCounter == 100)
- initExtension1();
- else if(stateCounter == 150)
- if((extensionConnected && motionPlusConnected) || (unknownExtensionConnected && !motionPlusConnected))
- initExtension2();
- else
- stateCounter = 299; // There is no extension connected
- else if(stateCounter == 200)
- readExtensionType();
- else if(stateCounter == 250) {
- if(wii_check_flag(WII_FLAG_NUNCHUCK_CONNECTED)) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nNunchuck was reconnected"), 0x80);
-#endif
- activateNunchuck = true;
- nunchuckConnected = true;
- }
- if(!motionPlusConnected)
- stateCounter = 449;
- } else if(stateCounter == 300) {
- if(motionPlusConnected) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nReactivating the Motion Plus"), 0x80);
-#endif
- initMotionPlus();
- } else
- stateCounter = 449;
- } else if(stateCounter == 350)
- activateMotionPlus();
- else if(stateCounter == 400)
- readExtensionType(); // Check if it has been activated
- else if(stateCounter == 450) {
- onInit();
- stateCounter = 0;
- unknownExtensionConnected = false;
- }
- } else
- stateCounter = 0;
- break;
- }
-}
-
-/************************************************************/
-/* HID Commands */
-/************************************************************/
-
-void WII::HID_Command(uint8_t* data, uint8_t nbytes) {
- if(motionPlusInside)
- pBtd->L2CAP_Command(hci_handle, data, nbytes, interrupt_scid[0], interrupt_scid[1]); // It's the new Wiimote with the Motion Plus Inside or Wii U Pro controller
- else
- pBtd->L2CAP_Command(hci_handle, data, nbytes, control_scid[0], control_scid[1]);
-}
-
-void WII::setAllOff() {
- HIDBuffer[1] = 0x11;
- HIDBuffer[2] = 0x00;
- HID_Command(HIDBuffer, 3);
-}
-
-void WII::setRumbleOff() {
- HIDBuffer[1] = 0x11;
- HIDBuffer[2] &= ~0x01; // Bit 0 control the rumble
- HID_Command(HIDBuffer, 3);
-}
-
-void WII::setRumbleOn() {
- HIDBuffer[1] = 0x11;
- HIDBuffer[2] |= 0x01; // Bit 0 control the rumble
- HID_Command(HIDBuffer, 3);
-}
-
-void WII::setRumbleToggle() {
- HIDBuffer[1] = 0x11;
- HIDBuffer[2] ^= 0x01; // Bit 0 control the rumble
- HID_Command(HIDBuffer, 3);
-}
-
-void WII::setLedRaw(uint8_t value) {
- HIDBuffer[1] = 0x11;
- HIDBuffer[2] = value | (HIDBuffer[2] & 0x01); // Keep the rumble bit
- HID_Command(HIDBuffer, 3);
-}
-
-void WII::setLedOff(LEDEnum a) {
- HIDBuffer[1] = 0x11;
- HIDBuffer[2] &= ~(pgm_read_byte(&WII_LEDS[(uint8_t)a]));
- HID_Command(HIDBuffer, 3);
-}
-
-void WII::setLedOn(LEDEnum a) {
- if(a == OFF)
- setLedRaw(0);
- else {
- HIDBuffer[1] = 0x11;
- HIDBuffer[2] |= pgm_read_byte(&WII_LEDS[(uint8_t)a]);
- HID_Command(HIDBuffer, 3);
- }
-}
-
-void WII::setLedToggle(LEDEnum a) {
- HIDBuffer[1] = 0x11;
- HIDBuffer[2] ^= pgm_read_byte(&WII_LEDS[(uint8_t)a]);
- HID_Command(HIDBuffer, 3);
-}
-
-void WII::setLedStatus() {
- HIDBuffer[1] = 0x11;
- HIDBuffer[2] = (HIDBuffer[2] & 0x01); // Keep the rumble bit
- if(wiimoteConnected)
- HIDBuffer[2] |= 0x10; // If it's connected LED1 will light up
- if(motionPlusConnected)
- HIDBuffer[2] |= 0x20; // If it's connected LED2 will light up
- if(nunchuckConnected)
- HIDBuffer[2] |= 0x40; // If it's connected LED3 will light up
-
- HID_Command(HIDBuffer, 3);
-}
-
-uint8_t WII::getBatteryLevel() {
- checkBatteryLevel = true; // This is needed so the library knows that the status response is a response to this function
- statusRequest(); // This will update the battery level
- return batteryLevel;
-};
-
-void WII::setReportMode(bool continuous, uint8_t mode) {
- uint8_t cmd_buf[4];
- cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
- cmd_buf[1] = 0x12;
- if(continuous)
- cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01); // Keep the rumble bit
- else
- cmd_buf[2] = 0x00 | (HIDBuffer[2] & 0x01); // Keep the rumble bit
- cmd_buf[3] = mode;
- HID_Command(cmd_buf, 4);
-}
-
-void WII::statusRequest() {
- uint8_t cmd_buf[3];
- cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
- cmd_buf[1] = 0x15;
- cmd_buf[2] = (HIDBuffer[2] & 0x01); // Keep the rumble bit
- HID_Command(cmd_buf, 3);
-}
-
-/************************************************************/
-/* Memmory Commands */
-/************************************************************/
-
-void WII::writeData(uint32_t offset, uint8_t size, uint8_t* data) {
- uint8_t cmd_buf[23];
- cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
- cmd_buf[1] = 0x16; // Write data
- cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01); // Write to memory, clear bit 2 to write to EEPROM
- cmd_buf[3] = (uint8_t)((offset & 0xFF0000) >> 16);
- cmd_buf[4] = (uint8_t)((offset & 0xFF00) >> 8);
- cmd_buf[5] = (uint8_t)(offset & 0xFF);
- cmd_buf[6] = size;
- uint8_t i = 0;
- for(; i < size; i++)
- cmd_buf[7 + i] = data[i];
- for(; i < 16; i++) // Set the rest to zero
- cmd_buf[7 + i] = 0x00;
- HID_Command(cmd_buf, 23);
-}
-
-void WII::initExtension1() {
- uint8_t buf[1];
- buf[0] = 0x55;
- writeData(0xA400F0, 1, buf);
-}
-
-void WII::initExtension2() {
- uint8_t buf[1];
- buf[0] = 0x00;
- writeData(0xA400FB, 1, buf);
-}
-
-void WII::initMotionPlus() {
- uint8_t buf[1];
- buf[0] = 0x55;
- writeData(0xA600F0, 1, buf);
-}
-
-void WII::activateMotionPlus() {
- uint8_t buf[1];
- if(pBtd->wiiUProController) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nActivating Wii U Pro Controller"), 0x80);
-#endif
- buf[0] = 0x00; // It seems like you can send anything but 0x04, 0x05, and 0x07
- } else if(activateNunchuck) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nActivating Motion Plus in pass-through mode"), 0x80);
-#endif
- buf[0] = 0x05; // Activate nunchuck pass-through mode
- }//else if(classicControllerConnected && extensionConnected)
- //buf[0] = 0x07;
- else {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nActivating Motion Plus in normal mode"), 0x80);
-#endif
- buf[0] = 0x04; // Don't use any extension
- }
- writeData(0xA600FE, 1, buf);
-}
-
-void WII::readData(uint32_t offset, uint16_t size, bool EEPROM) {
- uint8_t cmd_buf[8];
- cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
- cmd_buf[1] = 0x17; // Read data
- if(EEPROM)
- cmd_buf[2] = 0x00 | (HIDBuffer[2] & 0x01); // Read from EEPROM
- else
- cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01); // Read from memory
- cmd_buf[3] = (uint8_t)((offset & 0xFF0000) >> 16);
- cmd_buf[4] = (uint8_t)((offset & 0xFF00) >> 8);
- cmd_buf[5] = (uint8_t)(offset & 0xFF);
- cmd_buf[6] = (uint8_t)((size & 0xFF00) >> 8);
- cmd_buf[7] = (uint8_t)(size & 0xFF);
-
- HID_Command(cmd_buf, 8);
-}
-
-void WII::readExtensionType() {
- readData(0xA400FA, 6, false);
-}
-
-void WII::readCalData() {
- readData(0x0016, 8, true);
-}
-
-void WII::checkMotionPresent() {
- readData(0xA600FA, 6, false);
-}
-
-void WII::readWiiBalanceBoardCalibration() {
- readData(0xA40024, 24, false);
-}
-
-/************************************************************/
-/* WII Commands */
-/************************************************************/
-
-bool WII::getButtonPress(ButtonEnum b) { // Return true when a button is pressed
- if(wiiUProControllerConnected)
- return (ButtonState & pgm_read_dword(&WII_PROCONTROLLER_BUTTONS[(uint8_t)b]));
- else
- return (ButtonState & pgm_read_dword(&WII_BUTTONS[(uint8_t)b]));
-}
-
-bool WII::getButtonClick(ButtonEnum b) { // Only return true when a button is clicked
- uint32_t button;
- if(wiiUProControllerConnected)
- button = pgm_read_dword(&WII_PROCONTROLLER_BUTTONS[(uint8_t)b]);
- else
- button = pgm_read_dword(&WII_BUTTONS[(uint8_t)b]);
- bool click = (ButtonClickState & button);
- ButtonClickState &= ~button; // clear "click" event
- return click;
-}
-
-uint8_t WII::getAnalogHat(HatEnum a) {
- if(!nunchuckConnected)
- return 127; // Return center position
- else {
- uint8_t output = hatValues[(uint8_t)a];
- if(output == 0xFF || output == 0x00) // The joystick will only read 255 or 0 when the cable is unplugged or initializing, so we will just return the center position
- return 127;
- else
- return output;
- }
-}
-
-uint16_t WII::getAnalogHat(AnalogHatEnum a) {
- if(!wiiUProControllerConnected)
- return 2000;
- else {
- uint16_t output = hatValues[(uint8_t)a];
- if(output == 0x00) // The joystick will only read 0 when it is first initializing, so we will just return the center position
- return 2000;
- else
- return output;
- }
-}
-
-void WII::onInit() {
- if(pFuncOnInit)
- pFuncOnInit(); // Call the user function
- else
- setLedStatus();
-}
-
-/************************************************************/
-/* Wii Balance Board Commands */
-/************************************************************/
-
-float WII::getWeight(BalanceBoardEnum pos) {
- // Use interpolating between two points - based on: https://github.com/skorokithakis/gr8w8upd8m8/blob/master/gr8w8upd8m8.py
- // wiiBalanceBoardCal[pos][0] is calibration values for 0 kg
- // wiiBalanceBoardCal[pos][1] is calibration values for 17 kg
- // wiiBalanceBoardCal[pos][2] is calibration values for 34 kg
- if(wiiBalanceBoardRaw[pos] < wiiBalanceBoardCal[0][pos])
- return 0.0f; // Below 0 kg
- else if(wiiBalanceBoardRaw[pos] < wiiBalanceBoardCal[1][pos]) // Between 0 and 17 kg
- return 17.0f * (float)(wiiBalanceBoardRaw[pos] - wiiBalanceBoardCal[0][pos]) / (float)(wiiBalanceBoardCal[1][pos] - wiiBalanceBoardCal[0][pos]);
- else // More than 17 kg
- return 17.0f + 17.0f * (float)(wiiBalanceBoardRaw[pos] - wiiBalanceBoardCal[1][pos]) / (float)(wiiBalanceBoardCal[2][pos] - wiiBalanceBoardCal[1][pos]);
-};
-
-float WII::getTotalWeight() {
- return getWeight(TopRight) + getWeight(BotRight) + getWeight(TopLeft) + getWeight(BotLeft);
-};
-
-/************************************************************/
-/* The following functions are for the IR camera */
-/************************************************************/
-
-#ifdef WIICAMERA
-
-void WII::IRinitialize() { // Turns on and initialises the IR camera
-
- enableIRCamera1();
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nEnable IR Camera1 Complete"), 0x80);
-#endif
- delay(80);
-
- enableIRCamera2();
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nEnable IR Camera2 Complete"), 0x80);
-#endif
- delay(80);
-
- write0x08Value();
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nWrote hex number 0x08"), 0x80);
-#endif
- delay(80);
-
- writeSensitivityBlock1();
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nWrote Sensitivity Block 1"), 0x80);
-#endif
- delay(80);
-
- writeSensitivityBlock2();
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nWrote Sensitivity Block 2"), 0x80);
-#endif
- delay(80);
-
- uint8_t mode_num = 0x03;
- setWiiModeNumber(mode_num); // Change input for whatever mode you want i.e. 0x01, 0x03, or 0x05
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nSet Wii Mode Number To 0x"), 0x80);
- D_PrintHex (mode_num, 0x80);
-#endif
- delay(80);
-
- write0x08Value();
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nWrote Hex Number 0x08"), 0x80);
-#endif
- delay(80);
-
- setReportMode(false, 0x33);
- //setReportMode(false, 0x3f); // For full reporting mode, doesn't work yet
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nSet Report Mode to 0x33"), 0x80);
-#endif
- delay(80);
-
- statusRequest(); // Used to update wiiState - call isIRCameraEnabled() afterwards to check if it actually worked
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nIR Initialized"), 0x80);
-#endif
-}
-
-void WII::enableIRCamera1() {
- uint8_t cmd_buf[3];
- cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
- cmd_buf[1] = 0x13; // Output report 13
- cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01); // Keep the rumble bit and sets bit 2
- HID_Command(cmd_buf, 3);
-}
-
-void WII::enableIRCamera2() {
- uint8_t cmd_buf[3];
- cmd_buf[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
- cmd_buf[1] = 0x1A; // Output report 1A
- cmd_buf[2] = 0x04 | (HIDBuffer[2] & 0x01); // Keep the rumble bit and sets bit 2
- HID_Command(cmd_buf, 3);
-}
-
-void WII::writeSensitivityBlock1() {
- uint8_t buf[9];
- buf[0] = 0x00;
- buf[1] = 0x00;
- buf[2] = 0x00;
- buf[3] = 0x00;
- buf[4] = 0x00;
- buf[5] = 0x00;
- buf[6] = 0x90;
- buf[7] = 0x00;
- buf[8] = 0x41;
-
- writeData(0xB00000, 9, buf);
-}
-
-void WII::writeSensitivityBlock2() {
- uint8_t buf[2];
- buf[0] = 0x40;
- buf[1] = 0x00;
-
- writeData(0xB0001A, 2, buf);
-}
-
-void WII::write0x08Value() {
- uint8_t cmd = 0x08;
- writeData(0xb00030, 1, &cmd);
-}
-
-void WII::setWiiModeNumber(uint8_t mode_number) { // mode_number in hex i.e. 0x03 for extended mode
- writeData(0xb00033, 1, &mode_number);
-}
-#endif
diff --git a/lib/usbhost/USB_Host_Shield_2.0/Wii.h b/lib/usbhost/USB_Host_Shield_2.0/Wii.h
deleted file mode 100644
index 960f2273de8c..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/Wii.h
+++ /dev/null
@@ -1,518 +0,0 @@
-/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
-
- This software may be distributed and modified under the terms of the GNU
- General Public License version 2 (GPL2) as published by the Free Software
- Foundation and appearing in the file GPL2.TXT included in the packaging of
- this file. Please note that GPL2 Section 2[b] requires that all works based
- on this software must also be made publicly available under the terms of
- the GPL2 ("Copyleft").
-
- Contact information
- -------------------
-
- Kristian Lauszus, TKJ Electronics
- Web : http://www.tkjelectronics.com
- e-mail : kristianl@tkjelectronics.com
-
- IR camera support added by Allan Glover (adglover9.81@gmail.com) and Kristian Lauszus
- */
-
-#ifndef _wii_h_
-#define _wii_h_
-
-#include "BTD.h"
-#include "controllerEnums.h"
-
-/* Wii event flags */
-#define WII_FLAG_MOTION_PLUS_CONNECTED (1 << 0)
-#define WII_FLAG_NUNCHUCK_CONNECTED (1 << 1)
-#define WII_FLAG_CALIBRATE_BALANCE_BOARD (1 << 2)
-
-#define wii_check_flag(flag) (wii_event_flag & (flag))
-#define wii_set_flag(flag) (wii_event_flag |= (flag))
-#define wii_clear_flag(flag) (wii_event_flag &= ~(flag))
-
-/** Enum used to read the joystick on the Nunchuck. */
-enum HatEnum {
- /** Read the x-axis on the Nunchuck joystick. */
- HatX = 0,
- /** Read the y-axis on the Nunchuck joystick. */
- HatY = 1,
-};
-
-/** Enum used to read the weight on Wii Balance Board. */
-enum BalanceBoardEnum {
- TopRight = 0,
- BotRight = 1,
- TopLeft = 2,
- BotLeft = 3,
-};
-
-/**
- * This BluetoothService class implements support for the Wiimote including the Nunchuck and Motion Plus extension.
- *
- * It also support the Wii U Pro Controller.
- */
-class WII : public BluetoothService {
-public:
- /**
- * Constructor for the WII class.
- * @param p Pointer to BTD class instance.
- * @param pair Set this to true in order to pair with the Wiimote. If the argument is omitted then it won't pair with it.
- * One can use ::PAIR to set it to true.
- */
- WII(BTD *p, bool pair = false);
-
- /** @name BluetoothService implementation */
- /** Used this to disconnect any of the controllers. */
- void disconnect();
- /**@}*/
-
- /** @name Wii Controller 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).
- * @param b ::ButtonEnum to read.
- * @return getButtonPress(ButtonEnum b) will return a true as long as a button is held down, while getButtonClick(ButtonEnum b) will return true once for each button press.
- */
- bool getButtonPress(ButtonEnum b);
- bool getButtonClick(ButtonEnum b);
- /**@}*/
-
- /** @name Wii Controller functions */
-
- /** Call this to start the paring sequence with a controller */
- void pair(void) {
- if(pBtd)
- pBtd->pairWithWiimote();
- };
- /**
- * Used to read the joystick of the Nunchuck.
- * @param a Either ::HatX or ::HatY.
- * @return Return the analog value in the range from approximately 25-230.
- */
- uint8_t getAnalogHat(HatEnum a);
- /**
- * Used to read the joystick of the Wii U Pro Controller.
- * @param a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY.
- * @return Return the analog value in the range from approximately 800-3200.
- */
- uint16_t getAnalogHat(AnalogHatEnum a);
-
- /**
- * Pitch calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected.
- * @return Pitch in the range from 0-360.
- */
- double getPitch() {
- if(motionPlusConnected)
- return compPitch;
- return getWiimotePitch();
- };
-
- /**
- * Roll calculated from the Wiimote. A complimentary filter is used if the Motion Plus is connected.
- * @return Roll in the range from 0-360.
- */
- double getRoll() {
- if(motionPlusConnected)
- return compRoll;
- return getWiimoteRoll();
- };
-
- /**
- * This is the yaw calculated by the gyro.
- *
- * NOTE: This angle will drift a lot and is only available if the Motion Plus extension is connected.
- * @return The angle calculated using the gyro.
- */
- double getYaw() {
- return gyroYaw;
- };
-
- /** Used to set all LEDs and rumble off. */
- void setAllOff();
- /** Turn off rumble. */
- void setRumbleOff();
- /** Turn on rumble. */
- void setRumbleOn();
- /** Toggle rumble. */
- void setRumbleToggle();
-
- /**
- * Set LED value without using the ::LEDEnum.
- * @param value See: ::LEDEnum.
- */
- void setLedRaw(uint8_t value);
-
- /** Turn all LEDs off. */
- void setLedOff() {
- setLedRaw(0);
- };
- /**
- * Turn the specific ::LEDEnum off.
- * @param a The ::LEDEnum to turn off.
- */
- void setLedOff(LEDEnum a);
- /**
- * Turn the specific ::LEDEnum on.
- * @param a The ::LEDEnum to turn on.
- */
- void setLedOn(LEDEnum a);
- /**
- * Toggle the specific ::LEDEnum.
- * @param a The ::LEDEnum to toggle.
- */
- void setLedToggle(LEDEnum a);
- /**
- * This will set the LEDs, so the user can see which connections are active.
- *
- * The first ::LEDEnum indicate that the Wiimote is connected,
- * the second ::LEDEnum indicate indicate that a Motion Plus is also connected
- * the third ::LEDEnum will indicate that a Nunchuck controller is also connected.
- */
- void setLedStatus();
-
- /**
- * Return the battery level of the Wiimote.
- * @return The battery level in the range 0-255.
- */
- uint8_t getBatteryLevel();
-
- /**
- * Return the Wiimote state.
- * @return See: http://wiibrew.org/wiki/Wiimote#0x20:_Status.
- */
- uint8_t getWiiState() {
- return wiiState;
- };
- /**@}*/
-
- /**@{*/
- /** Variable used to indicate if a Wiimote is connected. */
- bool wiimoteConnected;
- /** Variable used to indicate if a Nunchuck controller is connected. */
- bool nunchuckConnected;
- /** Variable used to indicate if a Nunchuck controller is connected. */
- bool motionPlusConnected;
- /** Variable used to indicate if a Wii U Pro controller is connected. */
- bool wiiUProControllerConnected;
- /** Variable used to indicate if a Wii Balance Board is connected. */
- bool wiiBalanceBoardConnected;
- /**@}*/
-
- /* IMU Data, might be usefull if you need to do something more advanced than just calculating the angle */
-
- /**@{*/
-
- /** Pitch and roll calculated from the accelerometer inside the Wiimote. */
- double getWiimotePitch() {
- return (atan2(accYwiimote, accZwiimote) + PI) * RAD_TO_DEG;
- };
-
- double getWiimoteRoll() {
- return (atan2(accXwiimote, accZwiimote) + PI) * RAD_TO_DEG;
- };
- /**@}*/
-
- /**@{*/
-
- /** Pitch and roll calculated from the accelerometer inside the Nunchuck. */
- double getNunchuckPitch() {
- return (atan2(accYnunchuck, accZnunchuck) + PI) * RAD_TO_DEG;
- };
-
- double getNunchuckRoll() {
- return (atan2(accXnunchuck, accZnunchuck) + PI) * RAD_TO_DEG;
- };
- /**@}*/
-
- /**@{*/
- /** Accelerometer values used to calculate pitch and roll. */
- int16_t accXwiimote, accYwiimote, accZwiimote;
- int16_t accXnunchuck, accYnunchuck, accZnunchuck;
- /**@}*/
-
- /* Variables for the gyro inside the Motion Plus */
- /** This is the pitch calculated by the gyro - use this to tune WII#pitchGyroScale. */
- double gyroPitch;
- /** This is the roll calculated by the gyro - use this to tune WII#rollGyroScale. */
- double gyroRoll;
- /** This is the yaw calculated by the gyro - use this to tune WII#yawGyroScale. */
- double gyroYaw;
-
- /**@{*/
- /** The speed in deg/s from the gyro. */
- double pitchGyroSpeed;
- double rollGyroSpeed;
- double yawGyroSpeed;
- /**@}*/
-
- /**@{*/
- /** You might need to fine-tune these values. */
- uint16_t pitchGyroScale;
- uint16_t rollGyroScale;
- uint16_t yawGyroScale;
- /**@}*/
-
- /**@{*/
- /** Raw value read directly from the Motion Plus. */
- int16_t gyroYawRaw;
- int16_t gyroRollRaw;
- int16_t gyroPitchRaw;
- /**@}*/
-
- /**@{*/
- /** These values are set when the controller is first initialized. */
- int16_t gyroYawZero;
- int16_t gyroRollZero;
- int16_t gyroPitchZero;
- /**@}*/
-
- /** @name Wii Balance Board functions */
-
- /**
- * Used to get the weight at the specific position on the Wii Balance Board.
- * @param ::BalanceBoardEnum to read from.
- * @return Returns the weight in kg.
- */
- float getWeight(BalanceBoardEnum pos);
-
- /**
- * Used to get total weight on the Wii Balance Board.
- * @returnReturns the weight in kg.
- */
- float getTotalWeight();
-
- /**
- * Used to get the raw reading at the specific position on the Wii Balance Board.
- * @param ::BalanceBoardEnum to read from.
- * @return Returns the raw reading.
- */
- uint16_t getWeightRaw(BalanceBoardEnum pos) {
- return wiiBalanceBoardRaw[pos];
- };
- /**@}*/
-
-#ifdef WIICAMERA
- /** @name Wiimote IR camera functions
- * You will have to set ::ENABLE_WII_IR_CAMERA in settings.h to 1 in order use the IR camera.
- */
- /** Initialises the camera as per the steps from: http://wiibrew.org/wiki/Wiimote#IR_Camera */
- void IRinitialize();
-
- /**
- * IR object 1 x-position read from the Wii IR camera.
- * @return The x-position of the object in the range 0-1023.
- */
- uint16_t getIRx1() {
- return IR_object_x1;
- };
-
- /**
- * IR object 1 y-position read from the Wii IR camera.
- * @return The y-position of the object in the range 0-767.
- */
- uint16_t getIRy1() {
- return IR_object_y1;
- };
-
- /**
- * IR object 1 size read from the Wii IR camera.
- * @return The size of the object in the range 0-15.
- */
- uint8_t getIRs1() {
- return IR_object_s1;
- };
-
- /**
- * IR object 2 x-position read from the Wii IR camera.
- * @return The x-position of the object in the range 0-1023.
- */
- uint16_t getIRx2() {
- return IR_object_x2;
- };
-
- /**
- * IR object 2 y-position read from the Wii IR camera.
- * @return The y-position of the object in the range 0-767.
- */
- uint16_t getIRy2() {
- return IR_object_y2;
- };
-
- /**
- * IR object 2 size read from the Wii IR camera.
- * @return The size of the object in the range 0-15.
- */
- uint8_t getIRs2() {
- return IR_object_s2;
- };
-
- /**
- * IR object 3 x-position read from the Wii IR camera.
- * @return The x-position of the object in the range 0-1023.
- */
- uint16_t getIRx3() {
- return IR_object_x3;
- };
-
- /**
- * IR object 3 y-position read from the Wii IR camera.
- * @return The y-position of the object in the range 0-767.
- */
- uint16_t getIRy3() {
- return IR_object_y3;
- };
-
- /**
- * IR object 3 size read from the Wii IR camera.
- * @return The size of the object in the range 0-15.
- */
- uint8_t getIRs3() {
- return IR_object_s3;
- };
-
- /**
- * IR object 4 x-position read from the Wii IR camera.
- * @return The x-position of the object in the range 0-1023.
- */
- uint16_t getIRx4() {
- return IR_object_x4;
- };
-
- /**
- * IR object 4 y-position read from the Wii IR camera.
- * @return The y-position of the object in the range 0-767.
- */
- uint16_t getIRy4() {
- return IR_object_y4;
- };
-
- /**
- * IR object 4 size read from the Wii IR camera.
- * @return The size of the object in the range 0-15.
- */
- uint8_t getIRs4() {
- return IR_object_s4;
- };
-
- /**
- * Use this to check if the camera is enabled or not.
- * If not call WII#IRinitialize to initialize the IR camera.
- * @return True if it's enabled, false if not.
- */
- bool isIRCameraEnabled() {
- return (wiiState & 0x08);
- };
- /**@}*/
-#endif
-
-protected:
- /** @name BluetoothService implementation */
- /**
- * Used to pass acldata to the services.
- * @param ACLData Incoming acldata.
- */
- void ACLData(uint8_t* ACLData);
- /** Used to run part of the state machine. */
- void Run();
- /** Use this to reset the service. */
- void Reset();
- /**
- * 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();
- /**@}*/
-
-private:
-
- void L2CAP_task(); // L2CAP state machine
-
- /* Variables filled from HCI event management */
- 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 wii_event_flag; // Used for Wii flags
-
- uint32_t ButtonState;
- uint32_t OldButtonState;
- uint32_t ButtonClickState;
- uint16_t hatValues[4];
-
- uint8_t HIDBuffer[3]; // Used to store HID commands
-
- uint16_t stateCounter;
- bool unknownExtensionConnected;
- bool extensionConnected;
- bool checkBatteryLevel; // Set to true when getBatteryLevel() is called otherwise if should be false
- bool motionPlusInside; // True if it's a new Wiimote with the Motion Plus extension build into it
-
- /* L2CAP Channels */
- uint8_t control_scid[2]; // L2CAP source CID for HID_Control
- uint8_t control_dcid[2]; // 0x0060
- uint8_t interrupt_scid[2]; // L2CAP source CID for HID_Interrupt
- uint8_t interrupt_dcid[2]; // 0x0061
-
- /* HID Commands */
- void HID_Command(uint8_t* data, uint8_t nbytes);
- void setReportMode(bool continuous, uint8_t mode);
-
- void writeData(uint32_t offset, uint8_t size, uint8_t* data);
- void initExtension1();
- void initExtension2();
-
- void statusRequest(); // Used to update the Wiimote state and battery level
-
- void readData(uint32_t offset, uint16_t size, bool EEPROM);
- void readExtensionType();
- void readCalData();
- void readWiiBalanceBoardCalibration(); // Used by the library to read the Wii Balance Board calibration values
-
- void checkMotionPresent(); // Used to see if a Motion Plus is connected to the Wiimote
- void initMotionPlus();
- void activateMotionPlus();
-
- uint16_t wiiBalanceBoardRaw[4]; // Wii Balance Board raw values
- uint16_t wiiBalanceBoardCal[3][4]; // Wii Balance Board calibration values
-
- double compPitch; // Fusioned angle using a complimentary filter if the Motion Plus is connected
- double compRoll; // Fusioned angle using a complimentary filter if the Motion Plus is connected
-
- bool activateNunchuck;
- bool motionValuesReset; // This bool is true when the gyro values has been reset
- uint32_t timer;
-
- uint8_t wiiState; // Stores the value in l2capinbuf[12] - (0x01: Battery is nearly empty), (0x02: An Extension Controller is connected), (0x04: Speaker enabled), (0x08: IR enabled), (0x10: LED1, 0x20: LED2, 0x40: LED3, 0x80: LED4)
- uint8_t batteryLevel;
-
-#ifdef WIICAMERA
- /* Private function and variables for the readings from the IR Camera */
- void enableIRCamera1(); // Sets bit 2 of output report 13
- void enableIRCamera2(); // Sets bit 2 of output report 1A
- void writeSensitivityBlock1();
- void writeSensitivityBlock2();
- void write0x08Value();
- void setWiiModeNumber(uint8_t mode_number);
-
- uint16_t IR_object_x1; // IR x position 10 bits
- uint16_t IR_object_y1; // IR y position 10 bits
- uint8_t IR_object_s1; // IR size value
- uint16_t IR_object_x2;
- uint16_t IR_object_y2;
- uint8_t IR_object_s2;
- uint16_t IR_object_x3; // IR x position 10 bits
- uint16_t IR_object_y3; // IR y position 10 bits
- uint8_t IR_object_s3; // IR size value
- uint16_t IR_object_x4;
- uint16_t IR_object_y4;
- uint8_t IR_object_s4;
-#endif
-};
-#endif
diff --git a/lib/usbhost/USB_Host_Shield_2.0/WiiCameraReadme.md b/lib/usbhost/USB_Host_Shield_2.0/WiiCameraReadme.md
deleted file mode 100644
index 8577d73fb317..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/WiiCameraReadme.md
+++ /dev/null
@@ -1,13 +0,0 @@
-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.
-
-This library is large, if you run into memory problems when uploading to the Arduino, disable serial debugging.
-
-To enable the IR camera code, simply set ```ENABLE_WII_IR_CAMERA``` to 1 in [settings.h](settings.h).
-
-This library implements the following settings:
-
-* Report sensitivity mode: 00 00 00 00 00 00 90 00 41 40 00 Suggested by inio (high sensitivity)
-* Data Format: Extended mode (0x03). Full mode is not working yet. The output reports 0x3e and 0x3f need tampering with
- * In this mode the camera outputs x and y coordinates and a size dimension for the 4 brightest points.
-
-Again, read through to get an understanding of the camera and its settings.
diff --git a/lib/usbhost/USB_Host_Shield_2.0/XBOXOLD.cpp b/lib/usbhost/USB_Host_Shield_2.0/XBOXOLD.cpp
deleted file mode 100644
index 78e6e9a5f509..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/XBOXOLD.cpp
+++ /dev/null
@@ -1,337 +0,0 @@
-/* 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 "XBOXOLD.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
-
-/** Buttons on the controllers */
-const uint8_t XBOXOLD_BUTTONS[] PROGMEM = {
- 0x01, // UP
- 0x08, // RIGHT
- 0x02, // DOWN
- 0x04, // LEFT
-
- 0x20, // BACK
- 0x10, // START
- 0x40, // L3
- 0x80, // R3
-
- // A, B, X, Y, BLACK, WHITE, L1, and R1 are analog buttons
- 4, // BLACK
- 5, // WHTIE
- 6, // L1
- 7, // R1
-
- 1, // B
- 0, // A
- 2, // X
- 3, // Y
-};
-
-XBOXOLD::XBOXOLD(USB *p) :
-pUsb(p), // pointer to USB class instance - mandatory
-bAddress(0), // device address - mandatory
-bPollEnable(false) { // don't start polling before dongle is connected
- for(uint8_t i = 0; i < XBOX_MAX_ENDPOINTS; i++) {
- epInfo[i].epAddr = 0;
- epInfo[i].maxPktSize = (i) ? 0 : 8;
- epInfo[i].epAttribs = 0;
- epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
- }
-
- if(pUsb) // register in USB subsystem
- pUsb->RegisterDeviceClass(this); //set devConfig[] entry
-}
-
-uint8_t XBOXOLD::Init(uint8_t parent, uint8_t port, bool lowspeed) {
- uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
- USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf);
- uint8_t rcode;
- UsbDevice *p = NULL;
- EpInfo *oldep_ptr = NULL;
- uint16_t PID;
- uint16_t VID;
-
- // get memory address of USB device address pool
- AddressPool &addrPool = pUsb->GetAddressPool();
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nXBOXUSB Init"), 0x80);
-#endif
- // check if address has already been assigned to an instance
- if(bAddress) {
-#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);
-
- if(!p) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nAddress not found"), 0x80);
-#endif
- return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
- }
-
- if(!p->epinfo) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nepinfo is null"), 0x80);
-#endif
- return USB_ERROR_EPINFO_IS_NULL;
- }
-
- // Save old pointer to EP_RECORD of address 0
- oldep_ptr = p->epinfo;
-
- // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
- p->epinfo = epInfo;
-
- p->lowspeed = lowspeed;
-
- // Get device descriptor
- rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
- // Restore p->epinfo
- p->epinfo = oldep_ptr;
-
- if(rcode)
- goto FailGetDevDescr;
-
- VID = udd->idVendor;
- PID = udd->idProduct;
-
- 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);
-
- if(!bAddress)
- return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
-
- // Extract Max Packet Size from device descriptor
- epInfo[0].maxPktSize = udd->bMaxPacketSize0;
-
- // Assign new address to the device
- rcode = pUsb->setAddr(0, 0, bAddress);
- if(rcode) {
- p->lowspeed = false;
- addrPool.FreeAddress(bAddress);
- bAddress = 0;
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nsetAddr: "), 0x80);
- D_PrintHex (rcode, 0x80);
-#endif
- return rcode;
- }
-#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)
- return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
-
- p->lowspeed = lowspeed;
-
- // Assign epInfo to epinfo pointer - only EP0 is known
- rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
- if(rcode)
- goto FailSetDevTblEntry;
-
- /* The application will work in reduced host mode, so we can save program and data
- memory space. After verifying the VID we will use known values for the
- configuration values for device, interface, endpoints and HID for the XBOX controllers */
-
- /* Initialize data structures for endpoints of device */
- epInfo[ XBOX_INPUT_PIPE ].epAddr = 0x01; // XBOX report endpoint
- epInfo[ XBOX_INPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
- epInfo[ XBOX_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
- epInfo[ XBOX_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
- epInfo[ XBOX_INPUT_PIPE ].bmSndToggle = 0;
- epInfo[ XBOX_INPUT_PIPE ].bmRcvToggle = 0;
- epInfo[ XBOX_OUTPUT_PIPE ].epAddr = 0x02; // XBOX output endpoint
- epInfo[ XBOX_OUTPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
- epInfo[ XBOX_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
- epInfo[ XBOX_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
- epInfo[ XBOX_OUTPUT_PIPE ].bmSndToggle = 0;
- epInfo[ XBOX_OUTPUT_PIPE ].bmRcvToggle = 0;
-
- rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
- if(rcode)
- goto FailSetDevTblEntry;
-
- delay(200); // Give time for address change
-
- rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
- if(rcode)
- goto FailSetConfDescr;
-
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nXbox Controller Connected\r\n"), 0x80);
-#endif
- if(pFuncOnInit)
- pFuncOnInit(); // Call the user function
- XboxConnected = true;
- bPollEnable = true;
- return 0; // Successful configuration
-
- /* Diagnostic messages */
-FailGetDevDescr:
-#ifdef DEBUG_USB_HOST
- NotifyFailGetDevDescr();
- goto Fail;
-#endif
-
-FailSetDevTblEntry:
-#ifdef DEBUG_USB_HOST
- NotifyFailSetDevTblEntry();
- goto Fail;
-#endif
-
-FailSetConfDescr:
-#ifdef DEBUG_USB_HOST
- NotifyFailSetConfDescr();
-#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 Init Failed, error code: "), 0x80);
- NotifyFail(rcode);
-#endif
- Release();
- return rcode;
-}
-
-/* Performs a cleanup after failed Init() attempt */
-uint8_t XBOXOLD::Release() {
- XboxConnected = false;
- pUsb->GetAddressPool().FreeAddress(bAddress);
- bAddress = 0;
- bPollEnable = false;
- return 0;
-}
-
-uint8_t XBOXOLD::Poll() {
- if(!bPollEnable)
- return 0;
- uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
- pUsb->inTransfer(bAddress, epInfo[ XBOX_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
- readReport();
-#ifdef PRINTREPORT
- printReport(BUFFER_SIZE); // Uncomment "#define PRINTREPORT" to print the report send by the Xbox controller
-#endif
- return 0;
-}
-
-void XBOXOLD::readReport() {
- ButtonState = readBuf[2];
-
- for(uint8_t i = 0; i < sizeof (buttonValues); i++)
- buttonValues[i] = readBuf[i + 4]; // A, B, X, Y, BLACK, WHITE, L1, and R1
-
- hatValue[LeftHatX] = (int16_t)(((uint16_t)readBuf[12] << 8) | readBuf[13]);
- hatValue[LeftHatY] = (int16_t)(((uint16_t)readBuf[14] << 8) | readBuf[15]);
- hatValue[RightHatX] = (int16_t)(((uint16_t)readBuf[16] << 8) | readBuf[17]);
- hatValue[RightHatY] = (int16_t)(((uint16_t)readBuf[18] << 8) | readBuf[19]);
-
- //Notify(PSTR("\r\nButtonState"), 0x80);
- //PrintHex(ButtonState, 0x80);
-
- if(ButtonState != OldButtonState || memcmp(buttonValues, oldButtonValues, sizeof (buttonValues)) != 0) {
- ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
- OldButtonState = ButtonState;
-
- for(uint8_t i = 0; i < sizeof (buttonValues); i++) {
- if(oldButtonValues[i] == 0 && buttonValues[i] != 0)
- buttonClicked[i] = true; // Update A, B, X, Y, BLACK, WHITE, L1, and R1 click state
- oldButtonValues[i] = buttonValues[i];
- }
- }
-}
-
-void XBOXOLD::printReport(uint16_t length) { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox controller
-#ifdef PRINTREPORT
- if(readBuf == NULL)
- return;
- for(uint8_t i = 0; i < length; i++) {
- D_PrintHex (readBuf[i], 0x80);
- Notify(PSTR(" "), 0x80);
- }
- Notify(PSTR("\r\n"), 0x80);
-#endif
-}
-
-uint8_t XBOXOLD::getButtonPress(ButtonEnum b) {
- uint8_t button = pgm_read_byte(&XBOXOLD_BUTTONS[(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[button]; // Analog buttons
- return (ButtonState & button); // Digital buttons
-}
-
-bool XBOXOLD::getButtonClick(ButtonEnum b) {
- uint8_t button = pgm_read_byte(&XBOXOLD_BUTTONS[(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
- if(buttonClicked[button]) {
- buttonClicked[button] = false;
- return true;
- }
- return false;
- }
-
- bool click = (ButtonClickState & button);
- ButtonClickState &= ~button; // clear "click" event
- return click;
-}
-
-int16_t XBOXOLD::getAnalogHat(AnalogHatEnum a) {
- return hatValue[a];
-}
-
-/* Xbox Controller commands */
-void XBOXOLD::XboxCommand(uint8_t* data, uint16_t nbytes) {
- //bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x00), Report Type (Output 0x02), interface (0x00), datalength, datalength, data)
- pUsb->ctrlReq(bAddress, epInfo[XBOX_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x00, 0x02, 0x00, nbytes, nbytes, data, NULL);
-}
-
-void XBOXOLD::setRumbleOn(uint8_t lValue, uint8_t rValue) {
- uint8_t writeBuf[6];
-
- writeBuf[0] = 0x00;
- writeBuf[1] = 0x06;
- writeBuf[2] = 0x00;
- writeBuf[3] = rValue; // small weight
- writeBuf[4] = 0x00;
- writeBuf[5] = lValue; // big weight
-
- XboxCommand(writeBuf, 6);
-}
diff --git a/lib/usbhost/USB_Host_Shield_2.0/XBOXOLD.h b/lib/usbhost/USB_Host_Shield_2.0/XBOXOLD.h
deleted file mode 100644
index 9a36b5ccaca2..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/XBOXOLD.h
+++ /dev/null
@@ -1,185 +0,0 @@
-/* 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 _xboxold_h_
-#define _xboxold_h_
-
-#include "Usb.h"
-#include "hid.h"
-#include "controllerEnums.h"
-
-/* Data Xbox taken from descriptors */
-#define EP_MAXPKTSIZE 32 // Max size for data via USB
-
-/* Names we give to the 3 Xbox pipes */
-#define XBOX_CONTROL_PIPE 0
-#define XBOX_INPUT_PIPE 1
-#define XBOX_OUTPUT_PIPE 2
-
-// PID and VID of the different devices
-#define XBOX_VID 0x045E // Microsoft Corporation
-#define MADCATZ_VID 0x1BAD // For unofficial Mad Catz controllers
-#define JOYTECH_VID 0x162E // For unofficial Joytech controllers
-
-#define XBOX_OLD_PID1 0x0202 // Original Microsoft Xbox controller (US)
-#define XBOX_OLD_PID2 0x0285 // Original Microsoft Xbox controller (Japan)
-#define XBOX_OLD_PID3 0x0287 // Microsoft Microsoft Xbox Controller S
-#define XBOX_OLD_PID4 0x0289 // Smaller Microsoft Xbox controller (US)
-
-#define XBOX_MAX_ENDPOINTS 3
-
-/** This class implements support for a the original Xbox controller via USB. */
-class XBOXOLD : public USBDeviceConfig {
-public:
- /**
- * Constructor for the XBOXOLD class.
- * @param pUsb Pointer to USB class instance.
- */
- XBOXOLD(USB *pUsb);
-
- /** @name USBDeviceConfig implementation */
- /**
- * Initialize the Xbox Controller.
- * @param parent Hub number.
- * @param port Port number on the hub.
- * @param lowspeed Speed of the device.
- * @return 0 on success.
- */
- uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
- /**
- * Release the USB device.
- * @return 0 on success.
- */
- uint8_t Release();
- /**
- * Poll the USB Input endpoins and run the state machines.
- * @return 0 on success.
- */
- uint8_t Poll();
-
- /**
- * Get the device address.
- * @return The device address.
- */
- virtual uint8_t GetAddress() {
- return bAddress;
- };
-
- /**
- * Used to check if the controller has been initialized.
- * @return True if it's ready.
- */
- virtual bool isReady() {
- return bPollEnable;
- };
-
- /**
- * Used by the USB core to check what this driver support.
- * @param vid The device's VID.
- * @param pid The device's PID.
- * @return Returns true if the device's VID and PID matches this driver.
- */
- virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) {
- return ((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));
- };
- /**@}*/
-
- /** @name Xbox Controller functions */
- /**
- * getButtonPress(ButtonEnum b) will return true as long as the button is held down.
- *
- * While getButtonClick(ButtonEnum b) will only return it once.
- *
- * So you instance if you need to increase a variable once you would use getButtonClick(ButtonEnum b),
- * but if you need to drive a robot forward you would use getButtonPress(ButtonEnum b).
- * @param b ::ButtonEnum to read.
- * @return getButtonClick(ButtonEnum b) will return a bool, while getButtonPress(ButtonEnum b) will return a byte if reading ::L2 or ::R2.
- */
- uint8_t getButtonPress(ButtonEnum b);
- bool getButtonClick(ButtonEnum b);
- /**@}*/
-
- /** @name Xbox Controller functions */
- /**
- * Return the analog value from the joysticks on the controller.
- * @param a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY.
- * @return Returns a signed 16-bit integer.
- */
- int16_t getAnalogHat(AnalogHatEnum a);
-
- /** Turn rumble off the controller. */
- void setRumbleOff() {
- setRumbleOn(0, 0);
- };
- /**
- * Turn rumble on.
- * @param lValue Left motor (big weight) inside the controller.
- * @param rValue Right motor (small weight) inside the controller.
- */
- void setRumbleOn(uint8_t lValue, uint8_t rValue);
-
- /**
- * Used to call your own function when the controller is successfully initialized.
- * @param funcOnInit Function to call.
- */
- void attachOnInit(void (*funcOnInit)(void)) {
- pFuncOnInit = funcOnInit;
- };
- /**@}*/
-
- /** True if a Xbox controller is connected. */
- bool XboxConnected;
-
-protected:
- /** Pointer to USB class instance. */
- USB *pUsb;
- /** Device address. */
- uint8_t bAddress;
- /** Endpoint info structure. */
- EpInfo epInfo[XBOX_MAX_ENDPOINTS];
-
-private:
- /**
- * Called when the controller is successfully initialized.
- * Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
- * This is useful for instance if you want to set the LEDs in a specific way.
- */
- void (*pFuncOnInit)(void); // Pointer to function called in onInit()
-
- bool bPollEnable;
-
- /* Variables to store the digital buttons */
- uint8_t ButtonState;
- uint8_t OldButtonState;
- uint8_t ButtonClickState;
-
- /* Variables to store the analog buttons */
- uint8_t buttonValues[8]; // A, B, X, Y, BLACK, WHITE, L1, and R1
- uint8_t oldButtonValues[8];
- bool buttonClicked[8];
-
- int16_t hatValue[4]; // Joystick values
-
- uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data
-
- void readReport(); // Read incoming data
- void printReport(uint16_t length); // Print incoming date
-
- /* Private commands */
- void XboxCommand(uint8_t* data, uint16_t nbytes);
-};
-#endif
diff --git a/lib/usbhost/USB_Host_Shield_2.0/XBOXONE.cpp b/lib/usbhost/USB_Host_Shield_2.0/XBOXONE.cpp
deleted file mode 100644
index 2159c0528b1e..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/XBOXONE.cpp
+++ /dev/null
@@ -1,374 +0,0 @@
-/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
- Copyright (C) 2015 guruthree
-
- 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
-
- guruthree
- Web : https://github.com/guruthree/
- */
-
-#include "XBOXONE.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 ONE Controller
-
-XBOXONE::XBOXONE(USB *p) :
-pUsb(p), // pointer to USB class instance - mandatory
-bAddress(0), // device address - mandatory
-bPollEnable(false) { // don't start polling before dongle is connected
- for(uint8_t i = 0; i < XBOX_MAX_ENDPOINTS; i++) {
- epInfo[i].epAddr = 0;
- epInfo[i].maxPktSize = (i) ? 0 : 8;
- epInfo[i].epAttribs = 0;
- epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
- }
-
- if(pUsb) // register in USB subsystem
- pUsb->RegisterDeviceClass(this); //set devConfig[] entry
-}
-
-uint8_t XBOXONE::Init(uint8_t parent, uint8_t port, bool lowspeed) {
- uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
- USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf);
- uint8_t rcode;
- UsbDevice *p = NULL;
- EpInfo *oldep_ptr = NULL;
- uint16_t PID;
- uint16_t VID;
-
- // get memory address of USB device address pool
- AddressPool &addrPool = pUsb->GetAddressPool();
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nXBOXONE Init"), 0x80);
-#endif
- // check if address has already been assigned to an instance
- if(bAddress) {
-#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);
-
- if(!p) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nAddress not found"), 0x80);
-#endif
- return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
- }
-
- if(!p->epinfo) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nepinfo is null"), 0x80);
-#endif
- return USB_ERROR_EPINFO_IS_NULL;
- }
-
- // Save old pointer to EP_RECORD of address 0
- oldep_ptr = p->epinfo;
-
- // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
- p->epinfo = epInfo;
-
- p->lowspeed = lowspeed;
-
- // Get device descriptor
- rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
- // Restore p->epinfo
- p->epinfo = oldep_ptr;
-
- if(rcode)
- goto FailGetDevDescr;
-
- VID = udd->idVendor;
- PID = udd->idProduct;
-
- if(!VIDPIDOK(VID, PID)) // Check VID
- goto FailUnknownDevice;
-
- // Allocate new address according to device class
- bAddress = addrPool.AllocAddress(parent, false, port);
-
- if(!bAddress)
- return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
-
- // Extract Max Packet Size from device descriptor
- epInfo[0].maxPktSize = udd->bMaxPacketSize0;
-
- // Assign new address to the device
- rcode = pUsb->setAddr(0, 0, bAddress);
- if(rcode) {
- p->lowspeed = false;
- addrPool.FreeAddress(bAddress);
- bAddress = 0;
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nsetAddr: "), 0x80);
- D_PrintHex (rcode, 0x80);
-#endif
- return rcode;
- }
-#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)
- return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
-
- p->lowspeed = lowspeed;
-
- // Assign epInfo to epinfo pointer - only EP0 is known
- rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
- if(rcode)
- goto FailSetDevTblEntry;
-
- /* The application will work in reduced host mode, so we can save program and data
- memory space. After verifying the VID we will use known values for the
- configuration values for device, interface, endpoints and HID for the XBOXONE Controllers */
-
- /* Initialize data structures for endpoints of device */
- epInfo[ XBOX_OUTPUT_PIPE ].epAddr = 0x01; // XBOX one output endpoint
- epInfo[ XBOX_OUTPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
- epInfo[ XBOX_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
- epInfo[ XBOX_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
- epInfo[ XBOX_OUTPUT_PIPE ].bmSndToggle = 0;
- epInfo[ XBOX_OUTPUT_PIPE ].bmRcvToggle = 0;
- epInfo[ XBOX_INPUT_PIPE ].epAddr = 0x01; // XBOX one input endpoint
- epInfo[ XBOX_INPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
- epInfo[ XBOX_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
- epInfo[ XBOX_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
- epInfo[ XBOX_INPUT_PIPE ].bmSndToggle = 0;
- epInfo[ XBOX_INPUT_PIPE ].bmRcvToggle = 0;
-
- rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
- if(rcode)
- goto FailSetDevTblEntry;
-
- delay(200); // Give time for address change
-
- rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
- if(rcode)
- goto FailSetConfDescr;
-
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nXbox One Controller Connected\r\n"), 0x80);
-#endif
-
- delay(200); // let things settle
-
- // initialize the controller for input
- writeBuf[0] = 0x05;
- writeBuf[1] = 0x20;
- rcode = XboxCommand(writeBuf, 2);
- if (rcode)
- goto Fail;
-
- onInit();
- XboxOneConnected = true;
- bPollEnable = true;
- return 0; // Successful configuration
-
- /* Diagnostic messages */
-FailGetDevDescr:
-#ifdef DEBUG_USB_HOST
- NotifyFailGetDevDescr();
- goto Fail;
-#endif
-
-FailSetDevTblEntry:
-#ifdef DEBUG_USB_HOST
- NotifyFailSetDevTblEntry();
- goto Fail;
-#endif
-
-FailSetConfDescr:
-#ifdef DEBUG_USB_HOST
- NotifyFailSetConfDescr();
-#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 One Init Failed, error code: "), 0x80);
- NotifyFail(rcode);
-#endif
- Release();
- return rcode;
-}
-
-/* Performs a cleanup after failed Init() attempt */
-uint8_t XBOXONE::Release() {
- XboxOneConnected = false;
- pUsb->GetAddressPool().FreeAddress(bAddress);
- bAddress = 0;
- bPollEnable = false;
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nXbox One Controller Disconnected\r\n"), 0x80);
-#endif
- return 0;
-}
-
-uint8_t XBOXONE::Poll() {
- if(!bPollEnable)
- return 0;
- uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
- uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ XBOX_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf);
- if (!rcode) {
- readReport();
-#ifdef PRINTREPORT
- printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the Xbox ONE Controller
-#endif
- }
-#ifdef DEBUG_USB_HOST
- else if (rcode != 0x04) { // not a matter of no update to send
- Notify(PSTR("\r\nXbox One Poll Failed, error code: "), 0x80);
- NotifyFail(rcode);
- }
-#endif
- return rcode;
-}
-
-void XBOXONE::readReport() {
- if(readBuf == NULL)
- return;
- if(readBuf[0] == 0x07) {
- // The XBOX button has a separate message
- if(readBuf[4] == 1)
- ButtonState |= XBOX_BUTTONS[XBOX];
- else
- ButtonState &= ~XBOX_BUTTONS[XBOX];
- }
- if(readBuf[0] != 0x20) { // Check if it's the correct report, otherwise return - the controller also sends different status reports
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nXbox Poll: "), 0x80);
- D_PrintHex (readBuf[0], 0x80); // 0x03 is a heart beat report!
-#endif
- return;
- }
-
- uint16_t xbox = ButtonState & XBOX_BUTTONS[XBOX]; // Since the XBOX button is separate, save it and add it back in
- // xbox button from before, dpad, abxy, start/back, sync, stick click, shoulder buttons
- ButtonState = xbox | (((uint16_t)readBuf[5] & 0xF) << 8) | (readBuf[4] & 0xF0) | (((uint16_t)readBuf[4] & 0x0C) << 10) | ((readBuf[4] & 0x01) << 3) | (((uint16_t)readBuf[5] & 0xC0) << 8) | ((readBuf[5] & 0x30) >> 4);
-
- triggerValue[0] = (uint16_t)(((uint16_t)readBuf[7] << 8) | readBuf[6]);
- triggerValue[1] = (uint16_t)(((uint16_t)readBuf[9] << 8) | readBuf[8]);
-
- hatValue[LeftHatX] = (int16_t)(((uint16_t)readBuf[11] << 8) | readBuf[10]);
- hatValue[LeftHatY] = (int16_t)(((uint16_t)readBuf[13] << 8) | readBuf[12]);
- hatValue[RightHatX] = (int16_t)(((uint16_t)readBuf[15] << 8) | readBuf[14]);
- hatValue[RightHatY] = (int16_t)(((uint16_t)readBuf[17] << 8) | readBuf[16]);
-
- //Notify(PSTR("\r\nButtonState"), 0x80);
- //PrintHex(ButtonState, 0x80);
-
- if(ButtonState != OldButtonState) {
- ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
- OldButtonState = ButtonState;
- }
-
- // Handle click detection for triggers
- if(triggerValue[0] != 0 && triggerValueOld[0] == 0)
- L2Clicked = true;
- triggerValueOld[0] = triggerValue[0];
- if(triggerValue[1] != 0 && triggerValueOld[1] == 0)
- R2Clicked = true;
- triggerValueOld[1] = triggerValue[1];
-}
-
-void XBOXONE::printReport() { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox ONE Controller
-#ifdef PRINTREPORT
- if(readBuf == NULL)
- return;
- for(uint8_t i = 0; i < XBOX_REPORT_BUFFER_SIZE; i++) {
- D_PrintHex (readBuf[i], 0x80);
- Notify(PSTR(" "), 0x80);
- }
- Notify(PSTR("\r\n"), 0x80);
-#endif
-}
-
-uint16_t XBOXONE::getButtonPress(ButtonEnum b) {
- if(b == L2) // These are analog buttons
- return triggerValue[0];
- else if(b == R2)
- return triggerValue[1];
- return (bool)(ButtonState & ((uint16_t)pgm_read_word(&XBOX_BUTTONS[(uint8_t)b])));
-}
-
-bool XBOXONE::getButtonClick(ButtonEnum b) {
- if(b == L2) {
- if(L2Clicked) {
- L2Clicked = false;
- return true;
- }
- return false;
- } else if(b == R2) {
- if(R2Clicked) {
- R2Clicked = false;
- return true;
- }
- return false;
- }
- uint16_t button = pgm_read_word(&XBOX_BUTTONS[(uint8_t)b]);
- bool click = (ButtonClickState & button);
- ButtonClickState &= ~button; // clear "click" event
- return click;
-}
-
-int16_t XBOXONE::getAnalogHat(AnalogHatEnum a) {
- return hatValue[a];
-}
-
-/* Xbox Controller commands */
-uint8_t XBOXONE::XboxCommand(uint8_t* data, uint16_t nbytes) {
- uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ XBOX_OUTPUT_PIPE ].epAddr, nbytes, data);
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nXboxCommand, Return: "), 0x80);
- D_PrintHex (rcode, 0x80);
-#endif
- return rcode;
-}
-
-void XBOXONE::onInit() {
- // a short buzz to show the controller is active
- writeBuf[0] = 0x09;
- writeBuf[1] = 0x08;
- writeBuf[2] = 0x00;
- writeBuf[3] = 0x09;
- writeBuf[4] = 0x00;
- writeBuf[5] = 0x0f;
- writeBuf[6] = 0x04;
- writeBuf[7] = 0x04;
- writeBuf[8] = 0x20;
- writeBuf[9] = 0x20;
- writeBuf[10] = 0x80;
- XboxCommand(writeBuf, 11);
-
- if(pFuncOnInit)
- pFuncOnInit(); // Call the user function
-}
diff --git a/lib/usbhost/USB_Host_Shield_2.0/XBOXONE.h b/lib/usbhost/USB_Host_Shield_2.0/XBOXONE.h
deleted file mode 100644
index 11710fcf1a6f..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/XBOXONE.h
+++ /dev/null
@@ -1,172 +0,0 @@
-/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
- Copyright (C) 2015 guruthree
-
- 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
-
- guruthree
- Web : https://github.com/guruthree/
- */
-
-
-#ifndef _xboxone_h_
-#define _xboxone_h_
-
-#include "Usb.h"
-#include "xboxEnums.h"
-
-/* Data Xbox ONE taken from descriptors */
-#define EP_MAXPKTSIZE 32 // max size for data via USB
-
-/* Names we give to the 3 XboxONE pipes */
-#define XBOX_CONTROL_PIPE 0
-#define XBOX_OUTPUT_PIPE 1
-#define XBOX_INPUT_PIPE 2
-
-// PID and VID of the different devices
-#define XBOX_VID 0x045E // Microsoft Corporation
-#define XBOX_ONE_PID 0x02D1 // Microsoft One Wired controller
-
-#define XBOX_REPORT_BUFFER_SIZE 14 // Size of the input report buffer
-
-#define XBOX_MAX_ENDPOINTS 3
-
-/** This class implements support for a Xbox ONE controller connected via USB. */
-class XBOXONE : public USBDeviceConfig {
-public:
- /**
- * Constructor for the XBOXONE class.
- * @param pUsb Pointer to USB class instance.
- */
- XBOXONE(USB *pUsb);
-
- /** @name USBDeviceConfig implementation */
- /**
- * Initialize the Xbox Controller.
- * @param parent Hub number.
- * @param port Port number on the hub.
- * @param lowspeed Speed of the device.
- * @return 0 on success.
- */
- virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
- /**
- * Release the USB device.
- * @return 0 on success.
- */
- virtual uint8_t Release();
- /**
- * Poll the USB Input endpoins and run the state machines.
- * @return 0 on success.
- */
- virtual uint8_t Poll();
-
- /**
- * Get the device address.
- * @return The device address.
- */
- virtual uint8_t GetAddress() {
- return bAddress;
- };
-
- /**
- * Used to check if the controller has been initialized.
- * @return True if it's ready.
- */
- virtual bool isReady() {
- return bPollEnable;
- };
-
- /**
- * Used by the USB core to check what this driver support.
- * @param vid The device's VID.
- * @param pid The device's PID.
- * @return Returns true if the device's VID and PID matches this driver.
- */
- virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) {
- return (vid == XBOX_VID && pid == XBOX_ONE_PID);
- };
- /**@}*/
-
- /** @name Xbox Controller functions */
- /**
- * getButtonPress(ButtonEnum b) will return true as long as the button is held down.
- *
- * While getButtonClick(ButtonEnum b) will only return it once.
- *
- * So you instance if you need to increase a variable once you would use getButtonClick(ButtonEnum b),
- * but if you need to drive a robot forward you would use getButtonPress(ButtonEnum b).
- * @param b ::ButtonEnum to read.
- * @return getButtonClick(ButtonEnum b) will return a bool, while getButtonPress(ButtonEnum b) will return a word if reading ::L2 or ::R2.
- */
- uint16_t getButtonPress(ButtonEnum b);
- bool getButtonClick(ButtonEnum b);
-
- /**
- * Return the analog value from the joysticks on the controller.
- * @param a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY.
- * @return Returns a signed 16-bit integer.
- */
- int16_t getAnalogHat(AnalogHatEnum a);
-
- /**
- * Used to call your own function when the controller is successfully initialized.
- * @param funcOnInit Function to call.
- */
- void attachOnInit(void (*funcOnInit)(void)) {
- pFuncOnInit = funcOnInit;
- };
- /**@}*/
-
- /** True if a Xbox ONE controller is connected. */
- bool XboxOneConnected;
-
-protected:
- /** Pointer to USB class instance. */
- USB *pUsb;
- /** Device address. */
- uint8_t bAddress;
- /** Endpoint info structure. */
- EpInfo epInfo[XBOX_MAX_ENDPOINTS];
-
-private:
- /**
- * Called when the controller is successfully initialized.
- * Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
- */
- void onInit();
- void (*pFuncOnInit)(void); // Pointer to function called in onInit()
-
- bool bPollEnable;
-
- /* Variables to store the buttons */
- uint16_t ButtonState;
- uint16_t OldButtonState;
- uint16_t ButtonClickState;
- int16_t hatValue[4];
- uint16_t triggerValue[2];
- uint16_t triggerValueOld[2];
-
- bool L2Clicked; // These buttons are analog, so we use we use these bools to check if they where clicked or not
- bool R2Clicked;
-
- uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data
- uint8_t writeBuf[12]; // General purpose buffer for output data
-
- void readReport(); // read incoming data
- void printReport(); // print incoming date - Uncomment for debugging
-
- /* Private commands */
- uint8_t XboxCommand(uint8_t* data, uint16_t nbytes);
-};
-#endif
diff --git a/lib/usbhost/USB_Host_Shield_2.0/XBOXRECV.cpp b/lib/usbhost/USB_Host_Shield_2.0/XBOXRECV.cpp
deleted file mode 100644
index 41f1ff581647..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/XBOXRECV.cpp
+++ /dev/null
@@ -1,583 +0,0 @@
-/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
-
- This software may be distributed and modified under the terms of the GNU
- General Public License version 2 (GPL2) as published by the Free Software
- Foundation and appearing in the file GPL2.TXT included in the packaging of
- this file. Please note that GPL2 Section 2[b] requires that all works based
- on this software must also be made publicly available under the terms of
- the GPL2 ("Copyleft").
-
- Contact information
- -------------------
-
- Kristian Lauszus, TKJ Electronics
- Web : http://www.tkjelectronics.com
- e-mail : kristianl@tkjelectronics.com
-
- getBatteryLevel and checkStatus functions made by timstamp.co.uk found using BusHound from Perisoft.net
- */
-
-#include "XBOXRECV.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
-
-XBOXRECV::XBOXRECV(USB *p) :
-pUsb(p), // pointer to USB class instance - mandatory
-bAddress(0), // device address - mandatory
-bPollEnable(false) { // don't start polling before dongle is connected
- for(uint8_t i = 0; i < XBOX_MAX_ENDPOINTS; i++) {
- epInfo[i].epAddr = 0;
- epInfo[i].maxPktSize = (i) ? 0 : 8;
- epInfo[i].epAttribs = 0;
- epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
- }
-
- if(pUsb) // register in USB subsystem
- pUsb->RegisterDeviceClass(this); //set devConfig[] entry
-}
-
-uint8_t XBOXRECV::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
- const uint8_t constBufSize = sizeof (USB_DEVICE_DESCRIPTOR);
- uint8_t buf[constBufSize];
- USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf);
- uint8_t rcode;
- UsbDevice *p = NULL;
- EpInfo *oldep_ptr = NULL;
- uint16_t PID, VID;
-
- AddressPool &addrPool = pUsb->GetAddressPool(); // Get memory address of USB device address pool
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nXBOXRECV Init"), 0x80);
-#endif
-
- 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;
- }
-
- p = addrPool.GetUsbDevicePtr(0); // Get pointer to pseudo device with address 0 assigned
-
- if(!p) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nAddress not found"), 0x80);
-#endif
- return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
- }
-
- if(!p->epinfo) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nepinfo is null"), 0x80);
-#endif
- return USB_ERROR_EPINFO_IS_NULL;
- }
-
- 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;
-
- 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;
-
- VID = udd->idVendor;
- PID = udd->idProduct;
-
- if((VID != XBOX_VID && VID != MADCATZ_VID && VID != JOYTECH_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;
- }
-
- bAddress = addrPool.AllocAddress(parent, false, port); // Allocate new address according to device class
-
- if(!bAddress) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nOut of address space"), 0x80);
-#endif
- return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
- }
-
- epInfo[0].maxPktSize = udd->bMaxPacketSize0; // Extract Max Packet Size from device descriptor
-
- delay(20); // Wait a little before resetting device
-
- 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;
-
- 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) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nsetAddr: "), 0x80);
- D_PrintHex (rcode, 0x80);
-#endif
- p->lowspeed = false;
- goto Fail;
- }
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nAddr: "), 0x80);
- D_PrintHex (bAddress, 0x80);
-#endif
-
- p->lowspeed = false;
-
- 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;
-
- rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); // Assign epInfo to epinfo pointer - only EP0 is known
- if(rcode)
- goto FailSetDevTblEntry;
-
- /* The application will work in reduced host mode, so we can save program and data
- memory space. After verifying the VID we will use known values for the
- configuration values for device, interface, endpoints and HID for the XBOX360 Wireless receiver */
-
- /* Initialize data structures for endpoints of device */
- epInfo[ XBOX_INPUT_PIPE_1 ].epAddr = 0x01; // XBOX 360 report endpoint - poll interval 1ms
- epInfo[ XBOX_INPUT_PIPE_1 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
- epInfo[ XBOX_INPUT_PIPE_1 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
- epInfo[ XBOX_INPUT_PIPE_1 ].maxPktSize = EP_MAXPKTSIZE;
- epInfo[ XBOX_INPUT_PIPE_1 ].bmSndToggle = 0;
- epInfo[ XBOX_INPUT_PIPE_1 ].bmRcvToggle = 0;
- epInfo[ XBOX_OUTPUT_PIPE_1 ].epAddr = 0x01; // XBOX 360 output endpoint - poll interval 8ms
- epInfo[ XBOX_OUTPUT_PIPE_1 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
- epInfo[ XBOX_OUTPUT_PIPE_1 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
- epInfo[ XBOX_OUTPUT_PIPE_1 ].maxPktSize = EP_MAXPKTSIZE;
- epInfo[ XBOX_OUTPUT_PIPE_1 ].bmSndToggle = 0;
- epInfo[ XBOX_OUTPUT_PIPE_1 ].bmRcvToggle = 0;
-
- epInfo[ XBOX_INPUT_PIPE_2 ].epAddr = 0x03; // XBOX 360 report endpoint - poll interval 1ms
- epInfo[ XBOX_INPUT_PIPE_2 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
- epInfo[ XBOX_INPUT_PIPE_2 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
- epInfo[ XBOX_INPUT_PIPE_2 ].maxPktSize = EP_MAXPKTSIZE;
- epInfo[ XBOX_INPUT_PIPE_2 ].bmSndToggle = 0;
- epInfo[ XBOX_INPUT_PIPE_2 ].bmRcvToggle = 0;
- epInfo[ XBOX_OUTPUT_PIPE_2 ].epAddr = 0x03; // XBOX 360 output endpoint - poll interval 8ms
- epInfo[ XBOX_OUTPUT_PIPE_2 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
- epInfo[ XBOX_OUTPUT_PIPE_2 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
- epInfo[ XBOX_OUTPUT_PIPE_2 ].maxPktSize = EP_MAXPKTSIZE;
- epInfo[ XBOX_OUTPUT_PIPE_2 ].bmSndToggle = 0;
- epInfo[ XBOX_OUTPUT_PIPE_2 ].bmRcvToggle = 0;
-
- epInfo[ XBOX_INPUT_PIPE_3 ].epAddr = 0x05; // XBOX 360 report endpoint - poll interval 1ms
- epInfo[ XBOX_INPUT_PIPE_3 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
- epInfo[ XBOX_INPUT_PIPE_3 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
- epInfo[ XBOX_INPUT_PIPE_3 ].maxPktSize = EP_MAXPKTSIZE;
- epInfo[ XBOX_INPUT_PIPE_3 ].bmSndToggle = 0;
- epInfo[ XBOX_INPUT_PIPE_3 ].bmRcvToggle = 0;
- epInfo[ XBOX_OUTPUT_PIPE_3 ].epAddr = 0x05; // XBOX 360 output endpoint - poll interval 8ms
- epInfo[ XBOX_OUTPUT_PIPE_3 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
- epInfo[ XBOX_OUTPUT_PIPE_3 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
- epInfo[ XBOX_OUTPUT_PIPE_3 ].maxPktSize = EP_MAXPKTSIZE;
- epInfo[ XBOX_OUTPUT_PIPE_3 ].bmSndToggle = 0;
- epInfo[ XBOX_OUTPUT_PIPE_3 ].bmRcvToggle = 0;
-
- epInfo[ XBOX_INPUT_PIPE_4 ].epAddr = 0x07; // XBOX 360 report endpoint - poll interval 1ms
- epInfo[ XBOX_INPUT_PIPE_4 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
- epInfo[ XBOX_INPUT_PIPE_4 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
- epInfo[ XBOX_INPUT_PIPE_4 ].maxPktSize = EP_MAXPKTSIZE;
- epInfo[ XBOX_INPUT_PIPE_4 ].bmSndToggle = 0;
- epInfo[ XBOX_INPUT_PIPE_4 ].bmRcvToggle = 0;
- epInfo[ XBOX_OUTPUT_PIPE_4 ].epAddr = 0x07; // XBOX 360 output endpoint - poll interval 8ms
- epInfo[ XBOX_OUTPUT_PIPE_4 ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
- epInfo[ XBOX_OUTPUT_PIPE_4 ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
- epInfo[ XBOX_OUTPUT_PIPE_4 ].maxPktSize = EP_MAXPKTSIZE;
- epInfo[ XBOX_OUTPUT_PIPE_4 ].bmSndToggle = 0;
- epInfo[ XBOX_OUTPUT_PIPE_4 ].bmRcvToggle = 0;
-
- rcode = pUsb->setEpInfoEntry(bAddress, 9, epInfo);
- if(rcode)
- goto FailSetDevTblEntry;
-
- delay(200); //Give time for address change
-
- rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
- if(rcode)
- goto FailSetConfDescr;
-
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nXbox Wireless Receiver Connected\r\n"), 0x80);
-#endif
- XboxReceiverConnected = true;
- bPollEnable = true;
- checkStatusTimer = 0; // Reset timer
- return 0; // Successful configuration
-
- /* Diagnostic messages */
-FailSetDevTblEntry:
-#ifdef DEBUG_USB_HOST
- NotifyFailSetDevTblEntry();
- goto Fail;
-#endif
-
-FailSetConfDescr:
-#ifdef DEBUG_USB_HOST
- NotifyFailSetConfDescr();
-#endif
-
-Fail:
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nXbox 360 Init Failed, error code: "), 0x80);
- NotifyFail(rcode);
-#endif
- Release();
- return rcode;
-}
-
-/* Performs a cleanup after failed Init() attempt */
-uint8_t XBOXRECV::Release() {
- XboxReceiverConnected = false;
- for(uint8_t i = 0; i < 4; i++)
- Xbox360Connected[i] = 0x00;
- pUsb->GetAddressPool().FreeAddress(bAddress);
- bAddress = 0;
- bPollEnable = false;
- return 0;
-}
-
-uint8_t XBOXRECV::Poll() {
- if(!bPollEnable)
- return 0;
- 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++) {
- 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
-#ifdef EXTRADEBUG
- Notify(PSTR("Bytes Received: "), 0x80);
- D_PrintHex (bufferSize, 0x80);
- Notify(PSTR("\r\n"), 0x80);
-#endif
- readReport(i);
-#ifdef PRINTREPORT
- printReport(i, bufferSize); // Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller
-#endif
- }
- }
- return 0;
-}
-
-void XBOXRECV::readReport(uint8_t controller) {
- if(readBuf == NULL)
- return;
- // This report is send when a controller is connected and disconnected
- if(readBuf[0] == 0x08 && readBuf[1] != Xbox360Connected[controller]) {
- Xbox360Connected[controller] = readBuf[1];
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("Controller "), 0x80);
- Notify(controller, 0x80);
-#endif
- if(Xbox360Connected[controller]) {
-#ifdef DEBUG_USB_HOST
- const char* str = 0;
- switch(readBuf[1]) {
- case 0x80: str = PSTR(" as controller\r\n");
- break;
- case 0x40: str = PSTR(" as headset\r\n");
- break;
- case 0xC0: str = PSTR(" as controller+headset\r\n");
- break;
- }
- Notify(PSTR(": connected"), 0x80);
- Notify(str, 0x80);
-#endif
- onInit(controller);
- }
-#ifdef DEBUG_USB_HOST
- else
- Notify(PSTR(": disconnected\r\n"), 0x80);
-#endif
- return;
- }
- // Controller status report
- if(readBuf[1] == 0x00 && readBuf[3] & 0x13 && readBuf[4] >= 0x22) {
- controllerStatus[controller] = ((uint16_t)readBuf[3] << 8) | readBuf[4];
- return;
- }
- if(readBuf[1] != 0x01) // Check if it's the correct report - the receiver also sends different status reports
- return;
-
- // A controller must be connected if it's sending data
- if(!Xbox360Connected[controller])
- Xbox360Connected[controller] |= 0x80;
-
- ButtonState[controller] = (uint32_t)(readBuf[9] | ((uint16_t)readBuf[8] << 8) | ((uint32_t)readBuf[7] << 16) | ((uint32_t)readBuf[6] << 24));
-
- hatValue[controller][LeftHatX] = (int16_t)(((uint16_t)readBuf[11] << 8) | readBuf[10]);
- hatValue[controller][LeftHatY] = (int16_t)(((uint16_t)readBuf[13] << 8) | readBuf[12]);
- hatValue[controller][RightHatX] = (int16_t)(((uint16_t)readBuf[15] << 8) | readBuf[14]);
- hatValue[controller][RightHatY] = (int16_t)(((uint16_t)readBuf[17] << 8) | readBuf[16]);
-
- //Notify(PSTR("\r\nButtonState: "), 0x80);
- //PrintHex(ButtonState[controller], 0x80);
-
- if(ButtonState[controller] != OldButtonState[controller]) {
- buttonStateChanged[controller] = true;
- ButtonClickState[controller] = (ButtonState[controller] >> 16) & ((~OldButtonState[controller]) >> 16); // Update click state variable, but don't include the two trigger buttons L2 and R2
- if(((uint8_t)OldButtonState[controller]) == 0 && ((uint8_t)ButtonState[controller]) != 0) // The L2 and R2 buttons are special as they are analog buttons
- R2Clicked[controller] = true;
- if((uint8_t)(OldButtonState[controller] >> 8) == 0 && (uint8_t)(ButtonState[controller] >> 8) != 0)
- L2Clicked[controller] = true;
- OldButtonState[controller] = ButtonState[controller];
- }
-}
-
-void XBOXRECV::printReport(uint8_t controller, uint8_t nBytes) { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller
-#ifdef PRINTREPORT
- if(readBuf == NULL)
- return;
- Notify(PSTR("Controller "), 0x80);
- Notify(controller, 0x80);
- Notify(PSTR(": "), 0x80);
- for(uint8_t i = 0; i < nBytes; i++) {
- D_PrintHex (readBuf[i], 0x80);
- Notify(PSTR(" "), 0x80);
- }
- Notify(PSTR("\r\n"), 0x80);
-#endif
-}
-
-uint8_t XBOXRECV::getButtonPress(ButtonEnum b, uint8_t controller) {
- if(b == L2) // These are analog buttons
- return (uint8_t)(ButtonState[controller] >> 8);
- else if(b == R2)
- return (uint8_t)ButtonState[controller];
- return (bool)(ButtonState[controller] & ((uint32_t)pgm_read_word(&XBOX_BUTTONS[(uint8_t)b]) << 16));
-}
-
-bool XBOXRECV::getButtonClick(ButtonEnum b, uint8_t controller) {
- if(b == L2) {
- if(L2Clicked[controller]) {
- L2Clicked[controller] = false;
- return true;
- }
- return false;
- } else if(b == R2) {
- if(R2Clicked[controller]) {
- R2Clicked[controller] = false;
- return true;
- }
- return false;
- }
- uint16_t button = pgm_read_word(&XBOX_BUTTONS[(uint8_t)b]);
- bool click = (ButtonClickState[controller] & button);
- ButtonClickState[controller] &= ~button; // clear "click" event
- return click;
-}
-
-int16_t XBOXRECV::getAnalogHat(AnalogHatEnum a, uint8_t controller) {
- return hatValue[controller][a];
-}
-
-bool XBOXRECV::buttonChanged(uint8_t controller) {
- bool state = buttonStateChanged[controller];
- buttonStateChanged[controller] = false;
- return state;
-}
-
-/*
-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
- */
-uint8_t XBOXRECV::getBatteryLevel(uint8_t controller) {
- return ((controllerStatus[controller] & 0x00C0) >> 6);
-}
-
-void XBOXRECV::XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes) {
-#ifdef EXTRADEBUG
- uint8_t rcode;
-#endif
- 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;
- default:
- return;
- }
-#ifdef EXTRADEBUG
- rcode =
-#endif
- pUsb->outTransfer(bAddress, epInfo[ outputPipe ].epAddr, nbytes, data);
-#ifdef EXTRADEBUG
- if(rcode)
- Notify(PSTR("Error sending Xbox message\r\n"), 0x80);
-#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;
- writeBuf[2] = 0x08;
- writeBuf[3] = value | 0x40;
-
- XboxCommand(controller, writeBuf, 4);
-}
-
-void XBOXRECV::setLedOn(LEDEnum led, uint8_t controller) {
- if(led == OFF)
- setLedRaw(0, controller);
- else if(led != ALL) // All LEDs can't be on a the same time
- setLedRaw(pgm_read_byte(&XBOX_LEDS[(uint8_t)led]) + 4, controller);
-}
-
-void XBOXRECV::setLedBlink(LEDEnum led, uint8_t controller) {
- setLedRaw(pgm_read_byte(&XBOX_LEDS[(uint8_t)led]), controller);
-}
-
-void XBOXRECV::setLedMode(LEDModeEnum ledMode, uint8_t controller) { // This function is used to do some speciel LED stuff the controller supports
- setLedRaw((uint8_t)ledMode, controller);
-}
-
-/* PC runs this at interval of approx 2 seconds
-Thanks to BusHound from Perisoft.net for the Windows USB Analysis output
-Found by timstamp.co.uk
- */
-void XBOXRECV::checkStatus() {
- if(!bPollEnable)
- return;
- // Get controller info
- writeBuf[0] = 0x08;
- writeBuf[1] = 0x00;
- writeBuf[2] = 0x0f;
- writeBuf[3] = 0xc0;
- for(uint8_t i = 0; i < 4; i++) {
- XboxCommand(i, writeBuf, 4);
- }
- // Get battery status
- writeBuf[0] = 0x00;
- writeBuf[1] = 0x00;
- writeBuf[2] = 0x00;
- writeBuf[3] = 0x40;
- for(uint8_t i = 0; i < 4; i++) {
- if(Xbox360Connected[i])
- XboxCommand(i, writeBuf, 4);
- }
-}
-
-void XBOXRECV::setRumbleOn(uint8_t lValue, uint8_t rValue, uint8_t controller) {
- writeBuf[0] = 0x00;
- writeBuf[1] = 0x01;
- writeBuf[2] = 0x0f;
- writeBuf[3] = 0xc0;
- writeBuf[4] = 0x00;
- writeBuf[5] = lValue; // big weight
- writeBuf[6] = rValue; // small weight
-
- XboxCommand(controller, writeBuf, 7);
-}
-
-void XBOXRECV::onInit(uint8_t controller) {
- if(pFuncOnInit)
- pFuncOnInit(); // Call the user function
- else {
- LEDEnum led;
- if(controller == 0)
- led = LED1;
- else if(controller == 1)
- led = LED2;
- else if(controller == 2)
- led = LED3;
- else
- led = LED4;
- setLedOn(led, controller);
- }
-}
diff --git a/lib/usbhost/USB_Host_Shield_2.0/XBOXRECV.h b/lib/usbhost/USB_Host_Shield_2.0/XBOXRECV.h
deleted file mode 100644
index 4f9214653c7d..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/XBOXRECV.h
+++ /dev/null
@@ -1,276 +0,0 @@
-/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
-
- This software may be distributed and modified under the terms of the GNU
- General Public License version 2 (GPL2) as published by the Free Software
- Foundation and appearing in the file GPL2.TXT included in the packaging of
- this file. Please note that GPL2 Section 2[b] requires that all works based
- on this software must also be made publicly available under the terms of
- the GPL2 ("Copyleft").
-
- Contact information
- -------------------
-
- Kristian Lauszus, TKJ Electronics
- Web : http://www.tkjelectronics.com
- e-mail : kristianl@tkjelectronics.com
-
- getBatteryLevel and checkStatus functions made by timstamp.co.uk found using BusHound from Perisoft.net
- */
-
-#ifndef _xboxrecv_h_
-#define _xboxrecv_h_
-
-#include "Usb.h"
-#include "xboxEnums.h"
-
-/* Data Xbox 360 taken from descriptors */
-#define EP_MAXPKTSIZE 32 // max size for data via USB
-
-/* Names we give to the 9 Xbox360 pipes */
-#define XBOX_CONTROL_PIPE 0
-#define XBOX_INPUT_PIPE_1 1
-#define XBOX_OUTPUT_PIPE_1 2
-#define XBOX_INPUT_PIPE_2 3
-#define XBOX_OUTPUT_PIPE_2 4
-#define XBOX_INPUT_PIPE_3 5
-#define XBOX_OUTPUT_PIPE_3 6
-#define XBOX_INPUT_PIPE_4 7
-#define XBOX_OUTPUT_PIPE_4 8
-
-// PID and VID of the different devices
-#define XBOX_VID 0x045E // Microsoft Corporation
-#define MADCATZ_VID 0x1BAD // For unofficial Mad Catz receivers
-#define JOYTECH_VID 0x162E // For unofficial Joytech controllers
-
-#define XBOX_WIRELESS_RECEIVER_PID 0x0719 // Microsoft Wireless Gaming Receiver
-#define XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID 0x0291 // Third party Wireless Gaming Receiver
-
-#define XBOX_MAX_ENDPOINTS 9
-
-/**
- * This class implements support for a Xbox Wireless receiver.
- *
- * Up to four controllers can connect to one receiver, if more is needed one can use a second receiver via the USBHub class.
- */
-class XBOXRECV : public USBDeviceConfig {
-public:
- /**
- * Constructor for the XBOXRECV class.
- * @param pUsb Pointer to USB class instance.
- */
- 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.
- */
- uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed);
- /**
- * Initialize the Xbox wireless receiver.
- * @param parent Hub number.
- * @param port Port number on the hub.
- * @param lowspeed Speed of the device.
- * @return 0 on success.
- */
- uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
- /**
- * Release the USB device.
- * @return 0 on success.
- */
- uint8_t Release();
- /**
- * Poll the USB Input endpoins and run the state machines.
- * @return 0 on success.
- */
- uint8_t Poll();
-
- /**
- * Get the device address.
- * @return The device address.
- */
- virtual uint8_t GetAddress() {
- return bAddress;
- };
-
- /**
- * Used to check if the controller has been initialized.
- * @return True if it's ready.
- */
- virtual bool isReady() {
- return bPollEnable;
- };
-
- /**
- * Used by the USB core to check what this driver support.
- * @param vid The device's VID.
- * @param pid The device's PID.
- * @return Returns true if the device's VID and PID matches this driver.
- */
- virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) {
- return ((vid == XBOX_VID || vid == MADCATZ_VID || vid == JOYTECH_VID) && (pid == XBOX_WIRELESS_RECEIVER_PID || pid == XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID));
- };
- /**@}*/
-
- /** @name Xbox Controller functions */
- /**
- * getButtonPress(uint8_t controller, ButtonEnum b) will return true as long as the button is held down.
- *
- * While getButtonClick(uint8_t controller, ButtonEnum b) will only return it once.
- *
- * So you instance if you need to increase a variable once you would use getButtonClick(uint8_t controller, ButtonEnum b),
- * but if you need to drive a robot forward you would use getButtonPress(uint8_t controller, ButtonEnum b).
- * @param b ::ButtonEnum to read.
- * @param controller The controller to read from. Default to 0.
- * @return getButtonClick(uint8_t controller, ButtonEnum b) will return a bool, while getButtonPress(uint8_t controller, ButtonEnum b) will return a byte if reading ::L2 or ::R2.
- */
- uint8_t getButtonPress(ButtonEnum b, uint8_t controller = 0);
- bool getButtonClick(ButtonEnum b, uint8_t controller = 0);
- /**@}*/
-
- /** @name Xbox Controller functions */
- /**
- * Return the analog value from the joysticks on the controller.
- * @param a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY.
- * @param controller The controller to read from. Default to 0.
- * @return Returns a signed 16-bit integer.
- */
- int16_t getAnalogHat(AnalogHatEnum 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.
- */
- void setAllOff(uint8_t controller = 0) {
- setRumbleOn(0, 0, controller);
- setLedOff(controller);
- };
-
- /**
- * Turn rumble off the specific controller.
- * @param controller The controller to write to. Default to 0.
- */
- void setRumbleOff(uint8_t controller = 0) {
- setRumbleOn(0, 0, controller);
- };
- /**
- * Turn rumble on.
- * @param lValue Left motor (big weight) inside the controller.
- * @param rValue Right motor (small weight) inside the controller.
- * @param controller The controller to write to. Default to 0.
- */
- void setRumbleOn(uint8_t lValue, uint8_t rValue, uint8_t controller = 0);
- /**
- * Set LED value. Without using the ::LEDEnum or ::LEDModeEnum.
- * @param value See:
- * setLedOff(uint8_t controller), setLedOn(uint8_t controller, LED l),
- * setLedBlink(uint8_t controller, LED l), and setLedMode(uint8_t controller, LEDMode lm).
- * @param controller The controller to write to. Default to 0.
- */
- void setLedRaw(uint8_t value, uint8_t controller = 0);
-
- /**
- * Turn all LEDs off the specific controller.
- * @param controller The controller to write to. Default to 0.
- */
- void setLedOff(uint8_t controller = 0) {
- setLedRaw(0, controller);
- };
- /**
- * Turn on a LED by using ::LEDEnum.
- * @param l ::OFF, ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller.
- * @param controller The controller to write to. Default to 0.
- */
- void setLedOn(LEDEnum l, uint8_t controller = 0);
- /**
- * Turn on a LED by using ::LEDEnum.
- * @param l ::ALL, ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller.
- * @param controller The controller to write to. Default to 0.
- */
- void setLedBlink(LEDEnum l, uint8_t controller = 0);
- /**
- * Used to set special LED modes supported by the Xbox controller.
- * @param lm See ::LEDModeEnum.
- * @param controller The controller to write to. Default to 0.
- */
- void setLedMode(LEDModeEnum lm, uint8_t controller = 0);
- /**
- * Used to get the battery level from the controller.
- * @param controller The controller to read from. Default to 0.
- * @return Returns the battery level as an integer in the range of 0-3.
- */
- uint8_t getBatteryLevel(uint8_t controller = 0);
- /**
- * Used to check if a button has changed.
- * @param controller The controller to read from. Default to 0.
- * @return True if a button has changed.
- */
- bool buttonChanged(uint8_t controller = 0);
-
- /**
- * Used to call your own function when the controller is successfully initialized.
- * @param funcOnInit Function to call.
- */
- void attachOnInit(void (*funcOnInit)(void)) {
- pFuncOnInit = funcOnInit;
- };
- /**@}*/
-
- /** True if a wireless receiver is connected. */
- bool XboxReceiverConnected;
- /** Variable used to indicate if the XBOX 360 controller is successfully connected. */
- uint8_t Xbox360Connected[4];
-
-protected:
- /** Pointer to USB class instance. */
- USB *pUsb;
- /** Device address. */
- uint8_t bAddress;
- /** Endpoint info structure. */
- EpInfo epInfo[XBOX_MAX_ENDPOINTS];
-
-private:
- /**
- * Called when the controller is successfully initialized.
- * Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
- * This is useful for instance if you want to set the LEDs in a specific way.
- * @param controller The initialized controller.
- */
- void onInit(uint8_t controller);
- void (*pFuncOnInit)(void); // Pointer to function called in onInit()
-
- bool bPollEnable;
-
- /* Variables to store the buttons */
- uint32_t ButtonState[4];
- uint32_t OldButtonState[4];
- uint16_t ButtonClickState[4];
- int16_t hatValue[4][4];
- uint16_t controllerStatus[4];
- bool buttonStateChanged[4]; // True if a button has changed
-
- 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];
-
- 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
-
- void readReport(uint8_t controller); // read incoming data
- void printReport(uint8_t controller, uint8_t nBytes); // print incoming date - Uncomment for debugging
-
- /* Private commands */
- void XboxCommand(uint8_t controller, uint8_t* data, uint16_t nbytes);
- void checkStatus();
-};
-#endif
diff --git a/lib/usbhost/USB_Host_Shield_2.0/XBOXUSB.cpp b/lib/usbhost/USB_Host_Shield_2.0/XBOXUSB.cpp
deleted file mode 100644
index ddece21b454b..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/XBOXUSB.cpp
+++ /dev/null
@@ -1,361 +0,0 @@
-/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
-
- This software may be distributed and modified under the terms of the GNU
- General Public License version 2 (GPL2) as published by the Free Software
- Foundation and appearing in the file GPL2.TXT included in the packaging of
- this file. Please note that GPL2 Section 2[b] requires that all works based
- on this software must also be made publicly available under the terms of
- the GPL2 ("Copyleft").
-
- Contact information
- -------------------
-
- Kristian Lauszus, TKJ Electronics
- Web : http://www.tkjelectronics.com
- e-mail : kristianl@tkjelectronics.com
- */
-
-#include "XBOXUSB.h"
-// 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
-
-XBOXUSB::XBOXUSB(USB *p) :
-pUsb(p), // pointer to USB class instance - mandatory
-bAddress(0), // device address - mandatory
-bPollEnable(false) { // don't start polling before dongle is connected
- for(uint8_t i = 0; i < XBOX_MAX_ENDPOINTS; i++) {
- epInfo[i].epAddr = 0;
- epInfo[i].maxPktSize = (i) ? 0 : 8;
- epInfo[i].epAttribs = 0;
- epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
- }
-
- if(pUsb) // register in USB subsystem
- pUsb->RegisterDeviceClass(this); //set devConfig[] entry
-}
-
-uint8_t XBOXUSB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
- uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
- USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf);
- uint8_t rcode;
- UsbDevice *p = NULL;
- EpInfo *oldep_ptr = NULL;
- uint16_t PID;
- uint16_t VID;
-
- // get memory address of USB device address pool
- AddressPool &addrPool = pUsb->GetAddressPool();
-#ifdef EXTRADEBUG
- Notify(PSTR("\r\nXBOXUSB Init"), 0x80);
-#endif
- // check if address has already been assigned to an instance
- if(bAddress) {
-#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);
-
- if(!p) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nAddress not found"), 0x80);
-#endif
- return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
- }
-
- if(!p->epinfo) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nepinfo is null"), 0x80);
-#endif
- return USB_ERROR_EPINFO_IS_NULL;
- }
-
- // Save old pointer to EP_RECORD of address 0
- oldep_ptr = p->epinfo;
-
- // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
- p->epinfo = epInfo;
-
- p->lowspeed = lowspeed;
-
- // Get device descriptor
- rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
- // Restore p->epinfo
- p->epinfo = oldep_ptr;
-
- if(rcode)
- goto FailGetDevDescr;
-
- VID = udd->idVendor;
- PID = udd->idProduct;
-
- if(VID != XBOX_VID && VID != MADCATZ_VID && VID != JOYTECH_VID && VID != GAMESTOP_VID) // Check VID
- goto FailUnknownDevice;
- if(PID == XBOX_WIRELESS_PID) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nYou have plugged in a wireless Xbox 360 controller - it doesn't support USB communication"), 0x80);
-#endif
- goto FailUnknownDevice;
- } else if(PID == XBOX_WIRELESS_RECEIVER_PID || PID == XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID) {
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nThis library only supports Xbox 360 controllers via USB"), 0x80);
-#endif
- goto FailUnknownDevice;
- } else if(PID != XBOX_WIRED_PID && PID != MADCATZ_WIRED_PID && PID != GAMESTOP_WIRED_PID && PID != AFTERGLOW_WIRED_PID && PID != JOYTECH_WIRED_PID) // Check PID
- goto FailUnknownDevice;
-
- // Allocate new address according to device class
- bAddress = addrPool.AllocAddress(parent, false, port);
-
- if(!bAddress)
- return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
-
- // Extract Max Packet Size from device descriptor
- epInfo[0].maxPktSize = udd->bMaxPacketSize0;
-
- // Assign new address to the device
- rcode = pUsb->setAddr(0, 0, bAddress);
- if(rcode) {
- p->lowspeed = false;
- addrPool.FreeAddress(bAddress);
- bAddress = 0;
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nsetAddr: "), 0x80);
- D_PrintHex (rcode, 0x80);
-#endif
- return rcode;
- }
-#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)
- return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
-
- p->lowspeed = lowspeed;
-
- // Assign epInfo to epinfo pointer - only EP0 is known
- rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
- if(rcode)
- goto FailSetDevTblEntry;
-
- /* The application will work in reduced host mode, so we can save program and data
- memory space. After verifying the VID we will use known values for the
- configuration values for device, interface, endpoints and HID for the XBOX360 Controllers */
-
- /* Initialize data structures for endpoints of device */
- epInfo[ XBOX_INPUT_PIPE ].epAddr = 0x01; // XBOX 360 report endpoint
- epInfo[ XBOX_INPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
- epInfo[ XBOX_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
- epInfo[ XBOX_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
- epInfo[ XBOX_INPUT_PIPE ].bmSndToggle = 0;
- epInfo[ XBOX_INPUT_PIPE ].bmRcvToggle = 0;
- epInfo[ XBOX_OUTPUT_PIPE ].epAddr = 0x02; // XBOX 360 output endpoint
- epInfo[ XBOX_OUTPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
- epInfo[ XBOX_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
- epInfo[ XBOX_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
- epInfo[ XBOX_OUTPUT_PIPE ].bmSndToggle = 0;
- epInfo[ XBOX_OUTPUT_PIPE ].bmRcvToggle = 0;
-
- rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
- if(rcode)
- goto FailSetDevTblEntry;
-
- delay(200); // Give time for address change
-
- rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
- if(rcode)
- goto FailSetConfDescr;
-
-#ifdef DEBUG_USB_HOST
- Notify(PSTR("\r\nXbox 360 Controller Connected\r\n"), 0x80);
-#endif
- onInit();
- Xbox360Connected = true;
- bPollEnable = true;
- return 0; // Successful configuration
-
- /* Diagnostic messages */
-FailGetDevDescr:
-#ifdef DEBUG_USB_HOST
- NotifyFailGetDevDescr();
- goto Fail;
-#endif
-
-FailSetDevTblEntry:
-#ifdef DEBUG_USB_HOST
- NotifyFailSetDevTblEntry();
- goto Fail;
-#endif
-
-FailSetConfDescr:
-#ifdef DEBUG_USB_HOST
- NotifyFailSetConfDescr();
-#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);
- NotifyFail(rcode);
-#endif
- Release();
- return rcode;
-}
-
-/* Performs a cleanup after failed Init() attempt */
-uint8_t XBOXUSB::Release() {
- Xbox360Connected = false;
- pUsb->GetAddressPool().FreeAddress(bAddress);
- bAddress = 0;
- bPollEnable = false;
- return 0;
-}
-
-uint8_t XBOXUSB::Poll() {
- if(!bPollEnable)
- return 0;
- uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
- pUsb->inTransfer(bAddress, epInfo[ XBOX_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
- readReport();
-#ifdef PRINTREPORT
- printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller
-#endif
- return 0;
-}
-
-void XBOXUSB::readReport() {
- if(readBuf == NULL)
- return;
- if(readBuf[0] != 0x00 || readBuf[1] != 0x14) { // Check if it's the correct report - the controller also sends different status reports
- return;
- }
-
- ButtonState = (uint32_t)(readBuf[5] | ((uint16_t)readBuf[4] << 8) | ((uint32_t)readBuf[3] << 16) | ((uint32_t)readBuf[2] << 24));
-
- hatValue[LeftHatX] = (int16_t)(((uint16_t)readBuf[7] << 8) | readBuf[6]);
- hatValue[LeftHatY] = (int16_t)(((uint16_t)readBuf[9] << 8) | readBuf[8]);
- hatValue[RightHatX] = (int16_t)(((uint16_t)readBuf[11] << 8) | readBuf[10]);
- hatValue[RightHatY] = (int16_t)(((uint16_t)readBuf[13] << 8) | readBuf[12]);
-
- //Notify(PSTR("\r\nButtonState"), 0x80);
- //PrintHex(ButtonState, 0x80);
-
- if(ButtonState != OldButtonState) {
- ButtonClickState = (ButtonState >> 16) & ((~OldButtonState) >> 16); // Update click state variable, but don't include the two trigger buttons L2 and R2
- if(((uint8_t)OldButtonState) == 0 && ((uint8_t)ButtonState) != 0) // The L2 and R2 buttons are special as they are analog buttons
- R2Clicked = true;
- if((uint8_t)(OldButtonState >> 8) == 0 && (uint8_t)(ButtonState >> 8) != 0)
- L2Clicked = true;
- OldButtonState = ButtonState;
- }
-}
-
-void XBOXUSB::printReport() { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller
-#ifdef PRINTREPORT
- if(readBuf == NULL)
- return;
- for(uint8_t i = 0; i < XBOX_REPORT_BUFFER_SIZE; i++) {
- D_PrintHex (readBuf[i], 0x80);
- Notify(PSTR(" "), 0x80);
- }
- Notify(PSTR("\r\n"), 0x80);
-#endif
-}
-
-uint8_t XBOXUSB::getButtonPress(ButtonEnum b) {
- if(b == L2) // These are analog buttons
- return (uint8_t)(ButtonState >> 8);
- else if(b == R2)
- return (uint8_t)ButtonState;
- return (bool)(ButtonState & ((uint32_t)pgm_read_word(&XBOX_BUTTONS[(uint8_t)b]) << 16));
-}
-
-bool XBOXUSB::getButtonClick(ButtonEnum b) {
- if(b == L2) {
- if(L2Clicked) {
- L2Clicked = false;
- return true;
- }
- return false;
- } else if(b == R2) {
- if(R2Clicked) {
- R2Clicked = false;
- return true;
- }
- return false;
- }
- uint16_t button = pgm_read_word(&XBOX_BUTTONS[(uint8_t)b]);
- bool click = (ButtonClickState & button);
- ButtonClickState &= ~button; // clear "click" event
- return click;
-}
-
-int16_t XBOXUSB::getAnalogHat(AnalogHatEnum a) {
- return hatValue[a];
-}
-
-/* Xbox Controller commands */
-void XBOXUSB::XboxCommand(uint8_t* data, uint16_t nbytes) {
- //bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x00), Report Type (Output 0x02), interface (0x00), datalength, datalength, data)
- pUsb->ctrlReq(bAddress, epInfo[XBOX_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x00, 0x02, 0x00, nbytes, nbytes, data, NULL);
-}
-
-void XBOXUSB::setLedRaw(uint8_t value) {
- writeBuf[0] = 0x01;
- writeBuf[1] = 0x03;
- writeBuf[2] = value;
-
- XboxCommand(writeBuf, 3);
-}
-
-void XBOXUSB::setLedOn(LEDEnum led) {
- if(led == OFF)
- setLedRaw(0);
- else if(led != ALL) // All LEDs can't be on a the same time
- setLedRaw(pgm_read_byte(&XBOX_LEDS[(uint8_t)led]) + 4);
-}
-
-void XBOXUSB::setLedBlink(LEDEnum led) {
- setLedRaw(pgm_read_byte(&XBOX_LEDS[(uint8_t)led]));
-}
-
-void XBOXUSB::setLedMode(LEDModeEnum ledMode) { // This function is used to do some special LED stuff the controller supports
- setLedRaw((uint8_t)ledMode);
-}
-
-void XBOXUSB::setRumbleOn(uint8_t lValue, uint8_t rValue) {
- writeBuf[0] = 0x00;
- writeBuf[1] = 0x08;
- writeBuf[2] = 0x00;
- writeBuf[3] = lValue; // big weight
- writeBuf[4] = rValue; // small weight
- writeBuf[5] = 0x00;
- writeBuf[6] = 0x00;
- writeBuf[7] = 0x00;
-
- XboxCommand(writeBuf, 8);
-}
-
-void XBOXUSB::onInit() {
- if(pFuncOnInit)
- pFuncOnInit(); // Call the user function
- else
- setLedOn(LED1);
-}
diff --git a/lib/usbhost/USB_Host_Shield_2.0/XBOXUSB.h b/lib/usbhost/USB_Host_Shield_2.0/XBOXUSB.h
deleted file mode 100644
index 1ab37851a795..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/XBOXUSB.h
+++ /dev/null
@@ -1,225 +0,0 @@
-/* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
-
- This software may be distributed and modified under the terms of the GNU
- General Public License version 2 (GPL2) as published by the Free Software
- Foundation and appearing in the file GPL2.TXT included in the packaging of
- this file. Please note that GPL2 Section 2[b] requires that all works based
- on this software must also be made publicly available under the terms of
- the GPL2 ("Copyleft").
-
- Contact information
- -------------------
-
- Kristian Lauszus, TKJ Electronics
- Web : http://www.tkjelectronics.com
- e-mail : kristianl@tkjelectronics.com
- */
-
-#ifndef _xboxusb_h_
-#define _xboxusb_h_
-
-#include "Usb.h"
-#include "hid.h"
-#include "xboxEnums.h"
-
-/* Data Xbox 360 taken from descriptors */
-#define EP_MAXPKTSIZE 32 // max size for data via USB
-
-/* Names we give to the 3 Xbox360 pipes */
-#define XBOX_CONTROL_PIPE 0
-#define XBOX_INPUT_PIPE 1
-#define XBOX_OUTPUT_PIPE 2
-
-// PID and VID of the different devices
-#define XBOX_VID 0x045E // Microsoft Corporation
-#define MADCATZ_VID 0x1BAD // For unofficial Mad Catz controllers
-#define JOYTECH_VID 0x162E // For unofficial Joytech controllers
-#define GAMESTOP_VID 0x0E6F // Gamestop controller
-
-#define XBOX_WIRED_PID 0x028E // Microsoft 360 Wired controller
-#define XBOX_WIRELESS_PID 0x028F // Wireless controller only support charging
-#define XBOX_WIRELESS_RECEIVER_PID 0x0719 // Microsoft Wireless Gaming Receiver
-#define XBOX_WIRELESS_RECEIVER_THIRD_PARTY_PID 0x0291 // Third party Wireless Gaming Receiver
-#define MADCATZ_WIRED_PID 0xF016 // Mad Catz wired controller
-#define JOYTECH_WIRED_PID 0xBEEF // For Joytech wired controller
-#define GAMESTOP_WIRED_PID 0x0401 // Gamestop wired controller
-#define AFTERGLOW_WIRED_PID 0x0213 // Afterglow wired controller - it uses the same VID as a Gamestop controller
-
-#define XBOX_REPORT_BUFFER_SIZE 14 // Size of the input report buffer
-
-#define XBOX_MAX_ENDPOINTS 3
-
-/** This class implements support for a Xbox wired controller via USB. */
-class XBOXUSB : public USBDeviceConfig {
-public:
- /**
- * Constructor for the XBOXUSB class.
- * @param pUsb Pointer to USB class instance.
- */
- XBOXUSB(USB *pUsb);
-
- /** @name USBDeviceConfig implementation */
- /**
- * Initialize the Xbox Controller.
- * @param parent Hub number.
- * @param port Port number on the hub.
- * @param lowspeed Speed of the device.
- * @return 0 on success.
- */
- uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
- /**
- * Release the USB device.
- * @return 0 on success.
- */
- uint8_t Release();
- /**
- * Poll the USB Input endpoins and run the state machines.
- * @return 0 on success.
- */
- uint8_t Poll();
-
- /**
- * Get the device address.
- * @return The device address.
- */
- virtual uint8_t GetAddress() {
- return bAddress;
- };
-
- /**
- * Used to check if the controller has been initialized.
- * @return True if it's ready.
- */
- virtual bool isReady() {
- return bPollEnable;
- };
-
- /**
- * Used by the USB core to check what this driver support.
- * @param vid The device's VID.
- * @param pid The device's PID.
- * @return Returns true if the device's VID and PID matches this driver.
- */
- virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) {
- return ((vid == XBOX_VID || vid == MADCATZ_VID || vid == JOYTECH_VID || vid == GAMESTOP_VID) && (pid == XBOX_WIRED_PID || pid == MADCATZ_WIRED_PID || pid == GAMESTOP_WIRED_PID || pid == AFTERGLOW_WIRED_PID || pid == JOYTECH_WIRED_PID));
- };
- /**@}*/
-
- /** @name Xbox Controller functions */
- /**
- * getButtonPress(ButtonEnum b) will return true as long as the button is held down.
- *
- * While getButtonClick(ButtonEnum b) will only return it once.
- *
- * So you instance if you need to increase a variable once you would use getButtonClick(ButtonEnum b),
- * but if you need to drive a robot forward you would use getButtonPress(ButtonEnum b).
- * @param b ::ButtonEnum to read.
- * @return getButtonClick(ButtonEnum b) will return a bool, while getButtonPress(ButtonEnum b) will return a byte if reading ::L2 or ::R2.
- */
- uint8_t getButtonPress(ButtonEnum b);
- bool getButtonClick(ButtonEnum b);
- /**@}*/
-
- /** @name Xbox Controller functions */
- /**
- * Return the analog value from the joysticks on the controller.
- * @param a Either ::LeftHatX, ::LeftHatY, ::RightHatX or ::RightHatY.
- * @return Returns a signed 16-bit integer.
- */
- int16_t getAnalogHat(AnalogHatEnum a);
-
- /** Turn rumble off and all the LEDs on the controller. */
- void setAllOff() {
- setRumbleOn(0, 0);
- setLedRaw(0);
- };
-
- /** Turn rumble off the controller. */
- void setRumbleOff() {
- setRumbleOn(0, 0);
- };
- /**
- * Turn rumble on.
- * @param lValue Left motor (big weight) inside the controller.
- * @param rValue Right motor (small weight) inside the controller.
- */
- void setRumbleOn(uint8_t lValue, uint8_t rValue);
- /**
- * Set LED value. Without using the ::LEDEnum or ::LEDModeEnum.
- * @param value See:
- * setLedOff(), setLedOn(LEDEnum l),
- * setLedBlink(LEDEnum l), and setLedMode(LEDModeEnum lm).
- */
- void setLedRaw(uint8_t value);
-
- /** Turn all LEDs off the controller. */
- void setLedOff() {
- setLedRaw(0);
- };
- /**
- * Turn on a LED by using ::LEDEnum.
- * @param l ::OFF, ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller.
- */
- void setLedOn(LEDEnum l);
- /**
- * Turn on a LED by using ::LEDEnum.
- * @param l ::ALL, ::LED1, ::LED2, ::LED3 and ::LED4 is supported by the Xbox controller.
- */
- void setLedBlink(LEDEnum l);
- /**
- * Used to set special LED modes supported by the Xbox controller.
- * @param lm See ::LEDModeEnum.
- */
- void setLedMode(LEDModeEnum lm);
-
- /**
- * Used to call your own function when the controller is successfully initialized.
- * @param funcOnInit Function to call.
- */
- void attachOnInit(void (*funcOnInit)(void)) {
- pFuncOnInit = funcOnInit;
- };
- /**@}*/
-
- /** True if a Xbox 360 controller is connected. */
- bool Xbox360Connected;
-
-protected:
- /** Pointer to USB class instance. */
- USB *pUsb;
- /** Device address. */
- uint8_t bAddress;
- /** Endpoint info structure. */
- EpInfo epInfo[XBOX_MAX_ENDPOINTS];
-
-private:
- /**
- * Called when the controller is successfully initialized.
- * Use attachOnInit(void (*funcOnInit)(void)) to call your own function.
- * This is useful for instance if you want to set the LEDs in a specific way.
- */
- void onInit();
- void (*pFuncOnInit)(void); // Pointer to function called in onInit()
-
- bool bPollEnable;
-
- /* Variables to store the buttons */
- uint32_t ButtonState;
- uint32_t OldButtonState;
- uint16_t ButtonClickState;
- int16_t hatValue[4];
- uint16_t controllerStatus;
-
- bool L2Clicked; // These buttons are analog, so we use we use these bools to check if they where clicked or not
- bool R2Clicked;
-
- uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data
- uint8_t writeBuf[8]; // General purpose buffer for output data
-
- void readReport(); // read incoming data
- void printReport(); // print incoming date - Uncomment for debugging
-
- /* Private commands */
- void XboxCommand(uint8_t* data, uint16_t nbytes);
-};
-#endif
diff --git a/lib/usbhost/USB_Host_Shield_2.0/address.h b/lib/usbhost/USB_Host_Shield_2.0/address.h
deleted file mode 100644
index c3e1b3141f27..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/address.h
+++ /dev/null
@@ -1,282 +0,0 @@
-/* Copyright (C) 2011 Circuits At Home, LTD. 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
--------------------
-
-Circuits At Home, LTD
-Web : http://www.circuitsathome.com
-e-mail : support@circuitsathome.com
- */
-
-#if !defined(_usb_h_) || defined(__ADDRESS_H__)
-#error "Never include address.h directly; include Usb.h instead"
-#else
-#define __ADDRESS_H__
-
-
-
-/* NAK powers. To save space in endpoint data structure, amount of retries before giving up and returning 0x4 is stored in */
-/* bmNakPower as a power of 2. The actual nak_limit is then calculated as nak_limit = ( 2^bmNakPower - 1) */
-#define USB_NAK_MAX_POWER 15 //NAK binary order maximum value
-#define USB_NAK_DEFAULT 14 //default 32K-1 NAKs before giving up
-#define USB_NAK_NOWAIT 1 //Single NAK stops transfer
-#define USB_NAK_NONAK 0 //Do not count NAKs, stop retrying after USB Timeout
-
-struct EpInfo {
- uint8_t epAddr; // Endpoint address
- uint8_t maxPktSize; // Maximum packet size
-
- union {
- uint8_t epAttribs;
-
- struct {
- uint8_t bmSndToggle : 1; // Send toggle, when zero bmSNDTOG0, bmSNDTOG1 otherwise
- uint8_t bmRcvToggle : 1; // Send toggle, when zero bmRCVTOG0, bmRCVTOG1 otherwise
- uint8_t bmNakPower : 6; // Binary order for NAK_LIMIT value
- } __attribute__((packed));
- };
-} __attribute__((packed));
-
-// 7 6 5 4 3 2 1 0
-// ---------------------------------
-// | | H | P | P | P | A | A | A |
-// ---------------------------------
-//
-// H - if 1 the address is a hub address
-// P - parent hub address
-// A - device address / port number in case of hub
-//
-
-struct UsbDeviceAddress {
-
- union {
-
- struct {
- uint8_t bmAddress : 3; // device address/port number
- uint8_t bmParent : 3; // parent hub address
- uint8_t bmHub : 1; // hub flag
- uint8_t bmReserved : 1; // reserved, must be zero
- } __attribute__((packed));
- uint8_t devAddress;
- };
-} __attribute__((packed));
-
-#define bmUSB_DEV_ADDR_ADDRESS 0x07
-#define bmUSB_DEV_ADDR_PARENT 0x38
-#define bmUSB_DEV_ADDR_HUB 0x40
-
-struct UsbDevice {
- EpInfo *epinfo; // endpoint info pointer
- UsbDeviceAddress address;
- uint8_t epcount; // number of endpoints
- bool lowspeed; // indicates if a device is the low speed one
- // uint8_t devclass; // device class
-} __attribute__((packed));
-
-class AddressPool {
-public:
- virtual UsbDevice* GetUsbDevicePtr(uint8_t addr) = 0;
- virtual uint8_t AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 0) = 0;
- virtual void FreeAddress(uint8_t addr) = 0;
-};
-
-typedef void (*UsbDeviceHandleFunc)(UsbDevice *pdev);
-
-#define ADDR_ERROR_INVALID_INDEX 0xFF
-#define ADDR_ERROR_INVALID_ADDRESS 0xFF
-
-template
-class AddressPoolImpl : public AddressPool {
- EpInfo dev0ep; //Endpoint data structure used during enumeration for uninitialized device
-
- uint8_t hubCounter; // hub counter is kept
- // in order to avoid hub address duplication
-
- UsbDevice thePool[MAX_DEVICES_ALLOWED];
-
- // Initializes address pool entry
-
- void InitEntry(uint8_t index) {
- thePool[index].address.devAddress = 0;
- thePool[index].epcount = 1;
- thePool[index].lowspeed = 0;
- thePool[index].epinfo = &dev0ep;
- };
-
- // Returns thePool index for a given address
-
- uint8_t FindAddressIndex(uint8_t address = 0) {
- for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++) {
- if(thePool[i].address.devAddress == address)
- return i;
- }
- return 0;
- };
-
- // Returns thePool child index for a given parent
-
- uint8_t FindChildIndex(UsbDeviceAddress addr, uint8_t start = 1) {
- for(uint8_t i = (start < 1 || start >= MAX_DEVICES_ALLOWED) ? 1 : start; i < MAX_DEVICES_ALLOWED; i++) {
- if(thePool[i].address.bmParent == addr.bmAddress)
- return i;
- }
- return 0;
- };
-
- // Frees address entry specified by index parameter
-
- void FreeAddressByIndex(uint8_t index) {
- // Zero field is reserved and should not be affected
- if(index == 0)
- return;
-
- UsbDeviceAddress uda = thePool[index].address;
- // If a hub was switched off all port addresses should be freed
- if(uda.bmHub == 1) {
- for(uint8_t i = 1; (i = FindChildIndex(uda, i));)
- FreeAddressByIndex(i);
-
- // If the hub had the last allocated address, hubCounter should be decremented
- if(hubCounter == uda.bmAddress)
- hubCounter--;
- }
- InitEntry(index);
- }
-
- // Initializes the whole address pool at once
-
- void InitAllAddresses() {
- for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
- InitEntry(i);
-
- hubCounter = 0;
- };
-
-public:
-
- AddressPoolImpl() : hubCounter(0) {
- // Zero address is reserved
- InitEntry(0);
-
- thePool[0].address.devAddress = 0;
- thePool[0].epinfo = &dev0ep;
- dev0ep.epAddr = 0;
- dev0ep.maxPktSize = 8;
- dev0ep.epAttribs = 0; //set DATA0/1 toggles to 0
- dev0ep.bmNakPower = USB_NAK_MAX_POWER;
-
- InitAllAddresses();
- };
-
- // Returns a pointer to a specified address entry
-
- virtual UsbDevice* GetUsbDevicePtr(uint8_t addr) {
- if(!addr)
- return thePool;
-
- uint8_t index = FindAddressIndex(addr);
-
- return (!index) ? NULL : thePool + index;
- };
-
- // Performs an operation specified by pfunc for each addressed device
-
- void ForEachUsbDevice(UsbDeviceHandleFunc pfunc) {
- if(!pfunc)
- return;
-
- for(uint8_t i = 1; i < MAX_DEVICES_ALLOWED; i++)
- if(thePool[i].address.devAddress)
- pfunc(thePool + i);
- };
-
- // Allocates new address
-
- virtual uint8_t AllocAddress(uint8_t parent, bool is_hub = false, uint8_t port = 0) {
- /* if (parent != 0 && port == 0)
- USB_HOST_SERIAL.println("PRT:0"); */
- UsbDeviceAddress _parent;
- _parent.devAddress = parent;
- if(_parent.bmReserved || port > 7)
- //if(parent > 127 || port > 7)
- return 0;
-
- if(is_hub && hubCounter == 7)
- return 0;
-
- // finds first empty address entry starting from one
- uint8_t index = FindAddressIndex(0);
-
- if(!index) // if empty entry is not found
- return 0;
-
- if(_parent.devAddress == 0) {
- if(is_hub) {
- thePool[index].address.devAddress = 0x41;
- hubCounter++;
- } else
- thePool[index].address.devAddress = 1;
-
- return thePool[index].address.devAddress;
- }
-
- UsbDeviceAddress addr;
- addr.devAddress = 0; // Ensure all bits are zero
- addr.bmParent = _parent.bmAddress;
- if(is_hub) {
- addr.bmHub = 1;
- addr.bmAddress = ++hubCounter;
- } else {
- addr.bmHub = 0;
- addr.bmAddress = port;
- }
- thePool[index].address = addr;
- /*
- USB_HOST_SERIAL.print("Addr:");
- USB_HOST_SERIAL.print(addr.bmHub, HEX);
- USB_HOST_SERIAL.print(".");
- USB_HOST_SERIAL.print(addr.bmParent, HEX);
- USB_HOST_SERIAL.print(".");
- USB_HOST_SERIAL.println(addr.bmAddress, HEX);
- */
- return thePool[index].address.devAddress;
- };
-
- // Empties pool entry
-
- virtual void FreeAddress(uint8_t addr) {
- // if the root hub is disconnected all the addresses should be initialized
- if(addr == 0x41) {
- InitAllAddresses();
- return;
- }
- uint8_t index = FindAddressIndex(addr);
- FreeAddressByIndex(index);
- };
-
- // Returns number of hubs attached
- // It can be rather helpfull to find out if there are hubs attached than getting the exact number of hubs.
- //uint8_t GetNumHubs()
- //{
- // return hubCounter;
- //};
- //uint8_t GetNumDevices()
- //{
- // uint8_t counter = 0;
-
- // for (uint8_t i=1; iRegisterDeviceClass(this); //set devConfig[] entry
- }
-}
-
-uint8_t ADK::ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed) {
- return Init(parent, port, lowspeed); // Just call Init. Yes, really!
-}
-
-/* Connection initialization of an Android phone */
-uint8_t ADK::Init(uint8_t parent, uint8_t port, bool lowspeed) {
- uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
- USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast(buf);
- uint8_t rcode;
- uint8_t num_of_conf; // number of configurations
- UsbDevice *p = NULL;
- EpInfo *oldep_ptr = NULL;
-
- // get memory address of USB device address pool
- AddressPool &addrPool = pUsb->GetAddressPool();
-
- USBTRACE("\r\nADK Init");
-
- // check if address has already been assigned to an instance
- if(bAddress) {
- USBTRACE("\r\nAddress in use");
- return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
- }
-
- // Get pointer to pseudo device with address 0 assigned
- p = addrPool.GetUsbDevicePtr(0);
-
- if(!p) {
- USBTRACE("\r\nAddress not found");
- return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
- }
-
- if(!p->epinfo) {
- USBTRACE("epinfo is null\r\n");
- return USB_ERROR_EPINFO_IS_NULL;
- }
-
- // Save old pointer to EP_RECORD of address 0
- oldep_ptr = p->epinfo;
-
- // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
- p->epinfo = epInfo;
-
- p->lowspeed = lowspeed;
-
- // Get device descriptor
- rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf);
-
- // Restore p->epinfo
- p->epinfo = oldep_ptr;
-
- if(rcode) {
- goto FailGetDevDescr;
- }
-
- // Allocate new address according to device class
- bAddress = addrPool.AllocAddress(parent, false, port);
-
- // Extract Max Packet Size from device descriptor
- epInfo[0].maxPktSize = udd->bMaxPacketSize0;
-
- // Assign new address to the device
- rcode = pUsb->setAddr(0, 0, bAddress);
- if(rcode) {
- p->lowspeed = false;
- addrPool.FreeAddress(bAddress);
- bAddress = 0;
- //USBTRACE2("setAddr:",rcode);
- return rcode;
- }//if (rcode...
-
- //USBTRACE2("\r\nAddr:", bAddress);
- // Spec says you should wait at least 200ms.
- //delay(300);
-
- p->lowspeed = false;
-
- //get pointer to assigned address record
- p = addrPool.GetUsbDevicePtr(bAddress);
- if(!p) {
- return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
- }
-
- p->lowspeed = lowspeed;
-
- // Assign epInfo to epinfo pointer - only EP0 is known
- rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
- if(rcode) {
- goto FailSetDevTblEntry;
- }
-
- //check if ADK device is already in accessory mode; if yes, configure and exit
- if(udd->idVendor == ADK_VID &&
- (udd->idProduct == ADK_PID || udd->idProduct == ADB_PID)) {
- USBTRACE("\r\nAcc.mode device detected");
- /* go through configurations, find first bulk-IN, bulk-OUT EP, fill epInfo and quit */
- num_of_conf = udd->bNumConfigurations;
-
- //USBTRACE2("\r\nNC:",num_of_conf);
- for(uint8_t i = 0; i < num_of_conf; i++) {
- ConfigDescParser < 0, 0, 0, 0 > confDescrParser(this);
- delay(1);
- rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
-#if defined(XOOM)
- //added by Jaylen Scott Vanorden
- if(rcode) {
- USBTRACE2("\r\nGot 1st bad code for config: ", rcode);
- // Try once more
- rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
- }
-#endif
- if(rcode) {
- goto FailGetConfDescr;
- }
- if(bNumEP > 2) {
- break;
- }
- } // for (uint8_t i=0; isetEpInfoEntry(bAddress, 3, epInfo);
- if(rcode) {
- goto FailSetDevTblEntry;
- }
- }
-
- // Set Configuration Value
- rcode = pUsb->setConf(bAddress, 0, bConfNum);
- if(rcode) {
- goto FailSetConfDescr;
- }
- /* print endpoint structure */
- /*
- USBTRACE("\r\nEndpoint Structure:");
- USBTRACE("\r\nEP0:");
- USBTRACE2("\r\nAddr: ", epInfo[0].epAddr);
- USBTRACE2("\r\nMax.pkt.size: ", epInfo[0].maxPktSize);
- USBTRACE2("\r\nAttr: ", epInfo[0].epAttribs);
- USBTRACE("\r\nEpout:");
- USBTRACE2("\r\nAddr: ", epInfo[epDataOutIndex].epAddr);
- USBTRACE2("\r\nMax.pkt.size: ", epInfo[epDataOutIndex].maxPktSize);
- USBTRACE2("\r\nAttr: ", epInfo[epDataOutIndex].epAttribs);
- USBTRACE("\r\nEpin:");
- USBTRACE2("\r\nAddr: ", epInfo[epDataInIndex].epAddr);
- USBTRACE2("\r\nMax.pkt.size: ", epInfo[epDataInIndex].maxPktSize);
- USBTRACE2("\r\nAttr: ", epInfo[epDataInIndex].epAttribs);
- */
-
- USBTRACE("\r\nConfiguration successful");
- ready = true;
- return 0; //successful configuration
- }//if( buf->idVendor == ADK_VID...
-
- //probe device - get accessory protocol revision
- {
- uint16_t adkproto = -1;
- delay(1);
- rcode = getProto((uint8_t*) & adkproto);
-#if defined(XOOM)
- //added by Jaylen Scott Vanorden
- if(rcode) {
- USBTRACE2("\r\nGot 1st bad code for proto: ", rcode);
- // Try once more
- rcode = getProto((uint8_t*) & adkproto);
- }
-#endif
- if(rcode) {
- goto FailGetProto; //init fails
- }
- USBTRACE2("\r\nADK protocol rev. ", adkproto);
- }
-
- delay(100);
-
- //sending ID strings
- sendStr(ACCESSORY_STRING_MANUFACTURER, manufacturer);
- delay(10);
- sendStr(ACCESSORY_STRING_MODEL, model);
- delay(10);
- sendStr(ACCESSORY_STRING_DESCRIPTION, description);
- delay(10);
- sendStr(ACCESSORY_STRING_VERSION, version);
- delay(10);
- sendStr(ACCESSORY_STRING_URI, uri);
- delay(10);
- sendStr(ACCESSORY_STRING_SERIAL, serial);
-
- delay(100);
-
- //switch to accessory mode
- //the Android phone will reset
- rcode = switchAcc();
- if(rcode) {
- goto FailSwAcc; //init fails
- }
- rcode = USB_ERROR_CONFIG_REQUIRES_ADDITIONAL_RESET;
- delay(100); // Give Android a chance to do its reset. This is a guess, and possibly could be lower.
- goto SwAttempt; //switch to accessory mode attempted
-
- /* diagnostic messages */
-FailGetDevDescr:
-#ifdef DEBUG_USB_HOST
- NotifyFailGetDevDescr(rcode);
- goto Fail;
-#endif
-
-FailSetDevTblEntry:
-#ifdef DEBUG_USB_HOST
- NotifyFailSetDevTblEntry(rcode);
- goto Fail;
-#endif
-
-FailGetConfDescr:
-#ifdef DEBUG_USB_HOST
- NotifyFailGetConfDescr(rcode);
- goto Fail;
-#endif
-
-FailSetConfDescr:
-#ifdef DEBUG_USB_HOST
- NotifyFailSetConfDescr(rcode);
- goto Fail;
-#endif
-
-FailGetProto:
-#ifdef DEBUG_USB_HOST
- USBTRACE("\r\ngetProto:");
- goto Fail;
-#endif
-
-FailSwAcc:
-#ifdef DEBUG_USB_HOST
- USBTRACE("\r\nswAcc:");
- goto Fail;
-#endif
-
- //FailOnInit:
- // USBTRACE("OnInit:");
- // goto Fail;
- //
-SwAttempt:
-#ifdef DEBUG_USB_HOST
- USBTRACE("\r\nAccessory mode switch attempt");
-Fail:
-#endif
- //USBTRACE2("\r\nADK Init Failed, error code: ", rcode);
- //NotifyFail(rcode);
- Release();
- return rcode;
-}
-
-/* Extracts bulk-IN and bulk-OUT endpoint information from config descriptor */
-void ADK::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) {
- //ErrorMessage(PSTR("Conf.Val"), conf);
- //ErrorMessage(PSTR("Iface Num"), iface);
- //ErrorMessage(PSTR("Alt.Set"), alt);
-
- //added by Yuuichi Akagawa
- if(bNumEP == 3) {
- return;
- }
-
- bConfNum = conf;
-
- if((pep->bmAttributes & 0x02) == 2) {
- uint8_t index = ((pep->bEndpointAddress & 0x80) == 0x80) ? epDataInIndex : epDataOutIndex;
- // Fill in the endpoint info structure
- epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
- epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
-
- bNumEP++;
-
- //PrintEndpointDescriptor(pep);
- }
-}
-
-/* Performs a cleanup after failed Init() attempt */
-uint8_t ADK::Release() {
- pUsb->GetAddressPool().FreeAddress(bAddress);
-
- bNumEP = 1; //must have to be reset to 1
-
- bAddress = 0;
- ready = false;
- return 0;
-}
-
-uint8_t ADK::RcvData(uint16_t *bytes_rcvd, uint8_t *dataptr) {
- //USBTRACE2("\r\nAddr: ", bAddress );
- //USBTRACE2("\r\nEP: ",epInfo[epDataInIndex].epAddr);
- return pUsb->inTransfer(bAddress, epInfo[epDataInIndex].epAddr, bytes_rcvd, dataptr);
-}
-
-uint8_t ADK::SndData(uint16_t nbytes, uint8_t *dataptr) {
- return pUsb->outTransfer(bAddress, epInfo[epDataOutIndex].epAddr, nbytes, dataptr);
-}
-
-void ADK::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr) {
- Notify(PSTR("Endpoint descriptor:"), 0x80);
- Notify(PSTR("\r\nLength:\t\t"), 0x80);
- D_PrintHex (ep_ptr->bLength, 0x80);
- Notify(PSTR("\r\nType:\t\t"), 0x80);
- D_PrintHex (ep_ptr->bDescriptorType, 0x80);
- Notify(PSTR("\r\nAddress:\t"), 0x80);
- D_PrintHex (ep_ptr->bEndpointAddress, 0x80);
- Notify(PSTR("\r\nAttributes:\t"), 0x80);
- D_PrintHex (ep_ptr->bmAttributes, 0x80);
- Notify(PSTR("\r\nMaxPktSize:\t"), 0x80);
- D_PrintHex (ep_ptr->wMaxPacketSize, 0x80);
- Notify(PSTR("\r\nPoll Intrv:\t"), 0x80);
- D_PrintHex (ep_ptr->bInterval, 0x80);
- Notify(PSTR("\r\n"), 0x80);
-}
diff --git a/lib/usbhost/USB_Host_Shield_2.0/adk.h b/lib/usbhost/USB_Host_Shield_2.0/adk.h
deleted file mode 100644
index 4a2920b88a18..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/adk.h
+++ /dev/null
@@ -1,140 +0,0 @@
-/* Copyright (C) 2011 Circuits At Home, LTD. 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
--------------------
-
-Circuits At Home, LTD
-Web : http://www.circuitsathome.com
-e-mail : support@circuitsathome.com
- */
-
-/* Google ADK interface support header */
-
-#if !defined(_ADK_H_)
-#define _ADK_H_
-
-#include "Usb.h"
-
-#define ADK_VID 0x18D1
-#define ADK_PID 0x2D00
-#define ADB_PID 0x2D01
-
-#define XOOM //enables repeating getProto() and getConf() attempts
-//necessary for slow devices such as Motorola XOOM
-//defined by default, can be commented out to save memory
-
-/* requests */
-
-#define ADK_GETPROTO 51 //check USB accessory protocol version
-#define ADK_SENDSTR 52 //send identifying string
-#define ADK_ACCSTART 53 //start device in accessory mode
-
-#define bmREQ_ADK_GET USB_SETUP_DEVICE_TO_HOST|USB_SETUP_TYPE_VENDOR|USB_SETUP_RECIPIENT_DEVICE
-#define bmREQ_ADK_SEND USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_VENDOR|USB_SETUP_RECIPIENT_DEVICE
-
-#define ACCESSORY_STRING_MANUFACTURER 0
-#define ACCESSORY_STRING_MODEL 1
-#define ACCESSORY_STRING_DESCRIPTION 2
-#define ACCESSORY_STRING_VERSION 3
-#define ACCESSORY_STRING_URI 4
-#define ACCESSORY_STRING_SERIAL 5
-
-#define ADK_MAX_ENDPOINTS 3 //endpoint 0, bulk_IN, bulk_OUT
-
-class ADK;
-
-class ADK : public USBDeviceConfig, public UsbConfigXtracter {
-private:
- /* ID strings */
- const char* manufacturer;
- const char* model;
- const char* description;
- const char* version;
- const char* uri;
- const char* serial;
-
- /* ADK proprietary requests */
- uint8_t getProto(uint8_t* adkproto);
- uint8_t sendStr(uint8_t index, const char* str);
- uint8_t switchAcc(void);
-
-protected:
- static const uint8_t epDataInIndex; // DataIn endpoint index
- static const uint8_t epDataOutIndex; // DataOUT endpoint index
-
- /* mandatory members */
- USB *pUsb;
- uint8_t bAddress;
- uint8_t bConfNum; // configuration number
-
- uint8_t bNumEP; // total number of EP in the configuration
- bool ready;
-
- /* Endpoint data structure */
- EpInfo epInfo[ADK_MAX_ENDPOINTS];
-
- void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
-
-public:
- ADK(USB *pUsb, const char* manufacturer,
- const char* model,
- const char* description,
- const char* version,
- const char* uri,
- const char* serial);
-
- // Methods for receiving and sending data
- uint8_t RcvData(uint16_t *nbytesptr, uint8_t *dataptr);
- uint8_t SndData(uint16_t nbytes, uint8_t *dataptr);
-
-
- // USBDeviceConfig implementation
- uint8_t ConfigureDevice(uint8_t parent, uint8_t port, bool lowspeed);
- uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed);
- uint8_t Release();
-
- virtual uint8_t Poll() {
- return 0;
- };
-
- virtual uint8_t GetAddress() {
- return bAddress;
- };
-
- virtual bool isReady() {
- return ready;
- };
-
- virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) {
- return (vid == ADK_VID && (pid == ADK_PID || pid == ADB_PID));
- };
-
- //UsbConfigXtracter implementation
- void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep);
-}; //class ADK : public USBDeviceConfig ...
-
-/* get ADK protocol version */
-
-/* returns 2 bytes in *adkproto */
-inline uint8_t ADK::getProto(uint8_t* adkproto) {
- return ( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_GET, ADK_GETPROTO, 0, 0, 0, 2, 2, adkproto, NULL));
-}
-
-/* send ADK string */
-inline uint8_t ADK::sendStr(uint8_t index, const char* str) {
- return ( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_SEND, ADK_SENDSTR, 0, 0, index, strlen(str) + 1, strlen(str) + 1, (uint8_t*)str, NULL));
-}
-
-/* switch to accessory mode */
-inline uint8_t ADK::switchAcc(void) {
- return ( pUsb->ctrlReq(bAddress, 0, bmREQ_ADK_SEND, ADK_ACCSTART, 0, 0, 0, 0, 0, NULL, NULL));
-}
-
-#endif // _ADK_H_
diff --git a/lib/usbhost/USB_Host_Shield_2.0/avrpins.h b/lib/usbhost/USB_Host_Shield_2.0/avrpins.h
deleted file mode 100644
index 4e60e3a229a4..000000000000
--- a/lib/usbhost/USB_Host_Shield_2.0/avrpins.h
+++ /dev/null
@@ -1,1130 +0,0 @@
-/* Copyright (C) 2011 Circuits At Home, LTD. 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
--------------------
-
-Circuits At Home, LTD
-Web : http://www.circuitsathome.com
-e-mail : support@circuitsathome.com
- */
-
-/* derived from Konstantin Chizhov's AVR port templates */
-
-#if !defined(_usb_h_) || defined(_avrpins_h_)
-#error "Never include avrpins.h directly; include Usb.h instead"
-#else
-#define _avrpins_h_
-
-#if defined(__AVR__)
-
-// pointers are 16 bits on AVR
-#define pgm_read_pointer(p) pgm_read_word(p)
-
-// Support for these boards needs to be manually activated in settings.h or in a makefile
-#if !defined(BOARD_MEGA_ADK) && defined(__AVR_ATmega2560__) && (USE_UHS_MEGA_ADK || defined(ARDUINO_AVR_ADK))
-#define BOARD_MEGA_ADK
-#elif !defined(BOARD_BLACK_WIDDOW) && USE_UHS_BLACK_WIDDOW
-#define BOARD_BLACK_WIDDOW
-#endif
-
-#ifdef PORTA
-#define USE_PORTA
-#endif
-#ifdef PORTB
-#define USE_PORTB
-#endif
-#ifdef PORTC
-#define USE_PORTC
-#endif
-#ifdef PORTD
-#define USE_PORTD
-#endif
-#ifdef PORTE
-#define USE_PORTE
-#endif
-#ifdef PORTF
-#define USE_PORTF
-#endif
-#ifdef PORTG
-#define USE_PORTG
-#endif
-#ifdef PORTH
-#define USE_PORTH
-#endif
-#ifdef PORTJ
-#define USE_PORTJ
-#endif
-#ifdef PORTK
-#define USE_PORTK
-#endif
-#ifdef PORTL
-#define USE_PORTL
-#endif
-#ifdef PORTQ
-#define USE_PORTQ
-#endif
-#ifdef PORTR
-#define USE_PORTR
-#endif
-
-#ifdef TCCR0A
-#define USE_TCCR0A
-#endif
-#ifdef TCCR1A
-#define USE_TCCR1A
-#endif
-#ifdef TCCR2A
-#define USE_TCCR2A
-#endif
-
-//Port definitions for AtTiny, AtMega families.
-
-#define MAKE_PORT(portName, ddrName, pinName, className, ID) \
- class className{\
- public:\
- typedef uint8_t DataT;\
- public:\
- static void Write(DataT value){portName = value;}\
- static void ClearAndSet(DataT clearMask, DataT value){portName = (portName & ~clearMask) | value;}\
- static DataT Read(){return portName;}\
- static void DirWrite(DataT value){ddrName = value;}\
- static DataT DirRead(){return ddrName;}\
- static void Set(DataT value){portName |= value;}\
- static void Clear(DataT value){portName &= ~value;}\
- static void Toggle(DataT value){portName ^= value;}\
- static void DirSet(DataT value){ddrName |= value;}\
- static void DirClear(DataT value){ddrName &= ~value;}\
- static void DirToggle(DataT value){ddrName ^= value;}\
- static DataT PinRead(){return pinName;}\
- enum{Id = ID};\
- enum{Width=sizeof(DataT)*8};\
- };
-
-// TCCR registers to set/clear Arduino PWM
-#define MAKE_TCCR(TccrName, className) \
- class className{\
- public:\
- typedef uint8_t DataT;\
- public:\
- static void Write(DataT value){TccrName = value;}\
- static void ClearAndSet(DataT clearMask, DataT value){TccrName = (TccrName & ~clearMask) | value;}\
- static DataT Read(){return TccrName;}\
- static void Set(DataT value){TccrName |= value;}\
- static void Clear(DataT value){TccrName &= ~value;}\
- static void Toggle(DataT value){TccrName ^= value;}\
- enum{Width=sizeof(DataT)*8};\
- };
-
-#ifdef USE_PORTA
-
-MAKE_PORT(PORTA, DDRA, PINA, Porta, 'A')
-#endif
-#ifdef USE_PORTB
-MAKE_PORT(PORTB, DDRB, PINB, Portb, 'B')
-#endif
-#ifdef USE_PORTC
-MAKE_PORT(PORTC, DDRC, PINC, Portc, 'C')
-#endif
-#ifdef USE_PORTD
-MAKE_PORT(PORTD, DDRD, PIND, Portd, 'D')
-#endif
-#ifdef USE_PORTE
-MAKE_PORT(PORTE, DDRE, PINE, Porte, 'E')
-#endif
-#ifdef USE_PORTF
-MAKE_PORT(PORTF, DDRF, PINF, Portf, 'F')
-#endif
-#ifdef USE_PORTG
-MAKE_PORT(PORTG, DDRG, PING, Portg, 'G')
-#endif
-#ifdef USE_PORTH
-MAKE_PORT(PORTH, DDRH, PINH, Porth, 'H')
-#endif
-#ifdef USE_PORTJ
-MAKE_PORT(PORTJ, DDRJ, PINJ, Portj, 'J')
-#endif
-#ifdef USE_PORTK
-MAKE_PORT(PORTK, DDRK, PINK, Portk, 'K')
-#endif
-#ifdef USE_PORTL
-MAKE_PORT(PORTL, DDRL, PINL, Portl, 'L')
-#endif
-#ifdef USE_PORTQ
-MAKE_PORT(PORTQ, DDRQ, PINQ, Portq, 'Q')
-#endif
-#ifdef USE_PORTR
-MAKE_PORT(PORTR, DDRR, PINR, Portr, 'R')
-#endif
-
-#ifdef USE_TCCR0A
-MAKE_TCCR(TCCR0A, Tccr0a)
-#endif
-#ifdef USE_TCCR1A
-MAKE_TCCR(TCCR1A, Tccr1a)
-#endif
-#ifdef USE_TCCR2A
-MAKE_TCCR(TCCR2A, Tccr2a)
-#endif
-
-// this class represents one pin in a IO port.
-// It is fully static.
-template
-class TPin {
- // BOOST_STATIC_ASSERT(PIN < PORT::Width);
-public:
- typedef PORT Port;
-
- enum {
- Number = PIN
- };
-
- static void Set() {
- PORT::Set(1 << PIN);
- }
-
- static void Set(uint8_t val) {
- if(val)
- Set();
- else Clear();
- }
-
- static void SetDir(uint8_t val) {
- if(val)
- SetDirWrite();
- else SetDirRead();
- }
-
- static void Clear() {
- PORT::Clear(1 << PIN);
- }
-
- static void Toggle() {
- PORT::Toggle(1 << PIN);
- }
-
- static void SetDirRead() {
- PORT::DirClear(1 << PIN);
- }
-
- static void SetDirWrite() {
- PORT::DirSet(1 << PIN);
- }
-
- static uint8_t IsSet() {
- return PORT::PinRead() & (uint8_t)(1 << PIN);
- }
-
- static void WaiteForSet() {
- while(IsSet() == 0) {
- }
- }
-
- static void WaiteForClear() {
- while(IsSet()) {
- }
- }
-}; //class TPin...
-
-// this class represents one bit in TCCR port.
-// used to set/clear TCCRx bits
-// It is fully static.
-
-template
-class TCom {
- // BOOST_STATIC_ASSERT(PIN < PORT::Width);
-public:
- typedef TCCR Tccr;
-
- enum {
- Com = COM
- };
-
- static void Set() {
- TCCR::Set(1 << COM);
- }
-
- static void Clear() {
- TCCR::Clear(1 << COM);
- }
-
- static void Toggle() {
- TCCR::Toggle(1 << COM);
- }
-}; //class TCom...
-
-//Short pin definitions
-#ifdef USE_PORTA
-typedef TPin Pa0;
-typedef TPin Pa1;
-typedef TPin Pa2;
-typedef TPin Pa3;
-typedef TPin Pa4;
-typedef TPin Pa5;
-typedef TPin Pa6;
-typedef TPin Pa7;
-#endif
-
-#ifdef USE_PORTB
-typedef TPin Pb0;
-typedef TPin Pb1;
-typedef TPin Pb2;
-typedef TPin Pb3;
-typedef TPin Pb4;
-typedef TPin Pb5;
-typedef TPin Pb6;
-typedef TPin Pb7;
-#endif
-
-#ifdef USE_PORTC
-typedef TPin Pc0;
-typedef TPin Pc1;
-typedef TPin Pc2;
-typedef TPin Pc3;
-typedef TPin