瀏覽代碼

feat: wake on Steam short press, RF connection, and mode change

copilot-swe-agent[bot] 4 月之前
父節點
當前提交
265b6699ca
共有 1 個文件被更改,包括 16 次插入 和 4 次删除
  1. 16 4
      OpenPuck/OpenPuck.ino

+ 16 - 4
OpenPuck/OpenPuck.ino

@@ -999,10 +999,16 @@ static uint8_t rfConnTx(uint8_t ch, uint8_t s1, const uint8_t* payload, uint8_t
             const uint8_t* rep=&rfrx[idx+2];            // report 0x45: [0x45][seq][buttons u32]...
             bool fresh=(rep[1]!=g_lastSeq); if(fresh){ g_stNew++; g_lastSeq=rep[1]; }  // genuine new report vs stale poll-repeat
             uint32_t bb=btnsOf(rep);
-            // USB remote wakeup: if the host is sleeping and the user presses any button, signal it to wake up.
-            // The host must have enabled remote wakeup (SET_FEATURE DEVICE_REMOTE_WAKEUP) for this to succeed;
-            // tud_remote_wakeup() is a no-op when not suspended, so it is always safe to call here.
-            if(fresh && bb && USBDevice.suspended()) USBDevice.remoteWakeup();
+            // USB remote wakeup on Steam button short press (down + up within 1 s).
+            // A long press likely means the user is powering off the controller, so we ignore it.
+            { static bool steamWasDown=false; static unsigned long steamDownMs=0;
+              if(fresh){
+                bool steamNow=(bb & TB_STEAM)!=0;
+                if(steamNow && !steamWasDown) steamDownMs=millis();                                                            // rising edge: record press time
+                if(!steamNow && steamWasDown && millis()-steamDownMs<1000u && USBDevice.suspended()) USBDevice.remoteWakeup(); // falling edge within 1 s -> short press -> wake
+                steamWasDown=steamNow;
+              }
+            }
             // cache the latest decoded frame for the Switch streamer + Xbox/Steam paths
             g_swBtns=bb; g_swLX=(int16_t)s16off(rep,8); g_swLY=(int16_t)s16off(rep,10);
             g_swRX=(int16_t)s16off(rep,12); g_swRY=(int16_t)s16off(rep,14);
@@ -1417,6 +1423,7 @@ void setup() {
   USBDevice.attach();   // re-connect with the final descriptor (host re-reads it fresh -> deterministic enumeration)
   Serial.begin(115200);
   for (int i=0; i<300 && !USBDevice.mounted(); i++) delay(10);   // wait up to 3s for USB mount, but NEVER hang:
+  if (USBDevice.suspended()) USBDevice.remoteWakeup();             // wake host if bus was sleeping when we (re-)attached (e.g. after a mode change)
   loadBonds();                                                   // if a mode fails to enumerate, still run loop() so RF + the back-paddle mode chord keep working (can always switch back)
   Serial.printf("# copycat up: unit=%s board=%s, mode=%s\n", g_unit, g_board, g_usbMode==1?"XBOX(controller+mouse)":g_usbMode==2?"SWITCH(pro controller)":"STEAM(puck; auto-lizard when Steam closed)");
   // Hardware watchdog: if loop() ever stops feeding it (a wedged radio busy-wait, a HardFault spin, a blocked
@@ -1460,6 +1467,11 @@ void loop() {
     if (millis()-g_lastDisc >= (connNow ? 200u : 0u)) { g_lastDisc=millis(); g_rfCh=2; for (int s=0;s<NSLOT;s++) rfHostFrameOnce(s); }
   }
   if (g_connOn && millis()-g_connCooldown > 2500) { rfConnStep(); }            // connected-mode: poll controller, read input
+  { static bool wasRfConn=false;                                               // remote wakeup on new RF controller connection
+    bool nowRfConn=(g_connSlot>=0 && millis()-g_connReplyMs<300);
+    if(nowRfConn && !wasRfConn && USBDevice.suspended()) USBDevice.remoteWakeup();
+    wasRfConn=nowRfConn;
+  }
   { static bool wasHapticLinkUp=false;
     bool up=hapticLinkUp();
     if(up && !wasHapticLinkUp){ g_hapticBlockUntil = millis() + HAPTIC_RECONNECT_BLOCK_MS; g_hapticStop=4; }   // reconnect: drop Steam's stale startup haptics AND clear any haptic that latched on the controller before/across the switch (the "whine until Steam button" on entering Steam mode)