mirror of
https://github.com/felis/USB_Host_Shield_2.0.git
synced 2024-03-22 11:31:26 +01:00
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:
parent
b0b255cd95
commit
25572863b7
2 changed files with 26 additions and 19 deletions
44
XBOXONE.cpp
44
XBOXONE.cpp
|
@ -179,10 +179,11 @@ uint8_t XBOXONE::Init(uint8_t parent, uint8_t port, bool lowspeed) {
|
||||||
delay(200); // let things settle
|
delay(200); // let things settle
|
||||||
|
|
||||||
// Initialize the controller for input
|
// Initialize the controller for input
|
||||||
|
cmdCounter = 0; // Reset the counter used when sending out the commands
|
||||||
uint8_t writeBuf[5];
|
uint8_t writeBuf[5];
|
||||||
writeBuf[0] = 0x05;
|
writeBuf[0] = 0x05;
|
||||||
writeBuf[1] = 0x20;
|
writeBuf[1] = 0x20;
|
||||||
writeBuf[2] = 0x00;
|
// Byte 2 is set in "XboxCommand"
|
||||||
writeBuf[3] = 0x01;
|
writeBuf[3] = 0x01;
|
||||||
writeBuf[4] = 0x00;
|
writeBuf[4] = 0x00;
|
||||||
rcode = XboxCommand(writeBuf, 5);
|
rcode = XboxCommand(writeBuf, 5);
|
||||||
|
@ -402,6 +403,7 @@ int16_t XBOXONE::getAnalogHat(AnalogHatEnum a) {
|
||||||
|
|
||||||
/* Xbox Controller commands */
|
/* Xbox Controller commands */
|
||||||
uint8_t XBOXONE::XboxCommand(uint8_t* data, uint16_t nbytes) {
|
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);
|
uint8_t rcode = pUsb->outTransfer(bAddress, epInfo[ XBOX_ONE_OUTPUT_PIPE ].epAddr, nbytes, data);
|
||||||
#ifdef DEBUG_USB_HOST
|
#ifdef DEBUG_USB_HOST
|
||||||
Notify(PSTR("\r\nXboxCommand, Return: "), 0x80);
|
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
|
// The Xbox One packets are described at: https://github.com/quantus/xbox-one-controller-protocol
|
||||||
void XBOXONE::onInit() {
|
void XBOXONE::onInit() {
|
||||||
// A short buzz to show the controller is active
|
// A short buzz to show the controller is active
|
||||||
uint8_t writeBuf[11];
|
uint8_t writeBuf[13];
|
||||||
|
|
||||||
// Activate rumble
|
// Activate rumble
|
||||||
writeBuf[0] = 0x09;
|
writeBuf[0] = 0x09;
|
||||||
writeBuf[1] = 0x08; // 0x20 bit and all bits of 0x07 prevents rumble effect
|
writeBuf[1] = 0x00;
|
||||||
writeBuf[2] = 0x00; // This may have something to do with how many times effect is played
|
// Byte 2 is set in "XboxCommand"
|
||||||
|
|
||||||
// Single rumble effect
|
// Single rumble effect
|
||||||
writeBuf[3] = 0x09; // Substructure (what substructure rest of this packet has)
|
writeBuf[3] = 0x09; // Substructure (what substructure rest of this packet has)
|
||||||
|
@ -429,50 +431,54 @@ void XBOXONE::onInit() {
|
||||||
writeBuf[8] = 0x20; // L force
|
writeBuf[8] = 0x20; // L force
|
||||||
writeBuf[9] = 0x20; // R force
|
writeBuf[9] = 0x20; // R force
|
||||||
writeBuf[10] = 0x80; // Length of pulse
|
writeBuf[10] = 0x80; // Length of pulse
|
||||||
XboxCommand(writeBuf, 11);
|
writeBuf[11] = 0x00; // Off period
|
||||||
|
writeBuf[12] = 0x00; // Repeat count
|
||||||
|
XboxCommand(writeBuf, 13);
|
||||||
|
|
||||||
if(pFuncOnInit)
|
if(pFuncOnInit)
|
||||||
pFuncOnInit(); // Call the user function
|
pFuncOnInit(); // Call the user function
|
||||||
}
|
}
|
||||||
|
|
||||||
void XBOXONE::setRumbleOff() {
|
void XBOXONE::setRumbleOff() {
|
||||||
uint8_t writeBuf[12];
|
uint8_t writeBuf[13];
|
||||||
|
|
||||||
// Activate rumble
|
// Activate rumble
|
||||||
writeBuf[0] = 0x09;
|
writeBuf[0] = 0x09;
|
||||||
writeBuf[1] = 0x08; // 0x20 bit and all bits of 0x07 prevents rumble effect
|
writeBuf[1] = 0x00;
|
||||||
writeBuf[2] = 0x00; // This may have something to do with how many times effect is played
|
// Byte 2 is set in "XboxCommand"
|
||||||
|
|
||||||
// Continuous rumble effect
|
// 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[4] = 0x00; // Mode
|
||||||
writeBuf[5] = 0x0F; // Rumble mask (what motors are activated) (0000 lT rT L R)
|
writeBuf[5] = 0x0F; // Rumble mask (what motors are activated) (0000 lT rT L R)
|
||||||
writeBuf[6] = 0x00; // lT force
|
writeBuf[6] = 0x00; // lT force
|
||||||
writeBuf[7] = 0x00; // rT force
|
writeBuf[7] = 0x00; // rT force
|
||||||
writeBuf[8] = 0x00; // L force
|
writeBuf[8] = 0x00; // L force
|
||||||
writeBuf[9] = 0x00; // R force
|
writeBuf[9] = 0x00; // R force
|
||||||
writeBuf[10] = 0x00; // Length of pulse
|
writeBuf[10] = 0x00; // On period
|
||||||
writeBuf[11] = 0x00; // Period between pulses
|
writeBuf[11] = 0x00; // Off period
|
||||||
XboxCommand(writeBuf, 12);
|
writeBuf[12] = 0x00; // Repeat count
|
||||||
|
XboxCommand(writeBuf, 13);
|
||||||
}
|
}
|
||||||
|
|
||||||
void XBOXONE::setRumbleOn(uint8_t leftTrigger, uint8_t rightTrigger, uint8_t leftMotor, uint8_t rightMotor) {
|
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
|
// Activate rumble
|
||||||
writeBuf[0] = 0x09;
|
writeBuf[0] = 0x09;
|
||||||
writeBuf[1] = 0x08; // 0x20 bit and all bits of 0x07 prevents rumble effect
|
writeBuf[1] = 0x00;
|
||||||
writeBuf[2] = 0x00; // This may have something to do with how many times effect is played
|
// Byte 2 is set in "XboxCommand"
|
||||||
|
|
||||||
// Continuous rumble effect
|
// 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[4] = 0x00; // Mode
|
||||||
writeBuf[5] = 0x0F; // Rumble mask (what motors are activated) (0000 lT rT L R)
|
writeBuf[5] = 0x0F; // Rumble mask (what motors are activated) (0000 lT rT L R)
|
||||||
writeBuf[6] = leftTrigger; // lT force
|
writeBuf[6] = leftTrigger; // lT force
|
||||||
writeBuf[7] = rightTrigger; // rT force
|
writeBuf[7] = rightTrigger; // rT force
|
||||||
writeBuf[8] = leftMotor; // L force
|
writeBuf[8] = leftMotor; // L force
|
||||||
writeBuf[9] = rightMotor; // R force
|
writeBuf[9] = rightMotor; // R force
|
||||||
writeBuf[10] = 0x80; // Length of pulse
|
writeBuf[10] = 0xFF; // On period
|
||||||
writeBuf[11] = 0x00; // Period between pulses
|
writeBuf[11] = 0x00; // Off period
|
||||||
XboxCommand(writeBuf, 12);
|
writeBuf[12] = 0xFF; // Repeat count
|
||||||
|
XboxCommand(writeBuf, 13);
|
||||||
}
|
}
|
||||||
|
|
|
@ -229,6 +229,7 @@ private:
|
||||||
bool R2Clicked;
|
bool R2Clicked;
|
||||||
|
|
||||||
uint8_t readBuf[XBOX_ONE_EP_MAXPKTSIZE]; // General purpose buffer for input data
|
uint8_t readBuf[XBOX_ONE_EP_MAXPKTSIZE]; // General purpose buffer for input data
|
||||||
|
uint8_t cmdCounter;
|
||||||
|
|
||||||
void readReport(); // Used to read the incoming data
|
void readReport(); // Used to read the incoming data
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue