From 975bfc5420e7e53d134956ca919a29a921942c82 Mon Sep 17 00:00:00 2001 From: mark9064 <30447455+mark9064@users.noreply.github.com> Date: Fri, 23 Aug 2024 00:16:11 +0100 Subject: [PATCH 01/14] Size optimise NRF SDK build --- src/CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fd8ece62..dc3b6176 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -860,7 +860,6 @@ target_compile_options(nrf-sdk PRIVATE $<$: ${RELEASE_FLAGS}> $<$: ${CXX_FLAGS}> $<$: ${ASM_FLAGS}> - -O3 ) # NimBLE From fd019c7aada09dc78d72eb599798952d608baeb8 Mon Sep 17 00:00:00 2001 From: mark9064 <30447455+mark9064@users.noreply.github.com> Date: Mon, 22 Apr 2024 23:53:08 +0100 Subject: [PATCH 02/14] Use DirtyValue for timer --- src/displayapp/screens/Timer.cpp | 19 +++++++++++-------- src/displayapp/screens/Timer.h | 3 +++ 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/src/displayapp/screens/Timer.cpp b/src/displayapp/screens/Timer.cpp index a1ede6be..f6d5e73b 100644 --- a/src/displayapp/screens/Timer.cpp +++ b/src/displayapp/screens/Timer.cpp @@ -104,9 +104,7 @@ void Timer::UpdateMask() { void Timer::Refresh() { if (timer.IsRunning()) { - auto secondsRemaining = std::chrono::duration_cast(timer.GetTimeRemaining()); - minuteCounter.SetValue(secondsRemaining.count() / 60); - secondCounter.SetValue(secondsRemaining.count() % 60); + DisplayTime(); } else if (buttonPressing && xTaskGetTickCount() > pressTime + pdMS_TO_TICKS(150)) { lv_label_set_text_static(txtPlayPause, "Reset"); maskPosition += 15; @@ -119,6 +117,14 @@ void Timer::Refresh() { } } +void Timer::DisplayTime() { + displaySeconds = std::chrono::duration_cast(timer.GetTimeRemaining()); + if (displaySeconds.IsUpdated()) { + minuteCounter.SetValue(displaySeconds.Get().count() / 60); + secondCounter.SetValue(displaySeconds.Get().count() % 60); + } +} + void Timer::SetTimerRunning() { minuteCounter.HideControls(); secondCounter.HideControls(); @@ -133,9 +139,7 @@ void Timer::SetTimerStopped() { void Timer::ToggleRunning() { if (timer.IsRunning()) { - auto secondsRemaining = std::chrono::duration_cast(timer.GetTimeRemaining()); - minuteCounter.SetValue(secondsRemaining.count() / 60); - secondCounter.SetValue(secondsRemaining.count() % 60); + DisplayTime(); timer.StopTimer(); SetTimerStopped(); } else if (secondCounter.GetValue() + minuteCounter.GetValue() > 0) { @@ -147,7 +151,6 @@ void Timer::ToggleRunning() { } void Timer::Reset() { - minuteCounter.SetValue(0); - secondCounter.SetValue(0); + DisplayTime(); SetTimerStopped(); } diff --git a/src/displayapp/screens/Timer.h b/src/displayapp/screens/Timer.h index 409cae1c..0cb2bb08 100644 --- a/src/displayapp/screens/Timer.h +++ b/src/displayapp/screens/Timer.h @@ -5,6 +5,7 @@ #include "systemtask/SystemTask.h" #include "displayapp/LittleVgl.h" #include "displayapp/widgets/Counter.h" +#include "utility/DirtyValue.h" #include #include "components/timer/Timer.h" @@ -26,6 +27,7 @@ namespace Pinetime::Applications { void SetTimerRunning(); void SetTimerStopped(); void UpdateMask(); + void DisplayTime(); Pinetime::Controllers::Timer& timer; lv_obj_t* btnPlayPause; @@ -43,6 +45,7 @@ namespace Pinetime::Applications { bool buttonPressing = false; lv_coord_t maskPosition = 0; TickType_t pressTime = 0; + Utility::DirtyValue displaySeconds; }; } From 5040733a97560f8f0ef73f7df7982c5acaf15b47 Mon Sep 17 00:00:00 2001 From: mark9064 <30447455+mark9064@users.noreply.github.com> Date: Thu, 22 Aug 2024 16:49:18 +0100 Subject: [PATCH 03/14] Clean unused DisplayApp messages --- src/displayapp/DisplayApp.cpp | 32 +++++--------------------------- src/displayapp/Messages.h | 4 ++-- src/systemtask/SystemTask.cpp | 5 ----- 3 files changed, 7 insertions(+), 34 deletions(-) diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 3be7656d..79519621 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -209,21 +209,6 @@ 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); }; @@ -267,14 +252,16 @@ void DisplayApp::Refresh() { if (!systemTask->IsSleepDisabled() && IsPastDimTime()) { if (!isDimmed) { - DimScreen(); + isDimmed = true; + brightnessController.Set(Controllers::BrightnessController::Levels::Low); } if (IsPastSleepTime()) { systemTask->PushMessage(System::Messages::GoToSleep); state = States::Idle; } } else if (isDimmed) { - RestoreBrightness(); + isDimmed = false; + ApplyBrightness(); } break; default: @@ -285,9 +272,6 @@ void DisplayApp::Refresh() { Messages msg; if (xQueueReceive(msgQueue, &msg, queueTimeout) == pdTRUE) { switch (msg) { - case Messages::DimScreen: - DimScreen(); - break; case Messages::GoToSleep: while (brightnessController.Level() != Controllers::BrightnessController::Levels::Low) { brightnessController.Lower(); @@ -333,8 +317,7 @@ void DisplayApp::Refresh() { state = States::Running; break; case Messages::UpdateBleConnection: - // clockScreen.SetBleConnectionState(bleController.IsConnected() ? Screens::Clock::BleConnectionStates::Connected : - // Screens::Clock::BleConnectionStates::NotConnected); + // Only used for recovery firmware break; case Messages::NewNotification: LoadNewScreen(Apps::NotificationsPreview, DisplayApp::FullRefreshDirections::Down); @@ -449,16 +432,11 @@ void DisplayApp::Refresh() { case Messages::BleRadioEnableToggle: PushMessageToSystemTask(System::Messages::BleRadioEnableToggle); break; - case Messages::UpdateDateTime: - // Added to remove warning - // What should happen here? - break; case Messages::Chime: LoadNewScreen(Apps::Clock, DisplayApp::FullRefreshDirections::None); motorController.RunForDuration(35); break; case Messages::OnChargingEvent: - RestoreBrightness(); motorController.RunForDuration(15); break; } diff --git a/src/displayapp/Messages.h b/src/displayapp/Messages.h index 1418f6be..dcfff4c2 100644 --- a/src/displayapp/Messages.h +++ b/src/displayapp/Messages.h @@ -7,7 +7,6 @@ namespace Pinetime { enum class Messages : uint8_t { GoToSleep, GoToRunning, - UpdateDateTime, UpdateBleConnection, TouchEvent, ButtonPushed, @@ -17,7 +16,8 @@ namespace Pinetime { NewNotification, TimerDone, BleFirmwareUpdateStarted, - DimScreen, + // Resets the screen timeout timer when awake + // Does nothing when asleep NotifyDeviceActivity, ShowPairingKey, AlarmTriggered, diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 211e19ec..848fb54c 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -194,7 +194,6 @@ void SystemTask::Work() { if (!bleController.IsFirmwareUpdating()) { doNotGoToSleep = false; } - displayApp.PushMessage(Pinetime::Applications::Display::Messages::NotifyDeviceActivity); break; case Messages::DisableSleeping: doNotGoToSleep = true; @@ -245,8 +244,6 @@ void SystemTask::Work() { heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep); break; case Messages::OnNewTime: - displayApp.PushMessage(Pinetime::Applications::Display::Messages::NotifyDeviceActivity); - displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateDateTime); if (alarmController.State() == Controllers::AlarmController::AlarmState::Set) { alarmController.ScheduleAlarm(); } @@ -255,8 +252,6 @@ void SystemTask::Work() { if (settingsController.GetNotificationStatus() == Pinetime::Controllers::Settings::Notification::On) { if (state == SystemTaskState::Sleeping) { GoToRunning(); - } else { - displayApp.PushMessage(Pinetime::Applications::Display::Messages::NotifyDeviceActivity); } displayApp.PushMessage(Pinetime::Applications::Display::Messages::NewNotification); } From c8236afbefbcc4e22150da7324617d853561a0c5 Mon Sep 17 00:00:00 2001 From: mark9064 <30447455+mark9064@users.noreply.github.com> Date: Thu, 22 Aug 2024 16:51:52 +0100 Subject: [PATCH 04/14] Restrict debugging monitor to debug builds --- src/systemtask/SystemMonitor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/systemtask/SystemMonitor.cpp b/src/systemtask/SystemMonitor.cpp index 2edee7bf..8696c8ce 100644 --- a/src/systemtask/SystemMonitor.cpp +++ b/src/systemtask/SystemMonitor.cpp @@ -1,5 +1,5 @@ #include "systemtask/SystemTask.h" -#if configUSE_TRACE_FACILITY == 1 +#if NRF_LOG_ENABLED // FreeRtosMonitor #include #include From a2662028317bddf2c0e3060eeb02f202b18d958f Mon Sep 17 00:00:00 2001 From: Eli Tan <5410435+eliedrian@users.noreply.github.com> Date: Thu, 19 Sep 2024 04:31:15 +0800 Subject: [PATCH 05/14] notifications: Dismiss to watchface when empty (#1716) Set `running` to false to flag end of watchface when there are no more notifications left to display. I found it slightly annoying that dismissing all notifications leaves me with a "No notification to display" message. Instead of dismissing to a relatively useless message, dismiss to watchface. --- src/displayapp/screens/Notifications.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index 037c43a7..3a3f5f2b 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -82,7 +82,6 @@ void Notifications::Refresh() { } else if (mode == Modes::Preview && dismissingNotification) { running = false; - currentItem = std::make_unique(alertNotificationService, motorController); } else if (dismissingNotification) { dismissingNotification = false; @@ -113,11 +112,11 @@ void Notifications::Refresh() { alertNotificationService, motorController); } else { - currentItem = std::make_unique(alertNotificationService, motorController); + running = false; } } - running = currentItem->IsRunning() && running; + running = running && currentItem->IsRunning(); } void Notifications::OnPreviewInteraction() { @@ -173,7 +172,9 @@ bool Notifications::OnTouchEvent(Pinetime::Applications::TouchEvents event) { } else if (nextMessage.valid) { currentId = nextMessage.id; } else { - // don't update id, won't be found be refresh and try to load latest message or no message box + // don't update id, notification manager will try to fetch + // but not find it. Refresh will try to load latest message + // or dismiss to watchface } DismissToBlack(); return true; From b3756e45fa50ce81255dc3bb21cbce4af3254f2f Mon Sep 17 00:00:00 2001 From: mark9064 <30447455+mark9064@users.noreply.github.com> Date: Sat, 13 Jul 2024 12:00:40 +0100 Subject: [PATCH 06/14] Remove unused method declarations --- src/systemtask/SystemTask.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index 79f1cf44..11dea52c 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -79,9 +79,6 @@ namespace Pinetime { void OnTouchEvent(); - void OnIdle(); - void OnDim(); - bool IsSleepDisabled() { return doNotGoToSleep; } From c3d05901a05a274f30c15b8c0640b6ecdd973ac3 Mon Sep 17 00:00:00 2001 From: mark9064 <30447455+mark9064@users.noreply.github.com> Date: Thu, 22 Aug 2024 21:24:04 +0100 Subject: [PATCH 07/14] 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 --- src/components/ble/DfuService.cpp | 8 +- src/components/ble/NimbleController.cpp | 10 +- src/displayapp/DisplayApp.cpp | 23 +++- src/systemtask/SystemTask.cpp | 142 +++++++++++------------- src/systemtask/SystemTask.h | 5 +- 5 files changed, 100 insertions(+), 88 deletions(-) diff --git a/src/components/ble/DfuService.cpp b/src/components/ble/DfuService.cpp index b3f2ff10..2427513d 100644 --- a/src/components/ble/DfuService.cpp +++ b/src/components/ble/DfuService.cpp @@ -124,9 +124,11 @@ int DfuService::WritePacketHandler(uint16_t connectionHandle, os_mbuf* om) { bootloaderSize, applicationSize); - // wait until SystemTask has finished waking up all devices - while (systemTask.IsSleeping()) { - vTaskDelay(50); // 50ms + // Wait until SystemTask has disabled sleeping + // This isn't quite correct, as we don't actually know + // if BleFirmwareUpdateStarted has been received yet + while (!systemTask.IsSleepDisabled()) { + vTaskDelay(pdMS_TO_TICKS(5)); } dfuImage.Erase(); diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index f1411a3e..5059007a 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -454,9 +454,15 @@ void NimbleController::PersistBond(struct ble_gap_conn_desc& desc) { /* Wakeup Spi and SpiNorFlash before accessing the file system * This should be fixed in the FS driver */ - systemTask.PushMessage(Pinetime::System::Messages::GoToRunning); systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping); - vTaskDelay(10); + + // This isn't quite correct + // SystemTask could receive EnableSleeping right after passing this check + // We need some guarantee that the SystemTask has processed the above message + // before we can continue + while (!systemTask.IsSleepDisabled()) { + vTaskDelay(pdMS_TO_TICKS(5)); + } lfs_file_t file_p; diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 79519621..076b4f8a 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -255,9 +255,20 @@ void DisplayApp::Refresh() { isDimmed = true; brightnessController.Set(Controllers::BrightnessController::Levels::Low); } - if (IsPastSleepTime()) { - systemTask->PushMessage(System::Messages::GoToSleep); - state = States::Idle; + if (IsPastSleepTime() && uxQueueMessagesWaiting(msgQueue) == 0) { + PushMessageToSystemTask(System::Messages::GoToSleep); + // Can't set state to Idle here, something may send + // DisableSleeping before this GoToSleep arrives + // Instead we check we have no messages queued before sending GoToSleep + // This works as the SystemTask is higher priority than DisplayApp + // As soon as we send GoToSleep, SystemTask pre-empts DisplayApp + // Whenever DisplayApp is running again, it is guaranteed that + // SystemTask has handled the message + // If it responded, we will have a GoToSleep waiting in the queue + // By checking that there are no messages in the queue, we avoid + // resending GoToSleep when we already have a response + // SystemTask is resilient to duplicate messages, this is an + // optimisation to reduce pressure on the message queues } } else if (isDimmed) { isDimmed = false; @@ -273,6 +284,9 @@ void DisplayApp::Refresh() { if (xQueueReceive(msgQueue, &msg, queueTimeout) == pdTRUE) { switch (msg) { case Messages::GoToSleep: + if (state != States::Running) { + break; + } while (brightnessController.Level() != Controllers::BrightnessController::Levels::Low) { brightnessController.Lower(); vTaskDelay(100); @@ -307,6 +321,9 @@ void DisplayApp::Refresh() { lv_disp_trig_activity(nullptr); break; case Messages::GoToRunning: + if (state == States::Running) { + break; + } if (settingsController.GetAlwaysOnDisplay()) { lcd.LowPowerOff(); } else { 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(); + } - if (state == SystemTaskState::Sleeping && !(settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) || - settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::Shake) || - motionController.GetService()->IsMotionNotificationSubscribed())) { + // 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; +}; + +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); From 7ca0418c82173fa1cff9537eaf1f030b5a712e9a Mon Sep 17 00:00:00 2001 From: mark9064 <30447455+mark9064@users.noreply.github.com> Date: Fri, 23 Aug 2024 00:15:24 +0100 Subject: [PATCH 08/14] Refactor doNotGoToSleep to a wakelock counter --- src/CMakeLists.txt | 3 +++ src/displayapp/screens/Alarm.cpp | 6 +++--- src/displayapp/screens/Alarm.h | 3 ++- src/displayapp/screens/FlashLight.cpp | 5 ++--- src/displayapp/screens/FlashLight.h | 3 ++- src/displayapp/screens/HeartRate.cpp | 9 ++++---- src/displayapp/screens/HeartRate.h | 3 ++- src/displayapp/screens/Metronome.cpp | 7 +++--- src/displayapp/screens/Metronome.h | 3 ++- src/displayapp/screens/Notifications.cpp | 7 +++--- src/displayapp/screens/Notifications.h | 3 ++- src/displayapp/screens/StopWatch.cpp | 7 +++--- src/displayapp/screens/StopWatch.h | 3 ++- src/systemtask/SystemTask.cpp | 16 ++++++-------- src/systemtask/SystemTask.h | 4 ++-- src/systemtask/WakeLock.cpp | 27 ++++++++++++++++++++++++ src/systemtask/WakeLock.h | 19 +++++++++++++++++ 17 files changed, 87 insertions(+), 41 deletions(-) create mode 100644 src/systemtask/WakeLock.cpp create mode 100644 src/systemtask/WakeLock.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dc3b6176..0a97a015 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -478,6 +478,7 @@ list(APPEND SOURCE_FILES systemtask/SystemTask.cpp systemtask/SystemMonitor.cpp + systemtask/WakeLock.cpp drivers/TwiMaster.cpp heartratetask/HeartRateTask.cpp @@ -542,6 +543,7 @@ list(APPEND RECOVERY_SOURCE_FILES systemtask/SystemTask.cpp systemtask/SystemMonitor.cpp + systemtask/WakeLock.cpp drivers/TwiMaster.cpp components/rle/RleDecoder.cpp components/heartrate/HeartRateController.cpp @@ -660,6 +662,7 @@ set(INCLUDE_FILES displayapp/InfiniTimeTheme.h systemtask/SystemTask.h systemtask/SystemMonitor.h + systemtask/WakeLock.h displayapp/screens/Symbols.h drivers/TwiMaster.h heartratetask/HeartRateTask.h diff --git a/src/displayapp/screens/Alarm.cpp b/src/displayapp/screens/Alarm.cpp index cbc702f3..292fb075 100644 --- a/src/displayapp/screens/Alarm.cpp +++ b/src/displayapp/screens/Alarm.cpp @@ -48,7 +48,7 @@ Alarm::Alarm(Controllers::AlarmController& alarmController, Controllers::Settings::ClockType clockType, System::SystemTask& systemTask, Controllers::MotorController& motorController) - : alarmController {alarmController}, systemTask {systemTask}, motorController {motorController} { + : alarmController {alarmController}, wakeLock(systemTask), motorController {motorController} { hourCounter.Create(); lv_obj_align(hourCounter.GetObject(), nullptr, LV_ALIGN_IN_TOP_LEFT, 0, 0); @@ -205,7 +205,7 @@ void Alarm::SetAlerting() { lv_obj_set_hidden(btnStop, false); taskStopAlarm = lv_task_create(StopAlarmTaskCallback, pdMS_TO_TICKS(60 * 1000), LV_TASK_PRIO_MID, this); motorController.StartRinging(); - systemTask.PushMessage(System::Messages::DisableSleeping); + wakeLock.Lock(); } void Alarm::StopAlerting() { @@ -216,7 +216,7 @@ void Alarm::StopAlerting() { lv_task_del(taskStopAlarm); taskStopAlarm = nullptr; } - systemTask.PushMessage(System::Messages::EnableSleeping); + wakeLock.Release(); lv_obj_set_hidden(enableSwitch, false); lv_obj_set_hidden(btnStop, true); } diff --git a/src/displayapp/screens/Alarm.h b/src/displayapp/screens/Alarm.h index 444102cb..a875b275 100644 --- a/src/displayapp/screens/Alarm.h +++ b/src/displayapp/screens/Alarm.h @@ -22,6 +22,7 @@ #include "displayapp/screens/Screen.h" #include "displayapp/widgets/Counter.h" #include "displayapp/Controllers.h" +#include "systemtask/WakeLock.h" #include "Symbols.h" namespace Pinetime { @@ -43,7 +44,7 @@ namespace Pinetime { private: Controllers::AlarmController& alarmController; - System::SystemTask& systemTask; + System::WakeLock wakeLock; Controllers::MotorController& motorController; lv_obj_t *btnStop, *txtStop, *btnRecur, *txtRecur, *btnInfo, *enableSwitch; diff --git a/src/displayapp/screens/FlashLight.cpp b/src/displayapp/screens/FlashLight.cpp index f169fac1..7e0caff1 100644 --- a/src/displayapp/screens/FlashLight.cpp +++ b/src/displayapp/screens/FlashLight.cpp @@ -15,7 +15,7 @@ namespace { } FlashLight::FlashLight(System::SystemTask& systemTask, Controllers::BrightnessController& brightnessController) - : systemTask {systemTask}, brightnessController {brightnessController} { + : wakeLock(systemTask), brightnessController {brightnessController} { previousBrightnessLevel = brightnessController.Level(); brightnessController.Set(Controllers::BrightnessController::Levels::Low); @@ -47,14 +47,13 @@ FlashLight::FlashLight(System::SystemTask& systemTask, Controllers::BrightnessCo backgroundAction->user_data = this; lv_obj_set_event_cb(backgroundAction, EventHandler); - systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping); + wakeLock.Lock(); } FlashLight::~FlashLight() { lv_obj_clean(lv_scr_act()); lv_obj_set_style_local_bg_color(lv_scr_act(), LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_BLACK); brightnessController.Set(previousBrightnessLevel); - systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping); } void FlashLight::SetColors() { diff --git a/src/displayapp/screens/FlashLight.h b/src/displayapp/screens/FlashLight.h index c5404e93..00ef4a7e 100644 --- a/src/displayapp/screens/FlashLight.h +++ b/src/displayapp/screens/FlashLight.h @@ -3,6 +3,7 @@ #include "displayapp/screens/Screen.h" #include "components/brightness/BrightnessController.h" #include "systemtask/SystemTask.h" +#include "systemtask/WakeLock.h" #include #include @@ -23,7 +24,7 @@ namespace Pinetime { void SetIndicators(); void SetColors(); - Pinetime::System::SystemTask& systemTask; + Pinetime::System::WakeLock wakeLock; Controllers::BrightnessController& brightnessController; Controllers::BrightnessController::Levels brightnessLevel = Controllers::BrightnessController::Levels::High; diff --git a/src/displayapp/screens/HeartRate.cpp b/src/displayapp/screens/HeartRate.cpp index 9677be3b..1a84d349 100644 --- a/src/displayapp/screens/HeartRate.cpp +++ b/src/displayapp/screens/HeartRate.cpp @@ -29,7 +29,7 @@ namespace { } HeartRate::HeartRate(Controllers::HeartRateController& heartRateController, System::SystemTask& systemTask) - : heartRateController {heartRateController}, systemTask {systemTask} { + : heartRateController {heartRateController}, wakeLock(systemTask) { bool isHrRunning = heartRateController.State() != Controllers::HeartRateController::States::Stopped; label_hr = lv_label_create(lv_scr_act(), nullptr); @@ -63,7 +63,7 @@ HeartRate::HeartRate(Controllers::HeartRateController& heartRateController, Syst label_startStop = lv_label_create(btn_startStop, nullptr); UpdateStartStopButton(isHrRunning); if (isHrRunning) { - systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping); + wakeLock.Lock(); } taskRefresh = lv_task_create(RefreshTaskCallback, 100, LV_TASK_PRIO_MID, this); @@ -72,7 +72,6 @@ HeartRate::HeartRate(Controllers::HeartRateController& heartRateController, Syst HeartRate::~HeartRate() { lv_task_del(taskRefresh); lv_obj_clean(lv_scr_act()); - systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping); } void HeartRate::Refresh() { @@ -101,12 +100,12 @@ void HeartRate::OnStartStopEvent(lv_event_t event) { if (heartRateController.State() == Controllers::HeartRateController::States::Stopped) { heartRateController.Start(); UpdateStartStopButton(heartRateController.State() != Controllers::HeartRateController::States::Stopped); - systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping); + wakeLock.Lock(); lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::highlight); } else { heartRateController.Stop(); UpdateStartStopButton(heartRateController.State() != Controllers::HeartRateController::States::Stopped); - systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping); + wakeLock.Release(); lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, Colors::lightGray); } } diff --git a/src/displayapp/screens/HeartRate.h b/src/displayapp/screens/HeartRate.h index bf39209a..88b4918c 100644 --- a/src/displayapp/screens/HeartRate.h +++ b/src/displayapp/screens/HeartRate.h @@ -4,6 +4,7 @@ #include #include "displayapp/screens/Screen.h" #include "systemtask/SystemTask.h" +#include "systemtask/WakeLock.h" #include "Symbols.h" #include #include @@ -27,7 +28,7 @@ namespace Pinetime { private: Controllers::HeartRateController& heartRateController; - Pinetime::System::SystemTask& systemTask; + Pinetime::System::WakeLock wakeLock; void UpdateStartStopButton(bool isRunning); lv_obj_t* label_hr; lv_obj_t* label_bpm; diff --git a/src/displayapp/screens/Metronome.cpp b/src/displayapp/screens/Metronome.cpp index 314fde73..6b758470 100644 --- a/src/displayapp/screens/Metronome.cpp +++ b/src/displayapp/screens/Metronome.cpp @@ -22,7 +22,7 @@ namespace { } Metronome::Metronome(Controllers::MotorController& motorController, System::SystemTask& systemTask) - : motorController {motorController}, systemTask {systemTask} { + : motorController {motorController}, wakeLock(systemTask) { bpmArc = lv_arc_create(lv_scr_act(), nullptr); bpmArc->user_data = this; @@ -72,7 +72,6 @@ Metronome::Metronome(Controllers::MotorController& motorController, System::Syst Metronome::~Metronome() { lv_task_del(taskRefresh); - systemTask.PushMessage(System::Messages::EnableSleeping); lv_obj_clean(lv_scr_act()); } @@ -128,12 +127,12 @@ void Metronome::OnEvent(lv_obj_t* obj, lv_event_t event) { metronomeStarted = !metronomeStarted; if (metronomeStarted) { lv_label_set_text_static(lblPlayPause, Symbols::pause); - systemTask.PushMessage(System::Messages::DisableSleeping); + wakeLock.Lock(); startTime = xTaskGetTickCount(); counter = 1; } else { lv_label_set_text_static(lblPlayPause, Symbols::play); - systemTask.PushMessage(System::Messages::EnableSleeping); + wakeLock.Release(); } } break; diff --git a/src/displayapp/screens/Metronome.h b/src/displayapp/screens/Metronome.h index c498048e..fab7ff87 100644 --- a/src/displayapp/screens/Metronome.h +++ b/src/displayapp/screens/Metronome.h @@ -1,6 +1,7 @@ #pragma once #include "systemtask/SystemTask.h" +#include "systemtask/WakeLock.h" #include "components/motor/MotorController.h" #include "displayapp/screens/Screen.h" #include "Symbols.h" @@ -21,7 +22,7 @@ namespace Pinetime { TickType_t startTime = 0; TickType_t tappedTime = 0; Controllers::MotorController& motorController; - System::SystemTask& systemTask; + System::WakeLock wakeLock; int16_t bpm = 120; uint8_t bpb = 4; uint8_t counter = 1; diff --git a/src/displayapp/screens/Notifications.cpp b/src/displayapp/screens/Notifications.cpp index 3a3f5f2b..45f72f2e 100644 --- a/src/displayapp/screens/Notifications.cpp +++ b/src/displayapp/screens/Notifications.cpp @@ -20,7 +20,7 @@ Notifications::Notifications(DisplayApp* app, notificationManager {notificationManager}, alertNotificationService {alertNotificationService}, motorController {motorController}, - systemTask {systemTask}, + wakeLock(systemTask), mode {mode} { notificationManager.ClearNewNotificationFlag(); @@ -40,7 +40,7 @@ Notifications::Notifications(DisplayApp* app, validDisplay = false; } if (mode == Modes::Preview) { - systemTask.PushMessage(System::Messages::DisableSleeping); + wakeLock.Lock(); if (notification.category == Controllers::NotificationManager::Categories::IncomingCall) { motorController.StartRinging(); } else { @@ -65,7 +65,6 @@ Notifications::~Notifications() { lv_task_del(taskRefresh); // make sure we stop any vibrations before exiting motorController.StopRinging(); - systemTask.PushMessage(System::Messages::EnableSleeping); lv_obj_clean(lv_scr_act()); } @@ -120,7 +119,7 @@ void Notifications::Refresh() { } void Notifications::OnPreviewInteraction() { - systemTask.PushMessage(System::Messages::EnableSleeping); + wakeLock.Release(); motorController.StopRinging(); if (timeoutLine != nullptr) { lv_obj_del(timeoutLine); diff --git a/src/displayapp/screens/Notifications.h b/src/displayapp/screens/Notifications.h index 114316b3..8488dc5b 100644 --- a/src/displayapp/screens/Notifications.h +++ b/src/displayapp/screens/Notifications.h @@ -8,6 +8,7 @@ #include "components/ble/NotificationManager.h" #include "components/motor/MotorController.h" #include "systemtask/SystemTask.h" +#include "systemtask/WakeLock.h" namespace Pinetime { namespace Controllers { @@ -73,7 +74,7 @@ namespace Pinetime { Pinetime::Controllers::NotificationManager& notificationManager; Pinetime::Controllers::AlertNotificationService& alertNotificationService; Pinetime::Controllers::MotorController& motorController; - System::SystemTask& systemTask; + System::WakeLock wakeLock; Modes mode = Modes::Normal; std::unique_ptr currentItem; Pinetime::Controllers::NotificationManager::Notification::Id currentId; diff --git a/src/displayapp/screens/StopWatch.cpp b/src/displayapp/screens/StopWatch.cpp index f0359da4..ff852beb 100644 --- a/src/displayapp/screens/StopWatch.cpp +++ b/src/displayapp/screens/StopWatch.cpp @@ -34,7 +34,7 @@ namespace { constexpr TickType_t blinkInterval = pdMS_TO_TICKS(1000); } -StopWatch::StopWatch(System::SystemTask& systemTask) : systemTask {systemTask} { +StopWatch::StopWatch(System::SystemTask& systemTask) : wakeLock(systemTask) { static constexpr uint8_t btnWidth = 115; static constexpr uint8_t btnHeight = 80; btnPlayPause = lv_btn_create(lv_scr_act(), nullptr); @@ -79,7 +79,6 @@ StopWatch::StopWatch(System::SystemTask& systemTask) : systemTask {systemTask} { StopWatch::~StopWatch() { lv_task_del(taskRefresh); - systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping); lv_obj_clean(lv_scr_act()); } @@ -135,7 +134,7 @@ void StopWatch::Start() { SetInterfaceRunning(); startTime = xTaskGetTickCount(); currentState = States::Running; - systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping); + wakeLock.Lock(); } void StopWatch::Pause() { @@ -145,7 +144,7 @@ void StopWatch::Pause() { oldTimeElapsed = laps[lapsDone]; blinkTime = xTaskGetTickCount() + blinkInterval; currentState = States::Halted; - systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping); + wakeLock.Release(); } void StopWatch::Refresh() { diff --git a/src/displayapp/screens/StopWatch.h b/src/displayapp/screens/StopWatch.h index 3386d042..55a178dc 100644 --- a/src/displayapp/screens/StopWatch.h +++ b/src/displayapp/screens/StopWatch.h @@ -7,6 +7,7 @@ #include "portmacro_cmsis.h" #include "systemtask/SystemTask.h" +#include "systemtask/WakeLock.h" #include "displayapp/apps/Apps.h" #include "displayapp/Controllers.h" #include "Symbols.h" @@ -43,7 +44,7 @@ namespace Pinetime { void Start(); void Pause(); - Pinetime::System::SystemTask& systemTask; + Pinetime::System::WakeLock wakeLock; States currentState = States::Init; TickType_t startTime; TickType_t oldTimeElapsed = 0; diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 4c623883..e55c9ad8 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -189,15 +189,11 @@ void SystemTask::Work() { if (xQueueReceive(systemTasksMsgQueue, &msg, 100) == pdTRUE) { switch (msg) { case Messages::EnableSleeping: - // Make sure that exiting an app doesn't enable sleeping, - // if the exiting was caused by a firmware update - if (!bleController.IsFirmwareUpdating()) { - doNotGoToSleep = false; - } + wakeLocksHeld--; break; case Messages::DisableSleeping: GoToRunning(); - doNotGoToSleep = true; + wakeLocksHeld++; break; case Messages::GoToRunning: GoToRunning(); @@ -243,24 +239,24 @@ void SystemTask::Work() { break; case Messages::BleFirmwareUpdateStarted: GoToRunning(); - doNotGoToSleep = true; + wakeLocksHeld++; displayApp.PushMessage(Pinetime::Applications::Display::Messages::BleFirmwareUpdateStarted); break; case Messages::BleFirmwareUpdateFinished: if (bleController.State() == Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated) { NVIC_SystemReset(); } - doNotGoToSleep = false; + wakeLocksHeld--; break; case Messages::StartFileTransfer: NRF_LOG_INFO("[systemtask] FS Started"); GoToRunning(); - doNotGoToSleep = true; + wakeLocksHeld++; // TODO add intent of fs access icon or something break; case Messages::StopFileTransfer: NRF_LOG_INFO("[systemtask] FS Stopped"); - doNotGoToSleep = false; + wakeLocksHeld--; // TODO add intent of fs access icon or something break; case Messages::OnTouchEvent: diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index 339587c1..8a4e5954 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -80,7 +80,7 @@ namespace Pinetime { void OnTouchEvent(); bool IsSleepDisabled() { - return doNotGoToSleep; + return wakeLocksHeld > 0; } Pinetime::Controllers::NimbleController& nimble() { @@ -124,7 +124,7 @@ namespace Pinetime { bool isBleDiscoveryTimerRunning = false; uint8_t bleDiscoveryTimer = 0; TimerHandle_t measureBatteryTimer; - bool doNotGoToSleep = false; + uint8_t wakeLocksHeld = 0; SystemTaskState state = SystemTaskState::Running; void HandleButtonAction(Controllers::ButtonActions action); diff --git a/src/systemtask/WakeLock.cpp b/src/systemtask/WakeLock.cpp new file mode 100644 index 00000000..2953f7ee --- /dev/null +++ b/src/systemtask/WakeLock.cpp @@ -0,0 +1,27 @@ +#include "systemtask/WakeLock.h" + +using namespace Pinetime::System; + +WakeLock::WakeLock(SystemTask& systemTask) : systemTask {systemTask} { + lockHeld = false; +} + +WakeLock::~WakeLock() { + Release(); +} + +void WakeLock::Lock() { + if (lockHeld) { + return; + } + systemTask.PushMessage(Messages::DisableSleeping); + lockHeld = true; +} + +void WakeLock::Release() { + if (!lockHeld) { + return; + } + systemTask.PushMessage(Messages::EnableSleeping); + lockHeld = false; +} diff --git a/src/systemtask/WakeLock.h b/src/systemtask/WakeLock.h new file mode 100644 index 00000000..5424c009 --- /dev/null +++ b/src/systemtask/WakeLock.h @@ -0,0 +1,19 @@ +#pragma once + +#include "systemtask/SystemTask.h" + +namespace Pinetime { + namespace System { + class WakeLock { + public: + WakeLock(SystemTask& systemTask); + ~WakeLock(); + void Lock(); + void Release(); + + private: + bool lockHeld; + SystemTask& systemTask; + }; + } +} From ad3bf49c7b2864d8f06cedea8ad329e26360f297 Mon Sep 17 00:00:00 2001 From: mark9064 <30447455+mark9064@users.noreply.github.com> Date: Sat, 21 Sep 2024 23:29:15 +0100 Subject: [PATCH 09/14] Atomic HRS reads (#1845) - Combine the reading of all `HRS3300` registers into one I2C read so data is not partial - Downsizes both HRS and ALS to 16bit as the sensor does not generate larger than 16bit values in its current configuration - Increasing the resolution by 1 bit doubles the sensor acquisition time, since we are already at 10Hz we are never going to use a higher resolution - The PPG algorithm buffers for ALS/HRS are already 16bit anyway - Remove functions for setting gain / drive that are unused throughout the codebase - Calculate constants with constexpr --- src/components/heartrate/Ppg.cpp | 2 +- src/components/heartrate/Ppg.h | 2 +- src/drivers/Hrs3300.cpp | 57 ++++++++++++++--------------- src/drivers/Hrs3300.h | 10 +++-- src/heartratetask/HeartRateTask.cpp | 3 +- 5 files changed, 37 insertions(+), 37 deletions(-) diff --git a/src/components/heartrate/Ppg.cpp b/src/components/heartrate/Ppg.cpp index 3a6988ae..efbed852 100644 --- a/src/components/heartrate/Ppg.cpp +++ b/src/components/heartrate/Ppg.cpp @@ -142,7 +142,7 @@ Ppg::Ppg() { spectrum.fill(0.0f); } -int8_t Ppg::Preprocess(uint32_t hrs, uint32_t als) { +int8_t Ppg::Preprocess(uint16_t hrs, uint16_t als) { if (dataIndex < dataLength) { dataHRS[dataIndex++] = hrs; } diff --git a/src/components/heartrate/Ppg.h b/src/components/heartrate/Ppg.h index 4492b2c2..373e7985 100644 --- a/src/components/heartrate/Ppg.h +++ b/src/components/heartrate/Ppg.h @@ -14,7 +14,7 @@ namespace Pinetime { class Ppg { public: Ppg(); - int8_t Preprocess(uint32_t hrs, uint32_t als); + int8_t Preprocess(uint16_t hrs, uint16_t als); int HeartRate(); void Reset(bool resetDaqBuffer); static constexpr int deltaTms = 100; diff --git a/src/drivers/Hrs3300.cpp b/src/drivers/Hrs3300.cpp index 33889b6f..9c77975e 100644 --- a/src/drivers/Hrs3300.cpp +++ b/src/drivers/Hrs3300.cpp @@ -67,40 +67,37 @@ void Hrs3300::Disable() { WriteRegister(static_cast(Registers::PDriver), 0); } -uint32_t Hrs3300::ReadHrs() { - auto m = ReadRegister(static_cast(Registers::C0DataM)); - auto h = ReadRegister(static_cast(Registers::C0DataH)); - auto l = ReadRegister(static_cast(Registers::C0dataL)); - return ((l & 0x30) << 12) | (m << 8) | ((h & 0x0f) << 4) | (l & 0x0f); -} +Hrs3300::PackedHrsAls Hrs3300::ReadHrsAls() { + constexpr Registers dataRegisters[] = + {Registers::C1dataM, Registers::C0DataM, Registers::C0DataH, Registers::C1dataH, Registers::C1dataL, Registers::C0dataL}; + // Calculate smallest register address + constexpr uint8_t baseOffset = static_cast(*std::min_element(std::begin(dataRegisters), std::end(dataRegisters))); + // Calculate largest address to determine length of read needed + // Add one to largest relative index to find the length + constexpr uint8_t length = static_cast(*std::max_element(std::begin(dataRegisters), std::end(dataRegisters))) - baseOffset + 1; -uint32_t Hrs3300::ReadAls() { - auto m = ReadRegister(static_cast(Registers::C1dataM)); - auto h = ReadRegister(static_cast(Registers::C1dataH)); - auto l = ReadRegister(static_cast(Registers::C1dataL)); - return ((h & 0x3f) << 11) | (m << 3) | (l & 0x07); -} - -void Hrs3300::SetGain(uint8_t gain) { - constexpr uint8_t maxGain = 64U; - gain = std::min(gain, maxGain); - uint8_t hgain = 0; - while ((1 << hgain) < gain) { - ++hgain; + Hrs3300::PackedHrsAls res; + uint8_t buf[length]; + auto ret = twiMaster.Read(twiAddress, baseOffset, buf, length); + if (ret != TwiMaster::ErrorCodes::NoError) { + NRF_LOG_INFO("READ ERROR"); } + // hrs + uint8_t m = static_cast(Registers::C0DataM) - baseOffset; + uint8_t h = static_cast(Registers::C0DataH) - baseOffset; + uint8_t l = static_cast(Registers::C0dataL) - baseOffset; + // There are two extra bits (17 and 18) but they are not read here + // as resolutions >16bit aren't practically useful (too slow) and + // all hrs values throughout InfiniTime are 16bit + res.hrs = (buf[m] << 8) | ((buf[h] & 0x0f) << 4) | (buf[l] & 0x0f); - WriteRegister(static_cast(Registers::Hgain), hgain << 2); -} + // als + m = static_cast(Registers::C1dataM) - baseOffset; + h = static_cast(Registers::C1dataH) - baseOffset; + l = static_cast(Registers::C1dataL) - baseOffset; + res.als = ((buf[h] & 0x3f) << 11) | (buf[m] << 3) | (buf[l] & 0x07); -void Hrs3300::SetDrive(uint8_t drive) { - auto en = ReadRegister(static_cast(Registers::Enable)); - auto pd = ReadRegister(static_cast(Registers::PDriver)); - - en = (en & 0xf7) | ((drive & 2) << 2); - pd = (pd & 0xbf) | ((drive & 1) << 6); - - WriteRegister(static_cast(Registers::Enable), en); - WriteRegister(static_cast(Registers::PDriver), pd); + return res; } void Hrs3300::WriteRegister(uint8_t reg, uint8_t data) { diff --git a/src/drivers/Hrs3300.h b/src/drivers/Hrs3300.h index 8bbdc69a..6f721448 100644 --- a/src/drivers/Hrs3300.h +++ b/src/drivers/Hrs3300.h @@ -21,6 +21,11 @@ namespace Pinetime { Hgain = 0x17 }; + struct PackedHrsAls { + uint16_t hrs; + uint16_t als; + }; + Hrs3300(TwiMaster& twiMaster, uint8_t twiAddress); Hrs3300(const Hrs3300&) = delete; Hrs3300& operator=(const Hrs3300&) = delete; @@ -30,10 +35,7 @@ namespace Pinetime { void Init(); void Enable(); void Disable(); - uint32_t ReadHrs(); - uint32_t ReadAls(); - void SetGain(uint8_t gain); - void SetDrive(uint8_t drive); + PackedHrsAls ReadHrsAls(); private: TwiMaster& twiMaster; diff --git a/src/heartratetask/HeartRateTask.cpp b/src/heartratetask/HeartRateTask.cpp index 9d82d11e..8a5a871b 100644 --- a/src/heartratetask/HeartRateTask.cpp +++ b/src/heartratetask/HeartRateTask.cpp @@ -70,7 +70,8 @@ void HeartRateTask::Work() { } if (measurementStarted) { - int8_t ambient = ppg.Preprocess(heartRateSensor.ReadHrs(), heartRateSensor.ReadAls()); + auto sensorData = heartRateSensor.ReadHrsAls(); + int8_t ambient = ppg.Preprocess(sensorData.hrs, sensorData.als); int bpm = ppg.HeartRate(); // If ambient light detected or a reset requested (bpm < 0) From 997e4cee8cc78a6e0b68cc78b604dc342f22b584 Mon Sep 17 00:00:00 2001 From: Reinhold Gschweicher Date: Sun, 22 Sep 2024 11:28:04 +0200 Subject: [PATCH 10/14] Hrs3300: fix includes for std::begin/std::end Fix for Hrs3300 PR about Atomic HRS reads: https://github.com/InfiniTimeOrg/InfiniTime/pull/1845 We use `std::begin` and `std::end`, but we don't include one of the headers that define those functions. See https://en.cppreference.com/w/cpp/iterator/begin for a list of headers that define `std::begin` and `std::end`. Starting with GCC 14 this leads to a compilation error presumably because they cleaned up their headers. Fix code by inlcuding `` --- src/drivers/Hrs3300.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/drivers/Hrs3300.cpp b/src/drivers/Hrs3300.cpp index 9c77975e..a4b72479 100644 --- a/src/drivers/Hrs3300.cpp +++ b/src/drivers/Hrs3300.cpp @@ -6,6 +6,7 @@ #include "drivers/Hrs3300.h" #include +#include #include #include From a0cd439efc9b0d0d9610dea7ff749f102d5a316d Mon Sep 17 00:00:00 2001 From: NeroBurner Date: Sat, 28 Sep 2024 08:14:08 +0200 Subject: [PATCH 11/14] Alarm persist to flash (#1367) * AlarmController: Add saving alarm time to file Save the set alarm time to the SPI NOR flash, so it does not reset to the default value when the watch resets, e.g. due to watchdog timeout or reflashing of a new version of InfiniTime. Just like the `Settings.h` `LoadSettingsFromFile()` the previous alarm at boot (if available) and `SaveSettingsToFile()` the current alarm when the `Alarm.h` screen is closed (only if the settings have changed). The alarm-settings file is stored in `.system/alarm.dat`. The `.system` folder is created if it doesn't yet exist. Fixes: https://github.com/InfiniTimeOrg/InfiniTime/issues/1330 * alarmController: close .system dir after usage Close the `lfs_dir` object for the `.system` dir after usage. Otherwise on the second changed alarm the system will lockup because the `.system` dir is already open and was never closed. --------- Co-authored-by: Galdor Takacs --- src/components/alarm/AlarmController.cpp | 101 ++++++++++++++++++++--- src/components/alarm/AlarmController.h | 46 +++++++---- src/displayapp/screens/Alarm.cpp | 26 +++--- src/main.cpp | 2 +- src/systemtask/SystemTask.cpp | 8 +- 5 files changed, 135 insertions(+), 48 deletions(-) diff --git a/src/components/alarm/AlarmController.cpp b/src/components/alarm/AlarmController.cpp index c4eb8ed0..7dbfb0e3 100644 --- a/src/components/alarm/AlarmController.cpp +++ b/src/components/alarm/AlarmController.cpp @@ -19,11 +19,13 @@ #include "systemtask/SystemTask.h" #include "task.h" #include +#include using namespace Pinetime::Controllers; using namespace std::chrono_literals; -AlarmController::AlarmController(Controllers::DateTime& dateTimeController) : dateTimeController {dateTimeController} { +AlarmController::AlarmController(Controllers::DateTime& dateTimeController, Controllers::FS& fs) + : dateTimeController {dateTimeController}, fs {fs} { } namespace { @@ -36,11 +38,28 @@ namespace { void AlarmController::Init(System::SystemTask* systemTask) { this->systemTask = systemTask; alarmTimer = xTimerCreate("Alarm", 1, pdFALSE, this, SetOffAlarm); + LoadSettingsFromFile(); + if (alarm.isEnabled) { + NRF_LOG_INFO("[AlarmController] Loaded alarm was enabled, scheduling"); + ScheduleAlarm(); + } +} + +void AlarmController::SaveAlarm() { + // verify if it is necessary to save + if (alarmChanged) { + SaveSettingsToFile(); + } + alarmChanged = false; } void AlarmController::SetAlarmTime(uint8_t alarmHr, uint8_t alarmMin) { - hours = alarmHr; - minutes = alarmMin; + if (alarm.hours == alarmHr && alarm.minutes == alarmMin) { + return; + } + alarm.hours = alarmHr; + alarm.minutes = alarmMin; + alarmChanged = true; } void AlarmController::ScheduleAlarm() { @@ -53,18 +72,19 @@ void AlarmController::ScheduleAlarm() { tm* tmAlarmTime = std::localtime(&ttAlarmTime); // If the time being set has already passed today,the alarm should be set for tomorrow - if (hours < dateTimeController.Hours() || (hours == dateTimeController.Hours() && minutes <= dateTimeController.Minutes())) { + if (alarm.hours < dateTimeController.Hours() || + (alarm.hours == dateTimeController.Hours() && alarm.minutes <= dateTimeController.Minutes())) { tmAlarmTime->tm_mday += 1; // tm_wday doesn't update automatically tmAlarmTime->tm_wday = (tmAlarmTime->tm_wday + 1) % 7; } - tmAlarmTime->tm_hour = hours; - tmAlarmTime->tm_min = minutes; + tmAlarmTime->tm_hour = alarm.hours; + tmAlarmTime->tm_min = alarm.minutes; tmAlarmTime->tm_sec = 0; // if alarm is in weekday-only mode, make sure it shifts to the next weekday - if (recurrence == RecurType::Weekdays) { + if (alarm.recurrence == RecurType::Weekdays) { if (tmAlarmTime->tm_wday == 0) { // Sunday, shift 1 day tmAlarmTime->tm_mday += 1; } else if (tmAlarmTime->tm_wday == 6) { // Saturday, shift 2 days @@ -79,7 +99,10 @@ void AlarmController::ScheduleAlarm() { xTimerChangePeriod(alarmTimer, secondsToAlarm * configTICK_RATE_HZ, 0); xTimerStart(alarmTimer, 0); - state = AlarmState::Set; + if (!alarm.isEnabled) { + alarm.isEnabled = true; + alarmChanged = true; + } } uint32_t AlarmController::SecondsToAlarm() const { @@ -88,20 +111,72 @@ uint32_t AlarmController::SecondsToAlarm() const { void AlarmController::DisableAlarm() { xTimerStop(alarmTimer, 0); - state = AlarmState::Not_Set; + isAlerting = false; + if (alarm.isEnabled) { + alarm.isEnabled = false; + alarmChanged = true; + } } void AlarmController::SetOffAlarmNow() { - state = AlarmState::Alerting; + isAlerting = true; systemTask->PushMessage(System::Messages::SetOffAlarm); } void AlarmController::StopAlerting() { - // Alarm state is off unless this is a recurring alarm - if (recurrence == RecurType::None) { - state = AlarmState::Not_Set; + isAlerting = false; + // Disable alarm unless it is recurring + if (alarm.recurrence == RecurType::None) { + alarm.isEnabled = false; + alarmChanged = true; } else { // set next instance ScheduleAlarm(); } } + +void AlarmController::SetRecurrence(RecurType recurrence) { + if (alarm.recurrence != recurrence) { + alarm.recurrence = recurrence; + alarmChanged = true; + } +} + +void AlarmController::LoadSettingsFromFile() { + lfs_file_t alarmFile; + AlarmSettings alarmBuffer; + + if (fs.FileOpen(&alarmFile, "/.system/alarm.dat", LFS_O_RDONLY) != LFS_ERR_OK) { + NRF_LOG_WARNING("[AlarmController] Failed to open alarm data file"); + return; + } + + fs.FileRead(&alarmFile, reinterpret_cast(&alarmBuffer), sizeof(alarmBuffer)); + fs.FileClose(&alarmFile); + if (alarmBuffer.version != alarmFormatVersion) { + NRF_LOG_WARNING("[AlarmController] Loaded alarm settings has version %u instead of %u, discarding", + alarmBuffer.version, + alarmFormatVersion); + return; + } + + alarm = alarmBuffer; + NRF_LOG_INFO("[AlarmController] Loaded alarm settings from file"); +} + +void AlarmController::SaveSettingsToFile() const { + lfs_dir systemDir; + if (fs.DirOpen("/.system", &systemDir) != LFS_ERR_OK) { + fs.DirCreate("/.system"); + } + fs.DirClose(&systemDir); + lfs_file_t alarmFile; + if (fs.FileOpen(&alarmFile, "/.system/alarm.dat", LFS_O_WRONLY | LFS_O_CREAT) != LFS_ERR_OK) { + NRF_LOG_WARNING("[AlarmController] Failed to open alarm data file for saving"); + return; + } + + fs.FileWrite(&alarmFile, reinterpret_cast(&alarm), sizeof(alarm)); + fs.FileClose(&alarmFile); + NRF_LOG_INFO("[AlarmController] Saved alarm settings with format version %u to file", alarm.version); +} diff --git a/src/components/alarm/AlarmController.h b/src/components/alarm/AlarmController.h index 8ac0de9a..278e9cdb 100644 --- a/src/components/alarm/AlarmController.h +++ b/src/components/alarm/AlarmController.h @@ -30,47 +30,65 @@ namespace Pinetime { namespace Controllers { class AlarmController { public: - AlarmController(Controllers::DateTime& dateTimeController); + AlarmController(Controllers::DateTime& dateTimeController, Controllers::FS& fs); void Init(System::SystemTask* systemTask); + void SaveAlarm(); void SetAlarmTime(uint8_t alarmHr, uint8_t alarmMin); void ScheduleAlarm(); void DisableAlarm(); void SetOffAlarmNow(); uint32_t SecondsToAlarm() const; void StopAlerting(); - enum class AlarmState { Not_Set, Set, Alerting }; enum class RecurType { None, Daily, Weekdays }; uint8_t Hours() const { - return hours; + return alarm.hours; } uint8_t Minutes() const { - return minutes; + return alarm.minutes; } - AlarmState State() const { - return state; + bool IsAlerting() const { + return isAlerting; + } + + bool IsEnabled() const { + return alarm.isEnabled; } RecurType Recurrence() const { - return recurrence; + return alarm.recurrence; } - void SetRecurrence(RecurType recurType) { - recurrence = recurType; - } + void SetRecurrence(RecurType recurrence); private: + // Versions 255 is reserved for now, so the version field can be made + // bigger, should it ever be needed. + static constexpr uint8_t alarmFormatVersion = 1; + + struct AlarmSettings { + uint8_t version = alarmFormatVersion; + uint8_t hours = 7; + uint8_t minutes = 0; + RecurType recurrence = RecurType::None; + bool isEnabled = false; + }; + + bool isAlerting = false; + bool alarmChanged = false; + Controllers::DateTime& dateTimeController; + Controllers::FS& fs; System::SystemTask* systemTask = nullptr; TimerHandle_t alarmTimer; - uint8_t hours = 7; - uint8_t minutes = 0; + AlarmSettings alarm; std::chrono::time_point alarmTime; - AlarmState state = AlarmState::Not_Set; - RecurType recurrence = RecurType::None; + + void LoadSettingsFromFile(); + void SaveSettingsToFile() const; }; } } diff --git a/src/displayapp/screens/Alarm.cpp b/src/displayapp/screens/Alarm.cpp index 292fb075..b1e67363 100644 --- a/src/displayapp/screens/Alarm.cpp +++ b/src/displayapp/screens/Alarm.cpp @@ -117,7 +117,7 @@ Alarm::Alarm(Controllers::AlarmController& alarmController, UpdateAlarmTime(); - if (alarmController.State() == Controllers::AlarmController::AlarmState::Alerting) { + if (alarmController.IsAlerting()) { SetAlerting(); } else { SetSwitchState(LV_ANIM_OFF); @@ -125,14 +125,15 @@ Alarm::Alarm(Controllers::AlarmController& alarmController, } Alarm::~Alarm() { - if (alarmController.State() == AlarmController::AlarmState::Alerting) { + if (alarmController.IsAlerting()) { StopAlerting(); } lv_obj_clean(lv_scr_act()); + alarmController.SaveAlarm(); } void Alarm::DisableAlarm() { - if (alarmController.State() == AlarmController::AlarmState::Set) { + if (alarmController.IsEnabled()) { alarmController.DisableAlarm(); lv_switch_off(enableSwitch, LV_ANIM_ON); } @@ -172,7 +173,7 @@ bool Alarm::OnButtonPushed() { HideInfo(); return true; } - if (alarmController.State() == AlarmController::AlarmState::Alerting) { + if (alarmController.IsAlerting()) { StopAlerting(); return true; } @@ -181,7 +182,7 @@ bool Alarm::OnButtonPushed() { bool Alarm::OnTouchEvent(Pinetime::Applications::TouchEvents event) { // Don't allow closing the screen by swiping while the alarm is alerting - return alarmController.State() == AlarmController::AlarmState::Alerting && event == TouchEvents::SwipeDown; + return alarmController.IsAlerting() && event == TouchEvents::SwipeDown; } void Alarm::OnValueChanged() { @@ -222,15 +223,10 @@ void Alarm::StopAlerting() { } void Alarm::SetSwitchState(lv_anim_enable_t anim) { - switch (alarmController.State()) { - case AlarmController::AlarmState::Set: - lv_switch_on(enableSwitch, anim); - break; - case AlarmController::AlarmState::Not_Set: - lv_switch_off(enableSwitch, anim); - break; - default: - break; + if (alarmController.IsEnabled()) { + lv_switch_on(enableSwitch, anim); + } else { + lv_switch_off(enableSwitch, anim); } } @@ -247,7 +243,7 @@ void Alarm::ShowInfo() { txtMessage = lv_label_create(btnMessage, nullptr); lv_obj_set_style_local_bg_color(btnMessage, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_NAVY); - if (alarmController.State() == AlarmController::AlarmState::Set) { + if (alarmController.IsEnabled()) { auto timeToAlarm = alarmController.SecondsToAlarm(); auto daysToAlarm = timeToAlarm / 86400; diff --git a/src/main.cpp b/src/main.cpp index ab50fa74..84f30eef 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -104,7 +104,7 @@ Pinetime::Controllers::DateTime dateTimeController {settingsController}; Pinetime::Drivers::Watchdog watchdog; Pinetime::Controllers::NotificationManager notificationManager; Pinetime::Controllers::MotionController motionController; -Pinetime::Controllers::AlarmController alarmController {dateTimeController}; +Pinetime::Controllers::AlarmController alarmController {dateTimeController, fs}; Pinetime::Controllers::TouchHandler touchHandler; Pinetime::Controllers::ButtonHandler buttonHandler; Pinetime::Controllers::BrightnessController brightnessController {}; diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index e55c9ad8..fc4e8f7e 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -216,7 +216,7 @@ void SystemTask::Work() { GoToSleep(); break; case Messages::OnNewTime: - if (alarmController.State() == Controllers::AlarmController::AlarmState::Set) { + if (alarmController.IsEnabled()) { alarmController.ScheduleAlarm(); } break; @@ -317,8 +317,7 @@ void SystemTask::Work() { case Messages::OnNewHour: using Pinetime::Controllers::AlarmController; if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep && - settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours && - alarmController.State() != AlarmController::AlarmState::Alerting) { + settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::Hours && !alarmController.IsAlerting()) { GoToRunning(); displayApp.PushMessage(Pinetime::Applications::Display::Messages::Chime); } @@ -326,8 +325,7 @@ void SystemTask::Work() { case Messages::OnNewHalfHour: using Pinetime::Controllers::AlarmController; if (settingsController.GetNotificationStatus() != Controllers::Settings::Notification::Sleep && - settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours && - alarmController.State() != AlarmController::AlarmState::Alerting) { + settingsController.GetChimeOption() == Controllers::Settings::ChimesOption::HalfHours && !alarmController.IsAlerting()) { GoToRunning(); displayApp.PushMessage(Pinetime::Applications::Display::Messages::Chime); } From 3db4e012ceb38602912edad75ccbbcd8834bcae6 Mon Sep 17 00:00:00 2001 From: NeroBurner Date: Sun, 29 Sep 2024 19:39:14 +0200 Subject: [PATCH 12/14] Remove unused pointer to DisplayApp member variables (#2125) In the screens that use `DisplayApp *app` and pass it to a child item, or use the reference just in the constructor. Afterwards the `app` member is not used. So remove it from the private member variables. Completely remove `app` parameter from `SettingDisplay` constructor as it is unused. --- src/displayapp/DisplayApp.cpp | 2 +- src/displayapp/screens/SystemInfo.cpp | 3 +-- src/displayapp/screens/SystemInfo.h | 1 - src/displayapp/screens/settings/SettingDisplay.cpp | 3 +-- src/displayapp/screens/settings/SettingDisplay.h | 3 +-- src/displayapp/screens/settings/SettingSetDateTime.cpp | 3 +-- src/displayapp/screens/settings/SettingSetDateTime.h | 1 - src/displayapp/screens/settings/SettingWatchFace.cpp | 3 +-- src/displayapp/screens/settings/SettingWatchFace.h | 1 - 9 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 076b4f8a..ff43bb81 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -582,7 +582,7 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio currentScreen = std::make_unique(settingsController); break; case Apps::SettingDisplay: - currentScreen = std::make_unique(this, settingsController); + currentScreen = std::make_unique(settingsController); break; case Apps::SettingSteps: currentScreen = std::make_unique(settingsController); diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index dd39f88a..d265fddd 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -40,8 +40,7 @@ SystemInfo::SystemInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::MotionController& motionController, const Pinetime::Drivers::Cst816S& touchPanel, const Pinetime::Drivers::SpiNorFlash& spiNorFlash) - : app {app}, - dateTimeController {dateTimeController}, + : dateTimeController {dateTimeController}, batteryController {batteryController}, brightnessController {brightnessController}, bleController {bleController}, diff --git a/src/displayapp/screens/SystemInfo.h b/src/displayapp/screens/SystemInfo.h index 3129c463..301662dc 100644 --- a/src/displayapp/screens/SystemInfo.h +++ b/src/displayapp/screens/SystemInfo.h @@ -35,7 +35,6 @@ namespace Pinetime { bool OnTouchEvent(TouchEvents event) override; private: - DisplayApp* app; Pinetime::Controllers::DateTime& dateTimeController; const Pinetime::Controllers::Battery& batteryController; Pinetime::Controllers::BrightnessController& brightnessController; diff --git a/src/displayapp/screens/settings/SettingDisplay.cpp b/src/displayapp/screens/settings/SettingDisplay.cpp index 57a64d7f..bbc188a9 100644 --- a/src/displayapp/screens/settings/SettingDisplay.cpp +++ b/src/displayapp/screens/settings/SettingDisplay.cpp @@ -24,8 +24,7 @@ namespace { constexpr std::array SettingDisplay::options; -SettingDisplay::SettingDisplay(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) - : app {app}, settingsController {settingsController} { +SettingDisplay::SettingDisplay(Pinetime::Controllers::Settings& settingsController) : settingsController {settingsController} { lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); diff --git a/src/displayapp/screens/settings/SettingDisplay.h b/src/displayapp/screens/settings/SettingDisplay.h index b6d147c8..3bd10a62 100644 --- a/src/displayapp/screens/settings/SettingDisplay.h +++ b/src/displayapp/screens/settings/SettingDisplay.h @@ -14,14 +14,13 @@ namespace Pinetime { class SettingDisplay : public Screen { public: - SettingDisplay(DisplayApp* app, Pinetime::Controllers::Settings& settingsController); + SettingDisplay(Pinetime::Controllers::Settings& settingsController); ~SettingDisplay() override; void UpdateSelected(lv_obj_t* object, lv_event_t event); void ToggleAlwaysOn(); private: - DisplayApp* app; static constexpr std::array options = {5000, 7000, 10000, 15000, 20000, 30000}; Controllers::Settings& settingsController; diff --git a/src/displayapp/screens/settings/SettingSetDateTime.cpp b/src/displayapp/screens/settings/SettingSetDateTime.cpp index cf9b0638..8926ff31 100644 --- a/src/displayapp/screens/settings/SettingSetDateTime.cpp +++ b/src/displayapp/screens/settings/SettingSetDateTime.cpp @@ -15,8 +15,7 @@ bool SettingSetDateTime::OnTouchEvent(Pinetime::Applications::TouchEvents event) SettingSetDateTime::SettingSetDateTime(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::DateTime& dateTimeController, Pinetime::Controllers::Settings& settingsController) - : app {app}, - dateTimeController {dateTimeController}, + : dateTimeController {dateTimeController}, settingsController {settingsController}, screens {app, 0, diff --git a/src/displayapp/screens/settings/SettingSetDateTime.h b/src/displayapp/screens/settings/SettingSetDateTime.h index 051b1abe..dea283f8 100644 --- a/src/displayapp/screens/settings/SettingSetDateTime.h +++ b/src/displayapp/screens/settings/SettingSetDateTime.h @@ -20,7 +20,6 @@ namespace Pinetime { void Quit(); private: - DisplayApp* app; Controllers::DateTime& dateTimeController; Controllers::Settings& settingsController; diff --git a/src/displayapp/screens/settings/SettingWatchFace.cpp b/src/displayapp/screens/settings/SettingWatchFace.cpp index e01e9f84..0d5168d2 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.cpp +++ b/src/displayapp/screens/settings/SettingWatchFace.cpp @@ -54,8 +54,7 @@ SettingWatchFace::SettingWatchFace(Pinetime::Applications::DisplayApp* app, std::array&& watchfaceItems, Pinetime::Controllers::Settings& settingsController, Pinetime::Controllers::FS& filesystem) - : app {app}, - watchfaceItems {std::move(watchfaceItems)}, + : watchfaceItems {std::move(watchfaceItems)}, settingsController {settingsController}, filesystem {filesystem}, screens {app, 0, CreateScreenList(), Screens::ScreenListModes::UpDown} { diff --git a/src/displayapp/screens/settings/SettingWatchFace.h b/src/displayapp/screens/settings/SettingWatchFace.h index 4c75b0ab..9edc1f7a 100644 --- a/src/displayapp/screens/settings/SettingWatchFace.h +++ b/src/displayapp/screens/settings/SettingWatchFace.h @@ -34,7 +34,6 @@ namespace Pinetime { bool OnTouchEvent(TouchEvents event) override; private: - DisplayApp* app; auto CreateScreenList() const; std::unique_ptr CreateScreen(unsigned int screenNum) const; From a2356f2f4a61f9df77b07d5762581682b1e28c24 Mon Sep 17 00:00:00 2001 From: NeroBurner Date: Sun, 29 Sep 2024 21:10:32 +0200 Subject: [PATCH 13/14] MusicService: add missing includes for TickType_t and xTaskGetTickCount (#2130) Add `FreeRTOS.h` include for the directly used data type `TickType_t` in the header and the function `xTaskGetTickCount` from FreeRTOS's `task.h` --- src/components/ble/MusicService.cpp | 2 ++ src/components/ble/MusicService.h | 1 + 2 files changed, 3 insertions(+) diff --git a/src/components/ble/MusicService.cpp b/src/components/ble/MusicService.cpp index 94d97f46..43cbec70 100644 --- a/src/components/ble/MusicService.cpp +++ b/src/components/ble/MusicService.cpp @@ -18,6 +18,8 @@ #include "components/ble/MusicService.h" #include "components/ble/NimbleController.h" #include +#include +#include namespace { // 0000yyxx-78fc-48fe-8e23-433b3a1942d0 diff --git a/src/components/ble/MusicService.h b/src/components/ble/MusicService.h index f4b902fe..93d94a34 100644 --- a/src/components/ble/MusicService.h +++ b/src/components/ble/MusicService.h @@ -25,6 +25,7 @@ #include #undef max #undef min +#include namespace Pinetime { namespace Controllers { From 8598142c27be692b224cf207d41785fea34f3daa Mon Sep 17 00:00:00 2001 From: NeroBurner Date: Wed, 9 Oct 2024 20:26:08 +0200 Subject: [PATCH 14/14] Remove unused submodule QCBOR (#2138) The submodule isn't used anymore. Remove the submodule reference completely. --- .gitmodules | 3 --- src/libs/QCBOR | 1 - 2 files changed, 4 deletions(-) delete mode 160000 src/libs/QCBOR diff --git a/.gitmodules b/.gitmodules index 7a4e307b..a6b4d5fd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,9 +4,6 @@ [submodule "src/libs/littlefs"] path = src/libs/littlefs url = https://github.com/littlefs-project/littlefs.git -[submodule "src/libs/QCBOR"] - path = src/libs/QCBOR - url = https://github.com/laurencelundblade/QCBOR.git [submodule "src/libs/arduinoFFT"] path = src/libs/arduinoFFT url = https://github.com/kosme/arduinoFFT.git diff --git a/src/libs/QCBOR b/src/libs/QCBOR deleted file mode 160000 index 56b17bf9..00000000 --- a/src/libs/QCBOR +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 56b17bf9f74096774944bcac0829adcd887d391e