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

View file

@ -183,11 +183,24 @@ void XBOXONESParser::Reset() {
oldDpad = 0; 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) { void XBOXONESParser::setRumbleOn(uint8_t leftTrigger, uint8_t rightTrigger, uint8_t leftMotor, uint8_t rightMotor) {
// See: https://lore.kernel.org/patchwork/patch/973394/ // See: https://lore.kernel.org/patchwork/patch/973394/
uint8_t buf[8]; 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[1] = leftTrigger;
buf[2] = rightTrigger; buf[2] = rightTrigger;
buf[3] = leftMotor; buf[3] = leftMotor;
@ -197,4 +210,3 @@ void XBOXONESParser::setRumbleOn(uint8_t leftTrigger, uint8_t rightTrigger, uint
buf[7] = 255; // Loop count buf[7] = 255; // Loop count
sendOutputReport(buf, sizeof(buf)); sendOutputReport(buf, sizeof(buf));
} }
#endif

View file

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

View file

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