Forráskód Böngészése

Fix relay/poll PID collision halving F1 rate in Steam mode

g_relayPid and g_pollPid both started at 0 and incremented once per
cycle, so they were always equal. When a relay fired, the controller
saw the same 2-bit PID on the relay and the E3 GET that followed and
silently dropped the GET as a duplicate — no F1 reply was sent.

This halved the Delivered rate to ~120 Hz in Steam mode (where the
relay queue is frequently non-empty due to continuous 0x87 keepalives
and haptic commands) while other modes looked fine.

Fix: initialise g_relayPid[4] to {2,2,2,2} so relay PID is always
(pollPid+2) mod 4. Both counters still increment once per cycle, so
they stay 2 apart forever and never collide.

Update the comment in haptics.h to describe this invariant.
copilot-swe-agent[bot] 3 hónapja
szülő
commit
f3142c6ef6
2 módosított fájl, 8 hozzáadás és 3 törlés
  1. 3 2
      OpenPuck/haptics.h
  2. 5 1
      OpenPuck/rf_link.cpp

+ 3 - 2
OpenPuck/haptics.h

@@ -121,8 +121,9 @@ void haptic82HostReport(const uint8_t *p, uint16_t n);
 bool hapticSteamRumble(uint16_t lowFreq, uint16_t highFreq, uint8_t slot = 0);
 
 // queue + flush the pending host/test/stop relay inside the poll cadence (called from rf_link).
-// rfConnFlushRelay's s1 must carry a PID distinct from the GET poll that follows it (rf_link cycles the shared
-// PID counter), so the controller doesn't dedup the GET as a retransmit of the relay.
+// rfConnFlushRelay's s1 must carry a PID distinct from the GET poll that follows it. g_relayPid
+// is initialised 2 ahead of g_pollPid and both increment once per cycle, so the 2-bit PIDs stay
+// 2 apart (mod 4) forever and never collide — keeping the controller from deduplicating the GET.
 // Stability test: when g_stabTest (WebUSB cmd 0x0F), buzz all controllers every 10s to keep them awake for an
 // unattended uptime-until-hang measurement. hapticStabTask() is called from loop().
 extern bool g_stabTest;

+ 5 - 1
OpenPuck/rf_link.cpp

@@ -108,7 +108,11 @@ int g_curSlot = -1;
 // +4 per cycle = 0 mod 4, so each slot's GET PID is constant => the controller never dequeues => ~60 new/s
 // instead of ~400. Each slot's counter increments once per poll-of-that-slot so it cycles 0,1,2,3 cleanly.
 static uint8_t g_pollPid[NSLOT] = {};
-static uint8_t g_relayPid[NSLOT] = {};
+// Relay PID is offset by 2 from poll PID so the two never share the same
+// 2-bit PID value in the same cycle. Both counters advance once per cycle;
+// starting 2 apart keeps them 2 apart (mod 4) forever, preventing the
+// controller from deduplicating the E3 GET as a retransmit of the relay.
+static uint8_t g_relayPid[NSLOT] = { 2, 2, 2, 2 };
 // All link statistics are PER SLOT: each controller's polls/replies/errors are counted (and reported --
 // serial stat line, WebUSB blob v13) against that controller only. The old scalar counters merged every
 // slot into one number, so the panel couldn't tell "controller B is drowning" from "everything is slow".