diff --git a/README.md b/README.md index 9583dbb..234658c 100644 --- a/README.md +++ b/README.md @@ -166,9 +166,10 @@ therefore intentionally a configurable command key, not the second Mic switch. On battery, the display dims after two minutes and enters desk sleep after five minutes. Dock Mode is detected from USB input power and extends those intervals -to ten and thirty minutes. The default wireless image turns off the shared -AMOLED/audio/motor rail during desk sleep while keeping BLE alive; the optional -USB-mic image keeps its audio rail on and uses brightness-only desk sleep. +to ten and thirty minutes. Both images use brightness-only desk sleep and keep +the shared AMOLED/audio/motor rail powered so a touch or button can restore the +display reliably while BLE remains online. This uses more standby power than +cutting the shared rail. Travel Mode is a real PM1 shutdown, so Agent alerts are missed until the power button or USB power starts the device again. The red-button double-click uses a firmware-confirmed clean shutdown instead of PM1's immediate hardware cut; a diff --git a/README.zh-CN.md b/README.zh-CN.md index b196e0e..17b52e5 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -143,9 +143,9 @@ Codex 会完成终端工作,但 macOS 仍可能要求用户亲自: 而不是第二个 Mic switch。 电池供电时,屏幕会在两分钟后变暗、五分钟后进入桌面休眠;接入 USB 电源后会 -自动进入 Dock Mode,并把这两个时间延长到十分钟和三十分钟。默认无线固件会在 -桌面休眠时关闭 AMOLED/音频/马达共用电源轨,但保持 BLE 在线;可选 USB 麦克风 -固件为了继续录音,会保持共用电源轨开启,并使用亮度归零式桌面休眠。旅行模式使用 +自动进入 Dock Mode,并把这两个时间延长到十分钟和三十分钟。两种固件都使用 +亮度归零式桌面休眠,并保持 AMOLED/音频/马达共用电源轨开启,使触屏或按键可以 +可靠地恢复显示,同时保持 BLE 在线;代价是待机功耗高于切断共用电源轨。旅行模式使用 PM1 真关机,因此在 按电源键或接入 USB 重新启动前,设备会错过 Agent 在线提醒。红键双击由固件先 显示关机提示并释放 HID,再请求 PM1 关机;长按红色电源键仍保留为硬件恢复 / diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index 975bba7..304a2db 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -63,24 +63,25 @@ promote the link to `CODEX LIVE`. ## Power lifecycle -The default wireless image has four display/power states: +Both firmware images have four display/power states: 1. active; 2. dimmed; -3. desk sleep, with the CO5300 put to sleep and the shared AMOLED/audio/motor - L3B rail disabled while the ESP32 and BLE continue running; +3. desk sleep, with display brightness set to zero while the CO5300 and shared + AMOLED/audio/motor L3B rail remain powered alongside the ESP32 and BLE; 4. Travel Mode, using M5PM1 shutdown so BLE and Agent alerts stop completely. The pinned M5GFX framebuffer wrapper did not forward physical AMOLED sleep or -repeat initialization. `scripts/patch_m5gfx_amoled_sleep.py` applies a narrow, -checked build-time patch so the controller is put to sleep before G8 is cut and -can replay its initialization sequence after G8/G5 power-reset recovery. +repeat initialization. `scripts/patch_m5gfx_amoled_sleep.py` still applies a +narrow, checked build-time patch so recovery experiments can replay the panel +initialization sequence, but normal desk sleep does not enter that path. USB input voltage selects Dock Mode: battery policy dims/sleeps after 2/5 -minutes, while Dock Mode uses 10/30 minutes. The optional USB-mic image cannot -remove L3B without also losing its microphone, so it keeps the rail on and uses -brightness-only desk sleep. A short red-power-button click toggles desk sleep; a -fast double-click runs the clean Travel shutdown path. The firmware disables +minutes, while Dock Mode uses 10/30 minutes. Both images keep L3B powered and +use brightness-only desk sleep. Physical C152 testing showed that cutting and +restoring the rail could leave the display black even though BLE, touch, and +buttons were awake. A short red-power-button click toggles desk sleep; a fast +double-click runs the clean Travel shutdown path. The firmware disables PM1's immediate double-click cut so it can release HID controls and show the offline warning first. A six-second center-dial hold provides a slower fallback. The red button's hardware long-hold download path remains available for @@ -96,5 +97,7 @@ insertion for cold wake; no IMU or scheduled RTC wake is configured. connected. - Companion stops updating; the UI marks data stale after three minutes. - Reset countdown reaches zero before a refreshed snapshot arrives. +- Brightness-only desk sleep uses more standby power than cutting L3B, but + avoids the observed black-display wake failure. - A future M5GFX source change no longer matches the checked AMOLED patch; the - build fails instead of silently producing brightness-only sleep. + build fails instead of silently dropping the recovery support. diff --git a/docs/PORTING.md b/docs/PORTING.md index 3c29f6e..7cf8180 100644 --- a/docs/PORTING.md +++ b/docs/PORTING.md @@ -41,12 +41,12 @@ 11. Only then connect the companion to the live App Server rate-limit feed. 12. Verify the battery percentage, charging bolt, Dock color, and all four health combinations, including `CODEX LIVE` together with `SYNC STALE`. -13. On battery, short-click the red button for desk sleep. Confirm AMOLED, - speaker, and motor power are off while a real Agent completion still wakes - the display and plays the chime. In the USB-mic image, verify that an - active host capture skips the chime without interrupting audio, while an - idle host permits the local chime and restores microphone capture. Repeat - at least 100 sleep/wake cycles. +13. On battery, short-click the red button for desk sleep. Confirm the screen is + black while BLE remains connected, then verify touch and red-button wake + both restore the display. Record the higher brightness-only standby draw. + In the USB-mic image, verify that an active host capture skips the chime + without interrupting audio, while an idle host permits the local chime and + restores microphone capture. Repeat at least 100 sleep/wake cycles. 14. With USB power attached, confirm Dock Mode uses the longer idle policy and a full battery still remains in Dock Mode even when not actively charging. 15. Unplug USB and rapidly double-click the red power button. Confirm the diff --git a/docs/TECHNICAL.md b/docs/TECHNICAL.md index f7d74eb..e746f15 100644 --- a/docs/TECHNICAL.md +++ b/docs/TECHNICAL.md @@ -76,12 +76,15 @@ every two seconds. Dock detection uses two consecutive samples with 4.0 V entry and 3.5 V exit thresholds, rather than charge state, because a full battery may stop charging while USB power remains present. -On the default image, desk sleep sends CO5300 Sleep In, releases QSPI, disables -physical M5IOE1 G8 (zero-based expander pin 7), and leaves BLE polling active. -Wake restores G8, pulses physical G5 (zero-based pin 4), and replays the pinned -panel initialization through the existing framebuffer. The build-time M5GFX -patch is exact-match and idempotent. Travel Mode releases held HID controls, -shows an offline warning, stops local feedback, and issues `M5PM1::shutdown()`. +On both images, desk sleep sets display brightness to zero while leaving the +CO5300 and physical M5IOE1 G8 (zero-based expander pin 7) powered, and BLE +polling remains active. Physical C152 validation showed that this path restores +the display on a touch or button wake; the earlier G8-off recovery could leave +the panel black even though inputs and BLE were already awake. The build-time +M5GFX patch remains exact-match and idempotent for recovery experiments. This +brightness-only policy consumes more standby power. Travel Mode releases held +HID controls, shows an offline warning, stops local feedback, and issues +`M5PM1::shutdown()`. It is normally triggered by a firmware-detected red-button double-click. PM1's immediate hardware double-off is disabled and read back at boot so the clean path runs first. A six-second center-dial hold is the fallback; red-button long diff --git a/src/main.cpp b/src/main.cpp index 3ecc38f..1f3c285 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -49,18 +49,14 @@ constexpr uint32_t kPowerButtonDoubleClickMs = 500; constexpr uint8_t kActiveBrightness = 120; constexpr uint8_t kDimBrightness = 24; // M5Unified's IOExpander_Base API is zero-based: physical M5IOE1 G8 is 7, -// while physical G5 is 4. +// while physical G5 is 4. Physical C152 testing showed that powering the +// AMOLED rail back up can leave the panel black while the ESP32, BLE, touch, +// and buttons are already awake. Keep the stable desk-sleep path +// brightness-only; the panel power helpers remain available for recovery work. constexpr uint8_t kIoeSharedL3bEnable = 7; constexpr uint8_t kIoePanelReset = 4; -#if defined(CODEX_STOPWATCH_USB_MIC) -// G8 powers the shared L3B rail, including the microphone path. The optional -// USB-mic image therefore keeps G8 on and uses brightness-only desk sleep. +constexpr bool kSleepPanelControllerInDeskSleep = false; constexpr bool kCutSharedRailInDeskSleep = false; -#else -// The default wireless image can remove the AMOLED/audio/motor L3B rail while -// leaving the ESP32, touch controller, PM1, and BLE transport alive. -constexpr bool kCutSharedRailInDeskSleep = true; -#endif #if !defined(CODEX_STOPWATCH_USB_MIC) constexpr uint32_t kCompletionChimeSampleRate = 12000; constexpr uint32_t kCompletionChimeDurationMs = 270; @@ -164,13 +160,10 @@ void enterDeskSleep() { if (speakerSuspended) M5.Speaker.end(); #endif M5.Display.setBrightness(0); -#if !defined(CODEX_STOPWATCH_USB_MIC) - // The USB microphone build keeps the shared AMOLED/audio rail powered and - // uses brightness-only desk sleep. The CO5300 Sleep Out path through the - // framebuffer wrapper is not reliable enough on C152 to use while docked. - M5.Display.sleep(); - M5.Display.waitDisplay(); -#endif + if (kSleepPanelControllerInDeskSleep) { + M5.Display.sleep(); + M5.Display.waitDisplay(); + } if (kCutSharedRailInDeskSleep) { // The repository-owned M5GFX patch forwards sleep to the physical AMOLED // and allows a repeat controller init while preserving its framebuffer. @@ -201,11 +194,9 @@ void wakeDeskSleep() { } displayRailOff = false; } -#if !defined(CODEX_STOPWATCH_USB_MIC) - else { + else if (kSleepPanelControllerInDeskSleep) { M5.Display.wakeup(); } -#endif M5.Display.setRotation(0); M5.Display.setTextWrap(false); appliedBrightness = kActiveBrightness;