Jariullah Safi il y a 4 mois
Parent
commit
22277e16cf
4 fichiers modifiés avec 60 ajouts et 0 suppressions
  1. 4 0
      ARCHITECTURE.md
  2. 3 0
      OpenPuck/OpenPuck.ino
  3. 27 0
      OpenPuck/status_led.cpp
  4. 26 0
      OpenPuck/status_led.h

+ 4 - 0
ARCHITECTURE.md

@@ -86,6 +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. |
 
 ## The controller abstraction
 
@@ -219,6 +220,9 @@ 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`).
+
 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) —
 a bare gamepad/vendor/composite presentation gets armed but ignored (notably Windows under Modern Standby).

+ 3 - 0
OpenPuck/OpenPuck.ino

@@ -30,6 +30,7 @@ using namespace Adafruit_LittleFS_Namespace;
 #include "webusb_config.h"
 #include "serial_console.h"
 #include "wake_hid.h"
+#include "status_led.h"
 
 #if CFG_TUD_HID < 4
 #error "build with -DCFG_TUD_HID=4 (extra_flags): up to 4 HID interfaces per mode"
@@ -39,6 +40,7 @@ static uint8_t g_usbCfgDesc[512];   // puck composite (4 HID + WebUSB) exceeds t
 
 void setup() {
   genSerial();
+  ledInit();
   rfGenSessionAddr();   // per-device unique RF session address (advertised in the host frame; isolates pucks)
   InternalFS.begin();
   loadCfg(); g_xbox = !modeIsPuck(g_usbMode);   // load persisted config + decide USB presentation BEFORE registering interfaces
@@ -103,4 +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)
 }

+ 27 - 0
OpenPuck/status_led.cpp

@@ -0,0 +1,27 @@
+#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
+
+static void ledWrite(int level){
+  digitalWrite(WAKE_LED_PIN_A, level);
+  digitalWrite(WAKE_LED_PIN_B, level);
+}
+
+void ledInit(){
+  pinMode(WAKE_LED_PIN_A, OUTPUT);
+  pinMode(WAKE_LED_PIN_B, OUTPUT);
+  ledWrite(WAKE_LED_OFF);
+}
+
+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
+}

+ 26 - 0
OpenPuck/status_led.h

@@ -0,0 +1,26 @@
+// status_led.h -- LED indication of the wake-armed state.
+//
+// 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).
+//
+// 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
+// P0.15 (= D24 in the Feather pin map -- SPI MISO, unused by this project). We drive BOTH pins so the
+// indicator works on either board. Override the pins/polarity below if your board differs.
+#pragma once
+
+#ifndef WAKE_LED_PIN_A
+#define WAKE_LED_PIN_A LED_BUILTIN   // Feather: P1.15 user LED (harmless unconnected pad on SuperMini clones)
+#endif
+#ifndef WAKE_LED_PIN_B
+#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)
+#endif
+
+void ledInit();   // call once from setup(): pins to output, LED off
+void ledTask();   // call every loop(): blip while USBDevice.suspended(), dark otherwise