瀏覽代碼

more descriptive led

Jariullah Safi 4 月之前
父節點
當前提交
9ba61f6ed5
共有 5 個文件被更改,包括 33 次插入 和 25 次删除
  1. 7 3
      ARCHITECTURE.md
  2. 2 2
      OpenPuck/OpenPuck.ino
  3. 3 2
      OpenPuck/rf_link.cpp
  4. 10 9
      OpenPuck/status_led.cpp
  5. 11 9
      OpenPuck/status_led.h

+ 7 - 3
ARCHITECTURE.md

@@ -86,7 +86,7 @@ just points at the `OpenPuck` directory). Modules are layered low → high:
 | `webusb_config.{h,cpp}` | The WebUSB binary config channel for the browser panel. |
 | `serial_console.{h,cpp}` | The CDC single-letter debug command line. |
 | `wake_hid.{h,cpp}` | A boot-mouse HID interface added to the clean controller modes so the host honors USB remote-wakeup (see "Wake from sleep"). |
-| `status_led.{h,cpp}` | Wake-armed LED indicator: a short blip every ~2s while the host is suspended, dark otherwise. Drives both the Feather user LED (P1.15) and the SuperMini clone's blue LED (P0.15); pins/polarity overridable. |
+| `status_led.{h,cpp}` | Wake-sent LED indicator: dark in all steady states; flashes 500 ms at each `remoteWakeup()`. Drives both the Feather user LED (P1.15) and the SuperMini clone's blue LED (P0.15); pins/polarity overridable. |
 
 ## The controller abstraction
 
