Added support for rumble functionality on the Xbox One S controller via Bluetooth

This commit is contained in:
Kristian Sloth Lauszus 2021-01-24 14:33:44 +01:00
parent 5af56accc3
commit 3915e96962
4 changed files with 21 additions and 22 deletions

View file

@ -74,28 +74,17 @@ protected:
};
/**@}*/
#if 0
/** @name XBOXONESParser implementation */
virtual void sendOutputReport(uint8_t *data, uint8_t nbytes) {
// See: https://lore.kernel.org/patchwork/patch/973394/
uint8_t buf[nbytes + 2];
buf[0] = 0x52; // HID BT Set_report (0x50) | Report Type (Output 0x02)
buf[0] = 0xA2; // HID BT DATA (0xA0) | Report Type (Output 0x02)
buf[1] = 0x03; // Report ID
memcpy(buf + 2, data, nbytes);
Notify(PSTR("\r\n"), 0x80);
for (uint8_t i = 0; i < sizeof(buf); i++) {
D_PrintHex<uint8_t > (buf[i], 0x80);
Notify(PSTR(" "), 0x80);
}
Notify(PSTR("\r\n"), 0x80);
//pBtd->L2CAP_Command(hci_handle, data, nbytes, interrupt_scid[0], interrupt_scid[1]);
pBtd->L2CAP_Command(hci_handle, buf, sizeof(buf), control_scid[0], control_scid[1]);
// Send the Bluetooth DATA output report on the interrupt channel
pBtd->L2CAP_Command(hci_handle, buf, sizeof(buf), interrupt_scid[0], interrupt_scid[1]);
};
/**@}*/
#endif
};
#endif

View file

@ -183,11 +183,24 @@ void XBOXONESParser::Reset() {
oldDpad = 0;
};
#if 0
void XBOXONESParser::setRumbleOff() {
// See: https://lore.kernel.org/patchwork/patch/973394/
uint8_t buf[8];
buf[0] = 0x0F; // Disable all rumble motors
buf[1] = 0;
buf[2] = 0;
buf[3] = 0;
buf[4] = 0;
buf[5] = 0; // Duration of effect in 10 ms
buf[6] = 0; // Start delay in 10 ms
buf[7] = 0; // Loop count
sendOutputReport(buf, sizeof(buf));
}
void XBOXONESParser::setRumbleOn(uint8_t leftTrigger, uint8_t rightTrigger, uint8_t leftMotor, uint8_t rightMotor) {
// See: https://lore.kernel.org/patchwork/patch/973394/
uint8_t buf[8];
buf[0] = 0x0F;//1 << 1 | 1 << 0; // Enable weak and strong feedback
buf[0] = 1 << 3 /* Left trigger */ | 1 << 2 /* Right trigger */ | 1 << 1 /* Left motor */ | 1 << 0 /* Right motor */;
buf[1] = leftTrigger;
buf[2] = rightTrigger;
buf[3] = leftMotor;
@ -197,4 +210,3 @@ void XBOXONESParser::setRumbleOn(uint8_t leftTrigger, uint8_t rightTrigger, uint
buf[7] = 255; // Loop count
sendOutputReport(buf, sizeof(buf));
}
#endif

View file

@ -81,7 +81,7 @@ public:
int16_t getAnalogHat(AnalogHatEnum a);
/** Used to set the rumble off. */
//void setRumbleOff();
void setRumbleOff();
/**
* Used to turn on rumble continuously.
@ -90,7 +90,7 @@ public:
* @param leftMotor Left motor force.
* @param rightMotor Right motor force.
*/
//void setRumbleOn(uint8_t leftTrigger, uint8_t rightTrigger, uint8_t leftMotor, uint8_t rightMotor);
void setRumbleOn(uint8_t leftTrigger, uint8_t rightTrigger, uint8_t leftMotor, uint8_t rightMotor);
protected:
/**
@ -108,7 +108,7 @@ protected:
* @param output Pointer to data buffer.
* @param nbytes Bytes to send.
*/
//virtual void sendOutputReport(uint8_t *data, uint8_t nbytes) = 0;
virtual void sendOutputReport(uint8_t *data, uint8_t nbytes) = 0;
private:
bool checkDpad(ButtonEnum b); // Used to check Xbox One S DPAD buttons

View file

@ -77,7 +77,6 @@ void loop() {
Serial.println();
}
#if 0 // This is currently not working
// Set rumble effect
static uint16_t oldL2Value, oldR2Value;
if (Xbox.getButtonPress(L2) != oldL2Value || Xbox.getButtonPress(R2) != oldR2Value) {
@ -90,7 +89,6 @@ void loop() {
else
Xbox.setRumbleOff();
}
#endif
if (Xbox.getButtonClick(UP))
Serial.println(F("Up"));