From 7c475c91e01821f00ed01d0014b30e8cd0d375f4 Mon Sep 17 00:00:00 2001 From: Fred Date: Sat, 14 Feb 2015 11:09:24 +0000 Subject: [PATCH 1/6] Xbox ONE Controller support --- README.md | 13 +- XBOXONE.cpp | 359 ++++++++++++++++++++++++++++++ XBOXONE.h | 180 +++++++++++++++ controllerEnums.h | 8 + examples/Xbox/XBOXONE/XBOXONE.ino | 110 +++++++++ keywords.txt | 6 + 6 files changed, 675 insertions(+), 1 deletion(-) create mode 100644 XBOXONE.cpp create mode 100644 XBOXONE.h create mode 100644 examples/Xbox/XBOXONE/XBOXONE.ino diff --git a/README.md b/README.md index e7f4ed56..a0372681 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,8 @@ For more information about the hardware see the [Hardware Manual](http://www.cir * 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 @@ -47,6 +49,7 @@ Help yourself by helping us support you! Many thousands of hours have been spent * [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) @@ -229,6 +232,14 @@ All the information regarding the Xbox 360 controller protocol are form these si * * +#### 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 is also supported via Bluetooth. @@ -308,4 +319,4 @@ See the "Interface modifications" section in the [hardware manual](https://www.c > 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);```. \ No newline at end of file +* 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);```. diff --git a/XBOXONE.cpp b/XBOXONE.cpp new file mode 100644 index 00000000..8df3500e --- /dev/null +++ b/XBOXONE.cpp @@ -0,0 +1,359 @@ +/* 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 360 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 seperate message + if (readBuf[4] == 1) { + ButtonState |= XBOX_BUTTONS[XBOX]; + } + else { + ButtonState &= XBOX_BUTTONS[XBOX]; + } + if(ButtonState != OldButtonState) { + ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable, but don't include the two trigger buttons L2 and R2 + OldButtonState = ButtonState; + } + } + 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 seperate, 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[LeftTrigger] = (uint16_t)(((uint16_t)readBuf[7] << 8) | readBuf[6]); + triggerValue[RightTrigger] = (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; + } +} + +void XBOXONE::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 XBOXONE::getButtonPress(ButtonEnum b) { + return (bool)(ButtonState & ((uint16_t)pgm_read_word(&XBOX_BUTTONS[(uint8_t)b]))); +} + +bool XBOXONE::getButtonClick(ButtonEnum b) { + 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]; +} + +uint16_t XBOXONE::getTrigger(TriggerEnum a) { + return triggerValue[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/XBOXONE.h b/XBOXONE.h new file mode 100644 index 00000000..cbfe82ea --- /dev/null +++ b/XBOXONE.h @@ -0,0 +1,180 @@ +/* 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 + +// Used in control endpoint header for HID Commands +#define bmREQ_HID_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE +#define HID_REQUEST_SET_REPORT 0x09 + +#define XBOX_MAX_ENDPOINTS 3 + +/** This class implements support for a Xbox wired controller 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 boolean 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 byte if reading ::L2 or ::R2. + */ + uint8_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); + + /** @name Xbox Controller functions */ + /** + * Return the analog value from the triggers on the controller. + * @param a Either ::LeftTrigger, or ::RightTrigger. + * @return Returns an unsigned 16-bit integer. + */ + uint16_t getTrigger(TriggerEnum 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]; + int16_t triggerValue[2]; + + 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/controllerEnums.h b/controllerEnums.h index 0169c763..9d971f85 100644 --- a/controllerEnums.h +++ b/controllerEnums.h @@ -159,6 +159,14 @@ enum AnalogHatEnum { RightHatY = 3, }; +/** Triggers on Xbox One controller. */ +enum TriggerEnum { + /** Left trigger */ + LeftTrigger = 0, + /** Right trigger */ + RightTrigger = 1, +}; + /** * Sensors inside the Sixaxis Dualshock 3, Move controller and PS4 controller. * Note: that the location is shifted 9 when it's connected via USB on the PS3 controller. diff --git a/examples/Xbox/XBOXONE/XBOXONE.ino b/examples/Xbox/XBOXONE/XBOXONE.ino new file mode 100644 index 00000000..5e2c8d99 --- /dev/null +++ b/examples/Xbox/XBOXONE/XBOXONE.ino @@ -0,0 +1,110 @@ +/* + Example sketch for the Xbox ONE USB library - by guruthree, based on work by + Kristian Lauszus. + */ + +#include +// Satisfy IDE, which only needs to see the include statment in the ino. +#ifdef dobogusinclude +#include +#endif + +USB Usb; +XBOXONE Xbox(&Usb); + +void setup() { + Serial.begin(115200); + while (!Serial); // Wait for serial port to connect - used on Leonardo, Teensy and other boards with built-in USB CDC serial connection + if (Usb.Init() == -1) { + Serial.print(F("\r\nOSC did not start")); + while (1); //halt + } + Serial.print(F("\r\nXBOX USB Library Started")); +} +void loop() { + Usb.Task(); + if (Xbox.XboxOneConnected) { + + if (Xbox.getAnalogHat(LeftHatX) > 7500 || Xbox.getAnalogHat(LeftHatX) < -7500 || Xbox.getAnalogHat(LeftHatY) > 7500 || Xbox.getAnalogHat(LeftHatY) < -7500 || Xbox.getAnalogHat(RightHatX) > 7500 || Xbox.getAnalogHat(RightHatX) < -7500 || Xbox.getAnalogHat(RightHatY) > 7500 || Xbox.getAnalogHat(RightHatY) < -7500) { + if (Xbox.getAnalogHat(LeftHatX) > 7500 || Xbox.getAnalogHat(LeftHatX) < -7500) { + Serial.print(F("LeftHatX: ")); + Serial.print(Xbox.getAnalogHat(LeftHatX)); + Serial.print("\t"); + } + if (Xbox.getAnalogHat(LeftHatY) > 7500 || Xbox.getAnalogHat(LeftHatY) < -7500) { + Serial.print(F("LeftHatY: ")); + Serial.print(Xbox.getAnalogHat(LeftHatY)); + Serial.print("\t"); + } + if (Xbox.getAnalogHat(RightHatX) > 7500 || Xbox.getAnalogHat(RightHatX) < -7500) { + Serial.print(F("RightHatX: ")); + Serial.print(Xbox.getAnalogHat(RightHatX)); + Serial.print("\t"); + } + if (Xbox.getAnalogHat(RightHatY) > 7500 || Xbox.getAnalogHat(RightHatY) < -7500) { + Serial.print(F("RightHatY: ")); + Serial.print(Xbox.getAnalogHat(RightHatY)); + } + Serial.println(); + } + + if (Xbox.getTrigger(LeftTrigger) > 0 || Xbox.getTrigger(RightTrigger) > 0) { + if (Xbox.getTrigger(LeftTrigger) > 0) { + Serial.print(F("LeftTrigger: ")); + Serial.print(Xbox.getTrigger(LeftTrigger)); + Serial.print("\t"); + } + if (Xbox.getTrigger(RightTrigger) > 0) { + Serial.print(F("RightTrigger: ")); + Serial.print(Xbox.getTrigger(RightTrigger)); + Serial.print("\t"); + } + Serial.println(); + } + + if (Xbox.getButtonClick(UP)) { + Serial.println(F("Up")); + } + if (Xbox.getButtonClick(DOWN)) { + Serial.println(F("Down")); + } + if (Xbox.getButtonClick(LEFT)) { + Serial.println(F("Left")); + } + if (Xbox.getButtonClick(RIGHT)) { + Serial.println(F("Right")); + } + + if (Xbox.getButtonClick(START)) { + Serial.println(F("Start")); + } + if (Xbox.getButtonClick(BACK)) { + Serial.println(F("Back")); + } + if (Xbox.getButtonClick(L3)) + Serial.println(F("L3")); + if (Xbox.getButtonClick(R3)) + Serial.println(F("R3")); + + if (Xbox.getButtonClick(L1)) + Serial.println(F("L1")); + if (Xbox.getButtonClick(R1)) + Serial.println(F("R1")); + if (Xbox.getButtonClick(XBOX)) { + Serial.println(F("Xbox")); + } + if (Xbox.getButtonClick(SYNC)) { + Serial.println(F("Sync")); + } + + if (Xbox.getButtonClick(A)) + Serial.println(F("A")); + if (Xbox.getButtonClick(B)) + Serial.println(F("B")); + if (Xbox.getButtonClick(X)) + Serial.println(F("X")); + if (Xbox.getButtonClick(Y)) + Serial.println(F("Y")); + } + delay(1); +} diff --git a/keywords.txt b/keywords.txt index c7bd007c..0d4469a6 100644 --- a/keywords.txt +++ b/keywords.txt @@ -56,6 +56,7 @@ get9DOFValues KEYWORD2 getStatus KEYWORD2 printStatusString KEYWORD2 getTemperature KEYWORD2 +getTrigger KEYWORD2 disconnect KEYWORD2 setAllOff KEYWORD2 @@ -139,6 +140,9 @@ LeftHatY LITERAL1 RightHatX LITERAL1 RightHatY LITERAL1 +LeftTrigger LITERAL1 +RightTrigger LITERAL1 + aX LITERAL1 aY LITERAL1 aZ LITERAL1 @@ -192,6 +196,7 @@ RumbleLow LITERAL1 #################################################### XBOXUSB KEYWORD1 +XBOXONE KEYWORD1 XBOXOLD KEYWORD1 XBOXRECV KEYWORD1 @@ -207,6 +212,7 @@ buttonChanged KEYWORD2 XboxReceiverConnected KEYWORD2 Xbox360Connected KEYWORD2 +XboxOneConnected KEYWORD2 #################################################### # Constants and enums (LITERAL1) From 2d4ab30005c996bed248ad0973ba9e6318338276 Mon Sep 17 00:00:00 2001 From: Fred Date: Sat, 14 Feb 2015 11:15:29 +0000 Subject: [PATCH 2/6] Fixed tabbing... --- XBOXONE.cpp | 66 ++++++++++++++++++++++++++--------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/XBOXONE.cpp b/XBOXONE.cpp index 8df3500e..4e54e240 100644 --- a/XBOXONE.cpp +++ b/XBOXONE.cpp @@ -239,16 +239,16 @@ uint8_t XBOXONE::Poll() { uint16_t BUFFER_SIZE = EP_MAXPKTSIZE; uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ XBOX_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); if (!rcode) { - readReport(); + readReport(); #ifdef PRINTREPORT - printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller + 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); - } + 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; } @@ -257,22 +257,22 @@ void XBOXONE::readReport() { if(readBuf == NULL) return; if(readBuf[0] == 0x07) { - // The XBOX button has a seperate message - if (readBuf[4] == 1) { - ButtonState |= XBOX_BUTTONS[XBOX]; - } - else { - ButtonState &= XBOX_BUTTONS[XBOX]; - } - if(ButtonState != OldButtonState) { - ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable, but don't include the two trigger buttons L2 and R2 - OldButtonState = ButtonState; - } + // The XBOX button has a seperate message + if (readBuf[4] == 1) { + ButtonState |= XBOX_BUTTONS[XBOX]; + } + else { + ButtonState &= XBOX_BUTTONS[XBOX]; + } + if(ButtonState != OldButtonState) { + ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable, but don't include the two trigger buttons L2 and R2 + OldButtonState = ButtonState; + } } 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! + Notify(PSTR("\r\nXbox Poll: "), 0x80); + D_PrintHex (readBuf[0], 0x80); // 0x03 is a heart beat report! #endif return; } @@ -298,7 +298,7 @@ void XBOXONE::readReport() { } } -void XBOXONE::printReport() { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox 360 Controller +void XBOXONE::printReport() { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox ONE Controller #ifdef PRINTREPORT if(readBuf == NULL) return; @@ -336,22 +336,22 @@ uint8_t XBOXONE::XboxCommand(uint8_t* data, uint16_t nbytes) { Notify(PSTR("\r\nXboxCommand, Return: "), 0x80); D_PrintHex (rcode, 0x80); #endif - return rcode; + 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; + // 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) From 519e2a530906342aec692016f9bf9801f02116df Mon Sep 17 00:00:00 2001 From: Fred Date: Sun, 15 Feb 2015 17:56:20 +0000 Subject: [PATCH 3/6] cleanup --- XBOXONE.h | 4 ---- examples/Xbox/XBOXONE/XBOXONE.ino | 1 - 2 files changed, 5 deletions(-) diff --git a/XBOXONE.h b/XBOXONE.h index cbfe82ea..6b6a349f 100644 --- a/XBOXONE.h +++ b/XBOXONE.h @@ -40,10 +40,6 @@ #define XBOX_REPORT_BUFFER_SIZE 14 // Size of the input report buffer -// Used in control endpoint header for HID Commands -#define bmREQ_HID_OUT USB_SETUP_HOST_TO_DEVICE|USB_SETUP_TYPE_CLASS|USB_SETUP_RECIPIENT_INTERFACE -#define HID_REQUEST_SET_REPORT 0x09 - #define XBOX_MAX_ENDPOINTS 3 /** This class implements support for a Xbox wired controller via USB. */ diff --git a/examples/Xbox/XBOXONE/XBOXONE.ino b/examples/Xbox/XBOXONE/XBOXONE.ino index 5e2c8d99..83c5397f 100644 --- a/examples/Xbox/XBOXONE/XBOXONE.ino +++ b/examples/Xbox/XBOXONE/XBOXONE.ino @@ -24,7 +24,6 @@ void setup() { void loop() { Usb.Task(); if (Xbox.XboxOneConnected) { - if (Xbox.getAnalogHat(LeftHatX) > 7500 || Xbox.getAnalogHat(LeftHatX) < -7500 || Xbox.getAnalogHat(LeftHatY) > 7500 || Xbox.getAnalogHat(LeftHatY) < -7500 || Xbox.getAnalogHat(RightHatX) > 7500 || Xbox.getAnalogHat(RightHatX) < -7500 || Xbox.getAnalogHat(RightHatY) > 7500 || Xbox.getAnalogHat(RightHatY) < -7500) { if (Xbox.getAnalogHat(LeftHatX) > 7500 || Xbox.getAnalogHat(LeftHatX) < -7500) { Serial.print(F("LeftHatX: ")); From 9979e50426b0de177891cfec87aca75cbfe46ea2 Mon Sep 17 00:00:00 2001 From: Fred Date: Sun, 15 Feb 2015 19:47:06 +0000 Subject: [PATCH 4/6] LeftTrigger/RightTrigger => L2/R2 for consistency --- XBOXONE.cpp | 36 ++++++++++++++++---- XBOXONE.h | 18 ++++------ controllerEnums.h | 8 ----- examples/Xbox/XBOXONE/XBOXONE.ino | 55 +++++++++++++++---------------- keywords.txt | 5 +-- 5 files changed, 63 insertions(+), 59 deletions(-) diff --git a/XBOXONE.cpp b/XBOXONE.cpp index 4e54e240..69e1a40e 100644 --- a/XBOXONE.cpp +++ b/XBOXONE.cpp @@ -281,8 +281,8 @@ void XBOXONE::readReport() { // 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[LeftTrigger] = (uint16_t)(((uint16_t)readBuf[7] << 8) | readBuf[6]); - triggerValue[RightTrigger] = (uint16_t)(((uint16_t)readBuf[9] << 8) | readBuf[8]); + 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]); @@ -296,6 +296,15 @@ void XBOXONE::readReport() { ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable OldButtonState = ButtonState; } + + if (triggerValue[0] != triggerValueOld[0]) { + triggerValueOld[0] = triggerValue[0]; + L2Clicked = true; + } + if (triggerValue[1] != triggerValueOld[1]) { + triggerValueOld[1] = triggerValue[1]; + R2Clicked = true; + } } void XBOXONE::printReport() { //Uncomment "#define PRINTREPORT" to print the report send by the Xbox ONE Controller @@ -310,11 +319,28 @@ void XBOXONE::printReport() { //Uncomment "#define PRINTREPORT" to print the rep #endif } -uint8_t XBOXONE::getButtonPress(ButtonEnum b) { +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 @@ -325,10 +351,6 @@ int16_t XBOXONE::getAnalogHat(AnalogHatEnum a) { return hatValue[a]; } -uint16_t XBOXONE::getTrigger(TriggerEnum a) { - return triggerValue[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); diff --git a/XBOXONE.h b/XBOXONE.h index 6b6a349f..7fab80ac 100644 --- a/XBOXONE.h +++ b/XBOXONE.h @@ -42,7 +42,7 @@ #define XBOX_MAX_ENDPOINTS 3 -/** This class implements support for a Xbox wired controller via USB. */ +/** This class implements support for a Xbox ONE controller connected via USB. */ class XBOXONE : public USBDeviceConfig { public: /** @@ -107,9 +107,9 @@ public: * 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. + * @return getButtonClick(ButtonEnum b) will return a bool, while getButtonPress(ButtonEnum b) will return a word if reading ::L2 or ::R2. */ - uint8_t getButtonPress(ButtonEnum b); + uint16_t getButtonPress(ButtonEnum b); bool getButtonClick(ButtonEnum b); /** @@ -119,14 +119,6 @@ public: */ int16_t getAnalogHat(AnalogHatEnum a); - /** @name Xbox Controller functions */ - /** - * Return the analog value from the triggers on the controller. - * @param a Either ::LeftTrigger, or ::RightTrigger. - * @return Returns an unsigned 16-bit integer. - */ - uint16_t getTrigger(TriggerEnum a); - /** * Used to call your own function when the controller is successfully initialized. * @param funcOnInit Function to call. @@ -163,6 +155,10 @@ private: uint16_t ButtonClickState; int16_t hatValue[4]; int16_t triggerValue[2]; + int16_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 diff --git a/controllerEnums.h b/controllerEnums.h index 9d971f85..0169c763 100644 --- a/controllerEnums.h +++ b/controllerEnums.h @@ -159,14 +159,6 @@ enum AnalogHatEnum { RightHatY = 3, }; -/** Triggers on Xbox One controller. */ -enum TriggerEnum { - /** Left trigger */ - LeftTrigger = 0, - /** Right trigger */ - RightTrigger = 1, -}; - /** * Sensors inside the Sixaxis Dualshock 3, Move controller and PS4 controller. * Note: that the location is shifted 9 when it's connected via USB on the PS3 controller. diff --git a/examples/Xbox/XBOXONE/XBOXONE.ino b/examples/Xbox/XBOXONE/XBOXONE.ino index 83c5397f..9526f53d 100644 --- a/examples/Xbox/XBOXONE/XBOXONE.ino +++ b/examples/Xbox/XBOXONE/XBOXONE.ino @@ -47,54 +47,51 @@ void loop() { Serial.println(); } - if (Xbox.getTrigger(LeftTrigger) > 0 || Xbox.getTrigger(RightTrigger) > 0) { - if (Xbox.getTrigger(LeftTrigger) > 0) { - Serial.print(F("LeftTrigger: ")); - Serial.print(Xbox.getTrigger(LeftTrigger)); + if (Xbox.getButtonPress(L2) > 0 || Xbox.getButtonPress(R2) > 0) { + if (Xbox.getButtonPress(L2) > 0) { + Serial.print(F("L2: ")); + Serial.print(Xbox.getButtonPress(L2)); Serial.print("\t"); } - if (Xbox.getTrigger(RightTrigger) > 0) { - Serial.print(F("RightTrigger: ")); - Serial.print(Xbox.getTrigger(RightTrigger)); + if (Xbox.getButtonPress(R2) > 0) { + Serial.print(F("R2: ")); + Serial.print(Xbox.getButtonPress(R2)); Serial.print("\t"); } Serial.println(); } - if (Xbox.getButtonClick(UP)) { + if (Xbox.getButtonClick(UP)) Serial.println(F("Up")); - } - if (Xbox.getButtonClick(DOWN)) { + if (Xbox.getButtonClick(DOWN)) Serial.println(F("Down")); - } - if (Xbox.getButtonClick(LEFT)) { + if (Xbox.getButtonClick(LEFT)) Serial.println(F("Left")); - } - if (Xbox.getButtonClick(RIGHT)) { + if (Xbox.getButtonClick(RIGHT)) Serial.println(F("Right")); - } - if (Xbox.getButtonClick(START)) { + if (Xbox.getButtonClick(START)) Serial.println(F("Start")); - } - if (Xbox.getButtonClick(BACK)) { + if (Xbox.getButtonClick(BACK)) Serial.println(F("Back")); - } - if (Xbox.getButtonClick(L3)) - Serial.println(F("L3")); - if (Xbox.getButtonClick(R3)) - Serial.println(F("R3")); + if (Xbox.getButtonClick(XBOX)) + Serial.println(F("Xbox")); + if (Xbox.getButtonClick(SYNC)) + Serial.println(F("Sync")); if (Xbox.getButtonClick(L1)) Serial.println(F("L1")); if (Xbox.getButtonClick(R1)) Serial.println(F("R1")); - if (Xbox.getButtonClick(XBOX)) { - Serial.println(F("Xbox")); - } - if (Xbox.getButtonClick(SYNC)) { - Serial.println(F("Sync")); - } + if (Xbox.getButtonClick(L2)) + Serial.println(F("L2")); + if (Xbox.getButtonClick(R2)) + Serial.println(F("R2")); + if (Xbox.getButtonClick(L3)) + Serial.println(F("L3")); + if (Xbox.getButtonClick(R3)) + Serial.println(F("R3")); + if (Xbox.getButtonClick(A)) Serial.println(F("A")); diff --git a/keywords.txt b/keywords.txt index 0d4469a6..2d3931dc 100644 --- a/keywords.txt +++ b/keywords.txt @@ -140,9 +140,6 @@ LeftHatY LITERAL1 RightHatX LITERAL1 RightHatY LITERAL1 -LeftTrigger LITERAL1 -RightTrigger LITERAL1 - aX LITERAL1 aY LITERAL1 aZ LITERAL1 @@ -364,4 +361,4 @@ RED LITERAL1 YELLOW LITERAL1 GREEN LITERAL1 ORANGE LITERAL1 -BLUE LITERAL1 \ No newline at end of file +BLUE LITERAL1 From 199612e93e8d1a956a8876560030818f76b67acd Mon Sep 17 00:00:00 2001 From: Fred Date: Sun, 15 Feb 2015 19:56:17 +0000 Subject: [PATCH 5/6] bug fix: would only detect first XBOX button press --- XBOXONE.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/XBOXONE.cpp b/XBOXONE.cpp index 69e1a40e..9be283a0 100644 --- a/XBOXONE.cpp +++ b/XBOXONE.cpp @@ -262,10 +262,10 @@ void XBOXONE::readReport() { ButtonState |= XBOX_BUTTONS[XBOX]; } else { - ButtonState &= XBOX_BUTTONS[XBOX]; + ButtonState &= ~XBOX_BUTTONS[XBOX]; } if(ButtonState != OldButtonState) { - ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable, but don't include the two trigger buttons L2 and R2 + ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable OldButtonState = ButtonState; } } @@ -296,7 +296,7 @@ void XBOXONE::readReport() { ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable OldButtonState = ButtonState; } - + // handle click detection for triggers if (triggerValue[0] != triggerValueOld[0]) { triggerValueOld[0] = triggerValue[0]; L2Clicked = true; From fcab83dcb398ec904db22009d21fa2c1fa133ba1 Mon Sep 17 00:00:00 2001 From: Kristian Sloth Lauszus Date: Wed, 25 Mar 2015 01:16:41 +0100 Subject: [PATCH 6/6] Fixed some bugs in: https://github.com/felis/USB_Host_Shield_2.0/pull/135 --- XBOXONE.cpp | 27 ++++++++++----------------- XBOXONE.h | 4 ++-- keywords.txt | 1 - 3 files changed, 12 insertions(+), 20 deletions(-) diff --git a/XBOXONE.cpp b/XBOXONE.cpp index 9be283a0..2159c052 100644 --- a/XBOXONE.cpp +++ b/XBOXONE.cpp @@ -257,17 +257,11 @@ void XBOXONE::readReport() { if(readBuf == NULL) return; if(readBuf[0] == 0x07) { - // The XBOX button has a seperate message - if (readBuf[4] == 1) { + // The XBOX button has a separate message + if(readBuf[4] == 1) ButtonState |= XBOX_BUTTONS[XBOX]; - } - else { + else ButtonState &= ~XBOX_BUTTONS[XBOX]; - } - if(ButtonState != OldButtonState) { - ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable - OldButtonState = ButtonState; - } } if(readBuf[0] != 0x20) { // Check if it's the correct report, otherwise return - the controller also sends different status reports #ifdef EXTRADEBUG @@ -277,7 +271,7 @@ void XBOXONE::readReport() { return; } - uint16_t xbox = ButtonState & XBOX_BUTTONS[XBOX]; // since the XBOX button is seperate, save it and add it back in + 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); @@ -296,15 +290,14 @@ void XBOXONE::readReport() { ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable OldButtonState = ButtonState; } - // handle click detection for triggers - if (triggerValue[0] != triggerValueOld[0]) { - triggerValueOld[0] = triggerValue[0]; + + // Handle click detection for triggers + if(triggerValue[0] != 0 && triggerValueOld[0] == 0) L2Clicked = true; - } - if (triggerValue[1] != triggerValueOld[1]) { - triggerValueOld[1] = triggerValue[1]; + 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 diff --git a/XBOXONE.h b/XBOXONE.h index 7fab80ac..02efbf21 100644 --- a/XBOXONE.h +++ b/XBOXONE.h @@ -154,8 +154,8 @@ private: uint16_t OldButtonState; uint16_t ButtonClickState; int16_t hatValue[4]; - int16_t triggerValue[2]; - int16_t triggerValueOld[2]; + 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; diff --git a/keywords.txt b/keywords.txt index 2d3931dc..bbbfb03e 100644 --- a/keywords.txt +++ b/keywords.txt @@ -56,7 +56,6 @@ get9DOFValues KEYWORD2 getStatus KEYWORD2 printStatusString KEYWORD2 getTemperature KEYWORD2 -getTrigger KEYWORD2 disconnect KEYWORD2 setAllOff KEYWORD2