Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

1094 lines
37KB

  1. /* USB EHCI Host for Teensy 3.6
  2. * Copyright 2017 Paul Stoffregen (paul@pjrc.com)
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a
  5. * copy of this software and associated documentation files (the
  6. * "Software"), to deal in the Software without restriction, including
  7. * without limitation the rights to use, copy, modify, merge, publish,
  8. * distribute, sublicense, and/or sell copies of the Software, and to
  9. * permit persons to whom the Software is furnished to do so, subject to
  10. * the following conditions:
  11. *
  12. * The above copyright notice and this permission notice shall be included
  13. * in all copies or substantial portions of the Software.
  14. *
  15. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  16. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  17. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  18. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  19. * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  20. * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  21. * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  22. */
  23. #include <Arduino.h>
  24. #include "USBHost_t36.h" // Read this header first for key info
  25. #define print USBHost::print_
  26. #define println USBHost::println_
  27. //#define DEBUG_JOYSTICK
  28. #ifdef DEBUG_JOYSTICK
  29. #define DBGPrintf USBHDBGSerial.printf
  30. #else
  31. #define DBGPrintf(...)
  32. #endif
  33. // PID/VID to joystick mapping - Only the XBOXOne is used to claim the USB interface directly,
  34. // The others are used after claim-hid code to know which one we have and to use it for
  35. // doing other features.
  36. JoystickController::product_vendor_mapping_t JoystickController::pid_vid_mapping[] = {
  37. { 0x045e, 0x02ea, XBOXONE, false },{ 0x045e, 0x02dd, XBOXONE, false },
  38. { 0x045e, 0x0719, XBOX360, false},
  39. { 0x045e, 0x028E, XBOX360, false}, // Switch?
  40. { 0x054C, 0x0268, PS3, true},
  41. { 0x054C, 0x042F, PS3, true}, // PS3 Navigation controller
  42. { 0x054C, 0x03D5, PS3_MOTION, true}, // PS3 Motion controller
  43. { 0x054C, 0x05C4, PS4, true}, {0x054C, 0x09CC, PS4, true },
  44. { 0x046D, 0xC626, SpaceNav, true}, // 3d Connextion Space Navigator, 0x10008
  45. { 0x046D, 0xC628, SpaceNav, true} // 3d Connextion Space Navigator, 0x10008
  46. };
  47. //-----------------------------------------------------------------------------
  48. void JoystickController::init()
  49. {
  50. contribute_Pipes(mypipes, sizeof(mypipes)/sizeof(Pipe_t));
  51. contribute_Transfers(mytransfers, sizeof(mytransfers)/sizeof(Transfer_t));
  52. contribute_String_Buffers(mystring_bufs, sizeof(mystring_bufs)/sizeof(strbuf_t));
  53. driver_ready_for_device(this);
  54. USBHIDParser::driver_ready_for_hid_collection(this);
  55. BluetoothController::driver_ready_for_bluetooth(this);
  56. }
  57. //-----------------------------------------------------------------------------
  58. JoystickController::joytype_t JoystickController::mapVIDPIDtoJoystickType(uint16_t idVendor, uint16_t idProduct, bool exclude_hid_devices)
  59. {
  60. for (uint8_t i = 0; i < (sizeof(pid_vid_mapping)/sizeof(pid_vid_mapping[0])); i++) {
  61. if ((idVendor == pid_vid_mapping[i].idVendor) && (idProduct == pid_vid_mapping[i].idProduct)) {
  62. println("Match PID/VID: ", i, DEC);
  63. if (exclude_hid_devices && pid_vid_mapping[i].hidDevice) return UNKNOWN;
  64. return pid_vid_mapping[i].joyType;
  65. }
  66. }
  67. return UNKNOWN; // Not in our list
  68. }
  69. //*****************************************************************************
  70. // Some simple query functions depend on which interface we are using...
  71. //*****************************************************************************
  72. uint16_t JoystickController::idVendor()
  73. {
  74. if (device != nullptr) return device->idVendor;
  75. if (mydevice != nullptr) return mydevice->idVendor;
  76. return 0;
  77. }
  78. uint16_t JoystickController::idProduct()
  79. {
  80. if (device != nullptr) return device->idProduct;
  81. if (mydevice != nullptr) return mydevice->idProduct;
  82. return 0;
  83. }
  84. const uint8_t *JoystickController::manufacturer()
  85. {
  86. if ((device != nullptr) && (device->strbuf != nullptr)) return &device->strbuf->buffer[device->strbuf->iStrings[strbuf_t::STR_ID_MAN]];
  87. //if ((btdevice != nullptr) && (btdevice->strbuf != nullptr)) return &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_MAN]];
  88. if ((mydevice != nullptr) && (mydevice->strbuf != nullptr)) return &mydevice->strbuf->buffer[mydevice->strbuf->iStrings[strbuf_t::STR_ID_MAN]];
  89. return nullptr;
  90. }
  91. const uint8_t *JoystickController::product()
  92. {
  93. if ((device != nullptr) && (device->strbuf != nullptr)) return &device->strbuf->buffer[device->strbuf->iStrings[strbuf_t::STR_ID_PROD]];
  94. if ((mydevice != nullptr) && (mydevice->strbuf != nullptr)) return &mydevice->strbuf->buffer[mydevice->strbuf->iStrings[strbuf_t::STR_ID_PROD]];
  95. if (btdevice != nullptr) return remote_name_;
  96. return nullptr;
  97. }
  98. const uint8_t *JoystickController::serialNumber()
  99. {
  100. if ((device != nullptr) && (device->strbuf != nullptr)) return &device->strbuf->buffer[device->strbuf->iStrings[strbuf_t::STR_ID_SERIAL]];
  101. if ((mydevice != nullptr) && (mydevice->strbuf != nullptr)) return &mydevice->strbuf->buffer[mydevice->strbuf->iStrings[strbuf_t::STR_ID_SERIAL]];
  102. return nullptr;
  103. }
  104. bool JoystickController::setRumble(uint8_t lValue, uint8_t rValue, uint8_t timeout)
  105. {
  106. // Need to know which joystick we are on. Start off with XBox support - maybe need to add some enum value for the known
  107. // joystick types.
  108. rumble_lValue_ = lValue;
  109. rumble_rValue_ = rValue;
  110. rumble_timeout_ = timeout;
  111. switch (joystickType_) {
  112. default:
  113. break;
  114. case PS3:
  115. return transmitPS3UserFeedbackMsg();
  116. case PS3_MOTION:
  117. return transmitPS3MotionUserFeedbackMsg();
  118. case PS4:
  119. return transmitPS4UserFeedbackMsg();
  120. case XBOXONE:
  121. // Lets try sending a request to the XBox 1.
  122. txbuf_[0] = 0x9;
  123. txbuf_[1] = 0x0;
  124. txbuf_[2] = 0x0;
  125. txbuf_[3] = 0x09; // Substructure (what substructure rest of this packet has)
  126. txbuf_[4] = 0x00; // Mode
  127. txbuf_[5] = 0x0f; // Rumble mask (what motors are activated) (0000 lT rT L R)
  128. txbuf_[6] = 0x0; // lT force
  129. txbuf_[7] = 0x0; // rT force
  130. txbuf_[8] = lValue; // L force
  131. txbuf_[9] = rValue; // R force
  132. txbuf_[10] = 0xff; // Length of pulse
  133. txbuf_[11] = 0x00; // Period between pulses
  134. txbuf_[12] = 0x00; // Repeat
  135. if (!queue_Data_Transfer(txpipe_, txbuf_, 13, this)) {
  136. println("XBoxOne rumble transfer fail");
  137. }
  138. return true; //
  139. case XBOX360:
  140. txbuf_[0] = 0x00;
  141. txbuf_[1] = 0x01;
  142. txbuf_[2] = 0x0F;
  143. txbuf_[3] = 0xC0;
  144. txbuf_[4] = 0x00;
  145. txbuf_[5] = lValue;
  146. txbuf_[6] = rValue;
  147. txbuf_[7] = 0x00;
  148. txbuf_[8] = 0x00;
  149. txbuf_[9] = 0x00;
  150. txbuf_[10] = 0x00;
  151. txbuf_[11] = 0x00;
  152. if (!queue_Data_Transfer(txpipe_, txbuf_, 12, this)) {
  153. println("XBox360 rumble transfer fail");
  154. }
  155. return true;
  156. }
  157. return false;
  158. }
  159. bool JoystickController::setLEDs(uint8_t lr, uint8_t lg, uint8_t lb)
  160. {
  161. // Need to know which joystick we are on. Start off with XBox support - maybe need to add some enum value for the known
  162. // joystick types.
  163. if ((leds_[0] != lr) || (leds_[1] != lg) || (leds_[2] != lb)) {
  164. leds_[0] = lr;
  165. leds_[1] = lg;
  166. leds_[2] = lb;
  167. switch (joystickType_) {
  168. case PS3:
  169. return transmitPS3UserFeedbackMsg();
  170. case PS3_MOTION:
  171. return transmitPS3MotionUserFeedbackMsg();
  172. case PS4:
  173. return transmitPS4UserFeedbackMsg();
  174. case XBOX360:
  175. // 0: off, 1: all blink then return to before
  176. // 2-5(TL, TR, BL, BR) - blink on then stay on
  177. // 6-9() - On
  178. // ...
  179. txbuf_[1] = 0x00;
  180. txbuf_[2] = 0x08;
  181. txbuf_[3] = 0x40 + lr;
  182. txbuf_[4] = 0x00;
  183. txbuf_[5] = 0x00;
  184. txbuf_[6] = 0x00;
  185. txbuf_[7] = 0x00;
  186. txbuf_[8] = 0x00;
  187. txbuf_[9] = 0x00;
  188. txbuf_[10] = 0x00;
  189. txbuf_[11] = 0x00;
  190. if (!queue_Data_Transfer(txpipe_, txbuf_, 12, this)) {
  191. println("XBox360 set leds fail");
  192. }
  193. return true;
  194. case XBOXONE:
  195. default:
  196. return false;
  197. }
  198. }
  199. return false;
  200. }
  201. bool JoystickController::transmitPS4UserFeedbackMsg() {
  202. if (driver_) {
  203. uint8_t packet[32];
  204. memset(packet, 0, sizeof(packet));
  205. packet[0] = 0x05; // Report ID
  206. packet[1]= 0xFF;
  207. packet[4] = rumble_lValue_; // Small Rumble
  208. packet[5] = rumble_rValue_; // Big rumble
  209. packet[6] = leds_[0]; // RGB value
  210. packet[7] = leds_[1];
  211. packet[8] = leds_[2];
  212. // 9, 10 flash ON, OFF times in 100ths of second? 2.5 seconds = 255
  213. DBGPrintf("Joystick update Rumble/LEDs\n");
  214. return driver_->sendPacket(packet, 32);
  215. } else if (btdriver_) {
  216. uint8_t packet[79];
  217. memset(packet, 0, sizeof(packet));
  218. //0xa2, 0x11, 0xc0, 0x20, 0xf0, 0x04, 0x00
  219. packet[0] = 0x52;
  220. packet[1] = 0x11; // Report ID
  221. packet[2] = 0x80;
  222. //packet[3] = 0x20;
  223. packet[4] = 0xFF;
  224. packet[7] = rumble_lValue_; // Small Rumble
  225. packet[8] = rumble_rValue_; // Big rumble
  226. packet[9] = leds_[0]; // RGB value
  227. packet[10] = leds_[1];
  228. packet[11] = leds_[2];
  229. // 12, 13 flash ON, OFF times in 100ths of sedond? 2.5 seconds = 255
  230. DBGPrintf("Joystick update Rumble/LEDs\n");
  231. btdriver_->sendL2CapCommand(packet, sizeof(packet), 0x40);
  232. return true;
  233. }
  234. return false;
  235. }
  236. static const uint8_t PS3_USER_FEEDBACK_INIT[] = {
  237. 0x00, 0x00, 0x00, 0x00, 0x00,
  238. 0x00, 0x00, 0x00, 0x00, 0x00,
  239. 0xff, 0x27, 0x10, 0x00, 0x32,
  240. 0xff, 0x27, 0x10, 0x00, 0x32,
  241. 0xff, 0x27, 0x10, 0x00, 0x32,
  242. 0xff, 0x27, 0x10, 0x00, 0x32,
  243. 0x00, 0x00, 0x00, 0x00, 0x00,
  244. 0x00, 0x00, 0x00, 0x00, 0x00,
  245. 0x00, 0x00, 0x00, 0x00, 0x00,
  246. 0x00, 0x00, 0x00 };
  247. bool JoystickController::transmitPS3UserFeedbackMsg() {
  248. if (driver_) {
  249. memcpy(txbuf_, PS3_USER_FEEDBACK_INIT, 48);
  250. txbuf_[1] = rumble_lValue_? rumble_timeout_ : 0;
  251. txbuf_[2] = rumble_lValue_; // Small Rumble
  252. txbuf_[3] = rumble_rValue_? rumble_timeout_ : 0;
  253. txbuf_[4] = rumble_rValue_; // Big rumble
  254. txbuf_[9] = leds_[2] << 1; // RGB value // using third led now...
  255. //DBGPrintf("\nJoystick update Rumble/LEDs %d %d %d %d %d\n", txbuf_[1], txbuf_[2], txbuf_[3], txbuf_[4], txbuf_[9]);
  256. return driver_->sendControlPacket(0x21, 9, 0x201, 0, 48, txbuf_);
  257. } else if (btdriver_) {
  258. txbuf_[0] = 0x52;
  259. txbuf_[1] = 0x1;
  260. memcpy(&txbuf_[2], PS3_USER_FEEDBACK_INIT, 48);
  261. txbuf_[3] = rumble_lValue_? rumble_timeout_ : 0;
  262. txbuf_[4] = rumble_lValue_; // Small Rumble
  263. txbuf_[5] = rumble_rValue_? rumble_timeout_ : 0;
  264. txbuf_[6] = rumble_rValue_; // Big rumble
  265. txbuf_[11] = leds_[2] << 1; // RGB value
  266. DBGPrintf("\nJoystick update Rumble/LEDs %d %d %d %d %d\n", txbuf_[3], txbuf_[4], txbuf_[5], txbuf_[6], txbuf_[11]);
  267. btdriver_->sendL2CapCommand(txbuf_, 50, BluetoothController::CONTROL_SCID);
  268. return true;
  269. }
  270. return false;
  271. }
  272. #define MOVE_REPORT_BUFFER_SIZE 7
  273. #define MOVE_HID_BUFFERSIZE 50 // Size of the buffer for the Playstation Motion Controller
  274. bool JoystickController::transmitPS3MotionUserFeedbackMsg() {
  275. if (driver_) {
  276. txbuf_[0] = 0x02; // Set report ID, this is needed for Move commands to work
  277. txbuf_[2] = leds_[0];
  278. txbuf_[3] = leds_[1];
  279. txbuf_[4] = leds_[2];
  280. txbuf_[6] = rumble_lValue_; // Set the rumble value into the write buffer
  281. //return driver_->sendControlPacket(0x21, 9, 0x201, 0, MOVE_REPORT_BUFFER_SIZE, txbuf_);
  282. return driver_->sendPacket(txbuf_, MOVE_REPORT_BUFFER_SIZE);
  283. } else if (btdriver_) {
  284. txbuf_[0] = 0xA2; // HID BT DATA_request (0xA0) | Report Type (Output 0x02)
  285. txbuf_[1] = 0x02; // Report ID
  286. txbuf_[3] = leds_[0];
  287. txbuf_[4] = leds_[1];
  288. txbuf_[5] = leds_[2];
  289. txbuf_[7] = rumble_lValue_;
  290. btdriver_->sendL2CapCommand(txbuf_, MOVE_HID_BUFFERSIZE, BluetoothController::INTERRUPT_SCID);
  291. return true;
  292. }
  293. return false;
  294. }
  295. //*****************************************************************************
  296. // Support for Joysticks that Use HID data.
  297. //*****************************************************************************
  298. hidclaim_t JoystickController::claim_collection(USBHIDParser *driver, Device_t *dev, uint32_t topusage)
  299. {
  300. // only claim Desktop/Joystick and Desktop/Gamepad
  301. if (topusage != 0x10004 && topusage != 0x10005 && topusage != 0x10008) return CLAIM_NO;
  302. // only claim from one physical device
  303. if (mydevice != NULL && dev != mydevice) return CLAIM_NO;
  304. // Also don't allow us to claim if it is used as a standard usb object (XBox...)
  305. if (device != nullptr) return CLAIM_NO;
  306. mydevice = dev;
  307. collections_claimed++;
  308. anychange = true; // always report values on first read
  309. driver_ = driver; // remember the driver.
  310. driver_->setTXBuffers(txbuf_, nullptr, sizeof(txbuf_));
  311. connected_ = true; // remember that hardware is actually connected...
  312. // Lets see if we know what type of joystick this is. That is, is it a PS3 or PS4 or ...
  313. joystickType_ = mapVIDPIDtoJoystickType(mydevice->idVendor, mydevice->idProduct, false);
  314. DBGPrintf("JoystickController::claim_collection joystickType_=%d\n", joystickType_);
  315. switch (joystickType_) {
  316. case PS3:
  317. case PS3_MOTION: // not sure yet
  318. additional_axis_usage_page_ = 0x1;
  319. additional_axis_usage_start_ = 0x100;
  320. additional_axis_usage_count_ = 39;
  321. axis_change_notify_mask_ = (uint64_t)-1; // Start off assume all bits
  322. break;
  323. case PS4:
  324. additional_axis_usage_page_ = 0xFF00;
  325. additional_axis_usage_start_ = 0x21;
  326. additional_axis_usage_count_ = 54;
  327. axis_change_notify_mask_ = (uint64_t)0xfffffffffffff3ffl; // Start off assume all bits - 10 and 11
  328. break;
  329. default:
  330. additional_axis_usage_page_ = 0x09;
  331. additional_axis_usage_start_ = 0x21;
  332. additional_axis_usage_count_ = 5;
  333. axis_change_notify_mask_ = 0x3ff; // Start off assume only the 10 bits...
  334. }
  335. DBGPrintf("Claim Additional axis: %x %x %d\n", additional_axis_usage_page_, additional_axis_usage_start_, additional_axis_usage_count_);
  336. return CLAIM_REPORT;
  337. }
  338. void JoystickController::disconnect_collection(Device_t *dev)
  339. {
  340. if (--collections_claimed == 0) {
  341. mydevice = NULL;
  342. driver_ = nullptr;
  343. axis_mask_ = 0;
  344. axis_changed_mask_ = 0;
  345. }
  346. }
  347. void JoystickController::hid_input_begin(uint32_t topusage, uint32_t type, int lgmin, int lgmax)
  348. {
  349. // TODO: set up translation from logical min/max to consistent 16 bit scale
  350. }
  351. void JoystickController::hid_input_data(uint32_t usage, int32_t value)
  352. {
  353. DBGPrintf("joystickType_=%d\n", joystickType_);
  354. DBGPrintf("Joystick: usage=%X, value=%d\n", usage, value);
  355. uint32_t usage_page = usage >> 16;
  356. usage &= 0xFFFF;
  357. if (usage_page == 9 && usage >= 1 && usage <= 32) {
  358. uint32_t bit = 1 << (usage -1);
  359. if (value == 0) {
  360. if (buttons & bit) {
  361. buttons &= ~bit;
  362. anychange = true;
  363. }
  364. } else {
  365. if (!(buttons & bit)) {
  366. buttons |= bit;
  367. anychange = true;
  368. }
  369. }
  370. } else if (usage_page == 1 && usage >= 0x30 && usage <= 0x39) {
  371. // TODO: need scaling of value to consistent API, 16 bit signed?
  372. // TODO: many joysticks repeat slider usage. Detect & map to axis?
  373. uint32_t i = usage - 0x30;
  374. axis_mask_ |= (1 << i); // Keep record of which axis we have data on.
  375. if (axis[i] != value) {
  376. axis[i] = value;
  377. axis_changed_mask_ |= (1 << i);
  378. if (axis_changed_mask_ & axis_change_notify_mask_)
  379. anychange = true;
  380. }
  381. } else if (usage_page == additional_axis_usage_page_) {
  382. // see if the usage is witin range.
  383. //DBGPrintf("UP: usage_page=%x usage=%x User: %x %d\n", usage_page, usage, user_buttons_usage_start, user_buttons_count_);
  384. if ((usage >= additional_axis_usage_start_) && (usage < (additional_axis_usage_start_ + additional_axis_usage_count_))) {
  385. // We are in the user range.
  386. uint16_t usage_index = usage - additional_axis_usage_start_ + STANDARD_AXIS_COUNT;
  387. if (usage_index < (sizeof(axis)/sizeof(axis[0]))) {
  388. if (axis[usage_index] != value) {
  389. axis[usage_index] = value;
  390. if (usage_index > 63) usage_index = 63; // don't overflow our mask
  391. axis_changed_mask_ |= ((uint64_t)1 << usage_index); // Keep track of which ones changed.
  392. if (axis_changed_mask_ & axis_change_notify_mask_)
  393. anychange = true; // We have changes...
  394. }
  395. axis_mask_ |= ((uint64_t)1 << usage_index); // Keep record of which axis we have data on.
  396. }
  397. //DBGPrintf("UB: index=%x value=%x\n", usage_index, value);
  398. }
  399. } else {
  400. DBGPrintf("UP: usage_page=%x usage=%x add: %x %x %d\n", usage_page, usage, additional_axis_usage_page_, additional_axis_usage_start_, additional_axis_usage_count_);
  401. }
  402. // TODO: hat switch?
  403. }
  404. void JoystickController::hid_input_end()
  405. {
  406. if (anychange) {
  407. joystickEvent = true;
  408. }
  409. }
  410. bool JoystickController::hid_process_out_data(const Transfer_t *transfer)
  411. {
  412. //DBGPrintf("JoystickController::hid_process_out_data\n");
  413. return true;
  414. }
  415. void JoystickController::joystickDataClear() {
  416. joystickEvent = false;
  417. anychange = false;
  418. axis_changed_mask_ = 0;
  419. axis_mask_ = 0;
  420. }
  421. //*****************************************************************************
  422. // Support for Joysticks that are class specific and do not use HID
  423. // Example: XBox One controller.
  424. //*****************************************************************************
  425. static uint8_t xboxone_start_input[] = {0x05, 0x20, 0x00, 0x01, 0x00};
  426. static uint8_t xbox360w_inquire_present[] = {0x08, 0x00, 0x0F, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
  427. bool JoystickController::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len)
  428. {
  429. println("JoystickController claim this=", (uint32_t)this, HEX);
  430. // Don't try to claim if it is used as USB device or HID device
  431. if (mydevice != NULL) return false;
  432. if (device != nullptr) return false;
  433. // Try claiming at the interface level.
  434. if (type != 1) return false;
  435. print_hexbytes(descriptors, len);
  436. JoystickController::joytype_t jtype = mapVIDPIDtoJoystickType(dev->idVendor, dev->idProduct, true);
  437. println("Jtype=", (uint8_t)jtype, DEC);
  438. if (jtype == UNKNOWN)
  439. return false;
  440. // XBOX One
  441. // 0 1 2 3 4 5 6 7 8 *9 10 1 2 3 4 5 *6 7 8 9 20 1 2 3 4 5 6 7 8 9 30 1...
  442. // 09 04 00 00 02 FF 47 D0 00 07 05 02 03 40 00 04 07 05 82 03 40 00 04 09 04 01 00 00 FF 47 D0 00
  443. // Lets do some verifications to make sure.
  444. // XBOX 360 wireless... Has 8 interfaces. 4 joysticks (1, 3, 5, 7) and 4 headphones assume 2,4,6, 8...
  445. // Shows data for #1 only...
  446. // Also they have some unknown data type we need to ignore between interface and end points.
  447. // 0 1 2 3 4 5 6 7 8 *9 10 1 2 3 4 5 *6 7 8 9 20 1 2 3 4 5 6 7 8
  448. // 09 04 00 00 02 FF 5D 81 00 14 22 00 01 13 81 1D 00 17 01 02 08 13 01 0C 00 0C 01 02 08
  449. // 29 30 1 2 3 4 5 6 7 8 9 40 41 42
  450. // 07 05 81 03 20 00 01 07 05 01 03 20 00 08
  451. // Switch
  452. // 09 04 00 00 02 FF 5D 01 00
  453. // 10 21 10 01 01 24 81 14 03 00 03 13 02 00 03 00
  454. // 07 05 81 03 20 00 08
  455. // 07 05 02 03 20 00 08
  456. if (len < 9+7+7) return false;
  457. // Some common stuff for both XBoxs
  458. uint32_t count_end_points = descriptors[4];
  459. if (count_end_points < 2) return false;
  460. if (descriptors[5] != 0xff) return false; // bInterfaceClass, 3 = HID
  461. rx_ep_ = 0;
  462. uint32_t txep = 0;
  463. uint8_t rx_interval = 0;
  464. uint8_t tx_interval = 0;
  465. rx_size_ = 0;
  466. tx_size_ = 0;
  467. uint32_t descriptor_index = 9;
  468. if (descriptors[descriptor_index+1] == 0x22) {
  469. if (descriptors[descriptor_index] != 0x14) return false; // only support specific versions...
  470. descriptor_index += descriptors[descriptor_index]; // XBox360w ignore this unknown setup...
  471. }
  472. while ((rx_ep_ == 0) || txep == 0) {
  473. print(" Index:", descriptor_index, DEC);
  474. if (descriptor_index >= len) return false; // we ran off the end and did not get end points
  475. // see if the next data is an end point descript
  476. if ((descriptors[descriptor_index] == 7) && (descriptors[descriptor_index+1] == 5)) {
  477. if ((descriptors[descriptor_index+3] == 3) // Type 3...
  478. && (descriptors[descriptor_index+4] <= 64)
  479. && (descriptors[descriptor_index+5] == 0)) {
  480. // have a bulk EP size
  481. if (descriptors[descriptor_index+2] & 0x80 ) {
  482. rx_ep_ = descriptors[descriptor_index+2];
  483. rx_size_ = descriptors[descriptor_index+4];
  484. rx_interval = descriptors[descriptor_index+6];
  485. } else {
  486. txep = descriptors[descriptor_index+2];
  487. tx_size_ = descriptors[descriptor_index+4];
  488. tx_interval = descriptors[descriptor_index+6];
  489. }
  490. }
  491. }
  492. descriptor_index += descriptors[descriptor_index]; // setup to look at next one...
  493. }
  494. if ((rx_ep_ == 0) || (txep == 0)) return false; // did not find two end points.
  495. print("JoystickController, rx_ep_=", rx_ep_ & 15);
  496. print("(", rx_size_);
  497. print("), txep=", txep);
  498. print("(", tx_size_);
  499. println(")");
  500. rxpipe_ = new_Pipe(dev, 3, rx_ep_ & 15, 1, rx_size_, rx_interval);
  501. if (!rxpipe_) return false;
  502. txpipe_ = new_Pipe(dev, 3, txep, 0, tx_size_, tx_interval);
  503. if (!txpipe_) {
  504. //free_Pipe(rxpipe_);
  505. return false;
  506. }
  507. rxpipe_->callback_function = rx_callback;
  508. queue_Data_Transfer(rxpipe_, rxbuf_, rx_size_, this);
  509. txpipe_->callback_function = tx_callback;
  510. if (jtype == XBOXONE) {
  511. queue_Data_Transfer(txpipe_, xboxone_start_input, sizeof(xboxone_start_input), this);
  512. connected_ = true; // remember that hardware is actually connected...
  513. } else if (jtype == XBOX360) {
  514. queue_Data_Transfer(txpipe_, xbox360w_inquire_present, sizeof(xbox360w_inquire_present), this);
  515. connected_ = 0; // remember that hardware is actually connected...
  516. }
  517. memset(axis, 0, sizeof(axis)); // clear out any data.
  518. joystickType_ = jtype; // remember we are an XBox One.
  519. DBGPrintf(" JoystickController::claim joystickType_ %d\n", joystickType_);
  520. return true;
  521. }
  522. void JoystickController::control(const Transfer_t *transfer)
  523. {
  524. }
  525. /************************************************************/
  526. // Interrupt-based Data Movement
  527. /************************************************************/
  528. void JoystickController::rx_callback(const Transfer_t *transfer)
  529. {
  530. if (!transfer->driver) return;
  531. ((JoystickController *)(transfer->driver))->rx_data(transfer);
  532. }
  533. void JoystickController::tx_callback(const Transfer_t *transfer)
  534. {
  535. if (!transfer->driver) return;
  536. ((JoystickController *)(transfer->driver))->tx_data(transfer);
  537. }
  538. /************************************************************/
  539. // Interrupt-based Data Movement
  540. // XBox one input data when type == 0x20
  541. // Information came from several places on the web including:
  542. // https://github.com/quantus/xbox-one-controller-protocol
  543. /************************************************************/
  544. // 20 00 C5 0E 00 00 00 00 00 00 F0 06 AD FB 7A 0A DD F7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  545. // 20 00 E0 0E 40 00 00 00 00 00 F0 06 AD FB 7A 0A DD F7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  546. typedef struct {
  547. uint8_t type;
  548. uint8_t const_0;
  549. uint16_t id;
  550. // From online references button order:
  551. // sync, dummy, start, back, a, b, x, y
  552. // dpad up, down left, right
  553. // lb, rb, left stick, right stick
  554. // Axis:
  555. // lt, rt, lx, ly, rx, ry
  556. //
  557. uint16_t buttons;
  558. int16_t axis[6];
  559. } xbox1data20_t;
  560. typedef struct {
  561. uint8_t state;
  562. uint8_t id_or_type;
  563. uint16_t controller_status;
  564. uint16_t unknown;
  565. // From online references button order:
  566. // sync, dummy, start, back, a, b, x, y
  567. // dpad up, down left, right
  568. // lb, rb, left stick, right stick
  569. // Axis:
  570. // lt, rt, lx, ly, rx, ry
  571. //
  572. uint16_t buttons;
  573. uint8_t lt;
  574. uint8_t rt;
  575. int16_t axis[4];
  576. } xbox360data_t;
  577. static const uint8_t xbox_axis_order_mapping[] = {3, 4, 0, 1, 2, 5};
  578. void JoystickController::rx_data(const Transfer_t *transfer)
  579. {
  580. print("JoystickController::rx_data (", joystickType_, DEC);
  581. print("): ");
  582. print_hexbytes((uint8_t*)transfer->buffer, transfer->length);
  583. if (joystickType_ == XBOXONE) {
  584. // Process XBOX One data
  585. axis_mask_ = 0x3f;
  586. axis_changed_mask_ = 0; // assume none for now
  587. xbox1data20_t *xb1d = (xbox1data20_t *)transfer->buffer;
  588. if ((xb1d->type == 0x20) && (transfer->length >= sizeof (xbox1data20_t))) {
  589. // We have a data transfer. Lets see what is new...
  590. if (xb1d->buttons != buttons) {
  591. buttons = xb1d->buttons;
  592. anychange = true;
  593. joystickEvent = true;
  594. println(" Button Change: ", buttons, HEX);
  595. }
  596. for (uint8_t i = 0; i < sizeof (xbox_axis_order_mapping); i++) {
  597. // The first two values were unsigned.
  598. int axis_value = (i < 2)? (int)(uint16_t)xb1d->axis[i] : xb1d->axis[i];
  599. if (axis_value != axis[xbox_axis_order_mapping[i]]) {
  600. axis[xbox_axis_order_mapping[i]] = axis_value;
  601. axis_changed_mask_ |= (1 << xbox_axis_order_mapping[i]);
  602. anychange = true;
  603. }
  604. }
  605. joystickEvent = true;
  606. }
  607. } else if (joystickType_ == XBOX360) {
  608. // First byte appears to status - if the byte is 0x8 it is a connect or disconnect of the controller.
  609. xbox360data_t *xb360d = (xbox360data_t *)transfer->buffer;
  610. if (xb360d->state == 0x08) {
  611. if (xb360d->id_or_type != connected_) {
  612. connected_ = xb360d->id_or_type; // remember it...
  613. if (connected_) {
  614. println("XBox360w - Connected type:", connected_, HEX);
  615. // rx_ep_ should be 1, 3, 5, 7 for the wireless convert to 2-5 on led
  616. setLEDs(2+rx_ep_/2); // Right now hard coded to first joystick...
  617. } else {
  618. println("XBox360w - disconnected");
  619. }
  620. }
  621. } else if((xb360d->id_or_type == 0x00) && (xb360d->controller_status & 0x1300)) {
  622. // Controller status report - Maybe we should save away and allow the user access?
  623. println("XBox360w - controllerStatus: ", xb360d->controller_status, HEX);
  624. } else if(xb360d->id_or_type == 0x01) { // Lets only process report 1.
  625. //const uint8_t *pbuffer = (uint8_t*)transfer->buffer;
  626. //for (uint8_t i = 0; i < transfer->length; i++) DBGPrintf("%02x ", pbuffer[i]);
  627. //DBGPrintf("\n");
  628. if (buttons != xb360d->buttons) {
  629. buttons = xb360d->buttons;
  630. anychange = true;
  631. }
  632. axis_mask_ = 0x3f;
  633. axis_changed_mask_ = 0; // assume none for now
  634. for (uint8_t i = 0; i < 4; i++) {
  635. if (axis[i] != xb360d->axis[i]) {
  636. axis[i] = xb360d->axis[i];
  637. axis_changed_mask_ |= (1 << i);
  638. anychange = true;
  639. }
  640. }
  641. // the two triggers show up as 4 and 5
  642. if (axis[4] != xb360d->lt) {
  643. axis[4] = xb360d->lt;
  644. axis_changed_mask_ |= (1 << 4);
  645. anychange = true;
  646. }
  647. if (axis[5] != xb360d->rt) {
  648. axis[5] = xb360d->rt;
  649. axis_changed_mask_ |= (1 << 5);
  650. anychange = true;
  651. }
  652. if (anychange) joystickEvent = true;
  653. }
  654. }
  655. queue_Data_Transfer(rxpipe_, rxbuf_, rx_size_, this);
  656. }
  657. void JoystickController::tx_data(const Transfer_t *transfer)
  658. {
  659. }
  660. void JoystickController::disconnect()
  661. {
  662. axis_mask_ = 0;
  663. axis_changed_mask_ = 0;
  664. // TODO: free resources
  665. }
  666. bool JoystickController::claim_bluetooth(BluetoothController *driver, uint32_t bluetooth_class, uint8_t *remoteName)
  667. {
  668. // If we are already in use than don't grab another one. Likewise don't grab if it is used as USB or HID object
  669. if (btdevice && (btdevice != (Device_t*)driver)) return false;
  670. if (mydevice != NULL) return false;
  671. if (device != nullptr) return false;
  672. if ((((bluetooth_class & 0xff00) == 0x2500) || (((bluetooth_class & 0xff00) == 0x500))) && ((bluetooth_class & 0x3C) == 0x08)) {
  673. DBGPrintf("JoystickController::claim_bluetooth TRUE\n");
  674. btdriver_ = driver;
  675. btdevice = (Device_t*)driver; // remember this way
  676. if (remoteName) mapNameToJoystickType(remoteName);
  677. return true;
  678. }
  679. if (remoteName && mapNameToJoystickType(remoteName)) {
  680. if ((joystickType_ == PS3) || (joystickType_ == PS3_MOTION)) {
  681. DBGPrintf("JoystickController::claim_bluetooth TRUE PS3 hack...\n");
  682. btdriver_ = driver;
  683. btdevice = (Device_t*)driver; // remember this way
  684. special_process_required = SP_PS3_IDS; // PS3 maybe needs different IDS.
  685. return true;
  686. }
  687. }
  688. return false;
  689. }
  690. bool JoystickController::process_bluetooth_HID_data(const uint8_t *data, uint16_t length)
  691. {
  692. // Example data from PS4 controller
  693. //01 7e 7f 82 84 08 00 00 00 00
  694. // LX LY RX RY BT BT PS LT RT
  695. DBGPrintf("JoystickController::process_bluetooth_HID_data: data[0]=%x\n", data[0]);
  696. // May have to look at this one with other controllers...
  697. if (data[0] == 1) {
  698. //print(" Joystick Data: ");
  699. // print_hexbytes(data, length);
  700. if (length > TOTAL_AXIS_COUNT) length = TOTAL_AXIS_COUNT; // don't overflow arrays...
  701. DBGPrintf(" Joystick Data: ");
  702. for(uint16_t i =0; i < length; i++) DBGPrintf("%02x ", data[i]);
  703. DBGPrintf("\r\n");
  704. if (joystickType_ == PS3) {
  705. // Quick and dirty hack to match PS3 HID data
  706. uint32_t cur_buttons = data[2] | ((uint16_t)data[3] << 8) | ((uint32_t)data[4] << 16);
  707. if (cur_buttons != buttons) {
  708. buttons = cur_buttons;
  709. joystickEvent = true; // something changed.
  710. }
  711. uint64_t mask = 0x1;
  712. axis_mask_ = 0x27; // assume bits 0, 1, 2, 5
  713. for (uint16_t i = 0; i < 3; i++) {
  714. if (axis[i] != data[i+6]) {
  715. axis_changed_mask_ |= mask;
  716. axis[i] = data[i+6];
  717. }
  718. mask <<= 1; // shift down the mask.
  719. }
  720. if (axis[5] != data[9]) {
  721. axis_changed_mask_ |= (1<<5);
  722. axis[5] = data[9];
  723. }
  724. if (axis[3] != data[18]) {
  725. axis_changed_mask_ |= (1<<3);
  726. axis[3] = data[18];
  727. }
  728. if (axis[4] != data[19]) {
  729. axis_changed_mask_ |= (1<<4);
  730. axis[4] = data[19];
  731. }
  732. // Then rest of data
  733. mask = 0x1 << 10; // setup for other bits
  734. for (uint16_t i = 10; i < length; i++ ) {
  735. axis_mask_ |= mask;
  736. if(data[i] != axis[i]) {
  737. axis_changed_mask_ |= mask;
  738. axis[i] = data[i];
  739. }
  740. mask <<= 1; // shift down the mask.
  741. }
  742. } else if (joystickType_ == PS3_MOTION) {
  743. // Quick and dirty PS3_Motion data.
  744. uint32_t cur_buttons = data[1] | ((uint16_t)data[2] << 8) | ((uint32_t)data[3] << 16);
  745. if (cur_buttons != buttons) {
  746. buttons = cur_buttons;
  747. joystickEvent = true; // something changed.
  748. }
  749. // Hard to know what is best here. for now just copy raw data over...
  750. // will do this for now... Format of thought to be data.
  751. // data[1-3] Buttons (mentioned 4 as well but appears to be counter
  752. // axis[0-1] data[5] Trigger, Previous trigger value
  753. // 2-5 Unknown probably place holders for Axis like data for other PS3
  754. // 6 - Time stamp
  755. // 7 - Battery
  756. // 8-19 - Accel: XL, XH, YL, YH, ZL, ZH, XL2, XH2, YL2, YH2, ZL2, ZH2
  757. // 20-31 - Gyro: Xl,Xh,Yl,Yh,Zl,Zh,Xl2,Xh2,Yl2,Yh2,Zl2,Zh2
  758. // 32 - Temp High
  759. // 33 - Temp Low (4 bits) Maybe Magneto x High on other??
  760. uint64_t mask = 0x1;
  761. axis_mask_ = 0; // assume bits 0, 1, 2, 5
  762. // Then rest of data
  763. mask = 0x1 << 10; // setup for other bits
  764. for (uint16_t i = 5; i < length; i++ ) {
  765. axis_mask_ |= mask;
  766. if(data[i] != axis[i-5]) {
  767. axis_changed_mask_ |= mask;
  768. axis[i-5] = data[i];
  769. }
  770. mask <<= 1; // shift down the mask.
  771. }
  772. } else {
  773. uint64_t mask = 0x1;
  774. axis_mask_ = 0;
  775. for (uint16_t i = 0; i < length; i++ ) {
  776. axis_mask_ |= mask;
  777. if(data[i] != axis[i]) {
  778. axis_changed_mask_ |= mask;
  779. axis[i] = data[i];
  780. }
  781. mask <<= 1; // shift down the mask.
  782. // DBGPrintf("%02x ", axis[i]);
  783. }
  784. }
  785. if (axis_changed_mask_ & axis_change_notify_mask_)
  786. joystickEvent = true;
  787. connected_ = true;
  788. return true;
  789. } else if(data[0] == 0x11){
  790. DBGPrintf("\n Joystick Data: ");
  791. uint64_t mask = 0x1;
  792. axis_mask_ = 0;
  793. axis_changed_mask_ = 0;
  794. //This moves data to be equivalent to what we see for
  795. //data[0] = 0x01
  796. uint8_t tmp_data[length-2];
  797. for (uint16_t i = 0; i < (length-2); i++ ) {
  798. tmp_data[i] = 0;
  799. tmp_data[i] = data[i+2];
  800. }
  801. /*
  802. * [1] LX, [2] = LY, [3] = RX, [4] = RY
  803. * [5] combo, tri, cir, x, sqr, D-PAD (4bits, 0-3
  804. * [6] R3,L3, opt, share, R2, L2, R1, L1
  805. * [7] Counter (bit7-2), T-PAD, PS
  806. * [8] Left Trigger, [9] Right Trigger
  807. * [10-11] Timestamp
  808. * [12] Battery (0 to 0xff)
  809. * [13-14] acceleration x
  810. * [15-16] acceleration y
  811. * [17-18] acceleration z
  812. * [19-20] gyro x
  813. * [21-22] gyro y
  814. * [23-24] gyro z
  815. * [25-29] unknown
  816. * [30] 0x00,phone,mic, usb, battery level (4bits)
  817. * rest is trackpad? to do implement?
  818. */
  819. //PS Bit
  820. tmp_data[7] = (tmp_data[7] >> 0) & 1;
  821. //set arrow buttons to axis[0]
  822. tmp_data[10] = tmp_data[5] & ((1 << 4) - 1);
  823. //set buttons for last 4bits in the axis[5]
  824. tmp_data[5] = tmp_data[5] >> 4;
  825. // Quick and dirty hack to match PS4 HID data
  826. uint32_t cur_buttons = tmp_data[7] | (tmp_data[10]) | ((tmp_data[6]*10)) | ((uint16_t)tmp_data[5] << 16) ;
  827. if (cur_buttons != buttons) {
  828. buttons = cur_buttons;
  829. joystickEvent = true; // something changed.
  830. }
  831. mask = 0x1;
  832. axis_mask_ = 0x27; // assume bits 0, 1, 2, 5
  833. for (uint16_t i = 0; i < 3; i++) {
  834. if (axis[i] != tmp_data[i+1]) {
  835. axis_changed_mask_ |= mask;
  836. axis[i] = tmp_data[i+1];
  837. }
  838. mask <<= 1; // shift down the mask.
  839. }
  840. if (axis[5] != tmp_data[4]) {
  841. axis_changed_mask_ |= (1<<5);
  842. axis[5] = tmp_data[4];
  843. }
  844. if (axis[3] != tmp_data[8]) {
  845. axis_changed_mask_ |= (1<<3);
  846. axis[3] = tmp_data[8];
  847. }
  848. if (axis[4] != tmp_data[9]) {
  849. axis_changed_mask_ |= (1<<4);
  850. axis[4] = tmp_data[9];
  851. }
  852. //limit for masking
  853. mask = 0x1;
  854. for (uint16_t i = 6; i < (64); i++ ) {
  855. axis_mask_ |= mask;
  856. if(tmp_data[i] != axis[i]) {
  857. axis_changed_mask_ |= mask;
  858. axis[i] = tmp_data[i];
  859. }
  860. mask <<= 1; // shift down the mask.
  861. DBGPrintf("%02x ", axis[i]);
  862. }
  863. DBGPrintf("\n");
  864. //DBGPrintf("Axis Mask (axis_mask_, axis_changed_mask_; %d, %d\n", axis_mask_,axis_changed_mask_);
  865. joystickEvent = true;
  866. connected_ = true;
  867. }
  868. return false;
  869. }
  870. bool JoystickController::mapNameToJoystickType(const uint8_t *remoteName)
  871. {
  872. // Sort of a hack, but try to map the name given from remote to a type...
  873. if (strncmp((const char *)remoteName, "Wireless Controller", 19) == 0) {
  874. DBGPrintf(" JoystickController::mapNameToJoystickType %s - set to PS4\n", remoteName);
  875. joystickType_ = PS4;
  876. } else if (strncmp((const char *)remoteName, "PLAYSTATION(R)3", 15) == 0) {
  877. DBGPrintf(" JoystickController::mapNameToJoystickType %x %s - set to PS3\n", (uint32_t)this, remoteName);
  878. joystickType_ = PS3;
  879. } else if (strncmp((const char *)remoteName, "Navigation Controller", 21) == 0) {
  880. DBGPrintf(" JoystickController::mapNameToJoystickType %x %s - set to PS3\n", (uint32_t)this, remoteName);
  881. joystickType_ = PS3;
  882. } else if (strncmp((const char *)remoteName, "Motion Controller", 17) == 0) {
  883. DBGPrintf(" JoystickController::mapNameToJoystickType %x %s - set to PS3 Motion\n", (uint32_t)this, remoteName);
  884. joystickType_ = PS3_MOTION;
  885. } else if (strncmp((const char *)remoteName, "Xbox Wireless", 13) == 0) {
  886. DBGPrintf(" JoystickController::mapNameToJoystickType %x %s - set to XBOXONE\n", (uint32_t)this, remoteName);
  887. joystickType_ = XBOXONE;
  888. } else {
  889. DBGPrintf(" JoystickController::mapNameToJoystickType %s - Unknown\n", remoteName);
  890. }
  891. DBGPrintf(" Joystick Type: %d\n", joystickType_);
  892. return true;
  893. }
  894. bool JoystickController::remoteNameComplete(const uint8_t *remoteName)
  895. {
  896. // Sort of a hack, but try to map the name given from remote to a type...
  897. if (mapNameToJoystickType(remoteName)) {
  898. switch (joystickType_) {
  899. case PS4: special_process_required = SP_NEED_CONNECT; break;
  900. case PS3: special_process_required = SP_PS3_IDS; break;
  901. case PS3_MOTION: special_process_required = SP_PS3_IDS; break;
  902. default:
  903. break;
  904. }
  905. }
  906. return true;
  907. }
  908. void JoystickController::connectionComplete()
  909. {
  910. DBGPrintf(" JoystickController::connectionComplete %x joystick type %d\n", (uint32_t)this, joystickType_);
  911. switch (joystickType_) {
  912. case PS4:
  913. {
  914. uint8_t packet[2];
  915. packet[0] = 0x43; // HID BT Get_report (0x40) | Report Type (Feature 0x03)
  916. packet[1] = 0x02; // Report ID
  917. DBGPrintf("Set PS4 report\n");
  918. delay(1);
  919. btdriver_->sendL2CapCommand(packet, sizeof(packet), 0x40);
  920. }
  921. break;
  922. case PS3:
  923. {
  924. uint8_t packet[6];
  925. packet[0] = 0x53; // HID BT Set_report (0x50) | Report Type (Feature 0x03)
  926. packet[1] = 0xF4; // Report ID
  927. packet[2] = 0x42; // Special PS3 Controller enable commands
  928. packet[3] = 0x03;
  929. packet[4] = 0x00;
  930. packet[5] = 0x00;
  931. DBGPrintf("enable six axis\n");
  932. delay(1);
  933. btdriver_->sendL2CapCommand(packet, sizeof(packet), BluetoothController::CONTROL_SCID);
  934. }
  935. break;
  936. case PS3_MOTION:
  937. setLEDs(0, 0xff, 0); // Maybe try setting to green?
  938. default:
  939. break;
  940. }
  941. }
  942. void JoystickController::release_bluetooth()
  943. {
  944. btdevice = nullptr; // remember this way
  945. btdriver_ = nullptr;
  946. connected_ = false;
  947. special_process_required = false;
  948. }
  949. bool JoystickController::PS3Pair(uint8_t* bdaddr) {
  950. if (!driver_) return false;
  951. if (joystickType_ == PS3) {
  952. /* Set the internal Bluetooth address */
  953. txbuf_[0] = 0x01;
  954. txbuf_[1] = 0x00;
  955. for(uint8_t i = 0; i < 6; i++)
  956. txbuf_[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed, so it is MSB first
  957. // 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
  958. return driver_->sendControlPacket(0x21, 9, 0x3f5, 0, 8, txbuf_);
  959. } else if (joystickType_ == PS3_MOTION) {
  960. // Slightly different than other PS3 units...
  961. txbuf_[0] = 0x05;
  962. for(uint8_t i = 0; i < 6; i++)
  963. txbuf_[i + 1] = bdaddr[i]; // Order different looks like LSB First?
  964. txbuf_[7] = 0x10;
  965. txbuf_[8] = 0x01;
  966. txbuf_[9] = 0x02;
  967. txbuf_[10] = 0x12;
  968. // 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
  969. return driver_->sendControlPacket(0x21, 9, 0x305, 0, 11, txbuf_);
  970. }
  971. return false;
  972. }