Support to pair PS3 if it knows the BTADDR and user presses select and PS button and plugged in USB. Remembers remote name, and tries to get it when PAIR version of code is running. (Currently fails). Does some mapping of PS3 Bluetooth data to match USB HID data. Warning: as part of debuggigng why joystickType value was changing, I changed the class to make it a function you call instead of just a member variable. Should mark it inline... I think I caught all of the places in example code that was accessing it. If we find we want ability for user probram to update it, should add another member to explicityly set it.main
@@ -543,7 +543,7 @@ public: | |||
const uint8_t *manufacturer() | |||
{ return ((btdevice == nullptr) || (btdevice->strbuf == nullptr)) ? nullptr : &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_MAN]]; } | |||
const uint8_t *product() | |||
{ return ((btdevice == nullptr) || (btdevice->strbuf == nullptr)) ? nullptr : &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_PROD]]; } | |||
{ return remote_name_; } | |||
const uint8_t *serialNumber() | |||
{ return ((btdevice == nullptr) || (btdevice->strbuf == nullptr)) ? nullptr : &btdevice->strbuf->buffer[btdevice->strbuf->iStrings[strbuf_t::STR_ID_SERIAL]]; } | |||
private: | |||
@@ -557,9 +557,10 @@ private: | |||
friend class BluetoothController; | |||
protected: | |||
enum {SP_NEED_CONNECT=0x1, SP_PS3_IDS=0x2}; | |||
enum {REMOTE_NAME_SIZE=32}; | |||
uint8_t special_process_required = 0; | |||
Device_t *btdevice = NULL; | |||
strbuf_t *btstrbuf = NULL; | |||
uint8_t remote_name_[REMOTE_NAME_SIZE] = {0}; | |||
}; | |||
@@ -877,7 +878,11 @@ public: | |||
bool setLEDs(uint8_t lr, uint8_t lg=0, uint8_t lb=0); // sets Leds, | |||
enum { STANDARD_AXIS_COUNT = 10, ADDITIONAL_AXIS_COUNT = 54, TOTAL_AXIS_COUNT = (STANDARD_AXIS_COUNT+ADDITIONAL_AXIS_COUNT) }; | |||
typedef enum { UNKNOWN=0, PS3, PS4, XBOXONE, XBOX360} joytype_t; | |||
joytype_t joystickType = UNKNOWN; | |||
joytype_t joystickType() {return joystickType_;} | |||
// PS3 pair function. hack, requires that it be connect4ed by USB and we have the address of the Bluetooth dongle... | |||
bool PS3Pair(uint8_t* bdaddr); | |||
protected: | |||
@@ -901,6 +906,7 @@ protected: | |||
virtual bool remoteNameComplete(const uint8_t *remoteName); | |||
virtual void connectionComplete(void); | |||
joytype_t joystickType_ = UNKNOWN; | |||
private: | |||
// Class specific |
@@ -321,6 +321,7 @@ void BluetoothController::disconnect() | |||
USBHDBGSerial.printf("Bluetooth Disconnect"); | |||
if (device_driver_) { | |||
device_driver_->release_bluetooth(); | |||
device_driver_->remote_name_[0] = 0; | |||
device_driver_ = nullptr; | |||
} | |||
connection_complete_ = false; | |||
@@ -549,10 +550,16 @@ void BluetoothController::handle_hci_command_complete() | |||
break; | |||
case HCI_WRITE_SCAN_ENABLE: //0x0c1a | |||
DBGPrintf("Write_Scan_enable Completed\n"); | |||
// See if we have driver and a remote | |||
if (device_driver_ && connection_complete_) { // We have a driver call their | |||
device_driver_->connectionComplete(); | |||
connection_complete_ = false; // only call once | |||
// Now see if we have the remote name or not? | |||
if (device_driver_->remote_name_[0]) { | |||
device_driver_->connectionComplete(); | |||
connection_complete_ = false; // only call once | |||
} else { | |||
sendHCIRemoteNameRequest(); | |||
} | |||
} | |||
break; | |||
case HCI_WRITE_SSP_MODE: //0x0c56 | |||
@@ -792,6 +799,7 @@ void BluetoothController::handle_hci_disconnect_complete() | |||
rxbuf_[3]+(rxbuf_[4]<<8), rxbuf_[5]); | |||
if (device_driver_) { | |||
device_driver_->release_bluetooth(); | |||
device_driver_->remote_name_[0] = 0; | |||
device_driver_ = nullptr; | |||
// Restore to normal... | |||
@@ -802,7 +810,6 @@ void BluetoothController::handle_hci_disconnect_complete() | |||
device_connection_handle_ = 0; | |||
device_class_ = 0; | |||
memset(device_bdaddr_, 0, sizeof(device_bdaddr_)); | |||
//... | |||
} | |||
void BluetoothController::handle_hci_authentication_complete() | |||
@@ -815,6 +822,8 @@ void BluetoothController::handle_hci_authentication_complete() | |||
sendl2cap_ConnectionRequest(device_connection_handle_, connection_rxid_, control_dcid_, HID_CTRL_PSM); | |||
} | |||
void BluetoothController::handle_hci_remote_name_complete() { | |||
// STAT bd bd bd bd bd bd | |||
// 0x07 0xFF 0x00 0x79 0x22 0x23 0x0A 0xC5 0xCC 0x42 0x6C 0x75 0x65 0x74 0x6F 0x6F ... | |||
@@ -824,7 +833,7 @@ void BluetoothController::handle_hci_remote_name_complete() { | |||
for (uint8_t *psz = &rxbuf_[9]; *psz; psz++) DBGPrintf("%c", *psz); | |||
DBGPrintf("\n"); | |||
} | |||
// Lets try to allocate a string buffer to store the name out... | |||
if (device_driver_) { | |||
if (!device_driver_->remoteNameComplete(&rxbuf_[9])) { | |||
device_driver_->release_bluetooth(); | |||
@@ -834,9 +843,19 @@ void BluetoothController::handle_hci_remote_name_complete() { | |||
if (!device_driver_) { | |||
device_driver_ = find_driver(device_class_, &rxbuf_[9]); | |||
// not sure I should call remote name again, but they already process... | |||
if (device_driver_) { | |||
device_driver_->remoteNameComplete(&rxbuf_[9]); | |||
} | |||
} | |||
if (device_driver_) { | |||
// lets allocate a string object | |||
uint8_t buffer_index; | |||
for (buffer_index = 0; buffer_index < BTHIDInput::REMOTE_NAME_SIZE-1; buffer_index++) { | |||
device_driver_->remote_name_[buffer_index] = rxbuf_[9+buffer_index]; | |||
if (!device_driver_->remote_name_[buffer_index]) break; | |||
} | |||
device_driver_->remote_name_[buffer_index] = 0; // make sure null terminated | |||
if (device_driver_->special_process_required & BTHIDInput::SP_PS3_IDS) { | |||
// Real hack see if PS3... | |||
control_dcid_ = 0x40; | |||
@@ -844,8 +863,16 @@ void BluetoothController::handle_hci_remote_name_complete() { | |||
} | |||
} | |||
// Lets now try to accept the connection. | |||
sendHCIAcceptConnectionRequest(); | |||
// If we are in the connection complete mode, then this is a pairing state and needed to call | |||
// get remote name later. | |||
if (connection_complete_) { | |||
if (device_driver_) { // We have a driver call their | |||
device_driver_->connectionComplete(); | |||
connection_complete_ = false; // only call once | |||
} | |||
} else { | |||
sendHCIAcceptConnectionRequest(); | |||
} | |||
} | |||
void BluetoothController::handle_hci_remote_version_information_complete() { |
@@ -97,7 +97,7 @@ void loop() | |||
} | |||
uint8_t ltv; | |||
uint8_t rtv; | |||
switch (joysticks[joystick_index].joystickType) { | |||
switch (joysticks[joystick_index].joystickType()) { | |||
default: | |||
break; | |||
case JoystickController::PS4: | |||
@@ -133,7 +133,7 @@ void loop() | |||
break; | |||
} | |||
if (buttons != buttons_prev) { | |||
if (joysticks[joystick_index].joystickType == JoystickController::PS3) { | |||
if (joysticks[joystick_index].joystickType() == JoystickController::PS3) { | |||
joysticks[joystick_index].setLEDs((buttons >> 12) & 0xf); // try to get to TRI/CIR/X/SQuare | |||
} else { | |||
uint8_t lr = (buttons & 1) ? 0xff : 0; |
@@ -18,8 +18,8 @@ JoystickController joystick1(myusb); | |||
//BluetoothController bluet(myusb, true, "0000"); // Version does pairing to device | |||
BluetoothController bluet(myusb); // version assumes it already was paired | |||
int user_axis[64]; | |||
uint16_t buttons_prev = 0; | |||
uint16_t buttons; | |||
uint32_t buttons_prev = 0; | |||
uint32_t buttons; | |||
RawHIDController rawhid1(myusb); | |||
RawHIDController rawhid2(myusb, 0xffc90004); | |||
@@ -39,6 +39,7 @@ const char * hid_driver_names[CNT_DEVICES] = {"Joystick1", "RawHid1", "RawHid2"} | |||
bool hid_driver_active[CNT_DEVICES] = {false, false, false}; | |||
bool show_changed_only = false; | |||
bool show_raw_data = false; | |||
bool show_changed_data = false; | |||
uint8_t joystick_left_trigger_value = 0; | |||
uint8_t joystick_right_trigger_value = 0; | |||
@@ -46,6 +47,7 @@ uint64_t joystick_full_notify_mask = (uint64_t)-1; | |||
int psAxis[64]; | |||
bool first_joystick_message = true; | |||
uint8_t last_bdaddr[6]={0,0,0,0,0,0}; | |||
void setup() | |||
{ | |||
@@ -113,6 +115,13 @@ void loop() | |||
if (psz && *psz) Serial.printf(" product: %s\n", psz); | |||
psz = drivers[i]->serialNumber(); | |||
if (psz && *psz) Serial.printf(" Serial: %s\n", psz); | |||
if (drivers[i] == &bluet) { | |||
const uint8_t *bdaddr = bluet.myBDAddr(); | |||
// remember it... | |||
Serial.printf(" BDADDR: %x:%x:%x:%x:%x:%x\n", bdaddr[0], bdaddr[1], bdaddr[2], bdaddr[3], bdaddr[4], bdaddr[5]); | |||
for (uint8_t i=0;i<6;i++) last_bdaddr[i] = bdaddr[i]; | |||
} | |||
} | |||
} | |||
} | |||
@@ -147,20 +156,26 @@ void loop() | |||
psz = joystick1.product(); | |||
if (psz && *psz) Serial.printf(" product: %s\n", psz); | |||
psz =joystick1.serialNumber(); | |||
if (psz && *psz) Serial.printf(" Serial: %s\n", psz); | |||
if (psz && *psz) Serial.printf(" Serial: %s\n", psz); | |||
// lets try to reduce number of fields that update | |||
joystick1.axisChangeNotifyMask(0xFFFFFl); | |||
} | |||
for (uint8_t i = 0; i<64; i++) { | |||
psAxis[i] = joystick1.getAxis(i); | |||
} | |||
switch (joystick1.joystickType) { | |||
switch (joystick1.joystickType()) { | |||
/* | |||
case JoystickController::UNKNOWN: | |||
case JoystickController::PS4: | |||
displayPS4Data(); | |||
break; | |||
*/ | |||
case JoystickController::PS3: | |||
displayPS3Data(); | |||
break; | |||
default: | |||
case JoystickController::XBOXONE: | |||
case JoystickController::XBOX360:; | |||
displayRawData(); | |||
@@ -237,14 +252,37 @@ void displayPS4Data() | |||
void displayPS3Data() | |||
{ | |||
buttons = psAxis[2] | ((uint16_t)psAxis[3] << 8); | |||
buttons = joystick1.getButtons(); | |||
//buttons = psAxis[2] | ((uint16_t)psAxis[3] << 8); | |||
// Use L3 (Left joystick button) to toggle Show Raw or not... | |||
if ((buttons & 0x02) && !(buttons_prev & 0x02)) show_raw_data = !show_raw_data; | |||
if ((buttons & 0x04) && !(buttons_prev & 0x04)) show_changed_data = !show_changed_data; | |||
// See about maybe pair... | |||
if ((buttons & 0x10000) && !(buttons_prev & 0x10000) && (buttons & 0x0001)) { | |||
// PS button just pressed and select button pressed act like PS4 share like... | |||
Serial.print("\nPS3 Pairing Request"); | |||
if (!last_bdaddr[0] && !last_bdaddr[1] && !last_bdaddr[2] && !last_bdaddr[3] && !last_bdaddr[4] && !last_bdaddr[5]) { | |||
Serial.println(" - failed - no Bluetooth adapter has been plugged in"); | |||
} else if (!hiddrivers[0]) { // Kludge see if we are connected as HID? | |||
Serial.println(" - failed - PS3 device not plugged into USB"); | |||
} else { | |||
Serial.printf(" - Attempt pair to: %x:%x:%x:%x:%x:%x\n", last_bdaddr[0], last_bdaddr[1], last_bdaddr[2], last_bdaddr[3], last_bdaddr[4], last_bdaddr[5]); | |||
if (! joystick1.PS3Pair(last_bdaddr)) { | |||
Serial.println(" Pairing call Failed"); | |||
} else { | |||
Serial.println(" Pairing complete (I hope), make sure Bluetooth adapter is plugged in and try PS3 without USB"); | |||
} | |||
} | |||
} | |||
if (show_raw_data) { | |||
displayRawData(); | |||
} else { | |||
Serial.printf("LX: %d, LY: %d, RX: %d, RY: %d \r\n", psAxis[6], psAxis[7], psAxis[8], psAxis[9]); | |||
Serial.printf("LX: %d, LY: %d, RX: %d, RY: %d \r\n", psAxis[0], psAxis[1], psAxis[2], psAxis[5]); | |||
Serial.printf("L-Trig: %d, R-Trig: %d\r\n", psAxis[18], psAxis[19]); | |||
Serial.printf("Buttons: %x\r\n", buttons); | |||
} | |||
@@ -278,16 +316,28 @@ void displayRawData() { | |||
uint64_t changed_mask = joystick1.axisChangedMask(); | |||
if (!changed_mask) return; | |||
Serial.printf("%lx %lx:", axis_mask, changed_mask); | |||
for (uint16_t index=0; axis_mask; index++) { | |||
Serial.printf("%02x ", psAxis[index]); | |||
axis_mask >>= 1; | |||
if (show_changed_data) { | |||
if (!changed_mask) return; | |||
changed_mask &= 0xfffffffffL; // try reducing which ones show... | |||
Serial.printf("%0x - ", joystick1.getButtons()); | |||
for (uint16_t index=0; changed_mask; index++) { | |||
if (changed_mask & 1) { | |||
Serial.printf("%d:%02x ", index, psAxis[index]); | |||
} | |||
changed_mask >>= 1; | |||
} | |||
} else { | |||
axis_mask &= 0xffffff; | |||
Serial.printf("%06x%06x: %06x - ", (uint32_t)(changed_mask >> 32), (uint32_t)(changed_mask & 0xffffffff), joystick1.getButtons()); | |||
for (uint16_t index=0; axis_mask; index++) { | |||
Serial.printf("%02x ", psAxis[index]); | |||
axis_mask >>= 1; | |||
} | |||
} | |||
Serial.println(); | |||
//for (uint8_t i = 0; i < 24; i++) { | |||
// Serial.printf(" %d:%d", i, psAxis[i]); | |||
//} | |||
//Serial.println(); | |||
Serial.println(); | |||
} | |||
@@ -178,7 +178,7 @@ void loop() | |||
} | |||
uint8_t ltv; | |||
uint8_t rtv; | |||
switch (joystick1.joystickType) { | |||
switch (joystick1.joystickType()) { | |||
default: | |||
break; | |||
case JoystickController::PS4: | |||
@@ -214,7 +214,7 @@ void loop() | |||
break; | |||
} | |||
if (buttons != buttons_prev) { | |||
if (joystick1.joystickType == JoystickController::PS3) { | |||
if (joystick1.joystickType() == JoystickController::PS3) { | |||
joystick1.setLEDs((buttons >> 12) & 0xf); // try to get to TRI/CIR/X/SQuare | |||
} else { | |||
uint8_t lr = (buttons & 1) ? 0xff : 0; |
@@ -178,7 +178,7 @@ void loop() | |||
} | |||
uint8_t ltv; | |||
uint8_t rtv; | |||
switch (joystick1.joystickType) { | |||
switch (joystick1.joystickType()) { | |||
default: | |||
break; | |||
case JoystickController::PS4: | |||
@@ -214,7 +214,7 @@ void loop() | |||
break; | |||
} | |||
if (buttons != buttons_prev) { | |||
if (joystick1.joystickType == JoystickController::PS3) { | |||
if (joystick1.joystickType() == JoystickController::PS3) { | |||
joystick1.setLEDs((buttons >> 12) & 0xf); // try to get to TRI/CIR/X/SQuare | |||
} else { | |||
uint8_t lr = (buttons & 1) ? 0xff : 0; |
@@ -100,6 +100,7 @@ const uint8_t *JoystickController::product() | |||
{ | |||
if ((device != nullptr) && (device->strbuf != nullptr)) return &device->strbuf->buffer[device->strbuf->iStrings[strbuf_t::STR_ID_PROD]]; | |||
if ((mydevice != nullptr) && (mydevice->strbuf != nullptr)) return &mydevice->strbuf->buffer[mydevice->strbuf->iStrings[strbuf_t::STR_ID_PROD]]; | |||
if (btdevice != nullptr) return remote_name_; | |||
return nullptr; | |||
} | |||
@@ -119,7 +120,7 @@ bool JoystickController::setRumble(uint8_t lValue, uint8_t rValue, uint8_t timeo | |||
rumble_rValue_ = rValue; | |||
rumble_timeout_ = timeout; | |||
switch (joystickType) { | |||
switch (joystickType_) { | |||
default: | |||
break; | |||
case PS3: | |||
@@ -175,7 +176,7 @@ bool JoystickController::setLEDs(uint8_t lr, uint8_t lg, uint8_t lb) | |||
leds_[1] = lg; | |||
leds_[2] = lb; | |||
switch (joystickType) { | |||
switch (joystickType_) { | |||
case PS3: | |||
return transmitPS3UserFeedbackMsg(); | |||
case PS4: | |||
@@ -311,8 +312,9 @@ hidclaim_t JoystickController::claim_collection(USBHIDParser *driver, Device_t * | |||
connected_ = true; // remember that hardware is actually connected... | |||
// Lets see if we know what type of joystick this is. That is, is it a PS3 or PS4 or ... | |||
joystickType = mapVIDPIDtoJoystickType(mydevice->idVendor, mydevice->idProduct, false); | |||
switch (joystickType) { | |||
joystickType_ = mapVIDPIDtoJoystickType(mydevice->idVendor, mydevice->idProduct, false); | |||
DBGPrintf("JoystickController::claim_collection joystickType_=%d\n", joystickType_); | |||
switch (joystickType_) { | |||
case PS3: | |||
additional_axis_usage_page_ = 0x1; | |||
additional_axis_usage_start_ = 0x100; | |||
@@ -526,7 +528,8 @@ bool JoystickController::claim(Device_t *dev, int type, const uint8_t *descripto | |||
connected_ = 0; // remember that hardware is actually connected... | |||
} | |||
memset(axis, 0, sizeof(axis)); // clear out any data. | |||
joystickType = jtype; // remember we are an XBox One. | |||
joystickType_ = jtype; // remember we are an XBox One. | |||
DBGPrintf(" JoystickController::claim joystickType_ %d\n", joystickType_); | |||
return true; | |||
} | |||
@@ -599,7 +602,7 @@ void JoystickController::rx_data(const Transfer_t *transfer) | |||
print("JoystickController::rx_data: "); | |||
print_hexbytes((uint8_t*)transfer->buffer, transfer->length); | |||
if (joystickType == XBOXONE) { | |||
if (joystickType_ == XBOXONE) { | |||
// Process XBOX One data | |||
axis_mask_ = 0x3f; | |||
axis_changed_mask_ = 0; // assume none for now | |||
@@ -622,7 +625,7 @@ void JoystickController::rx_data(const Transfer_t *transfer) | |||
joystickEvent = true; | |||
} | |||
} else if (joystickType == XBOX360) { | |||
} else if (joystickType_ == XBOX360) { | |||
// First byte appears to status - if the byte is 0x8 it is a connect or disconnect of the controller. | |||
xbox360data_t *xb360d = (xbox360data_t *)transfer->buffer; | |||
if (xb360d->state == 0x08) { | |||
@@ -703,7 +706,7 @@ bool JoystickController::claim_bluetooth(BluetoothController *driver, uint32_t b | |||
btdriver_ = driver; | |||
btdevice = (Device_t*)driver; // remember this way | |||
special_process_required = SP_PS3_IDS; // PS3 maybe needs different IDS. | |||
joystickType = PS3; | |||
joystickType_ = PS3; | |||
return true; | |||
} | |||
return false; | |||
@@ -721,24 +724,61 @@ bool JoystickController::process_bluetooth_HID_data(const uint8_t *data, uint16_ | |||
//print(" Joystick Data: "); | |||
//print_hexbytes(data, length); | |||
// DBGPrintf(" Joystick Data: "); | |||
uint64_t mask = 0x1; | |||
axis_mask_ = 0; | |||
axis_changed_mask_ = 0; | |||
if (length > TOTAL_AXIS_COUNT) length = TOTAL_AXIS_COUNT; // don't overflow arrays... | |||
for (uint16_t i = 0; i < length; i++ ) { | |||
axis_mask_ |= mask; | |||
if(data[i] != axis[i]) { | |||
axis_changed_mask_ |= mask; | |||
axis[i] = data[i]; | |||
} | |||
mask <<= 1; // shift down the mask. | |||
// DBGPrintf("%02x ", axis[i]); | |||
if (joystickType_ == PS3) { | |||
// Quick and dirty hack to match PS3 HID data | |||
uint32_t cur_buttons = data[2] | ((uint16_t)data[3] << 8) | ((uint32_t)data[4] << 16); | |||
if (cur_buttons != buttons) { | |||
buttons = cur_buttons; | |||
joystickEvent = true; // something changed. | |||
} | |||
uint64_t mask = 0x1; | |||
axis_mask_ = 0x27; // assume bits 0, 1, 2, 5 | |||
for (uint16_t i = 0; i < 3; i++) { | |||
if (axis[i] != data[i+6]) { | |||
axis_changed_mask_ |= mask; | |||
axis[i] = data[i+6]; | |||
} | |||
mask <<= 1; // shift down the mask. | |||
} | |||
if (axis[5] != data[9]) { | |||
axis_changed_mask_ |= (1<<5); | |||
axis[5] = data[9]; | |||
} | |||
// Then rest of data | |||
mask = 0x1 << 10; // setup for other bits | |||
for (uint16_t i = 10; i < length; i++ ) { | |||
axis_mask_ |= mask; | |||
if(data[i] != axis[i]) { | |||
axis_changed_mask_ |= mask; | |||
axis[i] = data[i]; | |||
} | |||
mask <<= 1; // shift down the mask. | |||
} | |||
} else { | |||
uint64_t mask = 0x1; | |||
axis_mask_ = 0; | |||
for (uint16_t i = 0; i < length; i++ ) { | |||
axis_mask_ |= mask; | |||
if(data[i] != axis[i]) { | |||
axis_changed_mask_ |= mask; | |||
axis[i] = data[i]; | |||
} | |||
mask <<= 1; // shift down the mask. | |||
// DBGPrintf("%02x ", axis[i]); | |||
} | |||
} | |||
// DBGPrintf("\n"); | |||
joystickEvent = true; | |||
if (axis_changed_mask_ & axis_change_notify_mask_) | |||
joystickEvent = true; | |||
connected_ = true; | |||
return true; | |||
} else if(data[0] == 0x11){ | |||
DBGPrintf(" Joystick Data: "); | |||
uint64_t mask = 0x1; | |||
@@ -750,8 +790,9 @@ bool JoystickController::process_bluetooth_HID_data(const uint8_t *data, uint16_ | |||
uint8_t tmp_data[length-2]; | |||
for (uint16_t i = 0; i < (length-2); i++ ) { | |||
tmp_data[i] = data[i+2]; | |||
DBGPrintf("%02x ",tmp_data[i]); | |||
} | |||
DBGPrintf("\n"); | |||
/* | |||
* [1] LX, [2] = LY, [3] = RX, [4] = RY | |||
* [5] combo, tri, cir, x, sqr, D-PAD (4bits, 0-3 | |||
@@ -783,9 +824,9 @@ bool JoystickController::process_bluetooth_HID_data(const uint8_t *data, uint16_ | |||
axis[i] = tmp_data[i]; | |||
} | |||
mask <<= 1; // shift down the mask. | |||
DBGPrintf("%02x ", axis[i]); | |||
//DBGPrintf("%02x ", axis[i]); | |||
} | |||
DBGPrintf("\n"); | |||
//DBGPrintf("\n"); | |||
joystickEvent = true; | |||
connected_ = true; | |||
} | |||
@@ -798,21 +839,22 @@ bool JoystickController::remoteNameComplete(const uint8_t *remoteName) | |||
if (strncmp((const char *)remoteName, "Wireless Controller", 19) == 0) { | |||
DBGPrintf(" JoystickController::remoteNameComplete %s - set to PS4\n", remoteName); | |||
special_process_required = SP_NEED_CONNECT; // We need to force this. | |||
joystickType = PS4; | |||
joystickType_ = PS4; | |||
} else if (strncmp((const char *)remoteName, "PLAYSTATION(R)3", 15) == 0) { | |||
DBGPrintf(" JoystickController::remoteNameComplete %s - set to PS3\n", remoteName); | |||
DBGPrintf(" JoystickController::remoteNameComplete %x %s - set to PS3\n", (uint32_t)this, remoteName); | |||
special_process_required = SP_PS3_IDS; // PS3 maybe needs different IDS. | |||
joystickType = PS3; | |||
joystickType_ = PS3; | |||
} else { | |||
DBGPrintf(" JoystickController::remoteNameComplete %s - Unknown\n", remoteName); | |||
} | |||
DBGPrintf(" Joystick Type: %d\n", joystickType_); | |||
return true; | |||
} | |||
void JoystickController::connectionComplete() | |||
{ | |||
DBGPrintf(" JoystickController::connectionComplete joystick type %d\n", joystickType); | |||
if (joystickType == PS4) { | |||
DBGPrintf(" JoystickController::connectionComplete %x joystick type %d\n", (uint32_t)this, joystickType_); | |||
if (joystickType_ == PS4) { | |||
uint8_t packet[2]; | |||
packet[0] = 0x43; // HID BT Get_report (0x40) | Report Type (Feature 0x03) | |||
packet[1] = 0x02; // Report ID | |||
@@ -820,7 +862,7 @@ void JoystickController::connectionComplete() | |||
delay(1); | |||
btdriver_->sendL2CapCommand(packet, sizeof(packet), 0x40); | |||
} else if (joystickType == PS3) { | |||
} else if (joystickType_ == PS3) { | |||
uint8_t packet[6]; | |||
packet[0] = 0x53; // HID BT Set_report (0x50) | Report Type (Feature 0x03) | |||
packet[1] = 0xF4; // Report ID | |||
@@ -845,3 +887,17 @@ void JoystickController::release_bluetooth() | |||
} | |||
bool JoystickController::PS3Pair(uint8_t* bdaddr) { | |||
if ((joystickType_ != PS3) || !driver_) return false; // not a PS2 nor plugged into USB... | |||
/* Set the internal Bluetooth address */ | |||
txbuf_[0] = 0x01; | |||
txbuf_[1] = 0x00; | |||
for(uint8_t i = 0; i < 6; i++) | |||
txbuf_[i + 2] = bdaddr[5 - i]; // Copy into buffer, has to be written reversed, so it is MSB first | |||
// 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 | |||
return driver_->sendControlPacket(0x21, 9, 0x3f5, 0, 8, txbuf_); | |||
} |