USB Host Shield 2.0
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].bmSndToggle = 0;
32  epInfo[i].bmRcvToggle = 0;
34  }
35 
36  if(pUsb) // register in USB subsystem
37  pUsb->RegisterDeviceClass(this); //set devConfig[] entry
38 
39  my_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead
40  my_bdaddr[4] = btadr4;
41  my_bdaddr[3] = btadr3;
42  my_bdaddr[2] = btadr2;
43  my_bdaddr[1] = btadr1;
44  my_bdaddr[0] = btadr0;
45 }
46 
47 uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
48  uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
49  USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf);
50  uint8_t rcode;
51  UsbDevice *p = NULL;
52  EpInfo *oldep_ptr = NULL;
53  uint16_t PID;
54  uint16_t VID;
55 
56  // get memory address of USB device address pool
57  AddressPool &addrPool = pUsb->GetAddressPool();
58 #ifdef EXTRADEBUG
59  Notify(PSTR("\r\nPS3USB Init"), 0x80);
60 #endif
61  // check if address has already been assigned to an instance
62  if(bAddress) {
63 #ifdef DEBUG_USB_HOST
64  Notify(PSTR("\r\nAddress in use"), 0x80);
65 #endif
67  }
68 
69  // Get pointer to pseudo device with address 0 assigned
70  p = addrPool.GetUsbDevicePtr(0);
71 
72  if(!p) {
73 #ifdef DEBUG_USB_HOST
74  Notify(PSTR("\r\nAddress not found"), 0x80);
75 #endif
77  }
78 
79  if(!p->epinfo) {
80 #ifdef DEBUG_USB_HOST
81  Notify(PSTR("\r\nepinfo is null"), 0x80);
82 #endif
84  }
85 
86  // Save old pointer to EP_RECORD of address 0
87  oldep_ptr = p->epinfo;
88 
89  // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
90  p->epinfo = epInfo;
91 
92  p->lowspeed = lowspeed;
93 
94  // Get device descriptor
95  rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
96  // Restore p->epinfo
97  p->epinfo = oldep_ptr;
98 
99  if(rcode)
100  goto FailGetDevDescr;
101 
102  VID = udd->idVendor;
103  PID = udd->idProduct;
104 
105  if(VID != PS3_VID || (PID != PS3_PID && PID != PS3NAVIGATION_PID && PID != PS3MOVE_PID))
106  goto FailUnknownDevice;
107 
108  // Allocate new address according to device class
109  bAddress = addrPool.AllocAddress(parent, false, port);
110 
111  if(!bAddress)
113 
114  // Extract Max Packet Size from device descriptor
115  epInfo[0].maxPktSize = udd->bMaxPacketSize0;
116 
117  // Assign new address to the device
118  rcode = pUsb->setAddr(0, 0, bAddress);
119  if(rcode) {
120  p->lowspeed = false;
121  addrPool.FreeAddress(bAddress);
122  bAddress = 0;
123 #ifdef DEBUG_USB_HOST
124  Notify(PSTR("\r\nsetAddr: "), 0x80);
125  D_PrintHex<uint8_t > (rcode, 0x80);
126 #endif
127  return rcode;
128  }
129 #ifdef EXTRADEBUG
130  Notify(PSTR("\r\nAddr: "), 0x80);
131  D_PrintHex<uint8_t > (bAddress, 0x80);
132 #endif
133  //delay(300); // Spec says you should wait at least 200ms
134 
135  p->lowspeed = false;
136 
137  //get pointer to assigned address record
138  p = addrPool.GetUsbDevicePtr(bAddress);
139  if(!p)
141 
142  p->lowspeed = lowspeed;
143 
144  // Assign epInfo to epinfo pointer - only EP0 is known
145  rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
146  if(rcode)
147  goto FailSetDevTblEntry;
148 
149 
150  /* The application will work in reduced host mode, so we can save program and data
151  memory space. After verifying the PID and VID we will use known values for the
152  configuration values for device, interface, endpoints and HID for the PS3 Controllers */
153 
154  /* Initialize data structures for endpoints of device */
155  epInfo[ PS3_OUTPUT_PIPE ].epAddr = 0x02; // PS3 output endpoint
157  epInfo[ PS3_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
161  epInfo[ PS3_INPUT_PIPE ].epAddr = 0x01; // PS3 report endpoint
163  epInfo[ PS3_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
167 
168  rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
169  if(rcode)
170  goto FailSetDevTblEntry;
171 
172  delay(200); //Give time for address change
173 
174  rcode = pUsb->setConf(bAddress, epInfo[ PS3_CONTROL_PIPE ].epAddr, 1);
175  if(rcode)
176  goto FailSetConfDescr;
177 
178  if(PID == PS3_PID || PID == PS3NAVIGATION_PID) {
179  if(PID == PS3_PID) {
180 #ifdef DEBUG_USB_HOST
181  Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80);
182 #endif
183  PS3Connected = true;
184  } else { // must be a navigation controller
185 #ifdef DEBUG_USB_HOST
186  Notify(PSTR("\r\nNavigation Controller Connected"), 0x80);
187 #endif
188  PS3NavigationConnected = true;
189  }
190  enable_sixaxis(); // The PS3 controller needs a special command before it starts sending data
191 
192  // Needed for PS3 Dualshock and Navigation commands to work
193  for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
194  writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]);
195 
196  for(uint8_t i = 6; i < 10; i++)
197  readBuf[i] = 0x7F; // Set the analog joystick values to center position
198  } else { // must be a Motion controller
199 #ifdef DEBUG_USB_HOST
200  Notify(PSTR("\r\nMotion Controller Connected"), 0x80);
201 #endif
202  PS3MoveConnected = true;
203  writeBuf[0] = 0x02; // Set report ID, this is needed for Move commands to work
204  }
205  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) {
206  if(PS3MoveConnected)
207  setMoveBdaddr(my_bdaddr); // Set internal Bluetooth address
208  else
209  setBdaddr(my_bdaddr); // Set internal Bluetooth address
210 
211 #ifdef DEBUG_USB_HOST
212  Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80);
213  for(int8_t i = 5; i > 0; i--) {
214  D_PrintHex<uint8_t > (my_bdaddr[i], 0x80);
215  Notify(PSTR(":"), 0x80);
216  }
217  D_PrintHex<uint8_t > (my_bdaddr[0], 0x80);
218 #endif
219  }
220  onInit();
221 
222  bPollEnable = true;
223  Notify(PSTR("\r\n"), 0x80);
224  timer = (uint32_t)millis();
225  return 0; // Successful configuration
226 
227  /* Diagnostic messages */
228 FailGetDevDescr:
229 #ifdef DEBUG_USB_HOST
231  goto Fail;
232 #endif
233 
234 FailSetDevTblEntry:
235 #ifdef DEBUG_USB_HOST
237  goto Fail;
238 #endif
239 
240 FailSetConfDescr:
241 #ifdef DEBUG_USB_HOST
243 #endif
244  goto Fail;
245 
246 FailUnknownDevice:
247 #ifdef DEBUG_USB_HOST
248  NotifyFailUnknownDevice(VID, PID);
249 #endif
251 
252 Fail:
253 #ifdef DEBUG_USB_HOST
254  Notify(PSTR("\r\nPS3 Init Failed, error code: "), 0x80);
255  NotifyFail(rcode);
256 #endif
257  Release();
258  return rcode;
259 }
260 
261 /* Performs a cleanup after failed Init() attempt */
262 uint8_t PS3USB::Release() {
263  PS3Connected = false;
264  PS3MoveConnected = false;
265  PS3NavigationConnected = false;
267  bAddress = 0;
268  bPollEnable = false;
269  return 0;
270 }
271 
272 uint8_t PS3USB::Poll() {
273  if(!bPollEnable)
274  return 0;
275 
277  uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
278  pUsb->inTransfer(bAddress, epInfo[ PS3_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
279  if((int32_t)((uint32_t)millis() - timer) > 100) { // Loop 100ms before processing data
280  readReport();
281 #ifdef PRINTREPORT
282  printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
283 #endif
284  }
285  } 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
286  if((int32_t)((uint32_t)millis() - timer) > 4000) { // Send at least every 4th second
287  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
288  timer = (uint32_t)millis();
289  }
290  }
291  return 0;
292 }
293 
294 void PS3USB::readReport() {
295  ButtonState = (uint32_t)(readBuf[2] | ((uint16_t)readBuf[3] << 8) | ((uint32_t)readBuf[4] << 16));
296 
297  //Notify(PSTR("\r\nButtonState", 0x80);
298  //PrintHex<uint32_t>(ButtonState, 0x80);
299 
300  if(ButtonState != OldButtonState) {
301  ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
302  OldButtonState = ButtonState;
303  }
304 }
305 
306 void PS3USB::printReport() { // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
307 #ifdef PRINTREPORT
308  for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) {
309  D_PrintHex<uint8_t > (readBuf[i], 0x80);
310  Notify(PSTR(" "), 0x80);
311  }
312  Notify(PSTR("\r\n"), 0x80);
313 #endif
314 }
315 
317  return (ButtonState & pgm_read_dword(&PS3_BUTTONS[(uint8_t)b]));
318 }
319 
321  uint32_t button = pgm_read_dword(&PS3_BUTTONS[(uint8_t)b]);
322  bool click = (ButtonClickState & button);
323  ButtonClickState &= ~button; // Clear "click" event
324  return click;
325 }
326 
328  return (uint8_t)(readBuf[(pgm_read_byte(&PS3_ANALOG_BUTTONS[(uint8_t)a])) - 9]);
329 }
330 
332  return (uint8_t)(readBuf[((uint8_t)a + 6)]);
333 }
334 
336  return ((readBuf[((uint16_t)a) - 9] << 8) | readBuf[((uint16_t)a + 1) - 9]);
337 }
338 
340  if(PS3Connected) {
341  float accXval, accYval, accZval;
342 
343  // Data for the Kionix KXPC4 used in the DualShock 3
344  const float zeroG = 511.5f; // 1.65/3.3*1023 (1,65V)
345  accXval = -((float)getSensor(aX) - zeroG);
346  accYval = -((float)getSensor(aY) - zeroG);
347  accZval = -((float)getSensor(aZ) - zeroG);
348 
349  // Convert to 360 degrees resolution
350  // atan2 outputs the value of -Ï€ to Ï€ (radians)
351  // We are then converting it to 0 to 2Ï€ and then to degrees
352  if(a == Pitch)
353  return (atan2f(accYval, accZval) + PI) * RAD_TO_DEG;
354  else
355  return (atan2f(accXval, accZval) + PI) * RAD_TO_DEG;
356  } else
357  return 0;
358 }
359 
361  return (readBuf[((uint16_t)c >> 8) - 9] == ((uint8_t)c & 0xff));
362 }
363 
365  char statusOutput[102]; // Max string length plus null character
367  strcpy_P(statusOutput, PSTR("\r\nConnectionStatus: "));
368 
369  if(getStatus(Plugged)) strcat_P(statusOutput, PSTR("Plugged"));
370  else if(getStatus(Unplugged)) strcat_P(statusOutput, PSTR("Unplugged"));
371  else strcat_P(statusOutput, PSTR("Error"));
372 
373  strcat_P(statusOutput, PSTR(" - PowerRating: "));
374 
375  if(getStatus(Charging)) strcat_P(statusOutput, PSTR("Charging"));
376  else if(getStatus(NotCharging)) strcat_P(statusOutput, PSTR("Not Charging"));
377  else if(getStatus(Shutdown)) strcat_P(statusOutput, PSTR("Shutdown"));
378  else if(getStatus(Dying)) strcat_P(statusOutput, PSTR("Dying"));
379  else if(getStatus(Low)) strcat_P(statusOutput, PSTR("Low"));
380  else if(getStatus(High)) strcat_P(statusOutput, PSTR("High"));
381  else if(getStatus(Full)) strcat_P(statusOutput, PSTR("Full"));
382  else strcat_P(statusOutput, PSTR("Error"));
383 
384  strcat_P(statusOutput, PSTR(" - WirelessStatus: "));
385 
386  if(getStatus(CableRumble)) strcat_P(statusOutput, PSTR("Cable - Rumble is on"));
387  else if(getStatus(Cable)) strcat_P(statusOutput, PSTR("Cable - Rumble is off"));
388  else if(getStatus(BluetoothRumble)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is on"));
389  else if(getStatus(Bluetooth)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is off"));
390  else strcat_P(statusOutput, PSTR("Error"));
391  } else
392  strcpy_P(statusOutput, PSTR("\r\nError"));
393 
394  USB_HOST_SERIAL.write(statusOutput);
395 }
396 
397 /* Playstation Sixaxis Dualshock and Navigation Controller commands */
398 void PS3USB::PS3_Command(uint8_t *data, uint16_t nbytes) {
399  // 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)
400  pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x01, 0x02, 0x00, nbytes, nbytes, data, NULL);
401 }
402 
404  for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
405  writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); // Reset buffer
406 
407  PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
408 }
409 
411  uint8_t rumbleBuf[EP_MAXPKTSIZE];
412  memcpy(rumbleBuf, writeBuf, EP_MAXPKTSIZE);
413  rumbleBuf[1] = 0x00;
414  rumbleBuf[2] = 0x00; // Low mode off
415  rumbleBuf[3] = 0x00;
416  rumbleBuf[4] = 0x00; // High mode off
417  PS3_Command(rumbleBuf, 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  uint8_t rumbleBuf[EP_MAXPKTSIZE];
433  memcpy(rumbleBuf, writeBuf, EP_MAXPKTSIZE);
434  rumbleBuf[1] = rightDuration;
435  rumbleBuf[2] = rightPower;
436  rumbleBuf[3] = leftDuration;
437  rumbleBuf[4] = leftPower;
438  PS3_Command(rumbleBuf, PS3_REPORT_BUFFER_SIZE);
439 }
440 
441 void PS3USB::setLedRaw(uint8_t value) {
442  writeBuf[9] = value << 1;
443  PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
444 }
445 
447  writeBuf[9] &= ~((uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1));
448  PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
449 }
450 
452  if(a == OFF)
453  setLedRaw(0);
454  else {
455  writeBuf[9] |= (uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1);
456  PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
457  }
458 }
459 
461  writeBuf[9] ^= (uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1);
462  PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
463 }
464 
465 void PS3USB::setBdaddr(uint8_t *bdaddr) {
466  /* Set the internal Bluetooth address */
467  uint8_t buf[8];
468  buf[0] = 0x01;
469  buf[1] = 0x00;
470 
471  for(uint8_t i = 0; i < 6; i++)
472  buf[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed, so it is MSB first
473 
474  // 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
475  pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL);
476 }
477 
478 void PS3USB::getBdaddr(uint8_t *bdaddr) {
479  uint8_t buf[8];
480 
481  // 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
482  pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL);
483 
484  for(uint8_t i = 0; i < 6; i++)
485  bdaddr[5 - i] = buf[i + 2]; // Copy into buffer reversed, so it is LSB first
486 }
487 
488 void PS3USB::enable_sixaxis() { // Command used to enable the Dualshock 3 and Navigation controller to send data via USB
489  uint8_t cmd_buf[4];
490  cmd_buf[0] = 0x42; // Special PS3 Controller enable commands
491  cmd_buf[1] = 0x0c;
492  cmd_buf[2] = 0x00;
493  cmd_buf[3] = 0x00;
494 
495  // 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)
496  pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF4, 0x03, 0x00, 4, 4, cmd_buf, NULL);
497 }
498 
499 /* Playstation Move Controller commands */
500 void PS3USB::Move_Command(uint8_t *data, uint16_t nbytes) {
501  pUsb->outTransfer(bAddress, epInfo[ PS3_OUTPUT_PIPE ].epAddr, nbytes, data);
502 }
503 
504 void PS3USB::moveSetBulb(uint8_t r, uint8_t g, uint8_t b) { // Use this to set the Color using RGB values
505  // Set the Bulb's values into the write buffer
506  writeBuf[2] = r;
507  writeBuf[3] = g;
508  writeBuf[4] = b;
509 
510  Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
511 }
512 
513 void PS3USB::moveSetBulb(ColorsEnum color) { // Use this to set the Color using the predefined colors in "enums.h"
514  moveSetBulb((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
515 }
516 
517 void PS3USB::moveSetRumble(uint8_t rumble) {
518 #ifdef DEBUG_USB_HOST
519  if(rumble < 64 && rumble != 0) // The rumble value has to at least 64, or approximately 25% (64/255*100)
520  Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80);
521 #endif
522  writeBuf[6] = rumble; // Set the rumble value into the write buffer
523 
524  Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
525 }
526 
527 void PS3USB::setMoveBdaddr(uint8_t *bdaddr) {
528  /* Set the internal Bluetooth address */
529  uint8_t buf[11];
530  buf[0] = 0x05;
531  buf[7] = 0x10;
532  buf[8] = 0x01;
533  buf[9] = 0x02;
534  buf[10] = 0x12;
535 
536  for(uint8_t i = 0; i < 6; i++)
537  buf[i + 1] = bdaddr[i];
538 
539  // 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
540  pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00, 11, 11, buf, NULL);
541 }
542 
543 void PS3USB::getMoveBdaddr(uint8_t *bdaddr) {
544  uint8_t buf[16];
545 
546  // 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
547  pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0x04, 0x03, 0x00, 16, 16, buf, NULL);
548 
549  for(uint8_t i = 0; i < 6; i++)
550  bdaddr[i] = buf[10 + i];
551 }
552 
553 void PS3USB::getMoveCalibration(uint8_t *data) {
554  uint8_t buf[49];
555 
556  for(uint8_t i = 0; i < 3; i++) {
557  // 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
558  pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0x10, 0x03, 0x00, 49, 49, buf, NULL);
559 
560  for(uint8_t j = 0; j < 49; j++)
561  data[49 * i + j] = buf[j];
562  }
563 }
564 
565 void PS3USB::onInit() {
566  if(pFuncOnInit)
567  pFuncOnInit(); // Call the user function
568  else {
569  if(PS3MoveConnected)
570  moveSetBulb(Red);
571  else // Dualshock 3 or Navigation controller
572  setLedOn(static_cast<LEDEnum>(LED1));
573  }
574 }
USB::outTransfer
uint8_t outTransfer(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *data)
Definition: Usb.cpp:303
PS3USB::getMoveCalibration
void getMoveCalibration(uint8_t *data)
Definition: PS3USB.cpp:553
PS3USB::getButtonPress
bool getButtonPress(ButtonEnum b)
Definition: PS3USB.cpp:316
PS3_MAX_ENDPOINTS
#define PS3_MAX_ENDPOINTS
Definition: PS3USB.h:39
PS3USB::getButtonClick
bool getButtonClick(ButtonEnum b)
Definition: PS3USB.cpp:320
NotCharging
@ NotCharging
Definition: PS3Enums.h:120
AddressPool::GetUsbDevicePtr
virtual UsbDevice * GetUsbDevicePtr(uint8_t addr)=0
bmREQ_HID_OUT
#define bmREQ_HID_OUT
Definition: usbhid.h:63
Low
@ Low
Definition: PS3Enums.h:123
AddressPool
Definition: address.h:90
EpInfo::bmSndToggle
uint8_t bmSndToggle
Definition: address.h:47
PS3USB::getStatus
bool getStatus(StatusEnum c)
Definition: PS3USB.cpp:360
NotifyFail
#define NotifyFail(...)
Definition: message.h:62
UsbDevice::lowspeed
bool lowspeed
Definition: address.h:86
USB_TRANSFER_TYPE_INTERRUPT
#define USB_TRANSFER_TYPE_INTERRUPT
Definition: usb_ch9.h:93
USB::RegisterDeviceClass
uint8_t RegisterDeviceClass(USBDeviceConfig *pdev)
Definition: UsbCore.h:230
AddressPool::AllocAddress
virtual uint8_t AllocAddress(uint8_t parent, bool is_hub=false, uint8_t port=0)=0
PS3USB::setBdaddr
void setBdaddr(uint8_t *bdaddr)
Definition: PS3USB.cpp:465
USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE
#define USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE
Definition: UsbCore.h:98
PS3USB.h
PS3USB::Release
uint8_t Release()
Definition: PS3USB.cpp:262
LED1
@ LED1
Definition: controllerEnums.h:34
PS3USB::setRumbleOff
void setRumbleOff()
Definition: PS3USB.cpp:410
NotifyFailSetDevTblEntry
#define NotifyFailSetDevTblEntry(...)
Definition: message.h:58
Cable
@ Cable
Definition: PS3Enums.h:136
USB_HOST_SERIAL
#define USB_HOST_SERIAL
Definition: settings.h:49
USB::getDevDescr
uint8_t getDevDescr(uint8_t addr, uint8_t ep, uint16_t nbytes, uint8_t *dataptr)
defined(USB_METHODS_INLINE)
Definition: Usb.cpp:796
PS3MOVE_PID
#define PS3MOVE_PID
Definition: BTD.h:28
aZ
@ aZ
Definition: controllerEnums.h:187
PS3USB::getBdaddr
void getBdaddr(uint8_t *bdaddr)
Definition: PS3USB.cpp:478
Unplugged
@ Unplugged
Definition: PS3Enums.h:117
SensorEnum
SensorEnum
Definition: controllerEnums.h:185
PS3USB::setLedRaw
void setLedRaw(uint8_t value)
Definition: PS3USB.cpp:441
strcat_P
#define strcat_P(dest, src)
Definition: version_helper.h:79
PS3USB::getAnalogButton
uint8_t getAnalogButton(ButtonEnum a)
Definition: PS3USB.cpp:327
PS3_CONTROL_PIPE
#define PS3_CONTROL_PIPE
Definition: PS3USB.h:29
Bluetooth
@ Bluetooth
Definition: PS3Enums.h:138
EpInfo::epAddr
uint8_t epAddr
Definition: address.h:40
MOVE_REPORT_BUFFER_SIZE
#define MOVE_REPORT_BUFFER_SIZE
Definition: PS3Enums.h:40
AngleEnum
AngleEnum
Definition: controllerEnums.h:218
PS3USB::moveSetBulb
void moveSetBulb(uint8_t r, uint8_t g, uint8_t b)
Definition: PS3USB.cpp:504
Notify
#define Notify(...)
Definition: message.h:51
PS3USB::printStatusString
void printStatusString()
Definition: PS3USB.cpp:364
PS3USB::PS3MoveConnected
bool PS3MoveConnected
Definition: PS3USB.h:262
PS3USB::setLedToggle
void setLedToggle(LEDEnum a)
Definition: PS3USB.cpp:460
aY
@ aY
Definition: controllerEnums.h:187
NotifyFailGetDevDescr
#define NotifyFailGetDevDescr(...)
Definition: message.h:57
HID_REQUEST_SET_REPORT
#define HID_REQUEST_SET_REPORT
Definition: usbhid.h:72
PS3USB::getSensor
uint16_t getSensor(SensorEnum a)
Definition: PS3USB.cpp:335
PS3_LEDS
const uint8_t PS3_LEDS[]
Definition: PS3Enums.h:43
HID_REQUEST_GET_REPORT
#define HID_REQUEST_GET_REPORT
Definition: usbhid.h:69
USB_DEVICE_DESCRIPTOR
Definition: usb_ch9.h:105
EpInfo::bmNakPower
uint8_t bmNakPower
Definition: address.h:49
PS3_REPORT_BUFFER_SIZE
#define PS3_REPORT_BUFFER_SIZE
Definition: PS3Enums.h:24
PS3_VID
#define PS3_VID
Definition: BTD.h:25
LEDEnum
LEDEnum
Definition: controllerEnums.h:31
PS3USB::getMoveBdaddr
void getMoveBdaddr(uint8_t *bdaddr)
Definition: PS3USB.cpp:543
PS3USB::setAllOff
void setAllOff()
Definition: PS3USB.cpp:403
High
@ High
Definition: PS3Enums.h:124
Pitch
@ Pitch
Definition: controllerEnums.h:219
EP_MAXPKTSIZE
#define EP_MAXPKTSIZE
Definition: PS3USB.h:26
PS3USB::getAnalogHat
uint8_t getAnalogHat(AnalogHatEnum a)
Definition: PS3USB.cpp:331
USB_NAK_MAX_POWER
#define USB_NAK_MAX_POWER
Definition: address.h:34
PS3USB::PS3Connected
bool PS3Connected
Definition: PS3USB.h:256
PS3_BUTTONS
const uint32_t PS3_BUTTONS[]
Definition: PS3Enums.h:62
EpInfo
Definition: address.h:39
USB_NAK_NOWAIT
#define USB_NAK_NOWAIT
Definition: address.h:36
EpInfo::bmRcvToggle
uint8_t bmRcvToggle
Definition: address.h:48
PS3_INPUT_PIPE
#define PS3_INPUT_PIPE
Definition: PS3USB.h:31
USB::ctrlReq
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
RumbleEnum
RumbleEnum
Definition: controllerEnums.h:72
PS3USB::Poll
uint8_t Poll()
Definition: PS3USB.cpp:272
NotifyFailUnknownDevice
#define NotifyFailUnknownDevice(...)
Definition: message.h:61
PS3USB::epInfo
EpInfo epInfo[PS3_MAX_ENDPOINTS]
Definition: PS3USB.h:272
BluetoothRumble
@ BluetoothRumble
Definition: PS3Enums.h:137
PS3USB::setRumbleOn
void setRumbleOn(RumbleEnum mode)
Definition: PS3USB.cpp:420
Charging
@ Charging
Definition: PS3Enums.h:119
USB
Definition: UsbCore.h:210
EpInfo::epAttribs
uint8_t epAttribs
Definition: address.h:44
USB::inTransfer
uint8_t inTransfer(uint8_t addr, uint8_t ep, uint16_t *nbytesptr, uint8_t *data, uint8_t bInterval=0)
Definition: Usb.cpp:209
PS3USB::Init
uint8_t Init(uint8_t parent, uint8_t port, bool lowspeed)
Definition: PS3USB.cpp:47
pgm_read_dword
#define pgm_read_dword(addr)
Definition: version_helper.h:167
StatusEnum
StatusEnum
Definition: PS3Enums.h:113
USB_ERROR_EPINFO_IS_NULL
#define USB_ERROR_EPINFO_IS_NULL
Definition: UsbCore.h:96
PS3_ANALOG_BUTTONS
const uint8_t PS3_ANALOG_BUTTONS[]
Definition: PS3Enums.h:92
PS3NAVIGATION_PID
#define PS3NAVIGATION_PID
Definition: BTD.h:27
UsbDevice
Definition: address.h:82
PS3USB::setMoveBdaddr
void setMoveBdaddr(uint8_t *bdaddr)
Definition: PS3USB.cpp:527
CableRumble
@ CableRumble
Definition: PS3Enums.h:135
pgm_read_byte
#define pgm_read_byte(addr)
Definition: version_helper.h:161
PS3USB::getAngle
float getAngle(AngleEnum a)
Definition: PS3USB.cpp:339
USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL
#define USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL
Definition: UsbCore.h:95
ColorsEnum
ColorsEnum
Definition: controllerEnums.h:50
OFF
@ OFF
Definition: controllerEnums.h:32
USB::setConf
uint8_t setConf(uint8_t addr, uint8_t ep, uint8_t conf_value)
Definition: Usb.cpp:840
PS3_REPORT_BUFFER
const uint8_t PS3_REPORT_BUFFER[PS3_REPORT_BUFFER_SIZE]
Definition: PS3Enums.h:27
Plugged
@ Plugged
Definition: PS3Enums.h:116
Full
@ Full
Definition: PS3Enums.h:125
PS3USB::pUsb
USB * pUsb
Definition: PS3USB.h:268
PSTR
#define PSTR(str)
Definition: version_helper.h:54
PS3_PID
#define PS3_PID
Definition: BTD.h:26
USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL
#define USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL
Definition: UsbCore.h:93
NotifyFailSetConfDescr
#define NotifyFailSetConfDescr(...)
Definition: message.h:60
RumbleHigh
@ RumbleHigh
Definition: controllerEnums.h:73
PS3USB::setLedOn
void setLedOn(LEDEnum a)
Definition: PS3USB.cpp:451
PS3USB::moveSetRumble
void moveSetRumble(uint8_t rumble)
Definition: PS3USB.cpp:517
AddressPool::FreeAddress
virtual void FreeAddress(uint8_t addr)=0
USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED
#define USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED
Definition: UsbCore.h:90
USB::setAddr
uint8_t setAddr(uint8_t oldaddr, uint8_t ep, uint8_t newaddr)
Definition: Usb.cpp:831
EpInfo::maxPktSize
uint8_t maxPktSize
Definition: address.h:41
strcpy_P
#define strcpy_P(dest, src)
Definition: version_helper.h:91
Shutdown
@ Shutdown
Definition: PS3Enums.h:121
USB::setEpInfoEntry
uint8_t setEpInfoEntry(uint8_t addr, uint8_t epcount, EpInfo *eprecord_ptr)
Definition: Usb.cpp:64
aX
@ aX
Definition: controllerEnums.h:187
PS3USB::PS3USB
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
Red
@ Red
Definition: controllerEnums.h:52
bmREQ_HID_IN
#define bmREQ_HID_IN
Definition: usbhid.h:64
ButtonEnum
ButtonEnum
Definition: controllerEnums.h:78
PS3USB::PS3NavigationConnected
bool PS3NavigationConnected
Definition: PS3USB.h:264
PS3_OUTPUT_PIPE
#define PS3_OUTPUT_PIPE
Definition: PS3USB.h:30
PS3USB::setLedOff
void setLedOff()
Definition: PS3USB.h:215
AnalogHatEnum
AnalogHatEnum
Definition: controllerEnums.h:170
Dying
@ Dying
Definition: PS3Enums.h:122
PS3USB::bAddress
uint8_t bAddress
Definition: PS3USB.h:270
USB::GetAddressPool
AddressPool & GetAddressPool()
Definition: UsbCore.h:226
UsbDevice::epinfo
EpInfo * epinfo
Definition: address.h:83