@@ -175,6 +175,8 @@ static XboxOriginalReport xboxOriginalReport
175175 .rightStickY = 0 ,
176176};
177177
178+ #define XBONE_KEEPALIVE_TIMER 15000
179+
178180static XboxOneGamepad_Data_t xboneReport
179181{
180182 .sync = 0 ,
@@ -206,8 +208,6 @@ static uint16_t xboneReportSize;
206208
207209// Xbox One & PS4/PS5 Timing
208210static TouchpadData touchpadData;
209- static uint8_t last_report_counter = 0 ;
210- static uint16_t last_axis_counter = 0 ;
211211
212212static KeyboardReport keyboardReport
213213{
@@ -281,10 +281,12 @@ void Gamepad::setup()
281281
282282 // setup PS5 compatibility
283283 PS4Data::getInstance ().ps4ControllerType = gamepadOptions.ps4ControllerType ;
284+ last_report_counter = 0 ;
285+ last_axis_counter = 0 ;
284286
285287 // Xbox One Keep-Alive
286- keep_alive_timer = 0 ;
287- keep_alive_sequence = 0 ;
288+ keep_alive_timer = to_ms_since_boot ( get_absolute_time ()) ;
289+ keep_alive_sequence = 1 ;
288290 virtual_keycode_sequence = 0 ;
289291 xb1_guide_pressed = false ;
290292 xboneReportSize = sizeof (XboxOneGamepad_Data_t);
@@ -800,9 +802,8 @@ void Gamepad::sendReportSuccess() {
800802 // Successfully sent report, actually increment last report counter!
801803 if ( memcmp (&last_report[4 ], &((uint8_t *)&xboneReport)[4 ], xboneReportSize-4 ) != 0 ) {
802804 last_report_counter++;
803- if (last_report_counter == 0 ) {
805+ if (last_report_counter == 0 )
804806 last_report_counter = 1 ;
805- }
806807 memcpy (last_report, &xboneReport, xboneReportSize);
807808 }
808809 }
@@ -824,11 +825,9 @@ XboxOneGamepad_Data_t *Gamepad::getXBOneReport()
824825
825826 uint32_t now = to_ms_since_boot (get_absolute_time ());
826827 // Send Keep-Alive every 15 seconds (keep_alive_timer updates if send is successful)
827- if ( (now - keep_alive_timer) > 15000 ) {
828+ if ( (now - keep_alive_timer) > XBONE_KEEPALIVE_TIMER ) {
828829 memset (&xboneReport.Header , 0 , sizeof (GipHeader_t));
829- xboneReport.Header .command = GIP_KEEPALIVE;
830- xboneReport.Header .internal = 1 ;
831- xboneReport.Header .sequence = keep_alive_sequence;
830+ GIP_HEADER ((&xboneReport), GIP_KEEPALIVE, 1 , keep_alive_sequence);
832831 xboneReport.Header .length = 4 ;
833832 static uint8_t keepAlive[] = { 0x80 , 0x00 , 0x00 , 0x00 };
834833 memcpy (&((uint8_t *)&xboneReport)[4 ], &keepAlive, sizeof (keepAlive));
@@ -844,64 +843,65 @@ XboxOneGamepad_Data_t *Gamepad::getXBOneReport()
844843 virtual_keycode_sequence++; // will rollover
845844 if ( virtual_keycode_sequence == 0 )
846845 virtual_keycode_sequence = 1 ;
847- memset (&xboneReport.Header , 0 , sizeof (GipHeader_t));
848- xboneReport.Header .command = GIP_VIRTUAL_KEYCODE;
849- xboneReport.Header .internal = 1 ;
850- xboneReport.Header .sequence = virtual_keycode_sequence;
846+ GIP_HEADER ((&xboneReport), GIP_VIRTUAL_KEYCODE, 1 , virtual_keycode_sequence);
847+ xboneReport.Header .length = sizeof (xb1_guide_on);
851848 if ( pressedA1 () ) {
852849 xb1_guide_pressed = true ;
853- xboneReport.Header .length = sizeof (xb1_guide_on);
854850 memcpy (&((uint8_t *)&xboneReport)[4 ], &xb1_guide_on, sizeof (xb1_guide_on));
855851 } else {
856852 xb1_guide_pressed = false ;
857- xboneReport.Header .length = sizeof (xb1_guide_off);
858853 memcpy (&((uint8_t *)&xboneReport)[4 ], &xb1_guide_off, sizeof (xb1_guide_off));
859854 }
860855 }
861856 xboneReportSize = sizeof (GipHeader_t) + sizeof (xb1_guide_on);
862857 return &xboneReport;
863858 }
864859
865- GIP_HEADER ((&xboneReport), GIP_INPUT_REPORT, false , last_report_counter);
866-
867- xboneReport.a = pressedB1 ();
868- xboneReport.b = pressedB2 ();
869- xboneReport.x = pressedB3 ();
870- xboneReport.y = pressedB4 ();
871- xboneReport.leftShoulder = pressedL1 ();
872- xboneReport.rightShoulder = pressedR1 ();
873- xboneReport.leftThumbClick = pressedL3 ();
874- xboneReport.rightThumbClick = pressedR3 ();
875- xboneReport.start = pressedS2 ();
876- xboneReport.back = pressedS1 ();
877- xboneReport.guide = 0 ; // always 0
878- xboneReport.sync = 0 ;
879- xboneReport.dpadUp = pressedUp ();
880- xboneReport.dpadDown = pressedDown ();
881- xboneReport.dpadLeft = pressedLeft ();
882- xboneReport.dpadRight = pressedRight ();
883-
884- xboneReport.leftStickX = static_cast <int16_t >(state.lx ) + INT16_MIN;
885- xboneReport.leftStickY = static_cast <int16_t >(~state.ly ) + INT16_MIN;
886- xboneReport.rightStickX = static_cast <int16_t >(state.rx ) + INT16_MIN;
887- xboneReport.rightStickY = static_cast <int16_t >(~state.ry ) + INT16_MIN;
860+ // Only change xbox one input report if we have different inputs!
861+ XboxOneGamepad_Data_t newInputReport;
862+
863+ // This is due to our tusb_driver.cpp checking memcmp(last_report, report, size)
864+ memset (&newInputReport, 0 , sizeof (XboxOneGamepad_Data_t));
865+ GIP_HEADER ((&newInputReport), GIP_INPUT_REPORT, false , last_report_counter);
866+
867+ newInputReport.a = pressedB1 ();
868+ newInputReport.b = pressedB2 ();
869+ newInputReport.x = pressedB3 ();
870+ newInputReport.y = pressedB4 ();
871+ newInputReport.leftShoulder = pressedL1 ();
872+ newInputReport.rightShoulder = pressedR1 ();
873+ newInputReport.leftThumbClick = pressedL3 ();
874+ newInputReport.rightThumbClick = pressedR3 ();
875+ newInputReport.start = pressedS2 ();
876+ newInputReport.back = pressedS1 ();
877+ newInputReport.guide = 0 ; // always 0
878+ newInputReport.sync = 0 ;
879+ newInputReport.dpadUp = pressedUp ();
880+ newInputReport.dpadDown = pressedDown ();
881+ newInputReport.dpadLeft = pressedLeft ();
882+ newInputReport.dpadRight = pressedRight ();
883+
884+ newInputReport.leftStickX = static_cast <int16_t >(state.lx ) + INT16_MIN;
885+ newInputReport.leftStickY = static_cast <int16_t >(~state.ly ) + INT16_MIN;
886+ newInputReport.rightStickX = static_cast <int16_t >(state.rx ) + INT16_MIN;
887+ newInputReport.rightStickY = static_cast <int16_t >(~state.ry ) + INT16_MIN;
888888
889889 if (hasAnalogTriggers)
890890 {
891- xboneReport .leftTrigger = pressedL2 () ? 0x03FF : state.lt ;
892- xboneReport .rightTrigger = pressedR2 () ? 0x03FF : state.rt ;
891+ newInputReport .leftTrigger = pressedL2 () ? 0x03FF : state.lt ;
892+ newInputReport .rightTrigger = pressedR2 () ? 0x03FF : state.rt ;
893893 }
894894 else
895895 {
896- xboneReport .leftTrigger = pressedL2 () ? 0x03FF : 0 ;
897- xboneReport .rightTrigger = pressedR2 () ? 0x03FF : 0 ;
896+ newInputReport .leftTrigger = pressedL2 () ? 0x03FF : 0 ;
897+ newInputReport .rightTrigger = pressedR2 () ? 0x03FF : 0 ;
898898 }
899899
900- xboneReportSize = sizeof (XboxOneGamepad_Data_t);
901-
902900 // We changed inputs since generating our last report, increment last report counter (but don't update until success)
903- if ( memcmp (&last_report[4 ], &((uint8_t *)&xboneReport)[4 ], xboneReportSize-4 ) != 0 ) {
904- xboneReport.Header .sequence = last_report_counter+1 ;
901+ if ( memcmp (&last_report[4 ], &((uint8_t *)&newInputReport)[4 ], sizeof (XboxOneGamepad_Data_t)-4 ) != 0 ) {
902+ xboneReportSize = sizeof (XboxOneGamepad_Data_t);
903+ memcpy (&xboneReport, &newInputReport, xboneReportSize);
904+ xboneReport.Header .sequence = (last_report_counter + 1 == 0 ) ? 1 : last_report_counter + 1 ;
905905 }
906906
907907 return &xboneReport;
0 commit comments