USB Host Shield 2.0
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
PS3USB.cpp
Go to the documentation of this file.
1 /* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
2 
3  This software may be distributed and modified under the terms of the GNU
4  General Public License version 2 (GPL2) as published by the Free Software
5  Foundation and appearing in the file GPL2.TXT included in the packaging of
6  this file. Please note that GPL2 Section 2[b] requires that all works based
7  on this software must also be made publicly available under the terms of
8  the GPL2 ("Copyleft").
9 
10  Contact information
11  -------------------
12 
13  Kristian Lauszus, TKJ Electronics
14  Web : http://www.tkjelectronics.com
15  e-mail : kristianl@tkjelectronics.com
16  */
17 
18 #include "PS3USB.h"
19 // To enable serial debugging see "settings.h"
20 //#define EXTRADEBUG // Uncomment to get even more debugging data
21 //#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers
22 
23 PS3USB::PS3USB(USB *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0) :
24 pUsb(p), // pointer to USB class instance - mandatory
25 bAddress(0), // device address - mandatory
26 bPollEnable(false) // don't start polling before dongle is connected
27 {
28  for(uint8_t i = 0; i < PS3_MAX_ENDPOINTS; i++) {
29  epInfo[i].epAddr = 0;
30  epInfo[i].maxPktSize = (i) ? 0 : 8;
31  epInfo[i].epAttribs = 0;
33  }
34 
35  if(pUsb) // register in USB subsystem
36  pUsb->RegisterDeviceClass(this); //set devConfig[] entry
37 
38  my_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead
39  my_bdaddr[4] = btadr4;
40  my_bdaddr[3] = btadr3;
41  my_bdaddr[2] = btadr2;
42  my_bdaddr[1] = btadr1;
43  my_bdaddr[0] = btadr0;
44 }
45 
46 uint8_t PS3USB::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;
53  uint16_t VID;
54 
55  // get memory address of USB device address pool
56  AddressPool &addrPool = pUsb->GetAddressPool();
57 #ifdef EXTRADEBUG
58  Notify(PSTR("\r\nPS3USB 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(VID != PS3_VID || (PID != PS3_PID && PID != PS3NAVIGATION_PID && PID != PS3MOVE_PID))
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 
149  /* The application will work in reduced host mode, so we can save program and data
150  memory space. After verifying the PID and VID we will use known values for the
151  configuration values for device, interface, endpoints and HID for the PS3 Controllers */
152 
153  /* Initialize data structures for endpoints of device */
154  epInfo[ PS3_OUTPUT_PIPE ].epAddr = 0x02; // PS3 output endpoint
156  epInfo[ PS3_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
160  epInfo[ PS3_INPUT_PIPE ].epAddr = 0x01; // PS3 report endpoint
162  epInfo[ PS3_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
166 
167  rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
168  if(rcode)
169  goto FailSetDevTblEntry;
170 
171  delay(200); //Give time for address change
172 
173  rcode = pUsb->setConf(bAddress, epInfo[ PS3_CONTROL_PIPE ].epAddr, 1);
174  if(rcode)
175  goto FailSetConfDescr;
176 
177  if(PID == PS3_PID || PID == PS3NAVIGATION_PID) {
178  if(PID == PS3_PID) {
179 #ifdef DEBUG_USB_HOST
180  Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80);
181 #endif
182  PS3Connected = true;
183  } else { // must be a navigation controller
184 #ifdef DEBUG_USB_HOST
185  Notify(PSTR("\r\nNavigation Controller Connected"), 0x80);
186 #endif
187  PS3NavigationConnected = true;
188  }
189  enable_sixaxis(); // The PS3 controller needs a special command before it starts sending data
190 
191  // Needed for PS3 Dualshock and Navigation commands to work
192  for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
193  writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]);
194 
195  for(uint8_t i = 6; i < 10; i++)
196  readBuf[i] = 0x7F; // Set the analog joystick values to center position
197  } else { // must be a Motion controller
198 #ifdef DEBUG_USB_HOST
199  Notify(PSTR("\r\nMotion Controller Connected"), 0x80);
200 #endif
201  PS3MoveConnected = true;
202  writeBuf[0] = 0x02; // Set report ID, this is needed for Move commands to work
203  }
204  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) {
205  if(PS3MoveConnected)
206  setMoveBdaddr(my_bdaddr); // Set internal Bluetooth address
207  else
208  setBdaddr(my_bdaddr); // Set internal Bluetooth address
209 
210 #ifdef DEBUG_USB_HOST
211  Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80);
212  for(int8_t i = 5; i > 0; i--) {
213  D_PrintHex<uint8_t > (my_bdaddr[i], 0x80);
214  Notify(PSTR(":"), 0x80);
215  }
216  D_PrintHex<uint8_t > (my_bdaddr[0], 0x80);
217 #endif
218  }
219  onInit();
220 
221  bPollEnable = true;
222  Notify(PSTR("\r\n"), 0x80);
223  timer = millis();
224  return 0; // Successful configuration
225 
226  /* Diagnostic messages */
227 FailGetDevDescr:
228 #ifdef DEBUG_USB_HOST
230  goto Fail;
231 #endif
232 
233 FailSetDevTblEntry:
234 #ifdef DEBUG_USB_HOST
236  goto Fail;
237 #endif
238 
239 FailSetConfDescr:
240 #ifdef DEBUG_USB_HOST
242 #endif
243  goto Fail;
244 
245 FailUnknownDevice:
246 #ifdef DEBUG_USB_HOST
247  NotifyFailUnknownDevice(VID, PID);
248 #endif
250 
251 Fail:
252 #ifdef DEBUG_USB_HOST
253  Notify(PSTR("\r\nPS3 Init Failed, error code: "), 0x80);
254  NotifyFail(rcode);
255 #endif
256  Release();
257  return rcode;
258 }
259 
260 /* Performs a cleanup after failed Init() attempt */
261 uint8_t PS3USB::Release() {
262  PS3Connected = false;
263  PS3MoveConnected = false;
264  PS3NavigationConnected = false;
266  bAddress = 0;
267  bPollEnable = false;
268  return 0;
269 }
270 
271 uint8_t PS3USB::Poll() {
272  if(!bPollEnable)
273  return 0;
274 
276  uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
277  pUsb->inTransfer(bAddress, epInfo[ PS3_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
278  if(millis() - timer > 100) { // Loop 100ms before processing data
279  readReport();
280 #ifdef PRINTREPORT
281  printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
282 #endif
283  }
284  } else if(PS3MoveConnected) { // One can only set the color of the bulb, set the rumble, set and get the bluetooth address and calibrate the magnetometer via USB
285  if(millis() - timer > 4000) { // Send at least every 4th second
286  Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE); // The Bulb and rumble values, has to be written again and again, for it to stay turned on
287  timer = millis();
288  }
289  }
290  return 0;
291 }
292 
293 void PS3USB::readReport() {
294  ButtonState = (uint32_t)(readBuf[2] | ((uint16_t)readBuf[3] << 8) | ((uint32_t)readBuf[4] << 16));
295 
296  //Notify(PSTR("\r\nButtonState", 0x80);
297  //PrintHex<uint32_t>(ButtonState, 0x80);
298 
299  if(ButtonState != OldButtonState) {
300  ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
301  OldButtonState = ButtonState;
302  }
303 }
304 
305 void PS3USB::printReport() { // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
306 #ifdef PRINTREPORT
307  for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) {
308  D_PrintHex<uint8_t > (readBuf[i], 0x80);
309  Notify(PSTR(" "), 0x80);
310  }
311  Notify(PSTR("\r\n"), 0x80);
312 #endif
313 }
314 
316  return (ButtonState & pgm_read_dword(&PS3_BUTTONS[(uint8_t)b]));
317 }
318 
320  uint32_t button = pgm_read_dword(&PS3_BUTTONS[(uint8_t)b]);
321  bool click = (ButtonClickState & button);
322  ButtonClickState &= ~button; // Clear "click" event
323  return click;
324 }
325 
327  return (uint8_t)(readBuf[(pgm_read_byte(&PS3_ANALOG_BUTTONS[(uint8_t)a])) - 9]);
328 }
329 
331  return (uint8_t)(readBuf[((uint8_t)a + 6)]);
332 }
333 
335  return ((readBuf[((uint16_t)a) - 9] << 8) | readBuf[((uint16_t)a + 1) - 9]);
336 }
337 
339  if(PS3Connected) {
340  double accXval;
341  double accYval;
342  double accZval;
343 
344  // Data for the Kionix KXPC4 used in the DualShock 3
345  const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V)
346  accXval = -((double)getSensor(aX) - zeroG);
347  accYval = -((double)getSensor(aY) - zeroG);
348  accZval = -((double)getSensor(aZ) - zeroG);
349 
350  // Convert to 360 degrees resolution
351  // atan2 outputs the value of -Ï€ to Ï€ (radians)
352  // We are then converting it to 0 to 2Ï€ and then to degrees
353  if(a == Pitch)
354  return (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
355  else
356  return (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
357  } else
358  return 0;
359 }
360 
362  return (readBuf[((uint16_t)c >> 8) - 9] == ((uint8_t)c & 0xff));
363 }
364 
366  char statusOutput[100]; // Max string length plus null character
368  strcpy_P(statusOutput, PSTR("ConnectionStatus: "));
369 
370  if(getStatus(Plugged)) strcat_P(statusOutput, PSTR("Plugged"));
371  else if(getStatus(Unplugged)) strcat_P(statusOutput, PSTR("Unplugged"));
372  else strcat_P(statusOutput, PSTR("Error"));
373 
374  strcat_P(statusOutput, PSTR(" - PowerRating: "));
375 
376  if(getStatus(Charging)) strcat_P(statusOutput, PSTR("Charging"));
377  else if(getStatus(NotCharging)) strcat_P(statusOutput, PSTR("Not Charging"));
378  else if(getStatus(Shutdown)) strcat_P(statusOutput, PSTR("Shutdown"));
379  else if(getStatus(Dying)) strcat_P(statusOutput, PSTR("Dying"));
380  else if(getStatus(Low)) strcat_P(statusOutput, PSTR("Low"));
381  else if(getStatus(High)) strcat_P(statusOutput, PSTR("High"));
382  else if(getStatus(Full)) strcat_P(statusOutput, PSTR("Full"));
383  else strcat_P(statusOutput, PSTR("Error"));
384 
385  strcat_P(statusOutput, PSTR(" - WirelessStatus: "));
386 
387  if(getStatus(CableRumble)) strcat_P(statusOutput, PSTR("Cable - Rumble is on"));
388  else if(getStatus(Cable)) strcat_P(statusOutput, PSTR("Cable - Rumble is off"));
389  else if(getStatus(BluetoothRumble)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is on"));
390  else if(getStatus(Bluetooth)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is off"));
391  else strcat_P(statusOutput, PSTR("Error"));
392  } else
393  strcpy_P(statusOutput, PSTR("Error"));
394 
395  USB_HOST_SERIAL.write((uint8_t*)statusOutput, strlen(statusOutput));
396 }
397 
398 /* Playstation Sixaxis Dualshock and Navigation Controller commands */
399 void PS3USB::PS3_Command(uint8_t *data, uint16_t nbytes) {
400  // bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x01), Report Type (Output 0x02), interface (0x00), datalength, datalength, data)
401  pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x01, 0x02, 0x00, nbytes, nbytes, data, NULL);
402 }
403 
405  for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
406  writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); // Reset buffer
407 
408  PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
409 }
410 
412  writeBuf[1] = 0x00;
413  writeBuf[2] = 0x00; // Low mode off
414  writeBuf[3] = 0x00;
415  writeBuf[4] = 0x00; // High mode off
416 
417  PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
418 }
419 
421  if((mode & 0x30) > 0x00) {
422  uint8_t power[2] = {0xff, 0x00}; // Defaults to RumbleLow
423  if(mode == RumbleHigh) {
424  power[0] = 0x00;
425  power[1] = 0xff;
426  }
427  setRumbleOn(0xfe, power[0], 0xfe, power[1]);
428  }
429 }
430 
431 void PS3USB::setRumbleOn(uint8_t rightDuration, uint8_t rightPower, uint8_t leftDuration, uint8_t leftPower) {
432  writeBuf[1] = rightDuration;
433  writeBuf[2] = rightPower;
434  writeBuf[3] = leftDuration;
435  writeBuf[4] = leftPower;
436  PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
437 }
438 
439 void PS3USB::setLedRaw(uint8_t value) {
440  writeBuf[9] = value << 1;
441  PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
442 }
443 
445  writeBuf[9] &= ~((uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1));
446  PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
447 }
448 
450  if(a == OFF)
451  setLedRaw(0);
452  else {
453  writeBuf[9] |= (uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1);
454  PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
455  }
456 }
457 
459  writeBuf[9] ^= (uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1);
460  PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
461 }
462 
463 void PS3USB::setBdaddr(uint8_t *bdaddr) {
464  /* Set the internal Bluetooth address */
465  uint8_t buf[8];
466  buf[0] = 0x01;
467  buf[1] = 0x00;
468 
469  for(uint8_t i = 0; i < 6; i++)
470  buf[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed, so it is MSB first
471 
472  // bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
473  pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL);
474 }
475 
476 void PS3USB::getBdaddr(uint8_t *bdaddr) {
477  uint8_t buf[8];
478 
479  // bmRequest = Device to host (0x80) | Class (0x20) | Interface (0x01) = 0xA1, bRequest = Get Report (0x01), Report ID (0xF5), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
480  pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL);
481 
482  for(uint8_t i = 0; i < 6; i++)
483  bdaddr[5 - i] = buf[i + 2]; // Copy into buffer reversed, so it is LSB first
484 }
485 
486 void PS3USB::enable_sixaxis() { // Command used to enable the Dualshock 3 and Navigation controller to send data via USB
487  uint8_t cmd_buf[4];
488  cmd_buf[0] = 0x42; // Special PS3 Controller enable commands
489  cmd_buf[1] = 0x0c;
490  cmd_buf[2] = 0x00;
491  cmd_buf[3] = 0x00;
492 
493  // bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0xF4), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data)
494  pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF4, 0x03, 0x00, 4, 4, cmd_buf, NULL);
495 }
496 
497 /* Playstation Move Controller commands */
498 void PS3USB::Move_Command(uint8_t *data, uint16_t nbytes) {
499  pUsb->outTransfer(bAddress, epInfo[ PS3_OUTPUT_PIPE ].epAddr, nbytes, data);
500 }
501 
502 void PS3USB::moveSetBulb(uint8_t r, uint8_t g, uint8_t b) { // Use this to set the Color using RGB values
503  // Set the Bulb's values into the write buffer
504  writeBuf[2] = r;
505  writeBuf[3] = g;
506  writeBuf[4] = b;
507 
508  Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
509 }
510 
511 void PS3USB::moveSetBulb(ColorsEnum color) { // Use this to set the Color using the predefined colors in "enums.h"
512  moveSetBulb((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
513 }
514 
515 void PS3USB::moveSetRumble(uint8_t rumble) {
516 #ifdef DEBUG_USB_HOST
517  if(rumble < 64 && rumble != 0) // The rumble value has to at least 64, or approximately 25% (64/255*100)
518  Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80);
519 #endif
520  writeBuf[6] = rumble; // Set the rumble value into the write buffer
521 
522  Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
523 }
524 
525 void PS3USB::setMoveBdaddr(uint8_t *bdaddr) {
526  /* Set the internal Bluetooth address */
527  uint8_t buf[11];
528  buf[0] = 0x05;
529  buf[7] = 0x10;
530  buf[8] = 0x01;
531  buf[9] = 0x02;
532  buf[10] = 0x12;
533 
534  for(uint8_t i = 0; i < 6; i++)
535  buf[i + 1] = bdaddr[i];
536 
537  // bmRequest = Host to device (0x00) | Class (0x20) | Interface (0x01) = 0x21, bRequest = Set Report (0x09), Report ID (0x05), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
538  pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00, 11, 11, buf, NULL);
539 }
540 
541 void PS3USB::getMoveBdaddr(uint8_t *bdaddr) {
542  uint8_t buf[16];
543 
544  // bmRequest = Device to host (0x80) | Class (0x20) | Interface (0x01) = 0xA1, bRequest = Get Report (0x01), Report ID (0x04), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
545  pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0x04, 0x03, 0x00, 16, 16, buf, NULL);
546 
547  for(uint8_t i = 0; i < 6; i++)
548  bdaddr[i] = buf[10 + i];
549 }
550 
551 void PS3USB::getMoveCalibration(uint8_t *data) {
552  uint8_t buf[49];
553 
554  for(uint8_t i = 0; i < 3; i++) {
555  // bmRequest = Device to host (0x80) | Class (0x20) | Interface (0x01) = 0xA1, bRequest = Get Report (0x01), Report ID (0x10), Report Type (Feature 0x03), interface (0x00), datalength, datalength, data
556  pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0x10, 0x03, 0x00, 49, 49, buf, NULL);
557 
558  for(byte j = 0; j < 49; j++)
559  data[49 * i + j] = buf[j];
560  }
561 }
562 
563 void PS3USB::onInit() {
564  if(pFuncOnInit)
565  pFuncOnInit(); // Call the user function
566  else {
567  if(PS3MoveConnected)
568  moveSetBulb(Red);
569  else // Dualshock 3 or Navigation controller
570  setLedOn(LED1);
571  }
572 }
uint8_t bmRcvToggle
Definition: address.h:41
RumbleEnum
Definition: PS3Enums.h:163
Definition: PS3Enums.h:146
void getBdaddr(uint8_t *bdaddr)
Definition: PS3USB.cpp:476
EpInfo * epinfo
Definition: address.h:76
bool lowspeed
Definition: address.h:79
#define USB_ERROR_EPINFO_IS_NULL
Definition: UsbCore.h:67
uint8_t bmNakPower
Definition: address.h:42
void setLedRaw(uint8_t value)
Definition: PS3USB.cpp:439
bool PS3NavigationConnected
Definition: PS3USB.h:273
void setLedOff()
Definition: PS3USB.h:224
#define PS3_INPUT_PIPE
Definition: PS3USB.h:33
#define PS3MOVE_PID
Definition: BTD.h:27
void setBdaddr(uint8_t *bdaddr)
Definition: PS3USB.cpp:463
virtual uint8_t Release()
Definition: PS3USB.cpp:261
bool getButtonPress(ButtonEnum b)
Definition: PS3USB.cpp:315
#define PS3_OUTPUT_PIPE
Definition: PS3USB.h:32
#define NotifyFail(...)
Definition: message.h:55
bool PS3MoveConnected
Definition: PS3USB.h:271
AnalogHatEnum
uint8_t setConf(uint8_t addr, uint8_t ep, uint8_t conf_value)
Definition: Usb.cpp:805
StatusEnum
Definition: PS3Enums.h:135
void getMoveBdaddr(uint8_t *bdaddr)
Definition: PS3USB.cpp:541
#define PS3_VID
Definition: BTD.h:24
#define NotifyFailGetDevDescr(...)
Definition: message.h:50
uint8_t getAnalogButton(ButtonEnum a)
Definition: PS3USB.cpp:326
uint16_t getSensor(SensorEnum a)
Definition: PS3USB.cpp:334
uint8_t setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo *eprecord_ptr)
Definition: Usb.cpp:64
void setRumbleOff()
Definition: PS3USB.cpp:411
const uint32_t PS3_BUTTONS[]
Definition: PS3Enums.h:62
#define EP_MAXPKTSIZE
Definition: PS3USB.h:25
bool PS3Connected
Definition: PS3USB.h:265
virtual void FreeAddress(uint8_t addr)=0
LEDEnum
uint8_t epAttribs
Definition: address.h:37
uint8_t ctrlReq(uint8_t addr, uint8_t ep, uint8_t bmReqType, uint8_t bRequest, uint8_t wValLo, uint8_t wValHi, uint16_t wInd, uint16_t total, uint16_t nbytes, uint8_t *dataptr, USBReadParser *p)
Definition: Usb.cpp:126
virtual UsbDevice * GetUsbDevicePtr(uint8_t addr)=0
#define Notify(...)
Definition: message.h:44
#define PS3_CONTROL_PIPE
Definition: PS3USB.h:31
uint8_t setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr)
Definition: Usb.cpp:796
#define USB_HOST_SERIAL
Definition: settings.h:24
void setLedToggle(LEDEnum a)
Definition: PS3USB.cpp:458
uint8_t epAddr
Definition: address.h:33
#define NotifyFailUnknownDevice(...)
Definition: message.h:54
#define USB_NAK_MAX_POWER
Definition: address.h:27
void moveSetBulb(uint8_t r, uint8_t g, uint8_t b)
Definition: PS3USB.cpp:502
Definition: PS3Enums.h:145
virtual uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed)
Definition: PS3USB.cpp:46
Definition: PS3Enums.h:116
#define EP_INTERRUPT
Definition: PS3USB.h:28
Definition: address.h:32
#define MOVE_REPORT_BUFFER_SIZE
Definition: PS3Enums.h:40
void printStatusString()
Definition: PS3USB.cpp:365
void setAllOff()
Definition: PS3USB.cpp:404
uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *data)
Definition: Usb.cpp:292
ButtonEnum
#define HID_REQUEST_SET_REPORT
Definition: BTD.h:39
#define HID_REQUEST_GET_REPORT
Definition: hid.h:69
const uint8_t PS3_LEDS[]
Definition: PS3Enums.h:43
virtual uint8_t AllocAddress(uint8_t parent, bool is_hub=false, uint8_t port=0)=0
uint8_t bmSndToggle
Definition: address.h:40
uint8_t getAnalogHat(AnalogHatEnum a)
Definition: PS3USB.cpp:330
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE
Definition: UsbCore.h:69
USB * pUsb
Definition: PS3USB.h:277
ColorsEnum
Definition: PS3Enums.h:114
const uint8_t PS3_ANALOG_BUTTONS[]
Definition: PS3Enums.h:92
#define USB_NAK_NOWAIT
Definition: address.h:29
AngleEnum
double getAngle(AngleEnum a)
Definition: PS3USB.cpp:338
#define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL
Definition: UsbCore.h:66
#define PS3_PID
Definition: BTD.h:25
uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t *data)
Definition: Usb.cpp:206
#define PS3NAVIGATION_PID
Definition: BTD.h:26
void moveSetRumble(uint8_t rumble)
Definition: PS3USB.cpp:515
virtual uint8_t Poll()
Definition: PS3USB.cpp:271
#define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED
Definition: UsbCore.h:61
#define PS3_MAX_ENDPOINTS
Definition: PS3USB.h:48
EpInfo epInfo[PS3_MAX_ENDPOINTS]
Definition: PS3USB.h:281
void setRumbleOn(RumbleEnum mode)
Definition: PS3USB.cpp:420
#define bmREQ_HID_OUT
Definition: BTD.h:38
#define bmREQ_HID_IN
Definition: PS3USB.h:43
#define USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL
Definition: UsbCore.h:64
void setLedOn(LEDEnum a)
Definition: PS3USB.cpp:449
uint8_t maxPktSize
Definition: address.h:34
AddressPool & GetAddressPool()
Definition: UsbCore.h:192
uint8_t bAddress
Definition: PS3USB.h:279
void setMoveBdaddr(uint8_t *bdaddr)
Definition: PS3USB.cpp:525
#define PS3_REPORT_BUFFER_SIZE
Definition: PS3Enums.h:24
Definition: UsbCore.h:176
SensorEnum
uint8_t RegisterDeviceClass(USBDeviceConfig *pdev)
Definition: UsbCore.h:196
#define NotifyFailSetConfDescr(...)
Definition: message.h:53
PS3USB(USB *pUsb, uint8_t btadr5=0, uint8_t btadr4=0, uint8_t btadr3=0, uint8_t btadr2=0, uint8_t btadr1=0, uint8_t btadr0=0)
Definition: PS3USB.cpp:23
void getMoveCalibration(uint8_t *data)
Definition: PS3USB.cpp:551
Definition: PS3Enums.h:147
bool getStatus(StatusEnum c)
Definition: PS3USB.cpp:361
uint8_t getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *dataptr)
defined(USB_METHODS_INLINE)
Definition: Usb.cpp:761
#define NotifyFailSetDevTblEntry(...)
Definition: message.h:51
const uint8_t PS3_REPORT_BUFFER[PS3_REPORT_BUFFER_SIZE]
Definition: PS3Enums.h:27
bool getButtonClick(ButtonEnum b)
Definition: PS3USB.cpp:319