aboutsummaryrefslogtreecommitdiffstats
path: root/src/systemtask
diff options
context:
space:
mode:
authormark9064 <30447455+mark9064@users.noreply.github.com>2024-08-22 21:24:04 +0100
committerNeroBurner <pyro4hell@gmail.com>2024-09-21 21:08:07 +0200
commitc3d05901a05a274f30c15b8c0640b6ecdd973ac3 (patch)
treed63aaacce475f495670787f79019df8af6e2af7d /src/systemtask
parentb3756e45fa50ce81255dc3bb21cbce4af3254f2f (diff)
Refactor SystemTask state handling for resilience
State transitions now happen immediately where possible This simplifies state management in general, and prevents bugs such as the chime issue from occurring in the first place
Diffstat (limited to 'src/systemtask')
-rw-r--r--src/systemtask/SystemTask.cpp142
-rw-r--r--src/systemtask/SystemTask.h5
2 files changed, 67 insertions, 80 deletions
diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp
index 848fb54c..4c623883 100644
--- a/src/systemtask/SystemTask.cpp
+++ b/src/systemtask/SystemTask.cpp
@@ -196,29 +196,11 @@ void SystemTask::Work() {
}
break;
case Messages::DisableSleeping:
+ GoToRunning();
doNotGoToSleep = true;
break;
case Messages::GoToRunning:
- // SPI doesn't go to sleep for always on mode
- if (!settingsController.GetAlwaysOnDisplay()) {
- spi.Wakeup();
- }
-
- // Double Tap needs the touch screen to be in normal mode
- if (!settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) {
- touchPanel.Wakeup();
- }
-
- spiNorFlash.Wakeup();
-
- displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToRunning);
- heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp);
-
- if (bleController.IsRadioEnabled() && !bleController.IsConnected()) {
- nimbleController.RestartFastAdv();
- }
-
- state = SystemTaskState::Running;
+ GoToRunning();
break;
case Messages::TouchWakeUp: {
if (touchHandler.ProcessTouchInfo(touchPanel.GetTouchInfo())) {
@@ -235,13 +217,7 @@ void SystemTask::Work() {
break;
}
case Messages::GoToSleep:
- if (doNotGoToSleep) {
- break;
- }
- state = SystemTaskState::GoingToSleep; // Already set in PushMessage()
- NRF_LOG_INFO("[systemtask] Going to sleep");
- displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToSleep);
- heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep);
+ GoToSleep();
break;
case Messages::OnNewTime:
if (alarmController.State() == Controllers::AlarmController::AlarmState::Set) {
@@ -250,16 +226,14 @@ void SystemTask::Work() {
break;
case Messages::OnNewNotification:
if (settingsController.GetNotificationStatus() == Pinetime::Controllers::Settings::Notification::On) {
- if (state == SystemTaskState::Sleeping) {
+ if (IsSleeping()) {
GoToRunning();
}
displayApp.PushMessage(Pinetime::Applications::Display::Messages::NewNotification);
}
break;
case Messages::SetOffAlarm:
- if (state == SystemTaskState::Sleeping) {
- GoToRunning();
- }
+ GoToRunning();
displayApp.PushMessage(Pinetime::Applications::Display::Messages::AlarmTriggered);
break;
case Messages::BleConnected:
@@ -268,10 +242,8 @@ void SystemTask::Work() {
bleDiscoveryTimer = 5;
break;
case Messages::BleFirmwareUpdateStarted:
+ GoToRunning();
doNotGoToSleep = true;
- if (state == SystemTaskState::Sleeping) {
- GoToRunning();
- }
displayApp.PushMessage(Pinetime::Applications::Display::Messages::BleFirmwareUpdateStarted);
break;
case Messages::BleFirmwareUpdateFinished:
@@ -282,10 +254,8 @@ void SystemTask::Work() {
break;
case Messages::StartFileTransfer:
NRF_LOG_INFO("[systemtask] FS Started");
+ GoToRunning();
doNotGoToSleep = true;
- if (state == SystemTaskState::Sleeping) {
- GoToRunning();
- }
// TODO add intent of fs access icon or something
break;
case Messages::StopFileTransfer:
@@ -318,6 +288,13 @@ void SystemTask::Work() {
HandleButtonAction(action);
} break;
case Messages::OnDisplayTaskSleeping:
+ // The state was set to GoingToSleep when GoToSleep() was called
+ // If the state is no longer GoingToSleep, we have since transitioned back to Running
+ // In this case absorb the OnDisplayTaskSleeping
+ // as DisplayApp is about to receive GoToRunning
+ if (state != SystemTaskState::GoingToSleep) {
+ break;
+ }
if (BootloaderVersion::IsValid()) {
// First versions of the bootloader do not expose their version and cannot initialize the SPI NOR FLASH
// if it's in sleep mode. Avoid bricked device by disabling sleep mode on these versions.
@@ -346,14 +323,8 @@ void SystemTask::Work() {
if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep &&
settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours &&
alarmController.State() != AlarmController::AlarmState::Alerting) {
- // if sleeping, we can't send a chime to displayApp yet (SPI flash switched off)
- // request running first and repush the chime message
- if (state == SystemTaskState::Sleeping) {
- GoToRunning();
- PushMessage(msg);
- } else {
- displayApp.PushMessage(Pinetime::Applications::Display::Messages::Chime);
- }
+ GoToRunning();
+ displayApp.PushMessage(Pinetime::Applications::Display::Messages::Chime);
}
break;
case Messages::OnNewHalfHour:
@@ -361,22 +332,14 @@ void SystemTask::Work() {
if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep &&
settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours &&
alarmController.State() != AlarmController::AlarmState::Alerting) {
- // if sleeping, we can't send a chime to displayApp yet (SPI flash switched off)
- // request running first and repush the chime message
- if (state == SystemTaskState::Sleeping) {
- GoToRunning();
- PushMessage(msg);
- } else {
- displayApp.PushMessage(Pinetime::Applications::Display::Messages::Chime);
- }
+ GoToRunning();
+ displayApp.PushMessage(Pinetime::Applications::Display::Messages::Chime);
}
break;
case Messages::OnChargingEvent:
batteryController.ReadPowerState();
+ GoToRunning();
displayApp.PushMessage(Applications::Display::Messages::OnChargingEvent);
- if (state == SystemTaskState::Sleeping) {
- GoToRunning();
- }
break;
case Messages::MeasureBatteryTimerExpired:
batteryController.MeasureVoltage();
@@ -385,9 +348,7 @@ void SystemTask::Work() {
nimbleController.NotifyBatteryLevel(batteryController.PercentRemaining());
break;
case Messages::OnPairing:
- if (state == SystemTaskState::Sleeping) {
- GoToRunning();
- }
+ GoToRunning();
displayApp.PushMessage(Pinetime::Applications::Display::Messages::ShowPairingKey);
break;
case Messages::BleRadioEnableToggle:
@@ -422,14 +383,50 @@ void SystemTask::Work() {
#pragma clang diagnostic pop
}
-void SystemTask::UpdateMotion() {
- if (state == SystemTaskState::GoingToSleep || state == SystemTaskState::WakingUp) {
+void SystemTask::GoToRunning() {
+ if (state == SystemTaskState::Running) {
return;
}
+ // SPI doesn't go to sleep for always on mode
+ if (!settingsController.GetAlwaysOnDisplay()) {
+ spi.Wakeup();
+ }
+
+ // Double Tap needs the touch screen to be in normal mode
+ if (!settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) {
+ touchPanel.Wakeup();
+ }
- if (state == SystemTaskState::Sleeping && !(settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) ||
- settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake) ||
- motionController.GetService()->IsMotionNotificationSubscribed())) {
+ spiNorFlash.Wakeup();
+
+ displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToRunning);
+ heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp);
+
+ if (bleController.IsRadioEnabled() && !bleController.IsConnected()) {
+ nimbleController.RestartFastAdv();
+ }
+
+ state = SystemTaskState::Running;
+};
+
+void SystemTask::GoToSleep() {
+ if (IsSleeping()) {
+ return;
+ }
+ if (IsSleepDisabled()) {
+ return;
+ }
+ NRF_LOG_INFO("[systemtask] Going to sleep");
+ displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToSleep);
+ heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep);
+
+ state = SystemTaskState::GoingToSleep;
+};
+
+void SystemTask::UpdateMotion() {
+ if (IsSleeping() && !(settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) ||
+ settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake) ||
+ motionController.GetService()->IsMotionNotificationSubscribed())) {
return;
}
@@ -452,7 +449,7 @@ void SystemTask::UpdateMotion() {
}
if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::LowerWrist) && state == SystemTaskState::Running &&
motionController.ShouldLowerSleep()) {
- PushMessage(Messages::GoToSleep);
+ GoToSleep();
}
}
@@ -468,7 +465,7 @@ void SystemTask::HandleButtonAction(Controllers::ButtonActions action) {
switch (action) {
case Actions::Click:
// If the first action after fast wakeup is a click, it should be ignored.
- if (!fastWakeUpDone && state != SystemTaskState::GoingToSleep) {
+ if (!fastWakeUpDone) {
displayApp.PushMessage(Applications::Display::Messages::ButtonPushed);
}
break;
@@ -488,17 +485,10 @@ void SystemTask::HandleButtonAction(Controllers::ButtonActions action) {
fastWakeUpDone = false;
}
-void SystemTask::GoToRunning() {
- if (state == SystemTaskState::Sleeping) {
- state = SystemTaskState::WakingUp;
- PushMessage(Messages::GoToRunning);
- }
-}
-
void SystemTask::OnTouchEvent() {
if (state == SystemTaskState::Running) {
PushMessage(Messages::OnTouchEvent);
- } else if (state == SystemTaskState::Sleeping) {
+ } else {
if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::SingleTap) or
settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) {
PushMessage(Messages::TouchWakeUp);
@@ -507,10 +497,6 @@ void SystemTask::OnTouchEvent() {
}
void SystemTask::PushMessage(System::Messages msg) {
- if (msg == Messages::GoToSleep && !doNotGoToSleep) {
- state = SystemTaskState::GoingToSleep;
- }
-
if (in_isr()) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xQueueSendFromISR(systemTasksMsgQueue, &msg, &xHigherPriorityTaskWoken);
diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h
index 11dea52c..339587c1 100644
--- a/src/systemtask/SystemTask.h
+++ b/src/systemtask/SystemTask.h
@@ -52,7 +52,7 @@ namespace Pinetime {
namespace System {
class SystemTask {
public:
- enum class SystemTaskState { Sleeping, Running, GoingToSleep, WakingUp };
+ enum class SystemTaskState { Sleeping, Running, GoingToSleep };
SystemTask(Drivers::SpiMaster& spi,
Pinetime::Drivers::SpiNorFlash& spiNorFlash,
Drivers::TwiMaster& twiMaster,
@@ -88,7 +88,7 @@ namespace Pinetime {
};
bool IsSleeping() const {
- return state == SystemTaskState::Sleeping || state == SystemTaskState::WakingUp;
+ return state != SystemTaskState::Running;
}
private:
@@ -131,6 +131,7 @@ namespace Pinetime {
bool fastWakeUpDone = false;
void GoToRunning();
+ void GoToSleep();
void UpdateMotion();
bool stepCounterMustBeReset = false;
static constexpr TickType_t batteryMeasurementPeriod = pdMS_TO_TICKS(10 * 60 * 1000);