Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
PS3USB.cpp
00001 /* Copyright (C) 2012 Kristian Lauszus, TKJ Electronics. All rights reserved. 00002 00003 This software may be distributed and modified under the terms of the GNU 00004 General Public License version 2 (GPL2) as published by the Free Software 00005 Foundation and appearing in the file GPL2.TXT included in the packaging of 00006 this file. Please note that GPL2 Section 2[b] requires that all works based 00007 on this software must also be made publicly available under the terms of 00008 the GPL2 ("Copyleft"). 00009 00010 Contact information 00011 ------------------- 00012 00013 Kristian Lauszus, TKJ Electronics 00014 Web : http://www.tkjelectronics.com 00015 e-mail : kristianl@tkjelectronics.com 00016 */ 00017 00018 #include "stdio.h" 00019 #include "PS3USB.h" 00020 // To enable serial debugging see "settings.h" 00021 //#define EXTRADEBUG // Uncomment to get even more debugging data 00022 //#define PRINTREPORT // Uncomment to print the report send by the PS3 Controllers 00023 00024 PS3USB::PS3USB(USB *p, uint8_t btadr5, uint8_t btadr4, uint8_t btadr3, uint8_t btadr2, uint8_t btadr1, uint8_t btadr0) : 00025 pUsb(p), // pointer to USB class instance - mandatory 00026 bAddress(0), // device address - mandatory 00027 bPollEnable(false) // don't start polling before dongle is connected 00028 { 00029 for(uint8_t i = 0; i < PS3_MAX_ENDPOINTS; i++) { 00030 epInfo[i].epAddr = 0; 00031 epInfo[i].maxPktSize = (i) ? 0 : 8; 00032 epInfo[i].bmSndToggle = 0; 00033 epInfo[i].bmRcvToggle = 0; 00034 epInfo[i].bmNakPower = (i) ? USB_NAK_NOWAIT : USB_NAK_MAX_POWER; 00035 } 00036 00037 if(pUsb) // register in USB subsystem 00038 pUsb->RegisterDeviceClass(this); //set devConfig[] entry 00039 00040 my_bdaddr[5] = btadr5; // Change to your dongle's Bluetooth address instead 00041 my_bdaddr[4] = btadr4; 00042 my_bdaddr[3] = btadr3; 00043 my_bdaddr[2] = btadr2; 00044 my_bdaddr[1] = btadr1; 00045 my_bdaddr[0] = btadr0; 00046 00047 //printf("Constractor\n"); 00048 } 00049 00050 uint8_t PS3USB::Init(uint8_t parent, uint8_t port, bool lowspeed) { 00051 uint8_t buf[sizeof (USB_DEVICE_DESCRIPTOR)]; 00052 USB_DEVICE_DESCRIPTOR * udd = reinterpret_cast<USB_DEVICE_DESCRIPTOR*>(buf); 00053 uint8_t rcode; 00054 UsbDevice *p = NULL; 00055 EpInfo *oldep_ptr = NULL; 00056 uint16_t PID; 00057 uint16_t VID; 00058 00059 // get memory address of USB device address pool 00060 AddressPool &addrPool = pUsb->GetAddressPool(); 00061 printf("\r\nPS3USB Init"); 00062 #ifdef EXTRADEBUG 00063 Notify(PSTR("\r\nPS3USB Init"), 0x80); 00064 std:printf("\r\nPS3USB Init"); 00065 #endif 00066 // check if address has already been assigned to an instance 00067 if(bAddress) { 00068 #ifdef DEBUG_USB_HOST 00069 Notify(PSTR("\r\nAddress in use"), 0x80); 00070 #endif 00071 return USB_ERROR_CLASS_INSTANCE_ALREADY_IN_USE; 00072 } 00073 00074 // Get pointer to pseudo device with address 0 assigned 00075 p = addrPool.GetUsbDevicePtr(0); 00076 00077 if(!p) { 00078 #ifdef DEBUG_USB_HOST 00079 Notify(PSTR("\r\nAddress not found"), 0x80); 00080 #endif 00081 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; 00082 } 00083 00084 if(!p->epinfo) { 00085 #ifdef DEBUG_USB_HOST 00086 Notify(PSTR("\r\nepinfo is null"), 0x80); 00087 #endif 00088 return USB_ERROR_EPINFO_IS_NULL; 00089 } 00090 00091 // Save old pointer to EP_RECORD of address 0 00092 oldep_ptr = p->epinfo; 00093 00094 // Temporary assign new pointer to epInfo to p->epinfo in order to avoid toggle inconsistence 00095 p->epinfo = epInfo; 00096 00097 p->lowspeed = lowspeed; 00098 00099 // Get device descriptor 00100 rcode = pUsb->getDevDescr(0, 0, sizeof (USB_DEVICE_DESCRIPTOR), (uint8_t*)buf); // Get device descriptor - addr, ep, nbytes, data 00101 // Restore p->epinfo 00102 p->epinfo = oldep_ptr; 00103 00104 if(rcode) 00105 goto FailGetDevDescr; 00106 00107 VID = udd->idVendor; 00108 PID = udd->idProduct; 00109 00110 if(VID != PS3_VID || (PID != PS3_PID && PID != PS3NAVIGATION_PID && PID != PS3MOVE_PID)) 00111 goto FailUnknownDevice; 00112 00113 // Allocate new address according to device class 00114 bAddress = addrPool.AllocAddress(parent, false, port); 00115 00116 if(!bAddress) 00117 return USB_ERROR_OUT_OF_ADDRESS_SPACE_IN_POOL; 00118 00119 // Extract Max Packet Size from device descriptor 00120 epInfo[0].maxPktSize = udd->bMaxPacketSize0; 00121 00122 // Assign new address to the device 00123 rcode = pUsb->setAddr(0, 0, bAddress); 00124 if(rcode) { 00125 p->lowspeed = false; 00126 addrPool.FreeAddress(bAddress); 00127 bAddress = 0; 00128 #ifdef DEBUG_USB_HOST 00129 Notify(PSTR("\r\nsetAddr: "), 0x80); 00130 D_PrintHex<uint8_t > (rcode, 0x80); 00131 #endif 00132 return rcode; 00133 } 00134 #ifdef EXTRADEBUG 00135 Notify(PSTR("\r\nAddr: "), 0x80); 00136 D_PrintHex<uint8_t > (bAddress, 0x80); 00137 #endif 00138 //delay(300); // Spec says you should wait at least 200ms 00139 00140 p->lowspeed = false; 00141 00142 //get pointer to assigned address record 00143 p = addrPool.GetUsbDevicePtr(bAddress); 00144 if(!p) 00145 return USB_ERROR_ADDRESS_NOT_FOUND_IN_POOL; 00146 00147 p->lowspeed = lowspeed; 00148 00149 // Assign epInfo to epinfo pointer - only EP0 is known 00150 rcode = pUsb->setEpInfoEntry(bAddress, 1, epInfo); 00151 if(rcode) 00152 goto FailSetDevTblEntry; 00153 00154 00155 /* The application will work in reduced host mode, so we can save program and data 00156 memory space. After verifying the PID and VID we will use known values for the 00157 configuration values for device, interface, endpoints and HID for the PS3 Controllers */ 00158 00159 /* Initialize data structures for endpoints of device */ 00160 epInfo[ PS3_OUTPUT_PIPE ].epAddr = 0x02; // PS3 output endpoint 00161 epInfo[ PS3_OUTPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT; 00162 epInfo[ PS3_OUTPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints 00163 epInfo[ PS3_OUTPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE; 00164 epInfo[ PS3_OUTPUT_PIPE ].bmSndToggle = 0; 00165 epInfo[ PS3_OUTPUT_PIPE ].bmRcvToggle = 0; 00166 epInfo[ PS3_INPUT_PIPE ].epAddr = 0x01; // PS3 report endpoint 00167 epInfo[ PS3_INPUT_PIPE ].epAttribs = USB_TRANSFER_TYPE_INTERRUPT; 00168 epInfo[ PS3_INPUT_PIPE ].bmNakPower = USB_NAK_NOWAIT; // Only poll once for interrupt endpoints 00169 epInfo[ PS3_INPUT_PIPE ].maxPktSize = EP_MAXPKTSIZE; 00170 epInfo[ PS3_INPUT_PIPE ].bmSndToggle = 0; 00171 epInfo[ PS3_INPUT_PIPE ].bmRcvToggle = 0; 00172 00173 rcode = pUsb->setEpInfoEntry(bAddress, 3, epInfo); 00174 if(rcode) 00175 goto FailSetDevTblEntry; 00176 00177 delay(200); //Give time for address change 00178 00179 rcode = pUsb->setConf(bAddress, epInfo[ PS3_CONTROL_PIPE ].epAddr, 1); 00180 if(rcode) 00181 goto FailSetConfDescr; 00182 00183 if(PID == PS3_PID || PID == PS3NAVIGATION_PID) { 00184 if(PID == PS3_PID) { 00185 #ifdef DEBUG_USB_HOST 00186 Notify(PSTR("\r\nDualshock 3 Controller Connected"), 0x80); 00187 #endif 00188 PS3Connected = true; 00189 } else { // must be a navigation controller 00190 #ifdef DEBUG_USB_HOST 00191 Notify(PSTR("\r\nNavigation Controller Connected"), 0x80); 00192 #endif 00193 PS3NavigationConnected = true; 00194 } 00195 enable_sixaxis(); // The PS3 controller needs a special command before it starts sending data 00196 00197 // Needed for PS3 Dualshock and Navigation commands to work 00198 for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) 00199 writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); 00200 00201 for(uint8_t i = 6; i < 10; i++) 00202 readBuf[i] = 0x7F; // Set the analog joystick values to center position 00203 } else { // must be a Motion controller 00204 #ifdef DEBUG_USB_HOST 00205 Notify(PSTR("\r\nMotion Controller Connected"), 0x80); 00206 #endif 00207 PS3MoveConnected = true; 00208 writeBuf[0] = 0x02; // Set report ID, this is needed for Move commands to work 00209 } 00210 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) { 00211 if(PS3MoveConnected) 00212 setMoveBdaddr(my_bdaddr); // Set internal Bluetooth address 00213 else 00214 setBdaddr(my_bdaddr); // Set internal Bluetooth address 00215 00216 #ifdef DEBUG_USB_HOST 00217 Notify(PSTR("\r\nBluetooth Address was set to: "), 0x80); 00218 for(int8_t i = 5; i > 0; i--) { 00219 D_PrintHex<uint8_t > (my_bdaddr[i], 0x80); 00220 Notify(PSTR(":"), 0x80); 00221 } 00222 D_PrintHex<uint8_t > (my_bdaddr[0], 0x80); 00223 #endif 00224 } 00225 onInit(); 00226 00227 bPollEnable = true; 00228 Notify(PSTR("\r\n"), 0x80); 00229 timer = (uint32_t)millis(); 00230 return 0; // Successful configuration 00231 00232 /* Diagnostic messages */ 00233 FailGetDevDescr: 00234 #ifdef DEBUG_USB_HOST 00235 NotifyFailGetDevDescr(); 00236 goto Fail; 00237 #endif 00238 00239 FailSetDevTblEntry: 00240 #ifdef DEBUG_USB_HOST 00241 NotifyFailSetDevTblEntry(); 00242 goto Fail; 00243 #endif 00244 00245 FailSetConfDescr: 00246 #ifdef DEBUG_USB_HOST 00247 NotifyFailSetConfDescr(); 00248 #endif 00249 goto Fail; 00250 00251 FailUnknownDevice: 00252 #ifdef DEBUG_USB_HOST 00253 NotifyFailUnknownDevice(VID, PID); 00254 #endif 00255 rcode = USB_DEV_CONFIG_ERROR_DEVICE_NOT_SUPPORTED; 00256 00257 Fail: 00258 #ifdef DEBUG_USB_HOST 00259 Notify(PSTR("\r\nPS3 Init Failed, error code: "), 0x80); 00260 NotifyFail(rcode); 00261 #endif 00262 Release(); 00263 return rcode; 00264 } 00265 00266 /* Performs a cleanup after failed Init() attempt */ 00267 uint8_t PS3USB::Release() { 00268 PS3Connected = false; 00269 PS3MoveConnected = false; 00270 PS3NavigationConnected = false; 00271 pUsb->GetAddressPool().FreeAddress(bAddress); 00272 bAddress = 0; 00273 bPollEnable = false; 00274 return 0; 00275 } 00276 00277 uint8_t PS3USB::Poll() { 00278 if(!bPollEnable) 00279 return 0; 00280 00281 if(PS3Connected || PS3NavigationConnected) { 00282 uint16_t BUFFER_SIZE = EP_MAXPKTSIZE; 00283 pUsb->inTransfer(bAddress, epInfo[ PS3_INPUT_PIPE ].epAddr, &BUFFER_SIZE, readBuf); // input on endpoint 1 00284 if((int32_t)((uint32_t)millis() - timer) > 100) { // Loop 100ms before processing data 00285 readReport(); 00286 #ifdef PRINTREPORT 00287 printReport(); // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers 00288 #endif 00289 } 00290 } 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 00291 if((int32_t)((uint32_t)millis() - timer) > 4000) { // Send at least every 4th second 00292 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 00293 timer = (uint32_t)millis(); 00294 } 00295 } 00296 return 0; 00297 } 00298 00299 void PS3USB::readReport() { 00300 ButtonState = (uint32_t)(readBuf[2] | ((uint16_t)readBuf[3] << 8) | ((uint32_t)readBuf[4] << 16)); 00301 00302 //Notify(PSTR("\r\nButtonState", 0x80); 00303 //PrintHex<uint32_t>(ButtonState, 0x80); 00304 00305 if(ButtonState != OldButtonState) { 00306 ButtonClickState = ButtonState & ~OldButtonState; // Update click state variable 00307 OldButtonState = ButtonState; 00308 } 00309 } 00310 00311 void PS3USB::printReport() { // Uncomment "#define PRINTREPORT" to print the report send by the PS3 Controllers 00312 #ifdef PRINTREPORT 00313 for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) { 00314 D_PrintHex<uint8_t > (readBuf[i], 0x80); 00315 Notify(PSTR(" "), 0x80); 00316 } 00317 Notify(PSTR("\r\n"), 0x80); 00318 #endif 00319 } 00320 00321 bool PS3USB::getButtonPress(ButtonEnum b) { 00322 return (ButtonState & pgm_read_dword(&PS3_BUTTONS[(uint8_t)b])); 00323 } 00324 00325 bool PS3USB::getButtonClick(ButtonEnum b) { 00326 uint32_t button = pgm_read_dword(&PS3_BUTTONS[(uint8_t)b]); 00327 bool click = (ButtonClickState & button); 00328 ButtonClickState &= ~button; // Clear "click" event 00329 return click; 00330 } 00331 00332 uint8_t PS3USB::getAnalogButton(ButtonEnum a) { 00333 return (uint8_t)(readBuf[(pgm_read_byte(&PS3_ANALOG_BUTTONS[(uint8_t)a])) - 9]); 00334 } 00335 00336 uint8_t PS3USB::getAnalogHat(AnalogHatEnum a) { 00337 return (uint8_t)(readBuf[((uint8_t)a + 6)]); 00338 } 00339 00340 uint16_t PS3USB::getSensor(SensorEnum a) { 00341 return ((readBuf[((uint16_t)a) - 9] << 8) | readBuf[((uint16_t)a + 1) - 9]); 00342 } 00343 00344 float PS3USB::getAngle(AngleEnum a) { 00345 if(PS3Connected) { 00346 float accXval, accYval, accZval; 00347 00348 // Data for the Kionix KXPC4 used in the DualShock 3 00349 const float zeroG = 511.5f; // 1.65/3.3*1023 (1,65V) 00350 accXval = -((float)getSensor(aX) - zeroG); 00351 accYval = -((float)getSensor(aY) - zeroG); 00352 accZval = -((float)getSensor(aZ) - zeroG); 00353 00354 // Convert to 360 degrees resolution 00355 // atan2 outputs the value of -π to π (radians) 00356 // We are then converting it to 0 to 2π and then to degrees 00357 if(a == Pitch) 00358 return (atan2f(accYval, accZval) + PI) * RAD_TO_DEG; 00359 else 00360 return (atan2f(accXval, accZval) + PI) * RAD_TO_DEG; 00361 } else 00362 return 0; 00363 } 00364 00365 bool PS3USB::getStatus(StatusEnum c) { 00366 return (readBuf[((uint16_t)c >> 8) - 9] == ((uint8_t)c & 0xff)); 00367 } 00368 00369 void PS3USB::printStatusString() { 00370 char statusOutput[102]; // Max string length plus null character 00371 if(PS3Connected || PS3NavigationConnected) { 00372 strcpy_P(statusOutput, PSTR("\r\nConnectionStatus: ")); 00373 00374 if(getStatus(Plugged)) strcat_P(statusOutput, PSTR("Plugged")); 00375 else if(getStatus(Unplugged)) strcat_P(statusOutput, PSTR("Unplugged")); 00376 else strcat_P(statusOutput, PSTR("Error")); 00377 00378 strcat_P(statusOutput, PSTR(" - PowerRating: ")); 00379 00380 if(getStatus(Charging)) strcat_P(statusOutput, PSTR("Charging")); 00381 else if(getStatus(NotCharging)) strcat_P(statusOutput, PSTR("Not Charging")); 00382 else if(getStatus(Shutdown)) strcat_P(statusOutput, PSTR("Shutdown")); 00383 else if(getStatus(Dying)) strcat_P(statusOutput, PSTR("Dying")); 00384 else if(getStatus(Low)) strcat_P(statusOutput, PSTR("Low")); 00385 else if(getStatus(High)) strcat_P(statusOutput, PSTR("High")); 00386 else if(getStatus(Full)) strcat_P(statusOutput, PSTR("Full")); 00387 else strcat_P(statusOutput, PSTR("Error")); 00388 00389 strcat_P(statusOutput, PSTR(" - WirelessStatus: ")); 00390 00391 if(getStatus(CableRumble)) strcat_P(statusOutput, PSTR("Cable - Rumble is on")); 00392 else if(getStatus(Cable)) strcat_P(statusOutput, PSTR("Cable - Rumble is off")); 00393 else if(getStatus(BluetoothRumble)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is on")); 00394 else if(getStatus(Bluetooth)) strcat_P(statusOutput, PSTR("Bluetooth - Rumble is off")); 00395 else strcat_P(statusOutput, PSTR("Error")); 00396 } else 00397 strcpy_P(statusOutput, PSTR("\r\nError")); 00398 00399 //////USB_HOST_SERIAL.write(statusOutput); 00400 } 00401 00402 /* Playstation Sixaxis Dualshock and Navigation Controller commands */ 00403 void PS3USB::PS3_Command(uint8_t *data, uint16_t nbytes) { 00404 // 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) 00405 pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x01, 0x02, 0x00, nbytes, nbytes, data, NULL); 00406 } 00407 00408 void PS3USB::setAllOff() { 00409 for(uint8_t i = 0; i < PS3_REPORT_BUFFER_SIZE; i++) 00410 writeBuf[i] = pgm_read_byte(&PS3_REPORT_BUFFER[i]); // Reset buffer 00411 00412 PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE); 00413 } 00414 00415 void PS3USB::setRumbleOff() { 00416 uint8_t rumbleBuf[EP_MAXPKTSIZE]; 00417 memcpy(rumbleBuf, writeBuf, EP_MAXPKTSIZE); 00418 rumbleBuf[1] = 0x00; 00419 rumbleBuf[2] = 0x00; // Low mode off 00420 rumbleBuf[3] = 0x00; 00421 rumbleBuf[4] = 0x00; // High mode off 00422 PS3_Command(rumbleBuf, PS3_REPORT_BUFFER_SIZE); 00423 } 00424 00425 void PS3USB::setRumbleOn(RumbleEnum mode) { 00426 if((mode & 0x30) > 0x00) { 00427 uint8_t power[2] = {0xff, 0x00}; // Defaults to RumbleLow 00428 if(mode == RumbleHigh) { 00429 power[0] = 0x00; 00430 power[1] = 0xff; 00431 } 00432 setRumbleOn(0xfe, power[0], 0xfe, power[1]); 00433 } 00434 } 00435 00436 void PS3USB::setRumbleOn(uint8_t rightDuration, uint8_t rightPower, uint8_t leftDuration, uint8_t leftPower) { 00437 uint8_t rumbleBuf[EP_MAXPKTSIZE]; 00438 memcpy(rumbleBuf, writeBuf, EP_MAXPKTSIZE); 00439 rumbleBuf[1] = rightDuration; 00440 rumbleBuf[2] = rightPower; 00441 rumbleBuf[3] = leftDuration; 00442 rumbleBuf[4] = leftPower; 00443 PS3_Command(rumbleBuf, PS3_REPORT_BUFFER_SIZE); 00444 } 00445 00446 void PS3USB::setLedRaw(uint8_t value) { 00447 writeBuf[9] = value << 1; 00448 PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE); 00449 } 00450 00451 void PS3USB::setLedOff(LEDEnum a) { 00452 writeBuf[9] &= ~((uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1)); 00453 PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE); 00454 } 00455 00456 void PS3USB::setLedOn(LEDEnum a) { 00457 if(a == OFF) 00458 setLedRaw(0); 00459 else { 00460 writeBuf[9] |= (uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1); 00461 PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE); 00462 } 00463 } 00464 00465 void PS3USB::setLedToggle(LEDEnum a) { 00466 writeBuf[9] ^= (uint8_t)((pgm_read_byte(&PS3_LEDS[(uint8_t)a]) & 0x0f) << 1); 00467 PS3_Command(writeBuf, PS3_REPORT_BUFFER_SIZE); 00468 } 00469 00470 void PS3USB::setBdaddr(uint8_t *bdaddr) { 00471 /* Set the internal Bluetooth address */ 00472 uint8_t buf[8]; 00473 buf[0] = 0x01; 00474 buf[1] = 0x00; 00475 00476 for(uint8_t i = 0; i < 6; i++) 00477 buf[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed, so it is MSB first 00478 00479 // 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 00480 pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL); 00481 } 00482 00483 void PS3USB::getBdaddr(uint8_t *bdaddr) { 00484 uint8_t buf[8]; 00485 00486 // 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 00487 pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0xF5, 0x03, 0x00, 8, 8, buf, NULL); 00488 00489 for(uint8_t i = 0; i < 6; i++) 00490 bdaddr[5 - i] = buf[i + 2]; // Copy into buffer reversed, so it is LSB first 00491 } 00492 00493 void PS3USB::enable_sixaxis() { // Command used to enable the Dualshock 3 and Navigation controller to send data via USB 00494 uint8_t cmd_buf[4]; 00495 cmd_buf[0] = 0x42; // Special PS3 Controller enable commands 00496 cmd_buf[1] = 0x0c; 00497 cmd_buf[2] = 0x00; 00498 cmd_buf[3] = 0x00; 00499 00500 // 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) 00501 pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0xF4, 0x03, 0x00, 4, 4, cmd_buf, NULL); 00502 } 00503 00504 /* Playstation Move Controller commands */ 00505 void PS3USB::Move_Command(uint8_t *data, uint16_t nbytes) { 00506 pUsb->outTransfer(bAddress, epInfo[ PS3_OUTPUT_PIPE ].epAddr, nbytes, data); 00507 } 00508 00509 void PS3USB::moveSetBulb(uint8_t r, uint8_t g, uint8_t b) { // Use this to set the Color using RGB values 00510 // Set the Bulb's values into the write buffer 00511 writeBuf[2] = r; 00512 writeBuf[3] = g; 00513 writeBuf[4] = b; 00514 00515 Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE); 00516 } 00517 00518 void PS3USB::moveSetBulb(ColorsEnum color) { // Use this to set the Color using the predefined colors in "enums.h" 00519 moveSetBulb((uint8_t)(color >> 16), (uint8_t)(color >> 8), (uint8_t)(color)); 00520 } 00521 00522 void PS3USB::moveSetRumble(uint8_t rumble) { 00523 #ifdef DEBUG_USB_HOST 00524 if(rumble < 64 && rumble != 0) // The rumble value has to at least 64, or approximately 25% (64/255*100) 00525 Notify(PSTR("\r\nThe rumble value has to at least 64, or approximately 25%"), 0x80); 00526 #endif 00527 writeBuf[6] = rumble; // Set the rumble value into the write buffer 00528 00529 Move_Command(writeBuf, MOVE_REPORT_BUFFER_SIZE); 00530 } 00531 00532 void PS3USB::setMoveBdaddr(uint8_t *bdaddr) { 00533 /* Set the internal Bluetooth address */ 00534 uint8_t buf[11]; 00535 buf[0] = 0x05; 00536 buf[7] = 0x10; 00537 buf[8] = 0x01; 00538 buf[9] = 0x02; 00539 buf[10] = 0x12; 00540 00541 for(uint8_t i = 0; i < 6; i++) 00542 buf[i + 1] = bdaddr[i]; 00543 00544 // 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 00545 pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_OUT, HID_REQUEST_SET_REPORT, 0x05, 0x03, 0x00, 11, 11, buf, NULL); 00546 } 00547 00548 void PS3USB::getMoveBdaddr(uint8_t *bdaddr) { 00549 uint8_t buf[16]; 00550 00551 // 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 00552 pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0x04, 0x03, 0x00, 16, 16, buf, NULL); 00553 00554 for(uint8_t i = 0; i < 6; i++) 00555 bdaddr[i] = buf[10 + i]; 00556 } 00557 00558 void PS3USB::getMoveCalibration(uint8_t *data) { 00559 uint8_t buf[49]; 00560 00561 for(uint8_t i = 0; i < 3; i++) { 00562 // 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 00563 pUsb->ctrlReq(bAddress, epInfo[PS3_CONTROL_PIPE].epAddr, bmREQ_HID_IN, HID_REQUEST_GET_REPORT, 0x10, 0x03, 0x00, 49, 49, buf, NULL); 00564 00565 for(uint8_t j = 0; j < 49; j++) 00566 data[49 * i + j] = buf[j]; 00567 } 00568 } 00569 00570 void PS3USB::onInit() { 00571 if(pFuncOnInit) 00572 pFuncOnInit(); // Call the user function 00573 else { 00574 if(PS3MoveConnected) 00575 moveSetBulb(Red); 00576 else // Dualshock 3 or Navigation controller 00577 setLedOn(static_cast<LEDEnum>(CONTROLLER_LED1)); 00578 } 00579 } 00580
Generated on Thu Jul 14 2022 08:33:41 by
1.7.2