Keyboard firmwares for Atmel AVR and Cortex-M
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

PS3USB.cpp 22KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572
  1. /* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved.
  2. This software may be distributed and modified under the terms of the GNU
  3. General Public License version 2 (GPL2) as published by the Free Software
  4. Foundation and appearing in the file GPL2.TXT included in the packaging of
  5. this file. Please note that GPL2 Section 2[b] requires that all works based
  6. on this software must also be made publicly available under the terms of
  7. the GPL2 ("Copyleft").
  8. Contact information
  9. -------------------
  10. Kristian Lauszus, TKJ Electronics
  11. Web : http://www.tkjelectronics.com
  12. e-mail : [email protected]
  13. */
  14. #include "PS3USB.h"
  15. // To enable serial debugging see "settings.h"
  16. //#define EXTRADEBUG // Uncomment to get even more debugging data
  17. //#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers
  18. PS3USB::PS3USB(USB *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0) :
  19. pUsb(p), // pointer to USB class instance - mandatory
  20. bAddress(0), // device address - mandatory
  21. bPollEnable(false) // don't start polling before dongle is connected
  22. {
  23. for(uint8_t i = 0; i < PS3_MAX_ENDPOINTS; i++) {
  24. epInfo[i].epAddr = 0;
  25. epInfo[i].maxPktSize = (i) ? 0 : 8;
  26. epInfo[i].epAttribs = 0;
  27. epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER;
  28. }
  29. if(pUsb) // register in USB subsystem
  30. pUsb->RegisterDeviceClass(this); //set devConfig[] entry
  31. my_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead
  32. my_bdaddr[4] = btadr4;
  33. my_bdaddr[3] = btadr3;
  34. my_bdaddr[2] = btadr2;
  35. my_bdaddr[1] = btadr1;
  36. my_bdaddr[0] = btadr0;
  37. }
  38. uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) {
  39. uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)];
  40. USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf);
  41. uint8_t rcode;
  42. UsbDevice *p = NULL;
  43. EpInfo *oldep_ptr = NULL;
  44. uint16_t PID;
  45. uint16_t VID;
  46. // get memory address of USB device address pool
  47. AddressPool &addrPool = pUsb->GetAddressPool();
  48. #ifdef EXTRADEBUG
  49. Notify(PSTR("\r\nPS3USB Init"), 0x80);
  50. #endif
  51. // check if address has already been assigned to an instance
  52. if(bAddress) {
  53. #ifdef DEBUG_USB_HOST
  54. Notify(PSTR("\r\nAddress in use"), 0x80);
  55. #endif
  56. return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE;
  57. }
  58. // Get pointer to pseudo device with address 0 assigned
  59. p = addrPool.GetUsbDevicePtr(0);
  60. if(!p) {
  61. #ifdef DEBUG_USB_HOST
  62. Notify(PSTR("\r\nAddress not found"), 0x80);
  63. #endif
  64. return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
  65. }
  66. if(!p->epinfo) {
  67. #ifdef DEBUG_USB_HOST
  68. Notify(PSTR("\r\nepinfo is null"), 0x80);
  69. #endif
  70. return USB_ERROR_EPINFO_IS_NULL;
  71. }
  72. // Save old pointer to EP_RECORD of address 0
  73. oldep_ptr = p->epinfo;
  74. // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence
  75. p->epinfo = epInfo;
  76. p->lowspeed = lowspeed;
  77. // Get device descriptor
  78. rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data
  79. // Restore p->epinfo
  80. p->epinfo = oldep_ptr;
  81. if(rcode)
  82. goto FailGetDevDescr;
  83. VID = udd->idVendor;
  84. PID = udd->idProduct;
  85. if(VID != PS3_VID || (PID != PS3_PID && PID != PS3NAVIGATION_PID && PID != PS3MOVE_PID))
  86. goto FailUnknownDevice;
  87. // Allocate new address according to device class
  88. bAddress = addrPool.AllocAddress(parent, false, port);
  89. if(!bAddress)
  90. return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL;
  91. // Extract Max Packet Size from device descriptor
  92. epInfo[0].maxPktSize = udd->bMaxPacketSize0;
  93. // Assign new address to the device
  94. rcode = pUsb->setAddr(0, 0, bAddress);
  95. if(rcode) {
  96. p->lowspeed = false;
  97. addrPool.FreeAddress(bAddress);
  98. bAddress = 0;
  99. #ifdef DEBUG_USB_HOST
  100. Notify(PSTR("\r\nsetAddr: "), 0x80);
  101. D_PrintHex<uint8_t > (rcode, 0x80);
  102. #endif
  103. return rcode;
  104. }
  105. #ifdef EXTRADEBUG
  106. Notify(PSTR("\r\nAddr: "), 0x80);
  107. D_PrintHex<uint8_t > (bAddress, 0x80);
  108. #endif
  109. //delay(300); // Spec says you should wait at least 200ms
  110. p->lowspeed = false;
  111. //get pointer to assigned address record
  112. p = addrPool.GetUsbDevicePtr(bAddress);
  113. if(!p)
  114. return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL;
  115. p->lowspeed = lowspeed;
  116. // Assign epInfo to epinfo pointer - only EP0 is known
  117. rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo);
  118. if(rcode)
  119. goto FailSetDevTblEntry;
  120. /* The application will work in reduced host mode, so we can save program and data
  121. memory space. After verifying the PID and VID we will use known values for the
  122. configuration values for device, interface, endpoints and HID for the PS3 Controllers */
  123. /* Initialize data structures for endpoints of device */
  124. epInfo[ PS3_OUTPUT_PIPE ].epAddr = 0x02; // PS3 output endpoint
  125. epInfo[ PS3_OUTPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
  126. epInfo[ PS3_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
  127. epInfo[ PS3_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
  128. epInfo[ PS3_OUTPUT_PIPE ].bmSndToggle = 0;
  129. epInfo[ PS3_OUTPUT_PIPE ].bmRcvToggle = 0;
  130. epInfo[ PS3_INPUT_PIPE ].epAddr = 0x01; // PS3 report endpoint
  131. epInfo[ PS3_INPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT;
  132. epInfo[ PS3_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints
  133. epInfo[ PS3_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE;
  134. epInfo[ PS3_INPUT_PIPE ].bmSndToggle = 0;
  135. epInfo[ PS3_INPUT_PIPE ].bmRcvToggle = 0;
  136. rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo);
  137. if(rcode)
  138. goto FailSetDevTblEntry;
  139. delay(200); //Give time for address change
  140. rcode = pUsb->setConf(bAddress, epInfo[ PS3_CONTROL_PIPE ].epAddr, 1);
  141. if(rcode)
  142. goto FailSetConfDescr;
  143. if(PID == PS3_PID || PID == PS3NAVIGATION_PID) {
  144. if(PID == PS3_PID) {
  145. #ifdef DEBUG_USB_HOST
  146. Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80);
  147. #endif
  148. PS3Connected = true;
  149. } else { // must be a navigation controller
  150. #ifdef DEBUG_USB_HOST
  151. Notify(PSTR("\r\nNavigation Controller Connected"), 0x80);
  152. #endif
  153. PS3NavigationConnected = true;
  154. }
  155. enable_sixaxis(); // The PS3 controller needs a special command before it starts sending data
  156. // Needed for PS3 Dualshock and Navigation commands to work
  157. for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
  158. writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]);
  159. for(uint8_t i = 6; i < 10; i++)
  160. readBuf[i] = 0x7F; // Set the analog joystick values to center position
  161. } else { // must be a Motion controller
  162. #ifdef DEBUG_USB_HOST
  163. Notify(PSTR("\r\nMotion Controller Connected"), 0x80);
  164. #endif
  165. PS3MoveConnected = true;
  166. writeBuf[0] = 0x02; // Set report ID, this is needed for Move commands to work
  167. }
  168. 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) {
  169. if(PS3MoveConnected)
  170. setMoveBdaddr(my_bdaddr); // Set internal Bluetooth address
  171. else
  172. setBdaddr(my_bdaddr); // Set internal Bluetooth address
  173. #ifdef DEBUG_USB_HOST
  174. Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80);
  175. for(int8_t i = 5; i > 0; i--) {
  176. D_PrintHex<uint8_t > (my_bdaddr[i], 0x80);
  177. Notify(PSTR(":"), 0x80);
  178. }
  179. D_PrintHex<uint8_t > (my_bdaddr[0], 0x80);
  180. #endif
  181. }
  182. onInit();
  183. bPollEnable = true;
  184. Notify(PSTR("\r\n"), 0x80);
  185. timer = millis();
  186. return 0; // Successful configuration
  187. /* Diagnostic messages */
  188. FailGetDevDescr:
  189. #ifdef DEBUG_USB_HOST
  190. NotifyFailGetDevDescr();
  191. goto Fail;
  192. #endif
  193. FailSetDevTblEntry:
  194. #ifdef DEBUG_USB_HOST
  195. NotifyFailSetDevTblEntry();
  196. goto Fail;
  197. #endif
  198. FailSetConfDescr:
  199. #ifdef DEBUG_USB_HOST
  200. NotifyFailSetConfDescr();
  201. #endif
  202. goto Fail;
  203. FailUnknownDevice:
  204. #ifdef DEBUG_USB_HOST
  205. NotifyFailUnknownDevice(VID, PID);
  206. #endif
  207. rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED;
  208. Fail:
  209. #ifdef DEBUG_USB_HOST
  210. Notify(PSTR("\r\nPS3 Init Failed, error code: "), 0x80);
  211. NotifyFail(rcode);
  212. #endif
  213. Release();
  214. return rcode;
  215. }
  216. /* Performs a cleanup after failed Init() attempt */
  217. uint8_t PS3USB::Release() {
  218. PS3Connected = false;
  219. PS3MoveConnected = false;
  220. PS3NavigationConnected = false;
  221. pUsb->GetAddressPool().FreeAddress(bAddress);
  222. bAddress = 0;
  223. bPollEnable = false;
  224. return 0;
  225. }
  226. uint8_t PS3USB::Poll() {
  227. if(!bPollEnable)
  228. return 0;
  229. if(PS3Connected || PS3NavigationConnected) {
  230. uint16_t BUFFER_SIZE = EP_MAXPKTSIZE;
  231. pUsb->inTransfer(bAddress, epInfo[ PS3_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1
  232. if(millis() - timer > 100) { // Loop 100ms before processing data
  233. readReport();
  234. #ifdef PRINTREPORT
  235. printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
  236. #endif
  237. }
  238. } 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
  239. if(millis() - timer > 4000) { // Send at least every 4th second
  240. 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
  241. timer = millis();
  242. }
  243. }
  244. return 0;
  245. }
  246. void PS3USB::readReport() {
  247. ButtonState = (uint32_t)(readBuf[2] | ((uint16_t)readBuf[3] << 8) | ((uint32_t)readBuf[4] << 16));
  248. //Notify(PSTR("\r\nButtonState", 0x80);
  249. //PrintHex<uint32_t>(ButtonState, 0x80);
  250. if(ButtonState != OldButtonState) {
  251. ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable
  252. OldButtonState = ButtonState;
  253. }
  254. }
  255. void PS3USB::printReport() { // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers
  256. #ifdef PRINTREPORT
  257. for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) {
  258. D_PrintHex<uint8_t > (readBuf[i], 0x80);
  259. Notify(PSTR(" "), 0x80);
  260. }
  261. Notify(PSTR("\r\n"), 0x80);
  262. #endif
  263. }
  264. bool PS3USB::getButtonPress(ButtonEnum b) {
  265. return (ButtonState & pgm_read_dword(&PS3_BUTTONS[(uint8_t)b]));
  266. }
  267. bool PS3USB::getButtonClick(ButtonEnum b) {
  268. uint32_t button = pgm_read_dword(&PS3_BUTTONS[(uint8_t)b]);
  269. bool click = (ButtonClickState & button);
  270. ButtonClickState &= ~button; // Clear "click" event
  271. return click;
  272. }
  273. uint8_t PS3USB::getAnalogButton(ButtonEnum a) {
  274. return (uint8_t)(readBuf[(pgm_read_byte(&PS3_ANALOG_BUTTONS[(uint8_t)a])) - 9]);
  275. }
  276. uint8_t PS3USB::getAnalogHat(AnalogHatEnum a) {
  277. return (uint8_t)(readBuf[((uint8_t)a + 6)]);
  278. }
  279. uint16_t PS3USB::getSensor(SensorEnum a) {
  280. return ((readBuf[((uint16_t)a) - 9] << 8) | readBuf[((uint16_t)a + 1) - 9]);
  281. }
  282. double PS3USB::getAngle(AngleEnum a) {
  283. if(PS3Connected) {
  284. double accXval;
  285. double accYval;
  286. double accZval;
  287. // Data for the Kionix KXPC4 used in the DualShock 3
  288. const double zeroG = 511.5; // 1.65/3.3*1023 (1,65V)
  289. accXval = -((double)getSensor(aX) - zeroG);
  290. accYval = -((double)getSensor(aY) - zeroG);
  291. accZval = -((double)getSensor(aZ) - zeroG);
  292. // Convert to 360 degrees resolution
  293. // atan2 outputs the value of -π to π (radians)
  294. // We are then converting it to 0 to 2π and then to degrees
  295. if(a == Pitch)
  296. return (atan2(accYval, accZval) + PI) * RAD_TO_DEG;
  297. else
  298. return (atan2(accXval, accZval) + PI) * RAD_TO_DEG;
  299. } else
  300. return 0;
  301. }
  302. bool PS3USB::getStatus(StatusEnum c) {
  303. return (readBuf[((uint16_t)c >> 8) - 9] == ((uint8_t)c & 0xff));
  304. }
  305. void PS3USB::printStatusString() {
  306. char statusOutput[100]; // Max string length plus null character
  307. if(PS3Connected || PS3NavigationConnected) {
  308. strcpy_P(statusOutput, PSTR("ConnectionStatus: "));
  309. if(getStatus(Plugged)) strcat_P(statusOutput, PSTR("Plugged"));
  310. else if(getStatus(Unplugged)) strcat_P(statusOutput, PSTR("Unplugged"));
  311. else strcat_P(statusOutput, PSTR("Error"));
  312. strcat_P(statusOutput, PSTR(" - PowerRating: "));
  313. if(getStatus(Charging)) strcat_P(statusOutput, PSTR("Charging"));
  314. else if(getStatus(NotCharging)) strcat_P(statusOutput, PSTR("Not Charging"));
  315. else if(getStatus(Shutdown)) strcat_P(statusOutput, PSTR("Shutdown"));
  316. else if(getStatus(Dying)) strcat_P(statusOutput, PSTR("Dying"));
  317. else if(getStatus(Low)) strcat_P(statusOutput, PSTR("Low"));
  318. else if(getStatus(High)) strcat_P(statusOutput, PSTR("High"));
  319. else if(getStatus(Full)) strcat_P(statusOutput, PSTR("Full"));
  320. else strcat_P(statusOutput, PSTR("Error"));
  321. strcat_P(statusOutput, PSTR(" - WirelessStatus: "));
  322. if(getStatus(CableRumble)) strcat_P(statusOutput, PSTR("Cable - Rumble is on"));
  323. else if(getStatus(Cable)) strcat_P(statusOutput, PSTR("Cable - Rumble is off"));
  324. else if(getStatus(BluetoothRumble)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is on"));
  325. else if(getStatus(Bluetooth)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is off"));
  326. else strcat_P(statusOutput, PSTR("Error"));
  327. } else
  328. strcpy_P(statusOutput, PSTR("Error"));
  329. USB_HOST_SERIAL.write(statusOutput);
  330. }
  331. /* Playstation Sixaxis Dualshock and Navigation Controller commands */
  332. void PS3USB::PS3_Command(uint8_t *data, uint16_t nbytes) {
  333. // 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)
  334. pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x01, 0x02, 0x00, nbytes, nbytes, data, NULL);
  335. }
  336. void PS3USB::setAllOff() {
  337. for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++)
  338. writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); // Reset buffer
  339. PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
  340. }
  341. void PS3USB::setRumbleOff() {
  342. writeBuf[1] = 0x00;
  343. writeBuf[2] = 0x00; // Low mode off
  344. writeBuf[3] = 0x00;
  345. writeBuf[4] = 0x00; // High mode off
  346. PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
  347. }
  348. void PS3USB::setRumbleOn(RumbleEnum mode) {
  349. if((mode & 0x30) > 0x00) {
  350. uint8_t power[2] = {0xff, 0x00}; // Defaults to RumbleLow
  351. if(mode == RumbleHigh) {
  352. power[0] = 0x00;
  353. power[1] = 0xff;
  354. }
  355. setRumbleOn(0xfe, power[0], 0xfe, power[1]);
  356. }
  357. }
  358. void PS3USB::setRumbleOn(uint8_t rightDuration, uint8_t rightPower, uint8_t leftDuration, uint8_t leftPower) {
  359. writeBuf[1] = rightDuration;
  360. writeBuf[2] = rightPower;
  361. writeBuf[3] = leftDuration;
  362. writeBuf[4] = leftPower;
  363. PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
  364. }
  365. void PS3USB::setLedRaw(uint8_t value) {
  366. writeBuf[9] = value << 1;
  367. PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
  368. }
  369. void PS3USB::setLedOff(LEDEnum a) {
  370. writeBuf[9] &= ~((uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1));
  371. PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
  372. }
  373. void PS3USB::setLedOn(LEDEnum a) {
  374. if(a == OFF)
  375. setLedRaw(0);
  376. else {
  377. writeBuf[9] |= (uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1);
  378. PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
  379. }
  380. }
  381. void PS3USB::setLedToggle(LEDEnum a) {
  382. writeBuf[9] ^= (uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1);
  383. PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE);
  384. }
  385. void PS3USB::setBdaddr(uint8_t *bdaddr) {
  386. /* Set the internal Bluetooth address */
  387. uint8_t buf[8];
  388. buf[0] = 0x01;
  389. buf[1] = 0x00;
  390. for(uint8_t i = 0; i < 6; i++)
  391. buf[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed, so it is MSB first
  392. // 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
  393. pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL);
  394. }
  395. void PS3USB::getBdaddr(uint8_t *bdaddr) {
  396. uint8_t buf[8];
  397. // 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
  398. pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL);
  399. for(uint8_t i = 0; i < 6; i++)
  400. bdaddr[5 - i] = buf[i + 2]; // Copy into buffer reversed, so it is LSB first
  401. }
  402. void PS3USB::enable_sixaxis() { // Command used to enable the Dualshock 3 and Navigation controller to send data via USB
  403. uint8_t cmd_buf[4];
  404. cmd_buf[0] = 0x42; // Special PS3 Controller enable commands
  405. cmd_buf[1] = 0x0c;
  406. cmd_buf[2] = 0x00;
  407. cmd_buf[3] = 0x00;
  408. // 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)
  409. pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF4, 0x03, 0x00, 4, 4, cmd_buf, NULL);
  410. }
  411. /* Playstation Move Controller commands */
  412. void PS3USB::Move_Command(uint8_t *data, uint16_t nbytes) {
  413. pUsb->outTransfer(bAddress, epInfo[ PS3_OUTPUT_PIPE ].epAddr, nbytes, data);
  414. }
  415. void PS3USB::moveSetBulb(uint8_t r, uint8_t g, uint8_t b) { // Use this to set the Color using RGB values
  416. // Set the Bulb's values into the write buffer
  417. writeBuf[2] = r;
  418. writeBuf[3] = g;
  419. writeBuf[4] = b;
  420. Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
  421. }
  422. void PS3USB::moveSetBulb(ColorsEnum color) { // Use this to set the Color using the predefined colors in "enums.h"
  423. moveSetBulb((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color));
  424. }
  425. void PS3USB::moveSetRumble(uint8_t rumble) {
  426. #ifdef DEBUG_USB_HOST
  427. if(rumble < 64 && rumble != 0) // The rumble value has to at least 64, or approximately 25% (64/255*100)
  428. Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80);
  429. #endif
  430. writeBuf[6] = rumble; // Set the rumble value into the write buffer
  431. Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE);
  432. }
  433. void PS3USB::setMoveBdaddr(uint8_t *bdaddr) {
  434. /* Set the internal Bluetooth address */
  435. uint8_t buf[11];
  436. buf[0] = 0x05;
  437. buf[7] = 0x10;
  438. buf[8] = 0x01;
  439. buf[9] = 0x02;
  440. buf[10] = 0x12;
  441. for(uint8_t i = 0; i < 6; i++)
  442. buf[i + 1] = bdaddr[i];
  443. // 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
  444. pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00, 11, 11, buf, NULL);
  445. }
  446. void PS3USB::getMoveBdaddr(uint8_t *bdaddr) {
  447. uint8_t buf[16];
  448. // 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
  449. pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0x04, 0x03, 0x00, 16, 16, buf, NULL);
  450. for(uint8_t i = 0; i < 6; i++)
  451. bdaddr[i] = buf[10 + i];
  452. }
  453. void PS3USB::getMoveCalibration(uint8_t *data) {
  454. uint8_t buf[49];
  455. for(uint8_t i = 0; i < 3; i++) {
  456. // 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
  457. pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0x10, 0x03, 0x00, 49, 49, buf, NULL);
  458. for(byte j = 0; j < 49; j++)
  459. data[49 * i + j] = buf[j];
  460. }
  461. }
  462. void PS3USB::onInit() {
  463. if(pFuncOnInit)
  464. pFuncOnInit(); // Call the user function
  465. else {
  466. if(PS3MoveConnected)
  467. moveSetBulb(Red);
  468. else // Dualshock 3 or Navigation controller
  469. setLedOn(LED1);
  470. }
  471. }