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 
165  rcode = pUsb->setEpInfoEntry(bAddress, bNumEP, epInfo);
166  if(rcode)
167  goto FailSetDevTblEntry;
168 
169  delay(200); // Give time for address change
170 
171  rcode = pUsb->setConf(bAddress, epInfo[ XBOX_ONE_CONTROL_PIPE ].epAddr, bConfNum);
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,
240  uint8_t iface __attribute__((unused)),
241  uint8_t alt __attribute__((unused)),
242  uint8_t proto __attribute__((unused)),
243  const USB_ENDPOINT_DESCRIPTOR *pep)
244 {
245 
246  bConfNum = conf;
247  uint8_t index;
248 
249  if((pep->bmAttributes & bmUSB_TRANSFER_TYPE) == USB_TRANSFER_TYPE_INTERRUPT) { // Interrupt endpoint
250  index = (pep->bEndpointAddress & 0x80) == 0x80 ? XBOX_ONE_INPUT_PIPE : XBOX_ONE_OUTPUT_PIPE; // Set the endpoint index
251  } else
252  return;
253 
254  // Fill the rest of endpoint data structure
255  epInfo[index].epAddr = (pep->bEndpointAddress & 0x0F);
256  epInfo[index].maxPktSize = (uint8_t)pep->wMaxPacketSize;
257 #ifdef EXTRADEBUG
259 #endif
260  if(pollInterval < pep->bInterval) // Set the polling interval as the largest polling interval obtained from endpoints
261  pollInterval = pep->bInterval;
262  bNumEP++;
263 }
264 
266  __attribute__((unused)))
267 {
268 #ifdef EXTRADEBUG
269  Notify(PSTR("\r\nEndpoint descriptor:"), 0x80);
270  Notify(PSTR("\r\nLength:\t\t"), 0x80);
271  D_PrintHex<uint8_t > (ep_ptr->bLength, 0x80);
272  Notify(PSTR("\r\nType:\t\t"), 0x80);
273  D_PrintHex<uint8_t > (ep_ptr->bDescriptorType, 0x80);
274  Notify(PSTR("\r\nAddress:\t"), 0x80);
275  D_PrintHex<uint8_t > (ep_ptr->bEndpointAddress, 0x80);
276  Notify(PSTR("\r\nAttributes:\t"), 0x80);
277  D_PrintHex<uint8_t > (ep_ptr->bmAttributes, 0x80);
278  Notify(PSTR("\r\nMaxPktSize:\t"), 0x80);
279  D_PrintHex<uint16_t > (ep_ptr->wMaxPacketSize, 0x80);
280  Notify(PSTR("\r\nPoll Intrv:\t"), 0x80);
281  D_PrintHex<uint8_t > (ep_ptr->bInterval, 0x80);
282 #endif
283 }
284 
285 /* Performs a cleanup after failed Init() attempt */
286 uint8_t XBOXONE::Release() {
287  XboxOneConnected = false;
289  bAddress = 0; // Clear device address
290  bNumEP = 1; // Must have to be reset to 1
291  qNextPollTime = 0; // Reset next poll time
292  pollInterval = 0;
293  bPollEnable = false;
294 #ifdef DEBUG_USB_HOST
295  Notify(PSTR("\r\nXbox One Controller Disconnected\r\n"), 0x80);
296 #endif
297  return 0;
298 }
299 
300 uint8_t XBOXONE::Poll() {
301  uint8_t rcode = 0;
302 
303  if(!bPollEnable)
304  return 0;
305 
306  if((int32_t)((uint32_t)millis() - qNextPollTime) >= 0L) { // Do not poll if shorter than polling interval
307  qNextPollTime = (uint32_t)millis() + pollInterval; // Set new poll time
308  uint16_t length = (uint16_t)epInfo[ XBOX_ONE_INPUT_PIPE ].maxPktSize; // Read the maximum packet size from the endpoint
309  uint8_t rcode = pUsb->inTransfer(bAddress, epInfo[ XBOX_ONE_INPUT_PIPE ].epAddr, &length, readBuf, pollInterval);
310  if(!rcode) {
311  readReport();
312 #ifdef PRINTREPORT // Uncomment "#define PRINTREPORT" to print the report send by the Xbox ONE Controller
313  for(uint8_t i = 0; i < length; i++) {
314  D_PrintHex<uint8_t > (readBuf[i], 0x80);
315  Notify(PSTR(" "), 0x80);
316  }
317  Notify(PSTR("\r\n"), 0x80);
318 #endif
319  }
320 #ifdef DEBUG_USB_HOST
321  else if(rcode != hrNAK) { // Not a matter of no update to send
322  Notify(PSTR("\r\nXbox One Poll Failed, error code: "), 0x80);
323  NotifyFail(rcode);
324  }
325 #endif
326  }
327  return rcode;
328 }
329 
330 void XBOXONE::readReport() {
331  if(readBuf[0] == 0x07) {
332  // The XBOX button has a separate message
333  if(readBuf[4] == 1)
334  ButtonState |= pgm_read_word(&XBOX_BUTTONS[XBOX]);
335  else
336  ButtonState &= ~pgm_read_word(&XBOX_BUTTONS[XBOX]);
337 
338  if(ButtonState != OldButtonState) {
339  ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
340  OldButtonState = ButtonState;
341  }
342  }
343  if(readBuf[0] != 0x20) { // Check if it's the correct report, otherwise return - the controller also sends different status reports
344 #ifdef EXTRADEBUG
345  Notify(PSTR("\r\nXbox Poll: "), 0x80);
346  D_PrintHex<uint8_t > (readBuf[0], 0x80); // 0x03 is a heart beat report!
347 #endif
348  return;
349  }
350 
351  uint16_t xbox = ButtonState & pgm_read_word(&XBOX_BUTTONS[XBOX]); // Since the XBOX button is separate, save it and add it back in
352  // xbox button from before, dpad, abxy, start/back, sync, stick click, shoulder buttons
353  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);
354 
355  triggerValue[0] = (uint16_t)(((uint16_t)readBuf[7] << 8) | readBuf[6]);
356  triggerValue[1] = (uint16_t)(((uint16_t)readBuf[9] << 8) | readBuf[8]);
357 
358  hatValue[LeftHatX] = (int16_t)(((uint16_t)readBuf[11] << 8) | readBuf[10]);
359  hatValue[LeftHatY] = (int16_t)(((uint16_t)readBuf[13] << 8) | readBuf[12]);
360  hatValue[RightHatX] = (int16_t)(((uint16_t)readBuf[15] << 8) | readBuf[14]);
361  hatValue[RightHatY] = (int16_t)(((uint16_t)readBuf[17] << 8) | readBuf[16]);
362 
363  //Notify(PSTR("\r\nButtonState"), 0x80);
364  //PrintHex<uint16_t>(ButtonState, 0x80);
365 
366  if(ButtonState != OldButtonState) {
367  ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
368  OldButtonState = ButtonState;
369  }
370 
371  // Handle click detection for triggers
372  if(triggerValue[0] != 0 && triggerValueOld[0] == 0)
373  L2Clicked = true;
374  triggerValueOld[0] = triggerValue[0];
375  if(triggerValue[1] != 0 && triggerValueOld[1] == 0)
376  R2Clicked = true;
377  triggerValueOld[1] = triggerValue[1];
378 }
379 
381  if(b == L2) // These are analog buttons
382  return triggerValue[0];
383  else if(b == R2)
384  return triggerValue[1];
385  return (bool)(ButtonState & ((uint16_t)pgm_read_word(&XBOX_BUTTONS[(uint8_t)b])));
386 }
387 
389  if(b == L2) {
390  if(L2Clicked) {
391  L2Clicked = false;
392  return true;
393  }
394  return false;
395  } else if(b == R2) {
396  if(R2Clicked) {
397  R2Clicked = false;
398  return true;
399  }
400  return false;
401  }
402  uint16_t button = pgm_read_word(&XBOX_BUTTONS[(uint8_t)b]);
403  bool click = (ButtonClickState & button);
404  ButtonClickState &= ~button; // Clear "click" event
405  return click;
406 }
407 
409  return hatValue[a];
410 }
411 
412 /* Xbox Controller commands */
413 uint8_t XBOXONE::XboxCommand(uint8_t* data, uint16_t nbytes) {
414  data[2] = cmdCounter++; // Increment the output command counter
415  uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ XBOX_ONE_OUTPUT_PIPE ].epAddr, nbytes, data);
416 #ifdef DEBUG_USB_HOST
417  Notify(PSTR("\r\nXboxCommand, Return: "), 0x80);
418  D_PrintHex<uint8_t > (rcode, 0x80);
419 #endif
420  return rcode;
421 }
422 
423 // The Xbox One packets are described at: https://github.com/quantus/xbox-one-controller-protocol
424 void XBOXONE::onInit() {
425  // A short buzz to show the controller is active
426  uint8_t writeBuf[13];
427 
428  // Activate rumble
429  writeBuf[0] = 0x09;
430  writeBuf[1] = 0x00;
431  // Byte 2 is set in "XboxCommand"
432 
433  // Single rumble effect
434  writeBuf[3] = 0x09; // Substructure (what substructure rest of this packet has)
435  writeBuf[4] = 0x00; // Mode
436  writeBuf[5] = 0x0F; // Rumble mask (what motors are activated) (0000 lT rT L R)
437  writeBuf[6] = 0x04; // lT force
438  writeBuf[7] = 0x04; // rT force
439  writeBuf[8] = 0x20; // L force
440  writeBuf[9] = 0x20; // R force
441  writeBuf[10] = 0x80; // Length of pulse
442  writeBuf[11] = 0x00; // Off period
443  writeBuf[12] = 0x00; // Repeat count
444  XboxCommand(writeBuf, 13);
445 
446  if(pFuncOnInit)
447  pFuncOnInit(); // Call the user function
448 }
449 
451  uint8_t writeBuf[13];
452 
453  // Activate rumble
454  writeBuf[0] = 0x09;
455  writeBuf[1] = 0x00;
456  // Byte 2 is set in "XboxCommand"
457 
458  // Continuous rumble effect
459  writeBuf[3] = 0x09; // Substructure (what substructure rest of this packet has)
460  writeBuf[4] = 0x00; // Mode
461  writeBuf[5] = 0x0F; // Rumble mask (what motors are activated) (0000 lT rT L R)
462  writeBuf[6] = 0x00; // lT force
463  writeBuf[7] = 0x00; // rT force
464  writeBuf[8] = 0x00; // L force
465  writeBuf[9] = 0x00; // R force
466  writeBuf[10] = 0x00; // On period
467  writeBuf[11] = 0x00; // Off period
468  writeBuf[12] = 0x00; // Repeat count
469  XboxCommand(writeBuf, 13);
470 }
471 
472 void XBOXONE::setRumbleOn(uint8_t leftTrigger, uint8_t rightTrigger, uint8_t leftMotor, uint8_t rightMotor) {
473  uint8_t writeBuf[13];
474 
475  // Activate rumble
476  writeBuf[0] = 0x09;
477  writeBuf[1] = 0x00;
478  // Byte 2 is set in "XboxCommand"
479 
480  // Continuous rumble effect
481  writeBuf[3] = 0x09; // Substructure (what substructure rest of this packet has)
482  writeBuf[4] = 0x00; // Mode
483  writeBuf[5] = 0x0F; // Rumble mask (what motors are activated) (0000 lT rT L R)
484  writeBuf[6] = leftTrigger; // lT force
485  writeBuf[7] = rightTrigger; // rT force
486  writeBuf[8] = leftMotor; // L force
487  writeBuf[9] = rightMotor; // R force
488  writeBuf[10] = 0xFF; // On period
489  writeBuf[11] = 0x00; // Off period
490  writeBuf[12] = 0xFF; // Repeat count
491  XboxCommand(writeBuf, 13);
492 }
uint8_t bConfNum
Definition: XBOXONE.h:186
uint8_t getConfDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t conf, uint8_t *dataptr)
Definition: Usb.cpp:801
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:96
uint8_t bmNakPower
Definition: address.h:49
#define pgm_read_word(addr)
USB * pUsb
Definition: XBOXONE.h:179
#define NotifyFail(...)
Definition: message.h:62
AnalogHatEnum
uint8_t setConf(uint8_t addr, uint8_t ep, uint8_t conf_value)
Definition: Usb.cpp:840
uint8_t bAddress
Definition: XBOXONE.h:181
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:64
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:188
#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:831
#define NotifyFailGetConfDescr(...)
Definition: message.h:59
void PrintEndpointDescriptor(const USB_ENDPOINT_DESCRIPTOR *ep_ptr)
Definition: XBOXONE.cpp:265
uint8_t epAddr
Definition: address.h:40
bool XboxOneConnected
Definition: XBOXONE.h:175
#define XBOX_ONE_MAX_ENDPOINTS
Definition: XBOXONE.h:37
#define NotifyFailUnknownDevice(...)
Definition: message.h:61
void setRumbleOff()
Definition: XBOXONE.cpp:450
#define USB_NAK_MAX_POWER
Definition: address.h:34
virtual uint8_t Release()
Definition: XBOXONE.cpp:286
Definition: address.h:39
uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *data)
Definition: Usb.cpp:303
#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:380
uint32_t qNextPollTime
Definition: XBOXONE.h:190
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:98
#define PSTR(str)
#define XBOX_ONE_INPUT_PIPE
Definition: XBOXONE.h:35
EpInfo epInfo[XBOX_ONE_MAX_ENDPOINTS]
Definition: XBOXONE.h:183
bool getButtonClick(ButtonEnum b)
Definition: XBOXONE.cpp:388
virtual uint8_t Poll()
Definition: XBOXONE.cpp:300
#define USB_NAK_NOWAIT
Definition: address.h:36
#define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL
Definition: UsbCore.h:95
#define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED
Definition: UsbCore.h:90
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:209
#define USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL
Definition: UsbCore.h:93
uint8_t maxPktSize
Definition: address.h:41
AddressPool & GetAddressPool()
Definition: UsbCore.h:226
Definition: UsbCore.h:210
#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:408
const uint16_t XBOX_BUTTONS[]
Definition: xboxEnums.h:41
uint8_t RegisterDeviceClass(USBDeviceConfig *pdev)
Definition: UsbCore.h:230
#define NotifyFailSetConfDescr(...)
Definition: message.h:60
virtual bool VIDPIDOK(uint16_t vid, uint16_t pid)
Definition: XBOXONE.h:124
uint8_t getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *dataptr)
defined(USB_METHODS_INLINE)
Definition: Usb.cpp:796
#define NotifyFailSetDevTblEntry(...)
Definition: message.h:58
void setRumbleOn(uint8_t leftTrigger, uint8_t rightTrigger, uint8_t leftMotor, uint8_t rightMotor)
Definition: XBOXONE.cpp:472