Use a counter when sending Xbox commands

This is needed in order for rumble to work

This is how it is done in the Linux kernel - see: https://github.com/torvalds/linux/blob/master/drivers/input/joystick/xpad.c
This commit is contained in:
Kristian Sloth Lauszus 2018-03-15 20:26:43 +01:00
parent b0b255cd95
commit 25572863b7
2 changed files with 26 additions and 19 deletions

View file

@ -179,10 +179,11 @@ uint8_t XBOXONE::Init(uint8_t parent, uint8_t port, bool lowspeed) {
delay(200); // let things settle
// Initialize the controller for input
cmdCounter = 0; // Reset the counter used when sending out the commands
uint8_t writeBuf[5];
writeBuf[0] = 0x05;
writeBuf[1] = 0x20;
writeBuf[2] = 0x00;
// Byte 2 is set in "XboxCommand"
writeBuf[3] = 0x01;
writeBuf[4] = 0x00;
rcode = XboxCommand(writeBuf, 5);
@ -402,6 +403,7 @@ int16_t XBOXONE::getAnalogHat(AnalogHatEnum a) {
/* Xbox Controller commands */
uint8_t XBOXONE::XboxCommand(uint8_t* data, uint16_t nbytes) {
data[2] = cmdCounter++; // Increment the output command counter
uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ XBOX_ONE_OUTPUT_PIPE ].epAddr, nbytes, data);
#ifdef DEBUG_USB_HOST
Notify(PSTR("\r\nXboxCommand, Return: "), 0x80);
@ -413,12 +415,12 @@ uint8_t XBOXONE::XboxCommand(uint8_t* data, uint16_t nbytes) {
// The Xbox One packets are described at: https://github.com/quantus/xbox-one-controller-protocol
void XBOXONE::onInit() {
// A short buzz to show the controller is active
uint8_t writeBuf[11];
uint8_t writeBuf[13];
// Activate rumble
writeBuf[0] = 0x09;
writeBuf[1] = 0x08; // 0x20 bit and all bits of 0x07 prevents rumble effect
writeBuf[2] = 0x00; // This may have something to do with how many times effect is played
writeBuf[1] = 0x00;
// Byte 2 is set in "XboxCommand"
// Single rumble effect
writeBuf[3] = 0x09; // Substructure (what substructure rest of this packet has)
@ -429,50 +431,54 @@ void XBOXONE::onInit() {
writeBuf[8] = 0x20; // L force
writeBuf[9] = 0x20; // R force
writeBuf[10] = 0x80; // Length of pulse
XboxCommand(writeBuf, 11);
writeBuf[11] = 0x00; // Off period
writeBuf[12] = 0x00; // Repeat count
XboxCommand(writeBuf, 13);
if(pFuncOnInit)
pFuncOnInit(); // Call the user function
}
void XBOXONE::setRumbleOff() {
uint8_t writeBuf[12];
uint8_t writeBuf[13];
// Activate rumble
writeBuf[0] = 0x09;
writeBuf[1] = 0x08; // 0x20 bit and all bits of 0x07 prevents rumble effect
writeBuf[2] = 0x00; // This may have something to do with how many times effect is played
writeBuf[1] = 0x00;
// Byte 2 is set in "XboxCommand"
// Continuous rumble effect
writeBuf[3] = 0x08; // Substructure (what substructure rest of this packet has)
writeBuf[3] = 0x09; // Substructure (what substructure rest of this packet has)
writeBuf[4] = 0x00; // Mode
writeBuf[5] = 0x0F; // Rumble mask (what motors are activated) (0000 lT rT L R)
writeBuf[6] = 0x00; // lT force
writeBuf[7] = 0x00; // rT force
writeBuf[8] = 0x00; // L force
writeBuf[9] = 0x00; // R force
writeBuf[10] = 0x00; // Length of pulse
writeBuf[11] = 0x00; // Period between pulses
XboxCommand(writeBuf, 12);
writeBuf[10] = 0x00; // On period
writeBuf[11] = 0x00; // Off period
writeBuf[12] = 0x00; // Repeat count
XboxCommand(writeBuf, 13);
}
void XBOXONE::setRumbleOn(uint8_t leftTrigger, uint8_t rightTrigger, uint8_t leftMotor, uint8_t rightMotor) {
uint8_t writeBuf[12];
uint8_t writeBuf[13];
// Activate rumble
writeBuf[0] = 0x09;
writeBuf[1] = 0x08; // 0x20 bit and all bits of 0x07 prevents rumble effect
writeBuf[2] = 0x00; // This may have something to do with how many times effect is played
writeBuf[1] = 0x00;
// Byte 2 is set in "XboxCommand"
// Continuous rumble effect
writeBuf[3] = 0x08; // Substructure (what substructure rest of this packet has)
writeBuf[3] = 0x09; // Substructure (what substructure rest of this packet has)
writeBuf[4] = 0x00; // Mode
writeBuf[5] = 0x0F; // Rumble mask (what motors are activated) (0000 lT rT L R)
writeBuf[6] = leftTrigger; // lT force
writeBuf[7] = rightTrigger; // rT force
writeBuf[8] = leftMotor; // L force
writeBuf[9] = rightMotor; // R force
writeBuf[10] = 0x80; // Length of pulse
writeBuf[11] = 0x00; // Period between pulses
XboxCommand(writeBuf, 12);
writeBuf[10] = 0xFF; // On period
writeBuf[11] = 0x00; // Off period
writeBuf[12] = 0xFF; // Repeat count
XboxCommand(writeBuf, 13);
}

View file

@ -229,6 +229,7 @@ private:
bool R2Clicked;
uint8_t readBuf[XBOX_ONE_EP_MAXPKTSIZE]; // General purpose buffer for input data
uint8_t cmdCounter;
void readReport(); // Used to read the incoming data