From 084123b752c74f7b8a6da23cb9bce0ac4efa3715 Mon Sep 17 00:00:00 2001 From: "joaquim.org" Date: Sun, 11 Jul 2021 14:06:06 +0100 Subject: Using littlefs (#438) * add submodule littlefs * base fs * Save settings using littlefs * Small fixes and suggestions from PR * More small fixes from PR suggestions * Code clean up * Change SpiNorFlash functions to be private in FS --- src/systemtask/SystemTask.cpp | 11 ++++++++--- src/systemtask/SystemTask.h | 12 ++++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) (limited to 'src/systemtask') diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 13755f71..17e78230 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -59,7 +59,8 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi, Controllers::Settings& settingsController, Pinetime::Controllers::HeartRateController& heartRateController, Pinetime::Applications::DisplayApp& displayApp, - Pinetime::Applications::HeartRateTask& heartRateApp) + Pinetime::Applications::HeartRateTask& heartRateApp, + Pinetime::Controllers::FS& fs) : spi {spi}, lcd {lcd}, spiNorFlash {spiNorFlash}, @@ -77,10 +78,11 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi, motionSensor {motionSensor}, settingsController {settingsController}, heartRateController{heartRateController}, - nimbleController(*this, bleController, dateTimeController, notificationManager, batteryController, spiNorFlash, heartRateController), motionController{motionController}, displayApp{displayApp}, - heartRateApp(heartRateApp) { + heartRateApp(heartRateApp), + fs{fs}, + nimbleController(*this, bleController, dateTimeController, notificationManager, batteryController, spiNorFlash, heartRateController) { } @@ -107,6 +109,9 @@ void SystemTask::Work() { spi.Init(); spiNorFlash.Init(); spiNorFlash.Wakeup(); + + fs.Init(); + nimbleController.Init(); nimbleController.StartAdvertising(); brightnessController.Init(); diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index f563640c..bfb97264 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -16,13 +16,15 @@ #include "components/ble/NotificationManager.h" #include "components/motor/MotorController.h" #include "components/timer/TimerController.h" +#include "components/fs/FS.h" + #ifdef PINETIME_IS_RECOVERY #include "displayapp/DisplayAppRecovery.h" #include "displayapp/DummyLittleVgl.h" #else #include "components/settings/Settings.h" #include "displayapp/DisplayApp.h" - #include "displayapp/LittleVgl.h" + #include "displayapp/LittleVgl.h" #endif #include "drivers/Watchdog.h" @@ -59,7 +61,8 @@ namespace Pinetime { Controllers::Settings& settingsController, Pinetime::Controllers::HeartRateController& heartRateController, Pinetime::Applications::DisplayApp& displayApp, - Pinetime::Applications::HeartRateTask& heartRateApp); + Pinetime::Applications::HeartRateTask& heartRateApp, + Pinetime::Controllers::FS& fs); void Start(); void PushMessage(Messages msg); @@ -103,13 +106,14 @@ namespace Pinetime { Pinetime::Drivers::Bma421& motionSensor; Pinetime::Controllers::Settings& settingsController; Pinetime::Controllers::HeartRateController& heartRateController; - Pinetime::Controllers::NimbleController nimbleController; + Controllers::BrightnessController brightnessController; Pinetime::Controllers::MotionController& motionController; Pinetime::Applications::DisplayApp& displayApp; Pinetime::Applications::HeartRateTask& heartRateApp; - + Pinetime::Controllers::FS& fs; + Pinetime::Controllers::NimbleController nimbleController; static constexpr uint8_t pinSpiSck = 2; static constexpr uint8_t pinSpiMosi = 3; -- cgit v1.2.3-70-g09d2 From e21f6a7f414d1f832e8fddfeaab3b9de05aa3459 Mon Sep 17 00:00:00 2001 From: Jean-François Milants Date: Sun, 11 Jul 2021 16:55:06 +0200 Subject: Notify battery level every 10 minutes when connected to a BLE host. Refactor battery percent : only use uint8_t to store the battery % remaining. --- src/components/battery/BatteryController.cpp | 13 ++--- src/components/battery/BatteryController.h | 18 ++++--- src/components/ble/BatteryInformationService.cpp | 8 ++- src/components/ble/BatteryInformationService.h | 2 +- src/components/ble/NimbleController.cpp | 6 +++ src/components/ble/NimbleController.h | 3 +- src/displayapp/screens/BatteryIcon.cpp | 3 +- src/displayapp/screens/BatteryIcon.h | 2 +- src/displayapp/screens/BatteryInfo.cpp | 66 ++++++++++-------------- src/displayapp/screens/BatteryInfo.h | 2 +- src/displayapp/screens/PineTimeStyle.h | 2 +- src/displayapp/screens/SystemInfo.cpp | 2 +- src/displayapp/screens/WatchFaceAnalog.cpp | 1 - src/displayapp/screens/WatchFaceAnalog.h | 2 +- src/displayapp/screens/WatchFaceDigital.h | 2 +- src/systemtask/SystemTask.cpp | 5 ++ src/systemtask/SystemTask.h | 2 + 17 files changed, 71 insertions(+), 68 deletions(-) (limited to 'src/systemtask') diff --git a/src/components/battery/BatteryController.cpp b/src/components/battery/BatteryController.cpp index 76ad8cb3..fa476ea3 100644 --- a/src/components/battery/BatteryController.cpp +++ b/src/components/battery/BatteryController.cpp @@ -1,9 +1,7 @@ #include "BatteryController.h" #include #include -#include #include -#include using namespace Pinetime::Controllers; @@ -18,7 +16,6 @@ void Battery::Init() { } void Battery::Update() { - isCharging = !nrf_gpio_pin_read(chargingPin); isPowerPresent = !nrf_gpio_pin_read(powerPresentPin); @@ -33,13 +30,13 @@ void Battery::Update() { nrfx_saadc_sample(); } -void Battery::adcCallbackStatic(nrfx_saadc_evt_t const* event) { +void Battery::AdcCallbackStatic(nrfx_saadc_evt_t const* event) { instance->SaadcEventHandler(event); } void Battery::SaadcInit() { nrfx_saadc_config_t adcConfig = NRFX_SAADC_DEFAULT_CONFIG; - APP_ERROR_CHECK(nrfx_saadc_init(&adcConfig, adcCallbackStatic)); + APP_ERROR_CHECK(nrfx_saadc_init(&adcConfig, AdcCallbackStatic)); nrf_saadc_channel_config_t adcChannelConfig = {.resistor_p = NRF_SAADC_RESISTOR_DISABLED, .resistor_n = NRF_SAADC_RESISTOR_DISABLED, @@ -55,7 +52,6 @@ void Battery::SaadcInit() { } void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) { - const uint16_t battery_max = 4180; // maximum voltage of battery ( max charging voltage is 4.21 ) const uint16_t battery_min = 3200; // minimum voltage of battery before shutdown ( depends on the battery ) @@ -69,13 +65,10 @@ void Battery::SaadcEventHandler(nrfx_saadc_evt_t const* p_event) { // reference_voltage is 0.6V // p_event->data.done.p_buffer[0] = (adc_voltage / reference_voltage) * 1024 voltage = p_event->data.done.p_buffer[0] * 6000 / 1024; - percentRemaining = (voltage - battery_min) * 100 / (battery_max - battery_min); - percentRemaining = std::max(percentRemaining, 0); percentRemaining = std::min(percentRemaining, 100); - - percentRemainingBuffer.insert(percentRemaining); + percentRemainingBuffer.Insert(percentRemaining); samples++; if (samples > percentRemainingSamples) { diff --git a/src/components/battery/BatteryController.h b/src/components/battery/BatteryController.h index 26e24938..1333ad0e 100644 --- a/src/components/battery/BatteryController.h +++ b/src/components/battery/BatteryController.h @@ -19,7 +19,7 @@ namespace Pinetime { insert member function overwrites the next data to the current HEAD and moves the HEAD to the newly inserted value. */ - void insert(const int num) { + void Insert(const uint8_t num) { head %= cap; arr[head++] = num; if (sz != cap) { @@ -27,13 +27,13 @@ namespace Pinetime { } } - int GetAverage() const { + uint8_t GetAverage() const { int sum = std::accumulate(arr.begin(), arr.end(), 0); - return (sum / sz); + return static_cast(sum / sz); } private: - std::array arr; /**< internal array used to store the values*/ + std::array arr; /**< internal array used to store the values*/ uint8_t sz; /**< The current size of the array.*/ uint8_t cap; /**< Total capacity of the CircBuffer.*/ uint8_t head; /**< The current head of the CircBuffer*/ @@ -46,8 +46,11 @@ namespace Pinetime { void Init(); void Update(); - int PercentRemaining() const { - return percentRemainingBuffer.GetAverage(); + uint8_t PercentRemaining() const { + auto avg = percentRemainingBuffer.GetAverage(); + avg = std::min(avg, static_cast(100)); + avg = std::max(avg, static_cast(0)); + return avg; } uint16_t Voltage() const { @@ -57,6 +60,7 @@ namespace Pinetime { bool IsCharging() const { return isCharging; } + bool IsPowerPresent() const { return isPowerPresent; } @@ -80,7 +84,7 @@ namespace Pinetime { void SaadcInit(); void SaadcEventHandler(nrfx_saadc_evt_t const* p_event); - static void adcCallbackStatic(nrfx_saadc_evt_t const* event); + static void AdcCallbackStatic(nrfx_saadc_evt_t const* event); bool isReading = false; uint8_t samples = 0; diff --git a/src/components/ble/BatteryInformationService.cpp b/src/components/ble/BatteryInformationService.cpp index 10a78d67..7f176904 100644 --- a/src/components/ble/BatteryInformationService.cpp +++ b/src/components/ble/BatteryInformationService.cpp @@ -17,7 +17,7 @@ BatteryInformationService::BatteryInformationService(Controllers::Battery& batte characteristicDefinition {{.uuid = (ble_uuid_t*) &batteryLevelUuid, .access_cb = BatteryInformationServiceCallback, .arg = this, - .flags = BLE_GATT_CHR_F_READ, + .flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_NOTIFY, .val_handle = &batteryLevelHandle}, {0}}, serviceDefinition { @@ -48,4 +48,8 @@ int BatteryInformationService::OnBatteryServiceRequested(uint16_t connectionHand return (res == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES; } return 0; -} \ No newline at end of file +} +void BatteryInformationService::NotifyBatteryLevel(uint16_t connectionHandle, uint8_t level) { + auto* om = ble_hs_mbuf_from_flat(&level, 1); + ble_gattc_notify_custom(connectionHandle, batteryLevelHandle, om); +} diff --git a/src/components/ble/BatteryInformationService.h b/src/components/ble/BatteryInformationService.h index 7d060909..1303fd6c 100644 --- a/src/components/ble/BatteryInformationService.h +++ b/src/components/ble/BatteryInformationService.h @@ -17,7 +17,7 @@ namespace Pinetime { void Init(); int OnBatteryServiceRequested(uint16_t connectionHandle, uint16_t attributeHandle, ble_gatt_access_ctxt* context); - + void NotifyBatteryLevel(uint16_t connectionHandle, uint8_t level); private: Controllers::Battery& batteryController; static constexpr uint16_t batteryInformationServiceId {0x180F}; diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 2c1d0f99..5eb227bf 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -235,3 +235,9 @@ void NimbleController::StartDiscovery() { uint16_t NimbleController::connHandle() { return connectionHandle; } + +void NimbleController::NotifyBatteryLevel(uint8_t level) { + if(connectionHandle != BLE_HS_CONN_HANDLE_NONE) { + batteryInformationService.NotifyBatteryLevel(connectionHandle, level); + } +} diff --git a/src/components/ble/NimbleController.h b/src/components/ble/NimbleController.h index 5dd01e42..0cfe983c 100644 --- a/src/components/ble/NimbleController.h +++ b/src/components/ble/NimbleController.h @@ -70,6 +70,7 @@ namespace Pinetime { }; uint16_t connHandle(); + void NotifyBatteryLevel(uint8_t level); private: static constexpr const char* deviceName = "InfiniTime"; @@ -92,7 +93,7 @@ namespace Pinetime { HeartRateService heartRateService; uint8_t addrType; // 1 = Random, 0 = PUBLIC - uint16_t connectionHandle = 0; + uint16_t connectionHandle = BLE_HS_CONN_HANDLE_NONE; ble_uuid128_t dfuServiceUuid { .u {.type = BLE_UUID_TYPE_128}, diff --git a/src/displayapp/screens/BatteryIcon.cpp b/src/displayapp/screens/BatteryIcon.cpp index 6b54a305..bb6626a5 100644 --- a/src/displayapp/screens/BatteryIcon.cpp +++ b/src/displayapp/screens/BatteryIcon.cpp @@ -1,9 +1,10 @@ +#include #include "BatteryIcon.h" #include "Symbols.h" using namespace Pinetime::Applications::Screens; -const char* BatteryIcon::GetBatteryIcon(int batteryPercent) { +const char* BatteryIcon::GetBatteryIcon(uint8_t batteryPercent) { if (batteryPercent > 90) return Symbols::batteryFull; if (batteryPercent > 75) diff --git a/src/displayapp/screens/BatteryIcon.h b/src/displayapp/screens/BatteryIcon.h index 9c192ff7..b370b331 100644 --- a/src/displayapp/screens/BatteryIcon.h +++ b/src/displayapp/screens/BatteryIcon.h @@ -6,7 +6,7 @@ namespace Pinetime { class BatteryIcon { public: static const char* GetUnknownIcon(); - static const char* GetBatteryIcon(int batteryPercent); + static const char* GetBatteryIcon(uint8_t batteryPercent); static const char* GetPlugIcon(bool isCharging); }; } diff --git a/src/displayapp/screens/BatteryInfo.cpp b/src/displayapp/screens/BatteryInfo.cpp index 87c8b4bb..2af024e7 100644 --- a/src/displayapp/screens/BatteryInfo.cpp +++ b/src/displayapp/screens/BatteryInfo.cpp @@ -38,11 +38,7 @@ BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Cont percent = lv_label_create(lv_scr_act(), nullptr); lv_obj_set_style_local_text_font(percent, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76); - if (batteryPercent >= 0) { - lv_label_set_text_fmt(percent, "%02i%%", batteryPercent); - } else { - lv_label_set_text(percent, "--%"); - } + lv_label_set_text_fmt(percent, "%02i%%", batteryPercent); lv_label_set_align(percent, LV_LABEL_ALIGN_LEFT); lv_obj_align(percent, nullptr, LV_ALIGN_CENTER, 0, -60); @@ -72,24 +68,22 @@ BatteryInfo::~BatteryInfo() { void BatteryInfo::UpdateAnim() { batteryPercent = batteryController.PercentRemaining(); - if (batteryPercent >= 0) { - if (batteryController.IsCharging() and batteryPercent < 100) { - animation += 1; - if (animation >= 100) { - animation = 0; - } - - } else { - if (animation > batteryPercent) { - animation--; - } - if (animation < batteryPercent) { - animation++; - } + if (batteryController.IsCharging() and batteryPercent < 100) { + animation += 1; + if (animation >= 100) { + animation = 0; } - lv_bar_set_value(charging_bar, animation, LV_ANIM_OFF); + } else { + if (animation > batteryPercent) { + animation--; + } + if (animation < batteryPercent) { + animation++; + } } + + lv_bar_set_value(charging_bar, animation, LV_ANIM_OFF); } void BatteryInfo::UpdateScreen() { @@ -99,28 +93,22 @@ void BatteryInfo::UpdateScreen() { batteryPercent = batteryController.PercentRemaining(); batteryVoltage = batteryController.Voltage(); - if (batteryPercent >= 0) { - if (batteryController.IsCharging() and batteryPercent < 100) { - lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_RED); - lv_label_set_text_static(status, "Battery charging"); - } else if (batteryPercent == 100) { - lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_BLUE); - lv_label_set_text_static(status, "Battery is fully charged"); - } else if (batteryPercent < 10) { - lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_YELLOW); - lv_label_set_text_static(status, "Battery is low"); - } else { - lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_GREEN); - lv_label_set_text_static(status, "Battery discharging"); - } - - lv_label_set_text_fmt(percent, "%02i%%", batteryPercent); - + if (batteryController.IsCharging() and batteryPercent < 100) { + lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_RED); + lv_label_set_text_static(status, "Battery charging"); + } else if (batteryPercent == 100) { + lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_BLUE); + lv_label_set_text_static(status, "Battery is fully charged"); + } else if (batteryPercent < 10) { + lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_YELLOW); + lv_label_set_text_static(status, "Battery is low"); } else { - lv_label_set_text_static(status, "Reading Battery status"); - lv_label_set_text(percent, "--%"); + lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, LV_COLOR_GREEN); + lv_label_set_text_static(status, "Battery discharging"); } + lv_label_set_text_fmt(percent, "%02i%%", batteryPercent); + lv_obj_align(status, charging_bar, LV_ALIGN_OUT_BOTTOM_MID, 0, 20); lv_label_set_text_fmt(voltage, "%1i.%02i volts", batteryVoltage / 1000, batteryVoltage % 1000 / 10); } diff --git a/src/displayapp/screens/BatteryInfo.h b/src/displayapp/screens/BatteryInfo.h index 346dc571..da85c6dd 100644 --- a/src/displayapp/screens/BatteryInfo.h +++ b/src/displayapp/screens/BatteryInfo.h @@ -36,7 +36,7 @@ namespace Pinetime { lv_task_t* taskAnim; int8_t animation = 0; - int8_t batteryPercent = -1; + uint8_t batteryPercent = 0; uint16_t batteryVoltage = 0; }; } diff --git a/src/displayapp/screens/PineTimeStyle.h b/src/displayapp/screens/PineTimeStyle.h index 70794cc5..3b4ded1e 100644 --- a/src/displayapp/screens/PineTimeStyle.h +++ b/src/displayapp/screens/PineTimeStyle.h @@ -42,7 +42,7 @@ namespace Pinetime { Pinetime::Controllers::DateTime::Days currentDayOfWeek = Pinetime::Controllers::DateTime::Days::Unknown; uint8_t currentDay = 0; - DirtyValue batteryPercentRemaining {}; + DirtyValue batteryPercentRemaining {}; DirtyValue bleState {}; DirtyValue> currentDateTime {}; DirtyValue motionSensorOk {}; diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index 5ae3a595..f5bf0cc9 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -103,7 +103,7 @@ std::unique_ptr SystemInfo::CreateScreen1() { } std::unique_ptr SystemInfo::CreateScreen2() { - auto batteryPercent = static_cast(batteryController.PercentRemaining()); + auto batteryPercent = batteryController.PercentRemaining(); auto resetReason = [this]() { switch (watchdog.ResetReason()) { case Drivers::Watchdog::ResetReasons::Watchdog: diff --git a/src/displayapp/screens/WatchFaceAnalog.cpp b/src/displayapp/screens/WatchFaceAnalog.cpp index 0051408c..b0eb65bc 100644 --- a/src/displayapp/screens/WatchFaceAnalog.cpp +++ b/src/displayapp/screens/WatchFaceAnalog.cpp @@ -165,7 +165,6 @@ void WatchFaceAnalog::UpdateClock() { } bool WatchFaceAnalog::Refresh() { - batteryPercentRemaining = batteryController.PercentRemaining(); if (batteryPercentRemaining.IsUpdated()) { auto batteryPercent = batteryPercentRemaining.Get(); diff --git a/src/displayapp/screens/WatchFaceAnalog.h b/src/displayapp/screens/WatchFaceAnalog.h index 96225558..ac7f0ac5 100644 --- a/src/displayapp/screens/WatchFaceAnalog.h +++ b/src/displayapp/screens/WatchFaceAnalog.h @@ -48,7 +48,7 @@ namespace Pinetime { Pinetime::Controllers::DateTime::Days currentDayOfWeek = Pinetime::Controllers::DateTime::Days::Unknown; uint8_t currentDay = 0; - DirtyValue batteryPercentRemaining {0}; + DirtyValue batteryPercentRemaining {0}; DirtyValue> currentDateTime; DirtyValue notificationState {false}; diff --git a/src/displayapp/screens/WatchFaceDigital.h b/src/displayapp/screens/WatchFaceDigital.h index 246efc95..76c8d3dc 100644 --- a/src/displayapp/screens/WatchFaceDigital.h +++ b/src/displayapp/screens/WatchFaceDigital.h @@ -45,7 +45,7 @@ namespace Pinetime { Pinetime::Controllers::DateTime::Days currentDayOfWeek = Pinetime::Controllers::DateTime::Days::Unknown; uint8_t currentDay = 0; - DirtyValue batteryPercentRemaining {}; + DirtyValue batteryPercentRemaining {}; DirtyValue bleState {}; DirtyValue> currentDateTime {}; DirtyValue motionSensorOk {}; diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 17e78230..eb29638a 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -330,6 +330,11 @@ void SystemTask::Work() { } } + if (xTaskGetTickCount() - batteryNotificationTick > batteryNotificationPeriod) { + nimbleController.NotifyBatteryLevel(batteryController.PercentRemaining()); + batteryNotificationTick = xTaskGetTickCount(); + } + monitor.Process(); uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG); dateTimeController.UpdateTime(systick_counter); diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index bfb97264..f8cf6370 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -135,6 +135,8 @@ namespace Pinetime { void GoToRunning(); void UpdateMotion(); bool stepCounterMustBeReset = false; + static constexpr TickType_t batteryNotificationPeriod = 1000 * 60 * 10; // 1 tick ~= 1ms. 1ms * 60 * 10 = 10 minutes + TickType_t batteryNotificationTick = 0; #if configUSE_TRACE_FACILITY == 1 SystemMonitor monitor; -- cgit v1.2.3-70-g09d2 From 57b339707861c5688f5d432f1506a99df6bb0fce Mon Sep 17 00:00:00 2001 From: Kozova1 <30871100+Kozova1@users.noreply.github.com> Date: Wed, 14 Jul 2021 21:51:51 +0300 Subject: Multiple wakeup sources (#290) * Allow multiple wakeup modes at the same time. This commit adds multiple wakeup modes support. It does so by storing them as a uint8_t bitfield enum. It changes the following functions: Since multiple modes can be on now, older version would not cut it: WakeUpMode getWakeupMode() -> std::bitset<3> getWakeUpModes() Where each bit corresponds to a WakeUpMode We still need a way to check whether a specific wakeup mode is on, so: bool isWakeUpModeOn(const WakeUpMode mode) This function was changed to work correctly with the new implementation. setWakeUpMode(WakeupMode mode, bool enable) Previously, systemtask would exit SystemTask::OnTouchEvent() if the wake up mode was None or RaiseWrist, to prevent waking up when a touch was received. However, after enabling using multiple WakeUpModes, this caused a bug where when RaiseWrist was checked with SingleTap or DoubleTap, the tap detection wouldn't work. This commit fixes that bug. Next commit will update the settings WakeUpMode select UI to reflect these changes. Signed-off-by: Kozova1 * Updated UI to reflect multiple WakeUp sources being available. Signed-off-by: Kozova1 --- src/components/settings/Settings.h | 39 ++++++++++++--- src/displayapp/screens/settings/SettingWakeUp.cpp | 60 +++++++++++------------ src/displayapp/screens/settings/SettingWakeUp.h | 5 ++ src/systemtask/SystemTask.cpp | 18 +++---- 4 files changed, 73 insertions(+), 49 deletions(-) (limited to 'src/systemtask') diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 577455eb..93d6d217 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -1,5 +1,6 @@ #pragma once #include +#include #include "components/datetime/DateTimeController.h" #include "components/brightness/BrightnessController.h" #include "components/fs/FS.h" @@ -11,7 +12,11 @@ namespace Pinetime { public: enum class ClockType : uint8_t { H24, H12 }; enum class Vibration : uint8_t { ON, OFF }; - enum class WakeUpMode : uint8_t { None, SingleTap, DoubleTap, RaiseWrist }; + enum class WakeUpMode : uint8_t { + SingleTap = 0, + DoubleTap = 1, + RaiseWrist = 2, + }; Settings(Pinetime::Controllers::FS& fs); @@ -72,15 +77,33 @@ namespace Pinetime { return settings.screenTimeOut; }; - void setWakeUpMode(WakeUpMode wakeUp) { - if (wakeUp != settings.wakeUpMode) { + void setWakeUpMode(WakeUpMode wakeUp, bool enabled) { + if (!isWakeUpModeOn(wakeUp)) { settingsChanged = true; } - settings.wakeUpMode = wakeUp; + settings.wakeUpMode.set(static_cast(wakeUp), enabled); + // Handle special behavior + if (enabled) { + switch (wakeUp) { + case WakeUpMode::SingleTap: + settings.wakeUpMode.set(static_cast(WakeUpMode::DoubleTap), false); + break; + case WakeUpMode::DoubleTap: + settings.wakeUpMode.set(static_cast(WakeUpMode::SingleTap), false); + break; + case WakeUpMode::RaiseWrist: + break; + } + } }; - WakeUpMode getWakeUpMode() const { + + std::bitset<3> getWakeUpModes() const { return settings.wakeUpMode; - }; + } + + bool isWakeUpModeOn(const WakeUpMode mode) const { + return getWakeUpModes()[static_cast(mode)]; + } void SetBrightness(Controllers::BrightnessController::Levels level) { if (level != settings.brightLevel) { @@ -116,7 +139,7 @@ namespace Pinetime { uint8_t clockFace = 0; - WakeUpMode wakeUpMode = WakeUpMode::None; + std::bitset<3> wakeUpMode {0}; Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium; }; @@ -131,4 +154,4 @@ namespace Pinetime { void SaveSettingsToFile(); }; } -} \ No newline at end of file +} diff --git a/src/displayapp/screens/settings/SettingWakeUp.cpp b/src/displayapp/screens/settings/SettingWakeUp.cpp index 89f0c098..0e080353 100644 --- a/src/displayapp/screens/settings/SettingWakeUp.cpp +++ b/src/displayapp/screens/settings/SettingWakeUp.cpp @@ -16,7 +16,7 @@ namespace { SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Settings& settingsController) : Screen(app), settingsController {settingsController} { - + ignoringEvents = false; lv_obj_t* container1 = lv_cont_create(lv_scr_act(), nullptr); lv_obj_set_style_local_bg_opa(container1, LV_CONT_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); @@ -42,18 +42,10 @@ SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime:: optionsTotal = 0; cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); - lv_checkbox_set_text_static(cbOption[optionsTotal], " None"); - cbOption[optionsTotal]->user_data = this; - lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); - if (settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::None) { - lv_checkbox_set_checked(cbOption[optionsTotal], true); - } - optionsTotal++; - cbOption[optionsTotal] = lv_checkbox_create(container1, nullptr); lv_checkbox_set_text_static(cbOption[optionsTotal], " Single Tap"); cbOption[optionsTotal]->user_data = this; lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); - if (settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::SingleTap) { + if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::SingleTap)) { lv_checkbox_set_checked(cbOption[optionsTotal], true); } optionsTotal++; @@ -61,7 +53,7 @@ SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime:: lv_checkbox_set_text_static(cbOption[optionsTotal], " Double Tap"); cbOption[optionsTotal]->user_data = this; lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); - if (settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::DoubleTap) { + if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) { lv_checkbox_set_checked(cbOption[optionsTotal], true); } optionsTotal++; @@ -69,7 +61,7 @@ SettingWakeUp::SettingWakeUp(Pinetime::Applications::DisplayApp* app, Pinetime:: lv_checkbox_set_text_static(cbOption[optionsTotal], " Raise Wrist"); cbOption[optionsTotal]->user_data = this; lv_obj_set_event_cb(cbOption[optionsTotal], event_handler); - if (settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) { + if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist)) { lv_checkbox_set_checked(cbOption[optionsTotal], true); } optionsTotal++; @@ -85,27 +77,31 @@ bool SettingWakeUp::Refresh() { } void SettingWakeUp::UpdateSelected(lv_obj_t* object, lv_event_t event) { - if (event == LV_EVENT_VALUE_CHANGED) { - for (int i = 0; i < optionsTotal; i++) { - if (object == cbOption[i]) { - lv_checkbox_set_checked(cbOption[i], true); + using WakeUpMode = Pinetime::Controllers::Settings::WakeUpMode; + if (event == LV_EVENT_VALUE_CHANGED && !ignoringEvents) { + ignoringEvents = true; - if (i == 0) { - settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::None); - }; - if (i == 1) { - settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::SingleTap); - }; - if (i == 2) { - settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap); - }; - if (i == 3) { - settingsController.setWakeUpMode(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist); - }; - - } else { - lv_checkbox_set_checked(cbOption[i], false); + // Find the index of the checkbox that triggered the event + int index = 0; + for (; index < optionsTotal; ++index) { + if (cbOption[index] == object) { + break; } } + + // Toggle needed wakeup mode + auto mode = static_cast(index); + auto currentState = settingsController.isWakeUpModeOn(mode); + settingsController.setWakeUpMode(mode, !currentState); + + // Update checkbox according to current wakeup modes. + // This is needed because we can have extra logic when setting or unsetting wakeup modes, + // for example, when setting SingleTap, DoubleTap is unset and vice versa. + auto modes = settingsController.getWakeUpModes(); + for (int i = 0; i < optionsTotal; ++i) { + lv_checkbox_set_checked(cbOption[i], modes[i]); + } + + ignoringEvents = false; } -} \ No newline at end of file +} diff --git a/src/displayapp/screens/settings/SettingWakeUp.h b/src/displayapp/screens/settings/SettingWakeUp.h index 8b33eb06..248dd9ac 100644 --- a/src/displayapp/screens/settings/SettingWakeUp.h +++ b/src/displayapp/screens/settings/SettingWakeUp.h @@ -22,6 +22,11 @@ namespace Pinetime { Controllers::Settings& settingsController; uint8_t optionsTotal; lv_obj_t* cbOption[4]; + // When UpdateSelected is called, it uses lv_checkbox_set_checked, + // which can cause extra events to be fired, + // which might trigger UpdateSelected again, causing a loop. + // This variable is used as a mutex to prevent that. + bool ignoringEvents; }; } } diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index eb29638a..d8b965b1 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -211,7 +211,7 @@ void SystemTask::Work() { twiMaster.Wakeup(); // Double Tap needs the touch screen to be in normal mode - if (settingsController.getWakeUpMode() != Pinetime::Controllers::Settings::WakeUpMode::DoubleTap) { + if (!settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) { touchPanel.Wakeup(); } @@ -232,9 +232,9 @@ void SystemTask::Work() { auto touchInfo = touchPanel.GetTouchInfo(); twiMaster.Sleep(); if (touchInfo.isTouch and ((touchInfo.gesture == Pinetime::Drivers::Cst816S::Gestures::DoubleTap and - settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::DoubleTap) or + settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) or (touchInfo.gesture == Pinetime::Drivers::Cst816S::Gestures::SingleTap and - settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::SingleTap))) { + settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::SingleTap)))) { GoToRunning(); } } break; @@ -296,7 +296,7 @@ void SystemTask::Work() { spi.Sleep(); // Double Tap needs the touch screen to be in normal mode - if (settingsController.getWakeUpMode() != Pinetime::Controllers::Settings::WakeUpMode::DoubleTap) { + if (!settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) { touchPanel.Sleep(); } twiMaster.Sleep(); @@ -348,7 +348,7 @@ void SystemTask::UpdateMotion() { if (isGoingToSleep or isWakingUp) return; - if (isSleeping && settingsController.getWakeUpMode() != Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) + if (isSleeping && !settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist)) return; if (isSleeping) @@ -399,10 +399,10 @@ void SystemTask::OnTouchEvent() { PushMessage(Messages::OnTouchEvent); displayApp.PushMessage(Pinetime::Applications::Display::Messages::TouchEvent); } else if (!isWakingUp) { - if (settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::None or - settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) - return; - PushMessage(Messages::TouchWakeUp); + if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::SingleTap) or + settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) { + PushMessage(Messages::TouchWakeUp); + } } } -- cgit v1.2.3-70-g09d2 From 0a0f28fff4be4c9fd9030d9375459fb7b5fdd004 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Thu, 22 Jul 2021 22:57:45 +0300 Subject: Make firmware updating more foolproof (#469) * Make firmware updating more foolproof and fix bugs * No need to manually handle overflow * Make startTime TickType_t * Don't process TouchEvents::None * Fix sleep getting re-enabled issue more directly --- src/components/ble/DfuService.cpp | 9 ++++----- src/displayapp/DisplayApp.cpp | 7 ++++++- src/displayapp/screens/FirmwareUpdate.cpp | 33 +++++++++++++++++++++++++------ src/displayapp/screens/FirmwareUpdate.h | 9 +++++++-- src/systemtask/SystemTask.cpp | 11 ++++++++--- 5 files changed, 52 insertions(+), 17 deletions(-) (limited to 'src/systemtask') diff --git a/src/components/ble/DfuService.cpp b/src/components/ble/DfuService.cpp index e6bcea81..4179994d 100644 --- a/src/components/ble/DfuService.cpp +++ b/src/components/ble/DfuService.cpp @@ -266,13 +266,14 @@ int DfuService::ControlPointHandler(uint16_t connectionHandle, os_mbuf* om) { static_cast(ErrorCodes::NoError)}; notificationManager.AsyncSend(connectionHandle, controlPointCharacteristicHandle, data, 3); } else { - bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Error); NRF_LOG_INFO("Image Error : bad CRC"); uint8_t data[3] {static_cast(Opcodes::Response), static_cast(Opcodes::ValidateFirmware), static_cast(ErrorCodes::CrcError)}; notificationManager.AsyncSend(connectionHandle, controlPointCharacteristicHandle, data, 3); + bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Error); + Reset(); } return 0; @@ -283,10 +284,8 @@ int DfuService::ControlPointHandler(uint16_t connectionHandle, os_mbuf* om) { return 0; } NRF_LOG_INFO("[DFU] -> Activate image and reset!"); - bleController.StopFirmwareUpdate(); - systemTask.PushMessage(Pinetime::System::Messages::BleFirmwareUpdateFinished); - Reset(); bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated); + Reset(); return 0; default: return 0; @@ -294,6 +293,7 @@ int DfuService::ControlPointHandler(uint16_t connectionHandle, os_mbuf* om) { } void DfuService::OnTimeout() { + bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Error); Reset(); } @@ -307,7 +307,6 @@ void DfuService::Reset() { applicationSize = 0; expectedCrc = 0; notificationManager.Reset(); - bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Error); bleController.StopFirmwareUpdate(); systemTask.PushMessage(Pinetime::System::Messages::BleFirmwareUpdateFinished); } diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 071af0c8..4d32a7e5 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -177,9 +177,13 @@ void DisplayApp::Refresh() { } break; case Messages::TouchEvent: { - if (state != States::Running) + if (state != States::Running) { break; + } auto gesture = OnTouchEvent(); + if (gesture == TouchEvents::None) { + break; + } if (!currentScreen->OnTouchEvent(gesture)) { if (currentApp == Apps::Clock) { switch (gesture) { @@ -286,6 +290,7 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) break; case Apps::FirmwareUpdate: currentScreen = std::make_unique(this, bleController); + ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::None); break; case Apps::Notifications: diff --git a/src/displayapp/screens/FirmwareUpdate.cpp b/src/displayapp/screens/FirmwareUpdate.cpp index 4086b152..edb2e49d 100644 --- a/src/displayapp/screens/FirmwareUpdate.cpp +++ b/src/displayapp/screens/FirmwareUpdate.cpp @@ -27,9 +27,10 @@ FirmwareUpdate::FirmwareUpdate(Pinetime::Applications::DisplayApp* app, Pinetime lv_bar_set_value(bar1, 0, LV_ANIM_OFF); percentLabel = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text(percentLabel, ""); + lv_label_set_text(percentLabel, "Waiting..."); lv_obj_set_auto_realign(percentLabel, true); lv_obj_align(percentLabel, bar1, LV_ALIGN_OUT_TOP_MID, 0, 60); + startTime = xTaskGetTickCount(); } FirmwareUpdate::~FirmwareUpdate() { @@ -40,26 +41,42 @@ bool FirmwareUpdate::Refresh() { switch (bleController.State()) { default: case Pinetime::Controllers::Ble::FirmwareUpdateStates::Idle: + // This condition makes sure that the app is exited if somehow it got + // launched without a firmware update. This should never happen. + if (state != States::Error) { + if (xTaskGetTickCount() - startTime > (60 * 1024)) { + UpdateError(); + state = States::Error; + } + } else if (xTaskGetTickCount() - startTime > (5 * 1024)) { + running = false; + } + break; case Pinetime::Controllers::Ble::FirmwareUpdateStates::Running: if (state != States::Running) state = States::Running; - return DisplayProgression(); + DisplayProgression(); + break; case Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated: if (state != States::Validated) { UpdateValidated(); state = States::Validated; } - return running; + break; case Pinetime::Controllers::Ble::FirmwareUpdateStates::Error: if (state != States::Error) { UpdateError(); state = States::Error; } - return running; + if (xTaskGetTickCount() - startTime > (5 * 1024)) { + running = false; + } + break; } + return running; } -bool FirmwareUpdate::DisplayProgression() const { +void FirmwareUpdate::DisplayProgression() const { float current = bleController.FirmwareUpdateCurrentBytes() / 1024.0f; float total = bleController.FirmwareUpdateTotalBytes() / 1024.0f; int16_t pc = (current / total) * 100.0f; @@ -67,7 +84,6 @@ bool FirmwareUpdate::DisplayProgression() const { lv_label_set_text(percentLabel, percentStr); lv_bar_set_value(bar1, pc, LV_ANIM_OFF); - return running; } void FirmwareUpdate::UpdateValidated() { @@ -78,4 +94,9 @@ void FirmwareUpdate::UpdateValidated() { void FirmwareUpdate::UpdateError() { lv_label_set_recolor(percentLabel, true); lv_label_set_text(percentLabel, "#ff0000 Error!#"); + startTime = xTaskGetTickCount(); +} + +bool FirmwareUpdate::OnButtonPushed() { + return true; } diff --git a/src/displayapp/screens/FirmwareUpdate.h b/src/displayapp/screens/FirmwareUpdate.h index f4d34df0..90c99f4c 100644 --- a/src/displayapp/screens/FirmwareUpdate.h +++ b/src/displayapp/screens/FirmwareUpdate.h @@ -2,6 +2,7 @@ #include "Screen.h" #include +#include "FreeRTOS.h" namespace Pinetime { namespace Controllers { @@ -25,13 +26,17 @@ namespace Pinetime { lv_obj_t* titleLabel; mutable char percentStr[10]; - States state; + States state = States::Idle; - bool DisplayProgression() const; + void DisplayProgression() const; + + bool OnButtonPushed() override; void UpdateValidated(); void UpdateError(); + + TickType_t startTime; }; } } diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index d8b965b1..7efd1d6b 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -198,7 +198,11 @@ void SystemTask::Work() { Messages message = static_cast(msg); switch (message) { case Messages::EnableSleeping: - doNotGoToSleep = false; + // Make sure that exiting an app doesn't enable sleeping, + // if the exiting was caused by a firmware update + if (!bleController.IsFirmwareUpdating()) { + doNotGoToSleep = false; + } break; case Messages::DisableSleeping: doNotGoToSleep = true; @@ -275,10 +279,11 @@ void SystemTask::Work() { displayApp.PushMessage(Pinetime::Applications::Display::Messages::BleFirmwareUpdateStarted); break; case Messages::BleFirmwareUpdateFinished: + if (bleController.State() == Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated) { + NVIC_SystemReset(); + } doNotGoToSleep = false; xTimerStart(idleTimer, 0); - if (bleController.State() == Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated) - NVIC_SystemReset(); break; case Messages::OnTouchEvent: ReloadIdleTimer(); -- cgit v1.2.3-70-g09d2 From 34949a47c59e7a4d8f67a0188bba6d08a046340d Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Sat, 24 Jul 2021 21:29:10 +0300 Subject: Dim screen before sleep (#464) * Implement dimming --- src/displayapp/DisplayApp.cpp | 13 ++++++++++++- src/displayapp/Messages.h | 6 ++++-- src/systemtask/SystemTask.cpp | 45 ++++++++++++++++++++++++++++++++----------- src/systemtask/SystemTask.h | 7 ++++--- 4 files changed, 54 insertions(+), 17 deletions(-) (limited to 'src/systemtask') diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index b0948393..b5ad26f0 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -165,8 +165,15 @@ void DisplayApp::Refresh() { lastWakeTime = xTaskGetTickCount(); if (messageReceived) { switch (msg) { - case Messages::GoToSleep: + case Messages::DimScreen: + // Backup brightness is the brightness to return to after dimming or sleeping brightnessController.Backup(); + brightnessController.Set(Controllers::BrightnessController::Levels::Low); + break; + case Messages::RestoreBrightness: + brightnessController.Restore(); + break; + case Messages::GoToSleep: while (brightnessController.Level() != Controllers::BrightnessController::Levels::Off) { brightnessController.Lower(); vTaskDelay(100); @@ -230,6 +237,8 @@ void DisplayApp::Refresh() { } } else if (returnTouchEvent == gesture) { LoadApp(returnToApp, returnDirection); + brightnessController.Set(settingsController.GetBrightness()); + brightnessController.Backup(); } else if (touchMode == TouchModes::Gestures) { if (gesture == TouchEvents::Tap) { lvgl.SetNewTapEvent(info.x, info.y); @@ -243,6 +252,8 @@ void DisplayApp::Refresh() { } else { if (!currentScreen->OnButtonPushed()) { LoadApp(returnToApp, returnDirection); + brightnessController.Set(settingsController.GetBrightness()); + brightnessController.Backup(); } } break; diff --git a/src/displayapp/Messages.h b/src/displayapp/Messages.h index ce65f846..322505e6 100644 --- a/src/displayapp/Messages.h +++ b/src/displayapp/Messages.h @@ -13,8 +13,10 @@ namespace Pinetime { NewNotification, TimerDone, BleFirmwareUpdateStarted, - UpdateTimeOut + UpdateTimeOut, + DimScreen, + RestoreBrightness }; } } -} \ No newline at end of file +} diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 7efd1d6b..8915ce74 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -33,6 +33,13 @@ namespace { } } +void DimTimerCallback(TimerHandle_t xTimer) { + + NRF_LOG_INFO("DimTimerCallback"); + auto sysTask = static_cast(pvTimerGetTimerID(xTimer)); + sysTask->OnDim(); +} + void IdleTimerCallback(TimerHandle_t xTimer) { NRF_LOG_INFO("IdleTimerCallback"); @@ -105,7 +112,7 @@ void SystemTask::Work() { APP_GPIOTE_INIT(2); app_timer_init(); - + spi.Init(); spiNorFlash.Init(); spiNorFlash.Wakeup(); @@ -114,7 +121,6 @@ void SystemTask::Work() { nimbleController.Init(); nimbleController.StartAdvertising(); - brightnessController.Init(); lcd.Init(); twiMaster.Init(); @@ -179,8 +185,9 @@ void SystemTask::Work() { nrf_gpio_cfg_sense_input(pinPowerPresentIrq, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_HIGH); } - idleTimer = xTimerCreate("idleTimer", pdMS_TO_TICKS(settingsController.GetScreenTimeOut()), pdFALSE, this, IdleTimerCallback); - xTimerStart(idleTimer, 0); + idleTimer = xTimerCreate("idleTimer", pdMS_TO_TICKS(2000), pdFALSE, this, IdleTimerCallback); + dimTimer = xTimerCreate("dimTimer", pdMS_TO_TICKS(settingsController.GetScreenTimeOut() - 2000), pdFALSE, this, DimTimerCallback); + xTimerStart(dimTimer, 0); // Suppress endless loop diagnostic #pragma clang diagnostic push @@ -208,7 +215,7 @@ void SystemTask::Work() { doNotGoToSleep = true; break; case Messages::UpdateTimeOut: - xTimerChangePeriod(idleTimer, pdMS_TO_TICKS(settingsController.GetScreenTimeOut()), 0); + xTimerChangePeriod(dimTimer, pdMS_TO_TICKS(settingsController.GetScreenTimeOut() - 2000), 0); break; case Messages::GoToRunning: spi.Wakeup(); @@ -220,7 +227,7 @@ void SystemTask::Work() { } nimbleController.StartAdvertising(); - xTimerStart(idleTimer, 0); + xTimerStart(dimTimer, 0); spiNorFlash.Wakeup(); lcd.Wakeup(); @@ -230,6 +237,7 @@ void SystemTask::Work() { isSleeping = false; isWakingUp = false; + isDimmed = false; break; case Messages::TouchWakeUp: { twiMaster.Wakeup(); @@ -246,6 +254,7 @@ void SystemTask::Work() { isGoingToSleep = true; NRF_LOG_INFO("[systemtask] Going to sleep"); xTimerStop(idleTimer, 0); + xTimerStop(dimTimer, 0); displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToSleep); heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep); break; @@ -283,13 +292,15 @@ void SystemTask::Work() { NVIC_SystemReset(); } doNotGoToSleep = false; - xTimerStart(idleTimer, 0); + xTimerStart(dimTimer, 0); break; case Messages::OnTouchEvent: ReloadIdleTimer(); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::TouchEvent); break; case Messages::OnButtonEvent: ReloadIdleTimer(); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::ButtonPushed); break; case Messages::OnDisplayTaskSleeping: if (BootloaderVersion::IsValid()) { @@ -381,7 +392,6 @@ void SystemTask::OnButtonPushed() { if (!isSleeping) { NRF_LOG_INFO("[systemtask] Button pushed"); PushMessage(Messages::OnButtonEvent); - displayApp.PushMessage(Pinetime::Applications::Display::Messages::ButtonPushed); } else { if (!isWakingUp) { NRF_LOG_INFO("[systemtask] Button pushed, waking up"); @@ -402,7 +412,6 @@ void SystemTask::OnTouchEvent() { return; if (!isSleeping) { PushMessage(Messages::OnTouchEvent); - displayApp.PushMessage(Pinetime::Applications::Display::Messages::TouchEvent); } else if (!isWakingUp) { if (settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::SingleTap) or settingsController.isWakeUpModeOn(Pinetime::Controllers::Settings::WakeUpMode::DoubleTap)) { @@ -430,6 +439,15 @@ void SystemTask::PushMessage(System::Messages msg) { } } +void SystemTask::OnDim() { + if (doNotGoToSleep) + return; + NRF_LOG_INFO("Dim timeout -> Dim screen") + displayApp.PushMessage(Pinetime::Applications::Display::Messages::DimScreen); + xTimerStart(idleTimer, 0); + isDimmed = true; +} + void SystemTask::OnIdle() { if (doNotGoToSleep) return; @@ -437,8 +455,13 @@ void SystemTask::OnIdle() { PushMessage(Messages::GoToSleep); } -void SystemTask::ReloadIdleTimer() const { +void SystemTask::ReloadIdleTimer() { if (isSleeping || isGoingToSleep) return; - xTimerReset(idleTimer, 0); + if (isDimmed) { + displayApp.PushMessage(Pinetime::Applications::Display::Messages::RestoreBrightness); + isDimmed = false; + } + xTimerReset(dimTimer, 0); + xTimerStop(idleTimer, 0); } diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index f8cf6370..ba434298 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -71,6 +71,7 @@ namespace Pinetime { void OnTouchEvent(); void OnIdle(); + void OnDim(); Pinetime::Controllers::NimbleController& nimble() { return nimbleController; @@ -99,6 +100,7 @@ namespace Pinetime { std::atomic isSleeping {false}; std::atomic isGoingToSleep {false}; std::atomic isWakingUp {false}; + std::atomic isDimmed {false}; Pinetime::Drivers::Watchdog& watchdog; Pinetime::Controllers::NotificationManager& notificationManager; Pinetime::Controllers::MotorController& motorController; @@ -106,8 +108,6 @@ namespace Pinetime { Pinetime::Drivers::Bma421& motionSensor; Pinetime::Controllers::Settings& settingsController; Pinetime::Controllers::HeartRateController& heartRateController; - - Controllers::BrightnessController brightnessController; Pinetime::Controllers::MotionController& motionController; Pinetime::Applications::DisplayApp& displayApp; @@ -126,9 +126,10 @@ namespace Pinetime { static void Process(void* instance); void Work(); - void ReloadIdleTimer() const; + void ReloadIdleTimer(); bool isBleDiscoveryTimerRunning = false; uint8_t bleDiscoveryTimer = 0; + TimerHandle_t dimTimer; TimerHandle_t idleTimer; bool doNotGoToSleep = false; -- cgit v1.2.3-70-g09d2