From f1fbf9ddca72a388e70791e03e1b08c0b3455e02 Mon Sep 17 00:00:00 2001 From: Karel Tucek Date: Fri, 9 Jan 2026 16:14:46 +0100 Subject: [PATCH] Implement short wake in nohost light sleep condition. --- device/src/device_state.c | 2 +- right/src/event_scheduler.c | 2 +- right/src/event_scheduler.h | 2 +- right/src/power_mode.c | 27 +++++++++++++++++++++------ right/src/usb_report_updater.c | 1 + 5 files changed, 25 insertions(+), 9 deletions(-) diff --git a/device/src/device_state.c b/device/src/device_state.c index 71ada44ab..442d208d1 100644 --- a/device/src/device_state.c +++ b/device/src/device_state.c @@ -64,7 +64,7 @@ void handleStateTransition(connection_target_t remote, connection_id_t connectio #if DEVICE_HAS_OLED Widget_Refresh(&TargetWidget); #endif - EventScheduler_Reschedule(Timer_GetCurrentTime() + POWER_MODE_UPDATE_DELAY, EventSchedulerEvent_PowerMode, "update sleep mode from device state"); + EventScheduler_Reschedule(Timer_GetCurrentTime() + POWER_MODE_UPDATE_DELAY, EventSchedulerEvent_PowerModeUpdate, "update sleep mode from device state"); break; default: break; diff --git a/right/src/event_scheduler.c b/right/src/event_scheduler.c index cca1f2376..2d1fe8470 100644 --- a/right/src/event_scheduler.c +++ b/right/src/event_scheduler.c @@ -108,7 +108,7 @@ static void processEvt(event_scheduler_event_t evt) case EventSchedulerEvent_UpdateMergeSensor: MergeSensor_Update(); break; - case EventSchedulerEvent_PowerMode: + case EventSchedulerEvent_PowerModeUpdate: PowerMode_Update(); break; case EventSchedulerEvent_PowerModeRestart: diff --git a/right/src/event_scheduler.h b/right/src/event_scheduler.h index 1ffb48f85..73100485c 100644 --- a/right/src/event_scheduler.h +++ b/right/src/event_scheduler.h @@ -33,7 +33,7 @@ EventSchedulerEvent_MouseController, EventSchedulerEvent_ReenableUart, EventSchedulerEvent_UpdateMergeSensor, - EventSchedulerEvent_PowerMode, + EventSchedulerEvent_PowerModeUpdate, EventSchedulerEvent_PowerModeRestart, EventSchedulerEvent_EndBtPairing, EventSchedulerEvent_RestartBt, diff --git a/right/src/power_mode.c b/right/src/power_mode.c index 69c9671ad..a6e89486d 100644 --- a/right/src/power_mode.c +++ b/right/src/power_mode.c @@ -1,4 +1,5 @@ #include "power_mode.h" +#include "timer.h" #include "usb_composite_device.h" #include "event_scheduler.h" #include "led_manager.h" @@ -59,14 +60,18 @@ power_mode_config_t PowerModeConfig[PowerMode_Count] = { ATTR_UNUSED static bool usbAwake = false; +static uint32_t lastWakeEvent = 0; + volatile power_mode_t CurrentPowerMode = PowerMode_Awake; +#define LIGHT_SLEEP_NOHOST_WAKEUP_LENGTH 10000 + // originally written for Benedek's power callback // TODO: remove this and simplify the rest of the code if the callback is not used. void PowerMode_SetUsbAwake(bool awake) { #if DEVICE_IS_UHK80_RIGHT usbAwake = awake; - EventScheduler_Reschedule(Timer_GetCurrentTime() + POWER_MODE_UPDATE_DELAY, EventSchedulerEvent_PowerMode, "update sleep mode from power callback"); + EventScheduler_Reschedule(Timer_GetCurrentTime() + POWER_MODE_UPDATE_DELAY, EventSchedulerEvent_PowerModeUpdate, "update sleep mode from power callback"); #endif } @@ -85,12 +90,19 @@ void PowerMode_Update() { power_mode_t newPowerMode = someoneAwake ? PowerMode_Awake : PowerMode_LightSleep; - if (newPowerMode == someoneAwake) { - newPowerMode = RunningOnBattery ? PowerMode_Powersaving : PowerMode_Awake; - } - if (CurrentPowerMode <= PowerMode_LightSleep) { - PowerMode_ActivateMode(newPowerMode, false, false, "power mode update"); + if (newPowerMode <= PowerMode_Powersaving) { + PowerMode_ActivateMode(newPowerMode, false, false, "power mode update"); + return; + } + + if (newPowerMode == PowerMode_LightSleep && CurrentPowerMode < PowerMode_LightSleep) { + if (Timer_GetCurrentTime() - lastWakeEvent >= LIGHT_SLEEP_NOHOST_WAKEUP_LENGTH) { + PowerMode_ActivateMode(newPowerMode, false, false, "power mode update"); + } else { + EventScheduler_Schedule(lastWakeEvent + LIGHT_SLEEP_NOHOST_WAKEUP_LENGTH, EventSchedulerEvent_PowerModeUpdate, "no host short wakeup"); + } + } } } @@ -125,8 +137,11 @@ static void shutDown(power_mode_t mode) { } static void wake() { + lastWakeEvent = Timer_GetCurrentTime(); + EventScheduler_Schedule(lastWakeEvent + LIGHT_SLEEP_NOHOST_WAKEUP_LENGTH, EventSchedulerEvent_PowerModeUpdate, "waked - check for short wake condition"); CurrentPowerMode = PowerMode_Awake; notifyEveryone(); + } void PowerMode_ActivateMode(power_mode_t mode, bool toggle, bool force, const char* reason) { diff --git a/right/src/usb_report_updater.c b/right/src/usb_report_updater.c index 28ff044ea..0494aaea4 100644 --- a/right/src/usb_report_updater.c +++ b/right/src/usb_report_updater.c @@ -682,6 +682,7 @@ static void updateActionStates() { if (CurrentPowerMode > PowerMode_LastAwake && CurrentPowerMode <= PowerMode_LightSleep) { Trace_Printf("y1.%d", CurrentPowerMode); PowerMode_WakeHost(); + PowerMode_ActivateMode(PowerMode_Awake, false, true, "key action wakeup"); Trace_Printc("y4"); }