Sfoglia il codice sorgente

attempt to fix haptics regression

Jariullah Safi 4 mesi fa
parent
commit
290a39e16d
3 ha cambiato i file con 9 aggiunte e 14 eliminazioni
  1. 1 1
      OpenPuck/haptics.cpp
  2. 0 1
      OpenPuck/haptics.h
  3. 8 12
      OpenPuck/puck_hid.cpp

+ 1 - 1
OpenPuck/haptics.cpp

@@ -48,7 +48,7 @@ bool haptic82Blocked(){
 bool hapticRelaySlotOk(int slot){
 bool hapticRelaySlotOk(int slot){
   return g_connSlot>=0 && slot==g_connSlot;
   return g_connSlot>=0 && slot==g_connSlot;
 }
 }
-bool haptic82PayloadOn(const uint8_t* p, uint16_t n){
+static bool haptic82PayloadOn(const uint8_t* p, uint16_t n){
   if(n<3) return false;
   if(n<3) return false;
   for(uint16_t i=2;i<n;i++) if(p[i]) return true;   // observed form is [01 01 gain], but treat any trailing non-zero as active
   for(uint16_t i=2;i<n;i++) if(p[i]) return true;   // observed form is [01 01 gain], but treat any trailing non-zero as active
   return false;
   return false;

+ 0 - 1
OpenPuck/haptics.h

@@ -33,7 +33,6 @@ void hapticDumpLog();   // 'H' console dump of the recent OUTPUT-report history
 bool hapticLinkUp();
 bool hapticLinkUp();
 bool haptic82Blocked();
 bool haptic82Blocked();
 bool hapticRelaySlotOk(int slot);
 bool hapticRelaySlotOk(int slot);
-bool haptic82PayloadOn(const uint8_t* p, uint16_t n);   // true = haptic ON (nonzero gain); false = a STOP/OFF frame
 void haptic82HostReport(const uint8_t* p, uint16_t n);
 void haptic82HostReport(const uint8_t* p, uint16_t n);
 
 
 // queue + flush the pending host/test/stop relay inside the poll cadence (called from rf_link)
 // queue + flush the pending host/test/stop relay inside the poll cadence (called from rf_link)

+ 8 - 12
OpenPuck/puck_hid.cpp

@@ -48,11 +48,12 @@ static Adafruit_USBD_HID hid[NSLOT];
 // and ANY OUTPUT report likewise stamps g_steamAliveMs. When the heartbeat stops we fall back to lizard, so the
 // and ANY OUTPUT report likewise stamps g_steamAliveMs. When the heartbeat stops we fall back to lizard, so the
 // controller drives desktop keyboard+mouse whenever Steam isn't running. MODE_LIZARD forces lizard always.
 // controller drives desktop keyboard+mouse whenever Steam isn't running. MODE_LIZARD forces lizard always.
 static unsigned long g_steamAliveMs = 0;   // millis of last Steam OUTPUT/settings write; 0 at boot => lizard until Steam appears
 static unsigned long g_steamAliveMs = 0;   // millis of last Steam OUTPUT/settings write; 0 at boot => lizard until Steam appears
-// Fall back to lizard this long after Steam's ~3s settings heartbeat stops. 4s is just above the cadence ->
-// near-minimal switch delay when Steam quits, without flipping to lizard in the gaps while Steam runs. This used
-// to need 7s padding because a jittered heartbeat tripping lizard mid-haptic would gate out the haptic STOP and
-// strand a buzz -- but the relay now ALWAYS lets a STOP through (see handleSet), so that risk is gone.
-#define LIZARD_WD_MS 4000u
+// Fall back to lizard this long after Steam's ~3s settings heartbeat stops. Keep >2x the cadence (7s): the
+// haptic relay is gated by !lizardActive(), so a shorter window lets a single jittered/delayed heartbeat flip
+// lizard mid-session while Steam is still running -> a haptic that arrives in that window gets gated out
+// (dropped/missing haptic). 7s tolerates one missed beat. (This matches main; do not shorten without a lizard
+// trigger that doesn't depend on the heartbeat timeout.)
+#define LIZARD_WD_MS 7000u
 static bool g_autoLizard = true;            // master switch; false => Steam mode always forwards 0x45
 static bool g_autoLizard = true;            // master switch; false => Steam mode always forwards 0x45
 // Single source of truth, shared by the USB input path AND the haptic relay gate: if we ever relay a 0x82 to
 // Single source of truth, shared by the USB input path AND the haptic relay gate: if we ever relay a 0x82 to
 // the controller while presenting lizard (Steam isn't reading 0x45 back), Steam loops the same haptic -> buzz.
 // the controller while presenting lizard (Steam isn't reading 0x45 back), Steam loops the same haptic -> buzz.
@@ -81,11 +82,7 @@ static void handleSet(int slot, uint8_t rid, hid_report_type_t type, uint8_t con
                                    // driving -> leave lizard for gamepad NOW, so a haptic that arrives before the
                                    // driving -> leave lizard for gamepad NOW, so a haptic that arrives before the
                                    // first 0x87 doesn't get relayed while we're still presenting lizard (-> buzz loop).
                                    // first 0x87 doesn't get relayed while we're still presenting lizard (-> buzz loop).
     }
     }
-    // A haptic STOP (0x82 with all-zero payload) is ALWAYS allowed through, even while presenting lizard -- it
-    // can only CLEAR a buzz, never start one. This decouples the lizard delay from stuck haptics: if a jittered
-    // heartbeat flips lizard mid-haptic, the OFF still reaches the controller instead of being gated out.
-    bool isHapStop = (rid == 0x82 && !haptic82PayloadOn(b, n));
-    if (rid >= 0x80 && rid <= 0x86 && n >= 1 && hapticRelaySlotOk(slot) && (!lizardActive() || isHapStop)) {  // wrap as a SET sub-TLV like the report-01 path
+    if (rid >= 0x80 && rid <= 0x86 && n >= 1 && hapticRelaySlotOk(slot) && !lizardActive()) {  // wrap as a SET sub-TLV like the report-01 path
       if (!haptic82Blocked()) {
       if (!haptic82Blocked()) {
         uint8_t m = n > (uint16_t)(sizeof g_relayBuf - 2) ? (sizeof g_relayBuf - 2) : n;
         uint8_t m = n > (uint16_t)(sizeof g_relayBuf - 2) ? (sizeof g_relayBuf - 2) : n;
         g_relayBuf[0] = rid; g_relayBuf[1] = m; memcpy(g_relayBuf + 2, b, m);
         g_relayBuf[0] = rid; g_relayBuf[1] = m; memcpy(g_relayBuf + 2, b, m);
@@ -108,8 +105,7 @@ static void handleSet(int slot, uint8_t rid, hid_report_type_t type, uint8_t con
   if (rid == 1 && n >= 2) {   // report 0x01 = raw passthrough -> queue for RF relay to the controller
   if (rid == 1 && n >= 2) {   // report 0x01 = raw passthrough -> queue for RF relay to the controller
     if (cmd >= 0x80 && cmd <= 0x89) hapLogAdd((uint8_t)slot, cmd, b, n);   // capture feature-passthrough haptics/LED too (rid shown = cmd; bytes start [cmd][len]...)
     if (cmd >= 0x80 && cmd <= 0x89) hapLogAdd((uint8_t)slot, cmd, b, n);   // capture feature-passthrough haptics/LED too (rid shown = cmd; bytes start [cmd][len]...)
     bool haptic82 = (cmd == 0x82 && len <= pln);
     bool haptic82 = (cmd == 0x82 && len <= pln);
-    bool haptic82On = haptic82 && haptic82PayloadOn(pl, len);   // ON has nonzero gain; a STOP/OFF does not
-    bool relayOk = hapticRelaySlotOk(slot) && !(haptic82On && lizardActive());  // block only haptic-ON in lizard (would buzz-loop); always let the STOP through so a buzz can be cleared
+    bool relayOk = hapticRelaySlotOk(slot) && !(haptic82 && lizardActive());  // never push haptics to the controller while presenting lizard (Steam isn't reading 0x45 -> would buzz-loop)
     if (relayOk && (!haptic82 || !haptic82Blocked())) {
     if (relayOk && (!haptic82 || !haptic82Blocked())) {
       uint16_t m = n > sizeof g_relayBuf ? sizeof g_relayBuf : n;
       uint16_t m = n > sizeof g_relayBuf ? sizeof g_relayBuf : n;
       memcpy(g_relayBuf, b, m); g_relayN = m; g_relayPend = true;
       memcpy(g_relayBuf, b, m); g_relayN = m; g_relayPend = true;