Refactor into defined states

This commit is contained in:
mark9064 2024-08-25 22:57:24 +01:00 committed by JF
parent 97ba39988b
commit f032847ae1
6 changed files with 52 additions and 38 deletions

View File

@ -220,28 +220,27 @@ void DisplayApp::Refresh() {
TickType_t queueTimeout; TickType_t queueTimeout;
switch (state) { switch (state) {
case States::Idle: case States::Idle:
if (settingsController.GetAlwaysOnDisplay()) { queueTimeout = portMAX_DELAY;
if (!currentScreen->IsRunning()) { break;
LoadPreviousScreen(); case States::AOD:
if (!currentScreen->IsRunning()) {
LoadPreviousScreen();
}
// Check we've slept long enough
// Might not be true if the loop received an event
// If not true, then wait that amount of time
queueTimeout = CalculateSleepTime();
if (queueTimeout == 0) {
// Only advance the tick count when LVGL is done
// Otherwise keep running the task handler while it still has things to draw
// Note: under high graphics load, LVGL will always have more work to do
if (lv_task_handler() > 0) {
// Drop frames that we've missed if drawing/event handling took way longer than expected
while (queueTimeout == 0) {
alwaysOnTickCount += 1;
queueTimeout = CalculateSleepTime();
}
} }
// Check we've slept long enough
// Might not be true if the loop received an event
// If not true, then wait that amount of time
queueTimeout = CalculateSleepTime();
if (queueTimeout == 0) {
// Only advance the tick count when LVGL is done
// Otherwise keep running the task handler while it still has things to draw
// Note: under high graphics load, LVGL will always have more work to do
if (lv_task_handler() > 0) {
// Drop frames that we've missed if drawing/event handling took way longer than expected
while (queueTimeout == 0) {
alwaysOnTickCount += 1;
queueTimeout = CalculateSleepTime();
}
};
}
} else {
queueTimeout = portMAX_DELAY;
} }
break; break;
case States::Running: case States::Running:
@ -284,6 +283,7 @@ void DisplayApp::Refresh() {
if (xQueueReceive(msgQueue, &msg, queueTimeout) == pdTRUE) { if (xQueueReceive(msgQueue, &msg, queueTimeout) == pdTRUE) {
switch (msg) { switch (msg) {
case Messages::GoToSleep: case Messages::GoToSleep:
case Messages::GoToAOD:
if (state != States::Running) { if (state != States::Running) {
break; break;
} }
@ -292,7 +292,7 @@ void DisplayApp::Refresh() {
vTaskDelay(100); vTaskDelay(100);
} }
// Turn brightness down (or set to AlwaysOn mode) // Turn brightness down (or set to AlwaysOn mode)
if (settingsController.GetAlwaysOnDisplay()) { if (msg == Messages::GoToAOD) {
brightnessController.Set(Controllers::BrightnessController::Levels::AlwaysOn); brightnessController.Set(Controllers::BrightnessController::Levels::AlwaysOn);
} else { } else {
brightnessController.Set(Controllers::BrightnessController::Levels::Off); brightnessController.Set(Controllers::BrightnessController::Levels::Off);
@ -305,17 +305,18 @@ void DisplayApp::Refresh() {
while (!lv_task_handler()) { while (!lv_task_handler()) {
}; };
} }
// Turn LCD display off (or set to low power for AlwaysOn mode) if (msg == Messages::GoToAOD) {
if (settingsController.GetAlwaysOnDisplay()) {
lcd.LowPowerOn(); lcd.LowPowerOn();
// Record idle entry time // Record idle entry time
alwaysOnTickCount = 0; alwaysOnTickCount = 0;
alwaysOnStartTime = xTaskGetTickCount(); alwaysOnStartTime = xTaskGetTickCount();
PushMessageToSystemTask(Pinetime::System::Messages::OnDisplayTaskAOD);
state = States::AOD;
} else { } else {
lcd.Sleep(); lcd.Sleep();
PushMessageToSystemTask(Pinetime::System::Messages::OnDisplayTaskSleeping);
state = States::Idle;
} }
PushMessageToSystemTask(Pinetime::System::Messages::OnDisplayTaskSleeping);
state = States::Idle;
break; break;
case Messages::NotifyDeviceActivity: case Messages::NotifyDeviceActivity:
lv_disp_trig_activity(nullptr); lv_disp_trig_activity(nullptr);
@ -324,7 +325,7 @@ void DisplayApp::Refresh() {
if (state == States::Running) { if (state == States::Running) {
break; break;
} }
if (settingsController.GetAlwaysOnDisplay()) { if (state == States::AOD) {
lcd.LowPowerOff(); lcd.LowPowerOff();
} else { } else {
lcd.Wakeup(); lcd.Wakeup();

View File

@ -49,7 +49,7 @@ namespace Pinetime {
namespace Applications { namespace Applications {
class DisplayApp { class DisplayApp {
public: public:
enum class States { Idle, Running }; enum class States { Idle, Running, AOD };
enum class FullRefreshDirections { None, Up, Down, Left, Right, LeftAnim, RightAnim }; enum class FullRefreshDirections { None, Up, Down, Left, Right, LeftAnim, RightAnim };
DisplayApp(Drivers::St7789& lcd, DisplayApp(Drivers::St7789& lcd,

View File

@ -6,6 +6,7 @@ namespace Pinetime {
namespace Display { namespace Display {
enum class Messages : uint8_t { enum class Messages : uint8_t {
GoToSleep, GoToSleep,
GoToAOD,
GoToRunning, GoToRunning,
UpdateBleConnection, UpdateBleConnection,
TouchEvent, TouchEvent,

View File

@ -17,6 +17,7 @@ namespace Pinetime {
HandleButtonEvent, HandleButtonEvent,
HandleButtonTimerEvent, HandleButtonTimerEvent,
OnDisplayTaskSleeping, OnDisplayTaskSleeping,
OnDisplayTaskAOD,
EnableSleeping, EnableSleeping,
DisableSleeping, DisableSleeping,
OnNewDay, OnNewDay,

View File

@ -284,9 +284,10 @@ void SystemTask::Work() {
HandleButtonAction(action); HandleButtonAction(action);
} break; } break;
case Messages::OnDisplayTaskSleeping: case Messages::OnDisplayTaskSleeping:
case Messages::OnDisplayTaskAOD:
// The state was set to GoingToSleep when GoToSleep() was called // The state was set to GoingToSleep when GoToSleep() was called
// If the state is no longer GoingToSleep, we have since transitioned back to Running // If the state is no longer GoingToSleep, we have since transitioned back to Running
// In this case absorb the OnDisplayTaskSleeping // In this case absorb the OnDisplayTaskSleeping/AOD
// as DisplayApp is about to receive GoToRunning // as DisplayApp is about to receive GoToRunning
if (state != SystemTaskState::GoingToSleep) { if (state != SystemTaskState::GoingToSleep) {
break; break;
@ -298,7 +299,7 @@ void SystemTask::Work() {
} }
// Must keep SPI awake when still updating the display for always on // Must keep SPI awake when still updating the display for always on
if (!settingsController.GetAlwaysOnDisplay()) { if (msg == Messages::OnDisplayTaskSleeping) {
spi.Sleep(); spi.Sleep();
} }
@ -307,7 +308,11 @@ void SystemTask::Work() {
touchPanel.Sleep(); touchPanel.Sleep();
} }
state = SystemTaskState::Sleeping; if (msg == Messages::OnDisplayTaskSleeping) {
state = SystemTaskState::Sleeping;
} else {
state = SystemTaskState::AODSleeping;
}
break; break;
case Messages::OnNewDay: case Messages::OnNewDay:
// We might be sleeping (with TWI device disabled. // We might be sleeping (with TWI device disabled.
@ -381,8 +386,8 @@ void SystemTask::GoToRunning() {
if (state == SystemTaskState::Running) { if (state == SystemTaskState::Running) {
return; return;
} }
// SPI doesn't go to sleep for always on mode // SPI only switched off when entering Sleeping, not AOD or GoingToSleep
if (!settingsController.GetAlwaysOnDisplay()) { if (state == SystemTaskState::Sleeping) {
spi.Wakeup(); spi.Wakeup();
} }
@ -411,16 +416,22 @@ void SystemTask::GoToSleep() {
return; return;
} }
NRF_LOG_INFO("[systemtask] Going to sleep"); NRF_LOG_INFO("[systemtask] Going to sleep");
displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToSleep); if (settingsController.GetAlwaysOnDisplay()) {
displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToAOD);
} else {
displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToSleep);
}
heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep); heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep);
state = SystemTaskState::GoingToSleep; state = SystemTaskState::GoingToSleep;
}; };
void SystemTask::UpdateMotion() { void SystemTask::UpdateMotion() {
if (IsSleeping() && !(settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) || // Only consider disabling motion updates specifically in the Sleeping state
settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake) || // AOD needs motion on to show up to date step counts
motionController.GetService()->IsMotionNotificationSubscribed())) { if (state == SystemTaskState::Sleeping && !(settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) ||
settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake) ||
motionController.GetService()->IsMotionNotificationSubscribed())) {
return; return;
} }

View File

@ -52,7 +52,7 @@ namespace Pinetime {
namespace System { namespace System {
class SystemTask { class SystemTask {
public: public:
enum class SystemTaskState { Sleeping, Running, GoingToSleep }; enum class SystemTaskState { Sleeping, Running, GoingToSleep, AODSleeping };
SystemTask(Drivers::SpiMaster& spi, SystemTask(Drivers::SpiMaster& spi,
Pinetime::Drivers::SpiNorFlash& spiNorFlash, Pinetime::Drivers::SpiNorFlash& spiNorFlash,
Drivers::TwiMaster& twiMaster, Drivers::TwiMaster& twiMaster,