mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
Merge branch 'master' of github.com:felis/USB_Host_Shield_2.0
This commit is contained in:
commit
8318e5eeba
4 changed files with 155 additions and 74 deletions
6
BTD.cpp
6
BTD.cpp
|
@ -225,11 +225,11 @@ uint8_t BTD::Init(uint8_t parent __attribute__((unused)), uint8_t port __attribu
|
||||||
// First interface in the configuration must have Bluetooth assigned Class/Subclass/Protocol
|
// 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
|
// And 3 endpoints - interrupt-IN, bulk-IN, bulk-OUT, not necessarily in this order
|
||||||
for(uint8_t i = 0; i < num_of_conf; i++) {
|
for(uint8_t i = 0; i < num_of_conf; i++) {
|
||||||
if(VID == IOGEAR_GBU521_VID && PID == IOGEAR_GBU521_PID) {
|
if((VID == IOGEAR_GBU521_VID && PID == IOGEAR_GBU521_PID) || (VID == BELKIN_F8T065BF_VID && PID == BELKIN_F8T065BF_PID)) {
|
||||||
ConfigDescParser<USB_CLASS_VENDOR_SPECIFIC, WI_SUBCLASS_RF, WI_PROTOCOL_BT, CP_MASK_COMPARE_ALL> confDescrParser(this); // Needed for the IOGEAR GBU521
|
ConfigDescParser<USB_CLASS_VENDOR_SPECIFIC, WI_SUBCLASS_RF, WI_PROTOCOL_BT, CP_MASK_COMPARE_ALL> confDescrParser(this); // Workaround issue with some dongles
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||||
} else {
|
} else {
|
||||||
ConfigDescParser<USB_CLASS_WIRELESS_CTRL, WI_SUBCLASS_RF, WI_PROTOCOL_BT, CP_MASK_COMPARE_ALL> confDescrParser(this);
|
ConfigDescParser<USB_CLASS_WIRELESS_CTRL, WI_SUBCLASS_RF, WI_PROTOCOL_BT, CP_MASK_COMPARE_ALL> confDescrParser(this); // Set class id according to the specification
|
||||||
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||||
}
|
}
|
||||||
if(rcode) // Check error code
|
if(rcode) // Check error code
|
||||||
|
|
7
BTD.h
7
BTD.h
|
@ -27,8 +27,11 @@
|
||||||
#define PS3NAVIGATION_PID 0x042F // Navigation controller
|
#define PS3NAVIGATION_PID 0x042F // Navigation controller
|
||||||
#define PS3MOVE_PID 0x03D5 // Motion 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
|
// These dongles do not present themselves correctly, so we have to check for them manually
|
||||||
|
#define IOGEAR_GBU521_VID 0x0A5C
|
||||||
#define IOGEAR_GBU521_PID 0x21E8
|
#define IOGEAR_GBU521_PID 0x21E8
|
||||||
|
#define BELKIN_F8T065BF_VID 0x050D
|
||||||
|
#define BELKIN_F8T065BF_PID 0x065A
|
||||||
|
|
||||||
/* Bluetooth dongle data taken from descriptors */
|
/* Bluetooth dongle data taken from descriptors */
|
||||||
#define BULK_MAXPKTSIZE 64 // Max size for ACL data
|
#define BULK_MAXPKTSIZE 64 // Max size for ACL data
|
||||||
|
@ -264,7 +267,7 @@ public:
|
||||||
* @return Returns true if the device's VID and PID matches this driver.
|
* @return Returns true if the device's VID and PID matches this driver.
|
||||||
*/
|
*/
|
||||||
virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) {
|
virtual bool VIDPIDOK(uint16_t vid, uint16_t pid) {
|
||||||
if(vid == IOGEAR_GBU521_VID && pid == IOGEAR_GBU521_PID)
|
if((vid == IOGEAR_GBU521_VID && pid == IOGEAR_GBU521_PID) || (vid == BELKIN_F8T065BF_VID && pid == BELKIN_F8T065BF_PID))
|
||||||
return true;
|
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(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))
|
if(vid == PS3_VID && (pid == PS3_PID || pid == PS3NAVIGATION_PID || pid == PS3MOVE_PID))
|
||||||
|
|
154
XBOXONE.cpp
154
XBOXONE.cpp
|
@ -27,8 +27,11 @@
|
||||||
XBOXONE::XBOXONE(USB *p) :
|
XBOXONE::XBOXONE(USB *p) :
|
||||||
pUsb(p), // pointer to USB class instance - mandatory
|
pUsb(p), // pointer to USB class instance - mandatory
|
||||||
bAddress(0), // device address - 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
|
bPollEnable(false) { // don't start polling before dongle is connected
|
||||||
for(uint8_t i = 0; i < XBOX_MAX_ENDPOINTS; i++) {
|
for(uint8_t i = 0; i < XBOX_ONE_MAX_ENDPOINTS; i++) {
|
||||||
epInfo[i].epAddr = 0;
|
epInfo[i].epAddr = 0;
|
||||||
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
epInfo[i].maxPktSize = (i) ? 0 : 8;
|
||||||
epInfo[i].bmSndToggle = 0;
|
epInfo[i].bmSndToggle = 0;
|
||||||
|
@ -46,8 +49,8 @@ uint8_t XBOXONE::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
uint8_t rcode;
|
uint8_t rcode;
|
||||||
UsbDevice *p = NULL;
|
UsbDevice *p = NULL;
|
||||||
EpInfo *oldep_ptr = NULL;
|
EpInfo *oldep_ptr = NULL;
|
||||||
uint16_t PID;
|
uint16_t PID, VID;
|
||||||
uint16_t VID;
|
uint8_t num_of_conf; // Number of configurations
|
||||||
|
|
||||||
// get memory address of USB device address pool
|
// get memory address of USB device address pool
|
||||||
AddressPool &addrPool = pUsb->GetAddressPool();
|
AddressPool &addrPool = pUsb->GetAddressPool();
|
||||||
|
@ -142,31 +145,30 @@ uint8_t XBOXONE::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
if(rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
/* The application will work in reduced host mode, so we can save program and data
|
num_of_conf = udd->bNumConfigurations; // Number of configurations
|
||||||
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 */
|
USBTRACE2("NC:", num_of_conf);
|
||||||
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);
|
// Check if attached device is a Xbox One controller and fill endpoint data structure
|
||||||
|
for(uint8_t i = 0; i < num_of_conf; i++) {
|
||||||
|
ConfigDescParser<0, 0, 0, 0> confDescrParser(this); // Allow all devices, as we have already verified that it is a Xbox One controller from the VID and PID
|
||||||
|
rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
|
||||||
|
if(rcode) // Check error code
|
||||||
|
goto FailGetConfDescr;
|
||||||
|
if(bNumEP >= XBOX_ONE_MAX_ENDPOINTS) // All endpoints extracted
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(bNumEP < XBOX_ONE_MAX_ENDPOINTS)
|
||||||
|
goto FailUnknownDevice;
|
||||||
|
|
||||||
|
rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
|
||||||
if(rcode)
|
if(rcode)
|
||||||
goto FailSetDevTblEntry;
|
goto FailSetDevTblEntry;
|
||||||
|
|
||||||
delay(200); // Give time for address change
|
delay(200); // Give time for address change
|
||||||
|
|
||||||
rcode = pUsb->setConf(bAddress, epInfo[ XBOX_CONTROL_PIPE ].epAddr, 1);
|
rcode = pUsb->setConf(bAddress, epInfo[ XBOX_ONE_CONTROL_PIPE ].epAddr, bConfNum);
|
||||||
if(rcode)
|
if(rcode)
|
||||||
goto FailSetConfDescr;
|
goto FailSetConfDescr;
|
||||||
|
|
||||||
|
@ -176,7 +178,8 @@ uint8_t XBOXONE::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
|
|
||||||
delay(200); // let things settle
|
delay(200); // let things settle
|
||||||
|
|
||||||
// initialize the controller for input
|
// Initialize the controller for input
|
||||||
|
uint8_t writeBuf[5];
|
||||||
writeBuf[0] = 0x05;
|
writeBuf[0] = 0x05;
|
||||||
writeBuf[1] = 0x20;
|
writeBuf[1] = 0x20;
|
||||||
writeBuf[2] = 0x00;
|
writeBuf[2] = 0x00;
|
||||||
|
@ -204,6 +207,12 @@ FailSetDevTblEntry:
|
||||||
goto Fail;
|
goto Fail;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
FailGetConfDescr:
|
||||||
|
#ifdef DEBUG_USB_HOST
|
||||||
|
NotifyFailGetConfDescr();
|
||||||
|
goto Fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
FailSetConfDescr:
|
FailSetConfDescr:
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
NotifyFailSetConfDescr();
|
NotifyFailSetConfDescr();
|
||||||
|
@ -225,11 +234,53 @@ Fail:
|
||||||
return rcode;
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Extracts endpoint information from config descriptor */
|
||||||
|
void XBOXONE::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) {
|
||||||
|
bConfNum = conf;
|
||||||
|
uint8_t index;
|
||||||
|
|
||||||
|
if((pep->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_INTERRUPT) { // Interrupt endpoint
|
||||||
|
index = (pep->bEndpointAddress & 0x80) == 0x80 ? XBOX_ONE_INPUT_PIPE : XBOX_ONE_OUTPUT_PIPE; // Set the endpoint index
|
||||||
|
} 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 XBOXONE::PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr) {
|
||||||
|
#ifdef EXTRADEBUG
|
||||||
|
Notify(PSTR("\r\nEndpoint descriptor:"), 0x80);
|
||||||
|
Notify(PSTR("\r\nLength:\t\t"), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (ep_ptr->bLength, 0x80);
|
||||||
|
Notify(PSTR("\r\nType:\t\t"), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (ep_ptr->bDescriptorType, 0x80);
|
||||||
|
Notify(PSTR("\r\nAddress:\t"), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (ep_ptr->bEndpointAddress, 0x80);
|
||||||
|
Notify(PSTR("\r\nAttributes:\t"), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (ep_ptr->bmAttributes, 0x80);
|
||||||
|
Notify(PSTR("\r\nMaxPktSize:\t"), 0x80);
|
||||||
|
D_PrintHex<uint16_t > (ep_ptr->wMaxPacketSize, 0x80);
|
||||||
|
Notify(PSTR("\r\nPoll Intrv:\t"), 0x80);
|
||||||
|
D_PrintHex<uint8_t > (ep_ptr->bInterval, 0x80);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/* Performs a cleanup after failed Init() attempt */
|
/* Performs a cleanup after failed Init() attempt */
|
||||||
uint8_t XBOXONE::Release() {
|
uint8_t XBOXONE::Release() {
|
||||||
XboxOneConnected = false;
|
XboxOneConnected = false;
|
||||||
pUsb->GetAddressPool().FreeAddress(bAddress);
|
pUsb->GetAddressPool().FreeAddress(bAddress);
|
||||||
bAddress = 0;
|
bAddress = 0; // Clear device address
|
||||||
|
bNumEP = 1; // Must have to be reset to 1
|
||||||
|
qNextPollTime = 0; // Reset next poll time
|
||||||
|
pollInterval = 0;
|
||||||
bPollEnable = false;
|
bPollEnable = false;
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nXbox One Controller Disconnected\r\n"), 0x80);
|
Notify(PSTR("\r\nXbox One Controller Disconnected\r\n"), 0x80);
|
||||||
|
@ -238,28 +289,36 @@ uint8_t XBOXONE::Release() {
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t XBOXONE::Poll() {
|
uint8_t XBOXONE::Poll() {
|
||||||
|
uint8_t rcode = 0;
|
||||||
|
|
||||||
if(!bPollEnable)
|
if(!bPollEnable)
|
||||||
return 0;
|
return 0;
|
||||||
uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
|
|
||||||
uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ XBOX_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf);
|
if((int32_t)((uint32_t)millis() - qNextPollTime) >= 0L) { // Do not poll if shorter than polling interval
|
||||||
if (!rcode) {
|
qNextPollTime = (uint32_t)millis() + pollInterval; // Set new poll time
|
||||||
readReport();
|
uint16_t length = (uint16_t)epInfo[ XBOX_ONE_INPUT_PIPE ].maxPktSize; // Read the maximum packet size from the endpoint
|
||||||
#ifdef PRINTREPORT
|
uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ XBOX_ONE_INPUT_PIPE ].epAddr, &length, readBuf, pollInterval);
|
||||||
printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the Xbox ONE Controller
|
if(!rcode) {
|
||||||
|
readReport();
|
||||||
|
#ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send by the Xbox ONE Controller
|
||||||
|
for(uint8_t i = 0; i < length; i++) {
|
||||||
|
D_PrintHex<uint8_t > (readBuf[i], 0x80);
|
||||||
|
Notify(PSTR(" "), 0x80);
|
||||||
|
}
|
||||||
|
Notify(PSTR("\r\n"), 0x80);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
else if (rcode != 0x04) { // not a matter of no update to send
|
else if(rcode != hrNAK) { // Not a matter of no update to send
|
||||||
Notify(PSTR("\r\nXbox One Poll Failed, error code: "), 0x80);
|
Notify(PSTR("\r\nXbox One Poll Failed, error code: "), 0x80);
|
||||||
NotifyFail(rcode);
|
NotifyFail(rcode);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return rcode;
|
}
|
||||||
|
return rcode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XBOXONE::readReport() {
|
void XBOXONE::readReport() {
|
||||||
if(readBuf == NULL)
|
|
||||||
return;
|
|
||||||
if(readBuf[0] == 0x07) {
|
if(readBuf[0] == 0x07) {
|
||||||
// The XBOX button has a separate message
|
// The XBOX button has a separate message
|
||||||
if(readBuf[4] == 1)
|
if(readBuf[4] == 1)
|
||||||
|
@ -302,25 +361,13 @@ void XBOXONE::readReport() {
|
||||||
|
|
||||||
// Handle click detection for triggers
|
// Handle click detection for triggers
|
||||||
if(triggerValue[0] != 0 && triggerValueOld[0] == 0)
|
if(triggerValue[0] != 0 && triggerValueOld[0] == 0)
|
||||||
L2Clicked = true;
|
L2Clicked = true;
|
||||||
triggerValueOld[0] = triggerValue[0];
|
triggerValueOld[0] = triggerValue[0];
|
||||||
if(triggerValue[1] != 0 && triggerValueOld[1] == 0)
|
if(triggerValue[1] != 0 && triggerValueOld[1] == 0)
|
||||||
R2Clicked = true;
|
R2Clicked = true;
|
||||||
triggerValueOld[1] = triggerValue[1];
|
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<uint8_t > (readBuf[i], 0x80);
|
|
||||||
Notify(PSTR(" "), 0x80);
|
|
||||||
}
|
|
||||||
Notify(PSTR("\r\n"), 0x80);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
uint16_t XBOXONE::getButtonPress(ButtonEnum b) {
|
uint16_t XBOXONE::getButtonPress(ButtonEnum b) {
|
||||||
if(b == L2) // These are analog buttons
|
if(b == L2) // These are analog buttons
|
||||||
return triggerValue[0];
|
return triggerValue[0];
|
||||||
|
@ -345,7 +392,7 @@ bool XBOXONE::getButtonClick(ButtonEnum b) {
|
||||||
}
|
}
|
||||||
uint16_t button = pgm_read_word(&XBOX_BUTTONS[(uint8_t)b]);
|
uint16_t button = pgm_read_word(&XBOX_BUTTONS[(uint8_t)b]);
|
||||||
bool click = (ButtonClickState & button);
|
bool click = (ButtonClickState & button);
|
||||||
ButtonClickState &= ~button; // clear "click" event
|
ButtonClickState &= ~button; // Clear "click" event
|
||||||
return click;
|
return click;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -355,7 +402,7 @@ int16_t XBOXONE::getAnalogHat(AnalogHatEnum a) {
|
||||||
|
|
||||||
/* Xbox Controller commands */
|
/* Xbox Controller commands */
|
||||||
uint8_t XBOXONE::XboxCommand(uint8_t* data, uint16_t nbytes) {
|
uint8_t XBOXONE::XboxCommand(uint8_t* data, uint16_t nbytes) {
|
||||||
uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ XBOX_OUTPUT_PIPE ].epAddr, nbytes, data);
|
uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ XBOX_ONE_OUTPUT_PIPE ].epAddr, nbytes, data);
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nXboxCommand, Return: "), 0x80);
|
Notify(PSTR("\r\nXboxCommand, Return: "), 0x80);
|
||||||
D_PrintHex<uint8_t > (rcode, 0x80);
|
D_PrintHex<uint8_t > (rcode, 0x80);
|
||||||
|
@ -364,7 +411,8 @@ uint8_t XBOXONE::XboxCommand(uint8_t* data, uint16_t nbytes) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void XBOXONE::onInit() {
|
void XBOXONE::onInit() {
|
||||||
// a short buzz to show the controller is active
|
// A short buzz to show the controller is active
|
||||||
|
uint8_t writeBuf[11];
|
||||||
writeBuf[0] = 0x09;
|
writeBuf[0] = 0x09;
|
||||||
writeBuf[1] = 0x08;
|
writeBuf[1] = 0x08;
|
||||||
writeBuf[2] = 0x00;
|
writeBuf[2] = 0x00;
|
||||||
|
|
62
XBOXONE.h
62
XBOXONE.h
|
@ -26,15 +26,17 @@
|
||||||
#include "Usb.h"
|
#include "Usb.h"
|
||||||
#include "xboxEnums.h"
|
#include "xboxEnums.h"
|
||||||
|
|
||||||
/* Data Xbox ONE taken from descriptors */
|
/* Xbox One data taken from descriptors */
|
||||||
#define EP_MAXPKTSIZE 32 // max size for data via USB
|
#define XBOX_ONE_EP_MAXPKTSIZE 64 // Max size for data via USB
|
||||||
|
|
||||||
/* Names we give to the 3 XboxONE pipes */
|
/* Names we give to the 3 XboxONE pipes */
|
||||||
#define XBOX_CONTROL_PIPE 0
|
#define XBOX_ONE_CONTROL_PIPE 0
|
||||||
#define XBOX_OUTPUT_PIPE 1
|
#define XBOX_ONE_OUTPUT_PIPE 1
|
||||||
#define XBOX_INPUT_PIPE 2
|
#define XBOX_ONE_INPUT_PIPE 2
|
||||||
|
|
||||||
// PID and VID of the different devices - see: https://github.com/torvalds/linux/blob/master/drivers/input/joystick/xpad.c
|
#define XBOX_ONE_MAX_ENDPOINTS 3
|
||||||
|
|
||||||
|
// PID and VID of the different versions of the controller - see: https://github.com/torvalds/linux/blob/master/drivers/input/joystick/xpad.c
|
||||||
|
|
||||||
// Official controllers
|
// Official controllers
|
||||||
#define XBOX_VID1 0x045E // Microsoft Corporation
|
#define XBOX_VID1 0x045E // Microsoft Corporation
|
||||||
|
@ -59,12 +61,8 @@
|
||||||
#define XBOX_ONE_PID11 0x542A // Xbox ONE spectra
|
#define XBOX_ONE_PID11 0x542A // Xbox ONE spectra
|
||||||
#define XBOX_ONE_PID12 0x543A // PowerA Xbox One wired controller
|
#define XBOX_ONE_PID12 0x543A // PowerA Xbox 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. */
|
/** This class implements support for a Xbox ONE controller connected via USB. */
|
||||||
class XBOXONE : public USBDeviceConfig {
|
class XBOXONE : public USBDeviceConfig, public UsbConfigXtracter {
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor for the XBOXONE class.
|
* Constructor for the XBOXONE class.
|
||||||
|
@ -108,6 +106,14 @@ public:
|
||||||
return bPollEnable;
|
return bPollEnable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the poll interval taken from the endpoint descriptors.
|
||||||
|
* @return The poll interval in ms.
|
||||||
|
*/
|
||||||
|
uint8_t readPollInterval() {
|
||||||
|
return pollInterval;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Used by the USB core to check what this driver support.
|
* Used by the USB core to check what this driver support.
|
||||||
* @param vid The device's VID.
|
* @param vid The device's VID.
|
||||||
|
@ -161,7 +167,32 @@ protected:
|
||||||
/** Device address. */
|
/** Device address. */
|
||||||
uint8_t bAddress;
|
uint8_t bAddress;
|
||||||
/** Endpoint info structure. */
|
/** Endpoint info structure. */
|
||||||
EpInfo epInfo[XBOX_MAX_ENDPOINTS];
|
EpInfo epInfo[XBOX_ONE_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;
|
||||||
|
|
||||||
|
/** @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);
|
||||||
|
/**@}*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Used to print the USB Endpoint Descriptor.
|
||||||
|
* @param ep_ptr Pointer to USB Endpoint Descriptor.
|
||||||
|
*/
|
||||||
|
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR* ep_ptr);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
@ -171,6 +202,7 @@ private:
|
||||||
void onInit();
|
void onInit();
|
||||||
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
|
void (*pFuncOnInit)(void); // Pointer to function called in onInit()
|
||||||
|
|
||||||
|
uint8_t pollInterval;
|
||||||
bool bPollEnable;
|
bool bPollEnable;
|
||||||
|
|
||||||
/* Variables to store the buttons */
|
/* Variables to store the buttons */
|
||||||
|
@ -184,11 +216,9 @@ private:
|
||||||
bool L2Clicked; // These buttons are analog, so we use we use these bools to check if they where clicked or not
|
bool L2Clicked; // These buttons are analog, so we use we use these bools to check if they where clicked or not
|
||||||
bool R2Clicked;
|
bool R2Clicked;
|
||||||
|
|
||||||
uint8_t readBuf[EP_MAXPKTSIZE]; // General purpose buffer for input data
|
uint8_t readBuf[XBOX_ONE_EP_MAXPKTSIZE]; // General purpose buffer for input data
|
||||||
uint8_t writeBuf[12]; // General purpose buffer for output data
|
|
||||||
|
|
||||||
void readReport(); // read incoming data
|
void readReport(); // Used to read the incoming data
|
||||||
void printReport(); // print incoming date - Uncomment for debugging
|
|
||||||
|
|
||||||
/* Private commands */
|
/* Private commands */
|
||||||
uint8_t XboxCommand(uint8_t* data, uint16_t nbytes);
|
uint8_t XboxCommand(uint8_t* data, uint16_t nbytes);
|
||||||
|
|
Loading…
Reference in a new issue