@@ -220,8 +220,12 @@ graze and nearly impossible to keep asleep. The only wake triggers are a **Steam
    because some hosts ignore a bare resume signal unless real keyboard/mouse input follows it; it can't be
    sent *during* suspend (reports can't cross a suspended bus), so it's delivered immediately after resume.
 
-The wake-armed state is visible on the board LED: a short blip every ~2 s while the host is suspended, dark in
-normal operation (`status_led.cpp`).
+The board LED is a wake debugger (`status_led.cpp`): dark in all steady states (including while armed), and a
+500 ms flash at the moment a `remoteWakeup()` is actually sent. Flash + host stays asleep = the resume was sent
+and the host ignored it (fix host-side, e.g. `powercfg /deviceenablewake`); no flash = the firmware never fired
+(it didn't see the gesture, or didn't consider the bus suspended). USB remote wakeup is a **device-level**
+signal — one wake line per device, armed by a single `SET_FEATURE(DEVICE_REMOTE_WAKEUP)`; there is no
+per-interface arming on the wire. Which Windows device *node* gets credited is host-internal policy.
 
 Every mode advertises the remote-wakeup capability in its config descriptor, so the device is always *armed*.
 The catch is that a host only *honors* a resume from an allow-listed input device class (HID keyboard/mouse) —

+ 2 - 2
OpenPuck/OpenPuck.ino

@@ -80,7 +80,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
+  if (USBDevice.suspended()){ USBDevice.remoteWakeup(); ledWakePulse(); }   // wake host if bus was sleeping when we (re-)attached
   loadBonds();
   hapticInit();   // clear relay/active flags + arm the reconnect block & initial stop burst
   static const char* MODE_NAME[]={"STEAM(puck)","XBOX(xinput+mouse)","SWITCH(horipad)","LIZARD(puck kb/mouse)","SWITCH(pro+gyro)","PS5(dualsense)","HIDGYRO(ds4+motion)"};
@@ -105,5 +105,5 @@ void loop() {
   rfDiagTask();                     // service whichever RF RE/calibration mode is active (no-op in normal use)
   rfLinkTask();                     // host-frame beacons + connected-mode poll (decodes input -> g_in -> active controller) + QoS + stats
   hapticTask();                     // reconnect-block edge handling + steam 0x82 quiet timeout
-  ledTask();                        // blip the LED while wake is armed (host suspended)
+  ledTask();                        // times out the 500ms wake-sent LED flash
 }

+ 3 - 2
OpenPuck/rf_link.cpp

@@ -5,6 +5,7 @@
 #include "triton.h"
 #include "haptics.h"
 #include "controllers.h"
+#include "status_led.h"
 #include <Adafruit_TinyUSB.h>
 #include <Arduino.h>
 #include <string.h>
@@ -154,7 +155,7 @@ uint8_t rfConnTx(uint8_t ch, uint8_t s1, const uint8_t* payload, uint8_t plen){
                 bool steamNow=(bb & TB_STEAM)!=0;
                 if(steamNow && !steamWasDown) steamDownMs=millis();                                                            // rising edge: record press time
                 if(!steamNow && steamWasDown && millis()-steamDownMs<1000u && USBDevice.suspended()){                          // falling edge within 1 s -> short press -> wake
-                  USBDevice.remoteWakeup();
+                  USBDevice.remoteWakeup(); ledWakePulse();
                   if(g_active) g_active->wakeEvent();   // queue the post-resume input nudge (space+click on puck modes)
                 }
                 steamWasDown=steamNow;
@@ -253,7 +254,7 @@ void rfLinkTask(){
   { 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();
+      USBDevice.remoteWakeup(); ledWakePulse();
       if(g_active) g_active->wakeEvent();   // queue the post-resume input nudge (space+click on puck modes)
     }
     wasRfConn=nowRfConn;

+ 10 - 9
OpenPuck/status_led.cpp

@@ -1,10 +1,11 @@
 #include "status_led.h"
-#include <Adafruit_TinyUSB.h>
 #include <Arduino.h>
 
 #define WAKE_LED_OFF ((WAKE_LED_ON)==HIGH ? LOW : HIGH)
-#define BLIP_PERIOD_MS 2000u   // one blip every 2s while wake-armed
-#define BLIP_ON_MS       60u   // ~3% duty: visible at a glance, not a bedroom nightlight
+#define PULSE_MS 500u   // wake flash duration
+
+static unsigned long g_pulseMs = 0;
+static bool g_lit = false;
 
 static void ledWrite(int level){
   digitalWrite(WAKE_LED_PIN_A, level);
@@ -17,11 +18,11 @@ void ledInit(){
   ledWrite(WAKE_LED_OFF);
 }
 
+void ledWakePulse(){
+  g_pulseMs = millis(); g_lit = true;
+  ledWrite(WAKE_LED_ON);   // light immediately at the remoteWakeup() call site, not on the next loop
+}
+
 void ledTask(){
-  static bool lit=false;
-  bool want=false;
-  if (USBDevice.suspended()){                       // wake-armed: blip BLIP_ON_MS out of every BLIP_PERIOD_MS
-    want = (millis() % BLIP_PERIOD_MS) < BLIP_ON_MS;
-  }
-  if (want != lit){ lit = want; ledWrite(lit ? WAKE_LED_ON : WAKE_LED_OFF); }   // write only on change
+  if (g_lit && millis()-g_pulseMs >= PULSE_MS){ g_lit = false; ledWrite(WAKE_LED_OFF); }
 }

+ 11 - 9
OpenPuck/status_led.h

@@ -1,10 +1,11 @@
-// status_led.h -- LED indication of the wake-armed state.
+// status_led.h -- LED indication of wake activity.
 //
-// When the host puts the bus in suspend (PC asleep) the device is "wake-armed": input forwarding is gated off
-// and only the explicit gestures (Steam-button short press / controller connect) will wake the host (see
-// "Wake from sleep" in ARCHITECTURE.md). That state was previously invisible -- you couldn't tell whether the
-// puck considered the host asleep. ledTask() makes it visible: a short LED blip every ~2s while wake is armed,
-// LED off otherwise (normal operation keeps the LED dark; the blip duty is ~3% so it won't light up a bedroom).
+// The LED is DARK in all steady states -- including while wake is armed (host suspended) -- and flashes for
+// half a second at the moment a wake is actually sent (USBDevice.remoteWakeup() fired by a Steam-button short
+// press, a controller connect, or the boot-time wake). This turns the LED into a wake debugger you can read
+// from the couch: flash + PC stays asleep = the resume signal was sent and the HOST ignored it (fix on the
+// host: powercfg /deviceenablewake); no flash = the firmware never fired (it didn't see the gesture, or it
+// didn't consider the bus suspended).
 //
 // Board note: the sketch is built with the Feather nRF52840 variant, but the usual hardware is a SuperMini
 // "Pro Micro" clone. The Feather's user LED is P1.15 (D3, active high); the SuperMini's blue user LED is
@@ -19,8 +20,9 @@
 #define WAKE_LED_PIN_B 24            // SuperMini "Pro Micro" clone: P0.15 blue user LED (D24 in the Feather map)
 #endif
 #ifndef WAKE_LED_ON
-#define WAKE_LED_ON HIGH             // set LOW if your board's LED is wired active-low (blip pattern inverts)
+#define WAKE_LED_ON HIGH             // set LOW if your board's LED is wired active-low
 #endif
 
-void ledInit();   // call once from setup(): pins to output, LED off
-void ledTask();   // call every loop(): blip while USBDevice.suspended(), dark otherwise
+void ledInit();        // call once from setup(): pins to output, LED off
+void ledWakePulse();   // call at each USBDevice.remoteWakeup() site: LED on now, off after 500ms
+void ledTask();        // call every loop(): times out the pulse