USB Host Shield 2.0
XBOXONE.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
2  Copyright (C) 2015 guruthree
3 
4  This software may be distributed and modified under the terms of the GNU
5  General Public License version 2 (GPL2) as published by the Free Software
6  Foundation and appearing in the file GPL2.TXT included in the packaging of
7  this file. Please note that GPL2 Section 2[b] requires that all works based
8  on this software must also be made publicly available under the terms of
9  the GPL2 ("Copyleft").
10 
11  Contact information
12  -------------------
13 
14  Kristian Lauszus, TKJ Electronics
15  Web : http://www.tkjelectronics.com
16  e-mail : kristianl@tkjelectronics.com
17 
18  guruthree
19  Web : https://github.com/guruthree/
20  */
21 
22 #include "XBOXONE.h"
23 // To enable serial debugging see "settings.h"
24 //#define EXTRADEBUG // Uncomment to get even more debugging data
25 //#define PRINTREPORT // Uncomment to print the report send by the Xbox ONE Controller
26 
28 pUsb(p), // pointer to USB class instance - mandatory
29 bAddress(0), // device address - mandatory
30 bNumEP(1), // If config descriptor needs to be parsed
31 qNextPollTime(0), // Reset NextPollTime
32 pollInterval(0),
33 bPollEnable(false) { // don't start polling before dongle is connected
34  for(uint8_t i = 0; i < XBOX_ONE_MAX_ENDPOINTS; i++) {
35  epInfo[i].epAddr = 0;
36  epInfo[i].maxPktSize = (i) ? 0 : 8;
37  epInfo[i].bmSndToggle = 0;
38  epInfo[i].bmRcvToggle = 0;
40  }
41 
42  if(pUsb) // register in USB subsystem
43  pUsb->RegisterDeviceClass(this); //set devConfig[] entry
44 }
45 
46 uint8_t XBOXONE::Init(uint8_t parent, uint8_t port, bool lowspeed) {
47  uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
48  USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf);
49  uint8_t rcode;
50  UsbDevice *p = NULL;
51  EpInfo *oldep_ptr = NULL;
52  uint16_t PID, VID;
53  uint8_t num_of_conf; // Number of configurations
54 
55  // get memory address of USB device address pool
56  AddressPool &addrPool = pUsb->GetAddressPool();
57 #ifdef EXTRADEBUG
58  Notify(PSTR("\r\nXBOXONE Init"), 0x80);
59 #endif
60  // check if address has already been assigned to an instance
61  if(bAddress) {
62 #ifdef DEBUG_USB_HOST
63  Notify(PSTR("\r\nAddress in use"), 0x80);
64 #endif
66  }
67 
68  // Get pointer to pseudo device with address 0 assigned
69  p = addrPool.GetUsbDevicePtr(0);
70 
71  if(!p) {
72 #ifdef DEBUG_USB_HOST
73  Notify(PSTR("\r\nAddress not found"), 0x80);
74 #endif
76  }
77 
78  if(!p->epinfo) {
79 #ifdef DEBUG_USB_HOST
80  Notify(PSTR("\r\nepinfo is null"), 0x80);
81 #endif
83  }
84 
85  // Save old pointer to EP_RECORD of address 0
86  oldep_ptr = p->epinfo;
87 
88  // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
89  p->epinfo = epInfo;
90 
91  p->lowspeed = lowspeed;
92 
93  // Get device descriptor
94  rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
95  // Restore p->epinfo
96  p->epinfo = oldep_ptr;
97 
98  if(rcode)
99  goto FailGetDevDescr;
100 
101  VID = udd->idVendor;
102  PID = udd->idProduct;
103 
104  if(!VIDPIDOK(VID, PID)) // Check VID
105  goto FailUnknownDevice;
106 
107  // Allocate new address according to device class
108  bAddress = addrPool.AllocAddress(parent, false, port);
109 
110  if(!bAddress)
112 
113  // Extract Max Packet Size from device descriptor
114  epInfo[0].maxPktSize = udd->bMaxPacketSize0;
115 
116  // Assign new address to the device
117  rcode = pUsb->setAddr(0, 0, bAddress);
118  if(rcode) {
119  p->lowspeed = false;
120  addrPool.FreeAddress(bAddress);
121  bAddress = 0;
122 #ifdef DEBUG_USB_HOST
123  Notify(PSTR("\r\nsetAddr: "), 0x80);
124  D_PrintHex<uint8_t > (rcode, 0x80);
125 #endif
126  return rcode;
127  }
128 #ifdef EXTRADEBUG
129  Notify(PSTR("\r\nAddr: "), 0x80);
130  D_PrintHex<uint8_t > (bAddress, 0x80);
131 #endif
132  //delay(300); // Spec says you should wait at least 200ms
133 
134  p->lowspeed = false;
135 
136  //get pointer to assigned address record
137  p = addrPool.GetUsbDevicePtr(bAddress);
138  if(!p)
140 
141  p->lowspeed = lowspeed;
142 
143  // Assign epInfo to epinfo pointer - only EP0 is known
144  rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
145  if(rcode)
146  goto FailSetDevTblEntry;
147 
148  num_of_conf = udd->bNumConfigurations; // Number of configurations
149 
150  USBTRACE2("NC:", num_of_conf);
151 
152  // Check if attached device is a Xbox One controller and fill endpoint data structure
153  for(uint8_t i = 0; i < num_of_conf; i++) {
154  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
155  rcode = pUsb->getConfDescr(bAddress, 0, i, &confDescrParser);
156  if(rcode) // Check error code
157  goto FailGetConfDescr;
158  if(bNumEP >= XBOX_ONE_MAX_ENDPOINTS) // All endpoints extracted
159  break;
160  }
161 
163  goto FailUnknownDevice;
164 
166  if(rcode)
167  goto FailSetDevTblEntry;
168 
169  delay(200); // Give time for address change
170 
172  if(rcode)
173  goto FailSetConfDescr;
174 
175 #ifdef DEBUG_USB_HOST
176  Notify(PSTR("\r\nXbox One Controller Connected\r\n"), 0x80);
177 #endif
178 
179  delay(200); // let things settle
180 
181  // Initialize the controller for input
182  cmdCounter = 0; // Reset the counter used when sending out the commands
183  uint8_t writeBuf[5];
184  writeBuf[0] = 0x05;
185  writeBuf[1] = 0x20;
186  // Byte 2 is set in "XboxCommand"
187  writeBuf[3] = 0x01;
188  writeBuf[4] = 0x00;
189  rcode = XboxCommand(writeBuf, 5);
190  if (rcode)
191  goto Fail;
192 
193  onInit();
194  XboxOneConnected = true;
195  bPollEnable = true;
196  return 0; // Successful configuration
197 
198  /* Diagnostic messages */
199 FailGetDevDescr:
200 #ifdef DEBUG_USB_HOST
202  goto Fail;
203 #endif
204 
205 FailSetDevTblEntry:
206 #ifdef DEBUG_USB_HOST
208  goto Fail;
209 #endif
210 
211 FailGetConfDescr:
212 #ifdef DEBUG_USB_HOST
214  goto Fail;
215 #endif
216 
217 FailSetConfDescr:
218 #ifdef DEBUG_USB_HOST
220 #endif
221  goto Fail;
222 
223 FailUnknownDevice:
224 #ifdef DEBUG_USB_HOST
225  NotifyFailUnknownDevice(VID, PID);
226 #endif
228 
229 Fail:
230 #ifdef DEBUG_USB_HOST
231  Notify(PSTR("\r\nXbox One Init Failed, error code: "), 0x80);
232  NotifyFail(rcode);
233 #endif
234  Release();
235  return rcode;
236 }
237 
238 /* Extracts endpoint information from config descriptor */
239 void XBOXONE::EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *pep) {
240  bConfNum = conf;
241  uint8_t index;
242 
243  if((pep->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_INTERRUPT) { // Interrupt endpoint
244  index = (pep->bEndpointAddress & 0x80) == 0x80 ? XBOX_ONE_INPUT_PIPE : XBOX_ONE_OUTPUT_PIPE; // Set the endpoint index
245  } else
246  return;
247 
248  // Fill the rest of endpoint data structure
249  epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
250  epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
251 #ifdef EXTRADEBUG
253 #endif
254  if(pollInterval < pep->bInterval) // Set the polling interval as the largest polling interval obtained from endpoints
255  pollInterval = pep->bInterval;
256  bNumEP++;
257 }
258 
260 #ifdef EXTRADEBUG
261  Notify(PSTR("\r\nEndpoint descriptor:"), 0x80);
262  Notify(PSTR("\r\nLength:\t\t"), 0x80);
263  D_PrintHex<uint8_t > (ep_ptr->bLength, 0x80);
264  Notify(PSTR("\r\nType:\t\t"), 0x80);
265  D_PrintHex<uint8_t > (ep_ptr->bDescriptorType, 0x80);
266  Notify(PSTR("\r\nAddress:\t"), 0x80);
267  D_PrintHex<uint8_t > (ep_ptr->bEndpointAddress, 0x80);
268  Notify(PSTR("\r\nAttributes:\t"), 0x80);
269  D_PrintHex<uint8_t > (ep_ptr->bmAttributes, 0x80);
270  Notify(PSTR("\r\nMaxPktSize:\t"), 0x80);
271  D_PrintHex<uint16_t > (ep_ptr->wMaxPacketSize, 0x80);
272  Notify(PSTR("\r\nPoll Intrv:\t"), 0x80);
273  D_PrintHex<uint8_t > (ep_ptr->bInterval, 0x80);
274 #endif
275 }
276 
277 /* Performs a cleanup after failed Init() attempt */
278 uint8_t XBOXONE::Release() {
279  XboxOneConnected = false;
281  bAddress = 0; // Clear device address
282  bNumEP = 1; // Must have to be reset to 1
283  qNextPollTime = 0; // Reset next poll time
284  pollInterval = 0;
285  bPollEnable = false;
286 #ifdef DEBUG_USB_HOST
287  Notify(PSTR("\r\nXbox One Controller Disconnected\r\n"), 0x80);
288 #endif
289  return 0;
290 }
291 
292 uint8_t XBOXONE::Poll() {
293  uint8_t rcode = 0;
294 
295  if(!bPollEnable)
296  return 0;
297 
298  if((int32_t)((uint32_t)millis() - qNextPollTime) >= 0L) { // Do not poll if shorter than polling interval
299  qNextPollTime = (uint32_t)millis() + pollInterval; // Set new poll time
300  uint16_t length = (uint16_t)epInfo[ XBOX_ONE_INPUT_PIPE ].maxPktSize; // Read the maximum packet size from the endpoint
301  uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ XBOX_ONE_INPUT_PIPE ].epAddr, &length, readBuf, pollInterval);
302  if(!rcode) {
303  readReport();
304 #ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send by the Xbox ONE Controller
305  for(uint8_t i = 0; i < length; i++) {
306  D_PrintHex<uint8_t > (readBuf[i], 0x80);
307  Notify(PSTR(" "), 0x80);
308  }
309  Notify(PSTR("\r\n"), 0x80);
310 #endif
311  }
312 #ifdef DEBUG_USB_HOST
313  else if(rcode != hrNAK) { // Not a matter of no update to send
314  Notify(PSTR("\r\nXbox One Poll Failed, error code: "), 0x80);
315  NotifyFail(rcode);
316  }
317 #endif
318  }
319  return rcode;
320 }
321 
322 void XBOXONE::readReport() {
323  if(readBuf[0] == 0x07) {
324  // The XBOX button has a separate message
325  if(readBuf[4] == 1)
326  ButtonState |= pgm_read_word(&XBOX_BUTTONS[XBOX]);
327  else
328  ButtonState &= ~pgm_read_word(&XBOX_BUTTONS[XBOX]);
329 
330  if(ButtonState != OldButtonState) {
331  ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
332  OldButtonState = ButtonState;
333  }
334  }
335  if(readBuf[0] != 0x20) { // Check if it's the correct report, otherwise return - the controller also sends different status reports
336 #ifdef EXTRADEBUG
337  Notify(PSTR("\r\nXbox Poll: "), 0x80);
338  D_PrintHex<uint8_t > (readBuf[0], 0x80); // 0x03 is a heart beat report!
339 #endif
340  return;
341  }
342 
343  uint16_t xbox = ButtonState & pgm_read_word(&XBOX_BUTTONS[XBOX]); // Since the XBOX button is separate, save it and add it back in
344  // xbox button from before, dpad, abxy, start/back, sync, stick click, shoulder buttons
345  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);
346 
347  triggerValue[0] = (uint16_t)(((uint16_t)readBuf[7] << 8) | readBuf[6]);
348  triggerValue[1] = (uint16_t)(((uint16_t)readBuf[9] << 8) | readBuf[8]);
349 
350  hatValue[LeftHatX] = (int16_t)(((uint16_t)readBuf[11] << 8) | readBuf[10]);
351  hatValue[LeftHatY] = (int16_t)(((uint16_t)readBuf[13] << 8) | readBuf[12]);
352  hatValue[RightHatX] = (int16_t)(((uint16_t)readBuf[15] << 8) | readBuf[14]);
353  hatValue[RightHatY] = (int16_t)(((uint16_t)readBuf[17] << 8) | readBuf[16]);
354 
355  //Notify(PSTR("\r\nButtonState"), 0x80);
356  //PrintHex<uint16_t>(ButtonState, 0x80);
357 
358  if(ButtonState != OldButtonState) {
359  ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
360  OldButtonState = ButtonState;
361  }
362 
363  // Handle click detection for triggers
364  if(triggerValue[0] != 0 && triggerValueOld[0] == 0)
365  L2Clicked = true;
366  triggerValueOld[0] = triggerValue[0];
367  if(triggerValue[1] != 0 && triggerValueOld[1] == 0)
368  R2Clicked = true;
369  triggerValueOld[1] = triggerValue[1];
370 }
371 
373  if(b == L2) // These are analog buttons
374  return triggerValue[0];
375  else if(b == R2)
376  return triggerValue[1];
377  return (bool)(ButtonState & ((uint16_t)pgm_read_word(&XBOX_BUTTONS[(uint8_t)b])));
378 }
379 
381  if(b == L2) {
382  if(L2Clicked) {
383  L2Clicked = false;
384  return true;
385  }
386  return false;
387  } else if(b == R2) {
388  if(R2Clicked) {
389  R2Clicked = false;
390  return true;
391  }
392  return false;
393  }
394  uint16_t button = pgm_read_word(&XBOX_BUTTONS[(uint8_t)b]);
395  bool click = (ButtonClickState & button);
396  ButtonClickState &= ~button; // Clear "click" event
397  return click;
398 }
399 
401  return hatValue[a];
402 }
403 
404 /* Xbox Controller commands */
405 uint8_t XBOXONE::XboxCommand(uint8_t* data, uint16_t nbytes) {
406  data[2] = cmdCounter++; // Increment the output command counter
407  uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ XBOX_ONE_OUTPUT_PIPE ].epAddr, nbytes, data);
408 #ifdef DEBUG_USB_HOST
409  Notify(PSTR("\r\nXboxCommand, Return: "), 0x80);
410  D_PrintHex<uint8_t > (rcode, 0x80);
411 #endif
412  return rcode;
413 }
414 
415 // The Xbox One packets are described at: https://github.com/quantus/xbox-one-controller-protocol
416 void XBOXONE::onInit() {
417  // A short buzz to show the controller is active
418  uint8_t writeBuf[13];
419 
420  // Activate rumble
421  writeBuf[0] = 0x09;
422  writeBuf[1] = 0x00;
423  // Byte 2 is set in "XboxCommand"
424 
425  // Single rumble effect
426  writeBuf[3] = 0x09; // Substructure (what substructure rest of this packet has)
427  writeBuf[4] = 0x00; // Mode
428  writeBuf[5] = 0x0F; // Rumble mask (what motors are activated) (0000 lT rT L R)
429  writeBuf[6] = 0x04; // lT force
430  writeBuf[7] = 0x04; // rT force
431  writeBuf[8] = 0x20; // L force
432  writeBuf[9] = 0x20; // R force
433  writeBuf[10] = 0x80; // Length of pulse
434  writeBuf[11] = 0x00; // Off period
435  writeBuf[12] = 0x00; // Repeat count
436  XboxCommand(writeBuf, 13);
437 
438  if(pFuncOnInit)
439  pFuncOnInit(); // Call the user function
440 }
441 
443  uint8_t writeBuf[13];
444 
445  // Activate rumble
446  writeBuf[0] = 0x09;
447  writeBuf[1] = 0x00;
448  // Byte 2 is set in "XboxCommand"
449 
450  // Continuous rumble effect
451  writeBuf[3] = 0x09; // Substructure (what substructure rest of this packet has)
452  writeBuf[4] = 0x00; // Mode
453  writeBuf[5] = 0x0F; // Rumble mask (what motors are activated) (0000 lT rT L R)
454  writeBuf[6] = 0x00; // lT force
455  writeBuf[7] = 0x00; // rT force
456  writeBuf[8] = 0x00; // L force
457  writeBuf[9] = 0x00; // R force
458  writeBuf[10] = 0x00; // On period
459  writeBuf[11] = 0x00; // Off period
460  writeBuf[12] = 0x00; // Repeat count
461  XboxCommand(writeBuf, 13);
462 }
463 
464 void XBOXONE::setRumbleOn(uint8_t leftTrigger, uint8_t rightTrigger, uint8_t leftMotor, uint8_t rightMotor) {
465  uint8_t writeBuf[13];
466 
467  // Activate rumble
468  writeBuf[0] = 0x09;
469  writeBuf[1] = 0x00;
470  // Byte 2 is set in "XboxCommand"
471 
472  // Continuous rumble effect
473  writeBuf[3] = 0x09; // Substructure (what substructure rest of this packet has)
474  writeBuf[4] = 0x00; // Mode
475  writeBuf[5] = 0x0F; // Rumble mask (what motors are activated) (0000 lT rT L R)
476  writeBuf[6] = leftTrigger; // lT force
477  writeBuf[7] = rightTrigger; // rT force
478  writeBuf[8] = leftMotor; // L force
479  writeBuf[9] = rightMotor; // R force
480  writeBuf[10] = 0xFF; // On period
481  writeBuf[11] = 0x00; // Off period
482  writeBuf[12] = 0xFF; // Repeat count
483  XboxCommand(writeBuf, 13);
484 }
uint8_t bConfNum
Definition: XBOXONE.h:185
uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t *dataptr)
Definition: Usb.cpp:784
uint8_t bmRcvToggle
Definition: address.h:48
EpInfo * epinfo
Definition: address.h:83
bool lowspeed
Definition: address.h:86
#define USB_ERROR_EPINFO_IS_NULL
Definition: UsbCore.h:94
uint8_t bmNakPower
Definition: address.h:49
#define pgm_read_word(addr)
USB * pUsb
Definition: XBOXONE.h:178
#define NotifyFail(...)
Definition: message.h:62
AnalogHatEnum
uint8_t setConf(uint8_t addr, uint8_t ep, uint8_t conf_value)
Definition: Usb.cpp:823
uint8_t bAddress
Definition: XBOXONE.h:180
XBOXONE(USB *pUsb)
Definition: XBOXONE.cpp:27
#define USB_TRANSFER_TYPE_INTERRUPT
Definition: usb_ch9.h:93
#define NotifyFailGetDevDescr(...)
Definition: message.h:57
uint8_t setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo *eprecord_ptr)
Definition: Usb.cpp:71
void EndpointXtract(uint8_t conf, uint8_t iface, uint8_t alt, uint8_t proto, const USB_ENDPOINT_DESCRIPTOR *ep)
Definition: XBOXONE.cpp:239
virtual void FreeAddress(uint8_t addr)=0
virtual UsbDevice * GetUsbDevicePtr(uint8_t addr)=0
uint8_t bNumEP
Definition: XBOXONE.h:187
#define Notify(...)
Definition: message.h:51
#define USBTRACE2(s, r)
Definition: macros.h:84
uint8_t setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr)
Definition: Usb.cpp:814
#define NotifyFailGetConfDescr(...)
Definition: message.h:59
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR *ep_ptr)
Definition: XBOXONE.cpp:259
uint8_t epAddr
Definition: address.h:40
bool XboxOneConnected
Definition: XBOXONE.h:174
#define XBOX_ONE_MAX_ENDPOINTS
Definition: XBOXONE.h:37
#define NotifyFailUnknownDevice(...)
Definition: message.h:61
void setRumbleOff()
Definition: XBOXONE.cpp:442
#define USB_NAK_MAX_POWER
Definition: address.h:34
virtual uint8_t Release()
Definition: XBOXONE.cpp:278
Definition: address.h:39
uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *data)
Definition: Usb.cpp:300
#define hrNAK
Definition: max3421e.h:218
ButtonEnum
uint16_t wMaxPacketSize
Definition: usb_ch9.h:153
#define bmUSB_TRANSFER_TYPE
Definition: usb_ch9.h:94
uint16_t getButtonPress(ButtonEnum b)
Definition: XBOXONE.cpp:372
uint32_t qNextPollTime
Definition: XBOXONE.h:189
virtual uint8_t AllocAddress(uint8_t parent, bool is_hub=false, uint8_t port=0)=0
uint8_t bEndpointAddress
Definition: usb_ch9.h:151
uint8_t bmSndToggle
Definition: address.h:47
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE
Definition: UsbCore.h:96
#define PSTR(str)
#define XBOX_ONE_INPUT_PIPE
Definition: XBOXONE.h:35
EpInfo epInfo[XBOX_ONE_MAX_ENDPOINTS]
Definition: XBOXONE.h:182
bool getButtonClick(ButtonEnum b)
Definition: XBOXONE.cpp:380
virtual uint8_t Poll()
Definition: XBOXONE.cpp:292
#define USB_NAK_NOWAIT
Definition: address.h:36
#define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL
Definition: UsbCore.h:93
#define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED
Definition: UsbCore.h:88
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed)
Definition: XBOXONE.cpp:46
uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t *data, uint8_t bInterval=0)
Definition: Usb.cpp:213
#define USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL
Definition: UsbCore.h:91
uint8_t maxPktSize
Definition: address.h:41
AddressPool & GetAddressPool()
Definition: UsbCore.h:224
Definition: UsbCore.h:208
#define XBOX_ONE_CONTROL_PIPE
Definition: XBOXONE.h:33
#define XBOX_ONE_OUTPUT_PIPE
Definition: XBOXONE.h:34
int16_t getAnalogHat(AnalogHatEnum a)
Definition: XBOXONE.cpp:400
const uint16_t XBOX_BUTTONS[]
Definition: xboxEnums.h:41
uint8_t RegisterDeviceClass(USBDeviceConfig *pdev)
Definition: UsbCore.h:228
#define NotifyFailSetConfDescr(...)
Definition: message.h:60
virtual bool VIDPIDOK(uint16_t vid, uint16_t pid)
Definition: XBOXONE.h:123
uint8_t getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *dataptr)
defined(USB_METHODS_INLINE)
Definition: Usb.cpp:779
#define NotifyFailSetDevTblEntry(...)
Definition: message.h:58
void setRumbleOn(uint8_t leftTrigger, uint8_t rightTrigger, uint8_t leftMotor, uint8_t rightMotor)
Definition: XBOXONE.cpp:464