From 310ea81eec3bd35e13718dd85e578048ce20eb47 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Tue, 21 Feb 2023 23:30:43 +0200 Subject: [PATCH] inactivity: Use LVGL inactivity timers Replace custom FreeRTOS inactivity timers with LVGL inactivity timers. DisplayApp: Trigger display activity on timer done. inactivity: Add additional checks The backlight could be turned on by RestoreBrightness() on ble connect event. inactivity: Trigger activity on screen switch A notification timing out could put the watch to sleep immediately. While this could be ideal behaviour, it was caused by delay in processing the EnableSleeping event and pushing RestoreBrightness to DisplayApp. --- src/displayapp/DisplayApp.cpp | 47 +++++++++++-- src/displayapp/DisplayApp.h | 2 + src/displayapp/Messages.h | 1 - .../screens/settings/SettingDisplay.cpp | 1 - src/systemtask/Messages.h | 1 - src/systemtask/SystemTask.cpp | 68 ++----------------- src/systemtask/SystemTask.h | 8 +-- 7 files changed, 52 insertions(+), 76 deletions(-) diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index ccba7ee6..2aa828bb 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -155,6 +155,29 @@ void DisplayApp::Refresh() { LoadScreen(returnAppStack.Pop(), returnDirection); }; + auto DimScreen = [this]() { + if (brightnessController.Level() != Controllers::BrightnessController::Levels::Off) { + isDimmed = true; + brightnessController.Set(Controllers::BrightnessController::Levels::Low); + } + }; + + auto RestoreBrightness = [this]() { + if (brightnessController.Level() != Controllers::BrightnessController::Levels::Off) { + isDimmed = false; + lv_disp_trig_activity(nullptr); + ApplyBrightness(); + } + }; + + auto IsPastDimTime = [this]() -> bool { + return lv_disp_get_inactive_time(nullptr) >= pdMS_TO_TICKS(settingsController.GetScreenTimeOut() - 2000); + }; + + auto IsPastSleepTime = [this]() -> bool { + return lv_disp_get_inactive_time(nullptr) >= pdMS_TO_TICKS(settingsController.GetScreenTimeOut()); + }; + TickType_t queueTimeout; switch (state) { case States::Idle: @@ -165,6 +188,18 @@ void DisplayApp::Refresh() { LoadPreviousScreen(); } queueTimeout = lv_task_handler(); + + if (!systemTask->IsSleepDisabled() && IsPastDimTime()) { + if (!isDimmed) { + DimScreen(); + } + if (IsPastSleepTime()) { + systemTask->PushMessage(System::Messages::GoToSleep); + state = States::Idle; + } + } else if (isDimmed) { + RestoreBrightness(); + } break; default: queueTimeout = portMAX_DELAY; @@ -175,10 +210,10 @@ void DisplayApp::Refresh() { if (xQueueReceive(msgQueue, &msg, queueTimeout) == pdTRUE) { switch (msg) { case Messages::DimScreen: - brightnessController.Set(Controllers::BrightnessController::Levels::Low); + DimScreen(); break; case Messages::RestoreBrightness: - ApplyBrightness(); + RestoreBrightness(); break; case Messages::GoToSleep: while (brightnessController.Level() != Controllers::BrightnessController::Levels::Off) { @@ -191,12 +226,10 @@ void DisplayApp::Refresh() { break; case Messages::GoToRunning: lcd.Wakeup(); + lv_disp_trig_activity(nullptr); ApplyBrightness(); state = States::Running; break; - case Messages::UpdateTimeOut: - PushMessageToSystemTask(System::Messages::UpdateTimeOut); - break; case Messages::UpdateBleConnection: // clockScreen.SetBleConnectionState(bleController.IsConnected() ? Screens::Clock::BleConnectionStates::Connected : // Screens::Clock::BleConnectionStates::NotConnected); @@ -206,6 +239,7 @@ void DisplayApp::Refresh() { break; case Messages::TimerDone: if (currentApp == Apps::Timer) { + lv_disp_trig_activity(nullptr); auto* timer = static_cast(currentScreen.get()); timer->Reset(); } else { @@ -319,6 +353,7 @@ void DisplayApp::Refresh() { motorController.RunForDuration(35); break; case Messages::OnChargingEvent: + RestoreBrightness(); motorController.RunForDuration(15); break; } @@ -352,7 +387,7 @@ void DisplayApp::LoadNewScreen(Apps app, DisplayApp::FullRefreshDirections direc void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections direction) { lvgl.CancelTap(); - ApplyBrightness(); + lv_disp_trig_activity(nullptr); motorController.StopRinging(); currentScreen.reset(nullptr); diff --git a/src/displayapp/DisplayApp.h b/src/displayapp/DisplayApp.h index 09111865..58df99c0 100644 --- a/src/displayapp/DisplayApp.h +++ b/src/displayapp/DisplayApp.h @@ -128,6 +128,8 @@ namespace Pinetime { static constexpr size_t returnAppStackSize = 10; StaticStack returnAppStack; StaticStack appStackDirections; + + bool isDimmed = false; }; } } diff --git a/src/displayapp/Messages.h b/src/displayapp/Messages.h index b670b1aa..dada3088 100644 --- a/src/displayapp/Messages.h +++ b/src/displayapp/Messages.h @@ -17,7 +17,6 @@ namespace Pinetime { NewNotification, TimerDone, BleFirmwareUpdateStarted, - UpdateTimeOut, DimScreen, RestoreBrightness, ShowPairingKey, diff --git a/src/displayapp/screens/settings/SettingDisplay.cpp b/src/displayapp/screens/settings/SettingDisplay.cpp index a9476432..91f4d590 100644 --- a/src/displayapp/screens/settings/SettingDisplay.cpp +++ b/src/displayapp/screens/settings/SettingDisplay.cpp @@ -69,7 +69,6 @@ void SettingDisplay::UpdateSelected(lv_obj_t* object, lv_event_t event) { if (object == cbOption[i]) { lv_checkbox_set_checked(cbOption[i], true); settingsController.SetScreenTimeOut(options[i]); - app->PushMessage(Applications::Display::Messages::UpdateTimeOut); } else { lv_checkbox_set_checked(cbOption[i], false); } diff --git a/src/systemtask/Messages.h b/src/systemtask/Messages.h index 3768ae9b..d92755b7 100644 --- a/src/systemtask/Messages.h +++ b/src/systemtask/Messages.h @@ -12,7 +12,6 @@ namespace Pinetime { OnTimerDone, OnNewCall, BleConnected, - UpdateTimeOut, BleFirmwareUpdateStarted, BleFirmwareUpdateFinished, OnTouchEvent, diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 041cb209..539ff895 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -27,20 +27,6 @@ namespace { } } -void DimTimerCallback(TimerHandle_t xTimer) { - - NRF_LOG_INFO("DimTimerCallback"); - auto* sysTask = static_cast(pvTimerGetTimerID(xTimer)); - sysTask->OnDim(); -} - -void IdleTimerCallback(TimerHandle_t xTimer) { - - NRF_LOG_INFO("IdleTimerCallback"); - auto* sysTask = static_cast(pvTimerGetTimerID(xTimer)); - sysTask->OnIdle(); -} - void MeasureBatteryTimerCallback(TimerHandle_t xTimer) { auto* sysTask = static_cast(pvTimerGetTimerID(xTimer)); sysTask->PushMessage(Pinetime::System::Messages::MeasureBatteryTimerExpired); @@ -189,10 +175,7 @@ void SystemTask::Work() { batteryController.MeasureVoltage(); - idleTimer = xTimerCreate("idleTimer", pdMS_TO_TICKS(2000), pdFALSE, this, IdleTimerCallback); - dimTimer = xTimerCreate("dimTimer", pdMS_TO_TICKS(settingsController.GetScreenTimeOut() - 2000), pdFALSE, this, DimTimerCallback); measureBatteryTimer = xTimerCreate("measureBattery", batteryMeasurementPeriod, pdTRUE, this, MeasureBatteryTimerCallback); - xTimerStart(dimTimer, 0); xTimerStart(measureBatteryTimer, portMAX_DELAY); #pragma clang diagnostic push @@ -209,14 +192,11 @@ void SystemTask::Work() { if (!bleController.IsFirmwareUpdating()) { doNotGoToSleep = false; } - ReloadIdleTimer(); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::RestoreBrightness); break; case Messages::DisableSleeping: doNotGoToSleep = true; break; - case Messages::UpdateTimeOut: - xTimerChangePeriod(dimTimer, pdMS_TO_TICKS(settingsController.GetScreenTimeOut() - 2000), 0); - break; case Messages::GoToRunning: spi.Wakeup(); @@ -225,7 +205,6 @@ void SystemTask::Work() { touchPanel.Wakeup(); } - xTimerStart(dimTimer, 0); spiNorFlash.Wakeup(); displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToRunning); @@ -236,7 +215,6 @@ void SystemTask::Work() { } state = SystemTaskState::Running; - isDimmed = false; break; case Messages::TouchWakeUp: { if (touchHandler.ProcessTouchInfo(touchPanel.GetTouchInfo())) { @@ -258,13 +236,11 @@ void SystemTask::Work() { } state = SystemTaskState::GoingToSleep; // Already set in PushMessage() NRF_LOG_INFO("[systemtask] Going to sleep"); - xTimerStop(idleTimer, 0); - xTimerStop(dimTimer, 0); displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToSleep); heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep); break; case Messages::OnNewTime: - ReloadIdleTimer(); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::RestoreBrightness); displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateDateTime); if (alarmController.State() == Controllers::AlarmController::AlarmState::Set) { alarmController.ScheduleAlarm(); @@ -275,7 +251,7 @@ void SystemTask::Work() { if (state == SystemTaskState::Sleeping) { GoToRunning(); } else { - ReloadIdleTimer(); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::RestoreBrightness); } displayApp.PushMessage(Pinetime::Applications::Display::Messages::NewNotification); } @@ -293,7 +269,7 @@ void SystemTask::Work() { displayApp.PushMessage(Pinetime::Applications::Display::Messages::AlarmTriggered); break; case Messages::BleConnected: - ReloadIdleTimer(); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::RestoreBrightness); isBleDiscoveryTimerRunning = true; bleDiscoveryTimer = 5; break; @@ -309,7 +285,6 @@ void SystemTask::Work() { NVIC_SystemReset(); } doNotGoToSleep = false; - xTimerStart(dimTimer, 0); break; case Messages::StartFileTransfer: NRF_LOG_INFO("[systemtask] FS Started"); @@ -322,12 +297,10 @@ void SystemTask::Work() { case Messages::StopFileTransfer: NRF_LOG_INFO("[systemtask] FS Stopped"); doNotGoToSleep = false; - xTimerStart(dimTimer, 0); // TODO add intent of fs access icon or something break; case Messages::OnTouchEvent: if (touchHandler.ProcessTouchInfo(touchPanel.GetTouchInfo())) { - ReloadIdleTimer(); displayApp.PushMessage(Pinetime::Applications::Display::Messages::TouchEvent); } break; @@ -395,7 +368,6 @@ void SystemTask::Work() { case Messages::OnChargingEvent: batteryController.ReadPowerState(); displayApp.PushMessage(Applications::Display::Messages::OnChargingEvent); - ReloadIdleTimer(); if (state == SystemTaskState::Sleeping) { GoToRunning(); } @@ -481,7 +453,7 @@ void SystemTask::HandleButtonAction(Controllers::ButtonActions action) { return; } - ReloadIdleTimer(); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::RestoreBrightness); using Actions = Controllers::ButtonActions; @@ -542,33 +514,3 @@ void SystemTask::PushMessage(System::Messages msg) { xQueueSend(systemTasksMsgQueue, &msg, portMAX_DELAY); } } - -void SystemTask::OnDim() { - if (doNotGoToSleep) { - return; - } - NRF_LOG_INFO("Dim timeout -> Dim screen") - displayApp.PushMessage(Pinetime::Applications::Display::Messages::DimScreen); - xTimerStart(idleTimer, 0); - isDimmed = true; -} - -void SystemTask::OnIdle() { - if (doNotGoToSleep) { - return; - } - NRF_LOG_INFO("Idle timeout -> Going to sleep") - PushMessage(Messages::GoToSleep); -} - -void SystemTask::ReloadIdleTimer() { - if (state != SystemTaskState::Running) { - return; - } - if (isDimmed) { - displayApp.PushMessage(Pinetime::Applications::Display::Messages::RestoreBrightness); - isDimmed = false; - } - xTimerReset(dimTimer, 0); - xTimerStop(idleTimer, 0); -} diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index 72e88875..22d268be 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -84,6 +84,10 @@ namespace Pinetime { void OnIdle(); void OnDim(); + bool IsSleepDisabled() { + return doNotGoToSleep; + } + Pinetime::Controllers::NimbleController& nimble() { return nimbleController; }; @@ -123,14 +127,10 @@ namespace Pinetime { static void Process(void* instance); void Work(); - void ReloadIdleTimer(); bool isBleDiscoveryTimerRunning = false; uint8_t bleDiscoveryTimer = 0; - TimerHandle_t dimTimer; - TimerHandle_t idleTimer; TimerHandle_t measureBatteryTimer; bool doNotGoToSleep = false; - bool isDimmed = false; SystemTaskState state = SystemTaskState::Running; void HandleButtonAction(Controllers::ButtonActions action);