From 9342d62a44830113241f0fdbc2951db93e474e26 Mon Sep 17 00:00:00 2001 From: David Ventura Date: Sun, 16 May 2021 21:13:22 +0200 Subject: Emit event on power-present toggle (#320) * Emit event on power-present toggle * clang-format on changes * also update battery status on any event * update comments; remove double battery update * Fix formatting * Vibrate shortly on charging event * debounce charge event --- src/main.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'src/main.cpp') diff --git a/src/main.cpp b/src/main.cpp index 04cef6b5..61194b95 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -101,11 +101,13 @@ Pinetime::Drivers::Bma421 motionSensor {twiMaster, motionSensorTwiAddress}; Pinetime::Drivers::Hrs3300 heartRateSensor {twiMaster, heartRateSensorTwiAddress}; TimerHandle_t debounceTimer; +TimerHandle_t debounceChargeTimer; Pinetime::Controllers::Battery batteryController; Pinetime::Controllers::Ble bleController; void ble_manager_set_ble_connection_callback(void (*connection)()); void ble_manager_set_ble_disconnection_callback(void (*disconnection)()); static constexpr uint8_t pinTouchIrq = 28; +static constexpr uint8_t pinPowerPresentIrq = 19; std::unique_ptr systemTask; Pinetime::Controllers::Settings settingsController {spiNorFlash}; @@ -119,6 +121,13 @@ void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action } BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + if (pin == pinPowerPresentIrq and action == NRF_GPIOTE_POLARITY_TOGGLE) { + xTimerStartFromISR(debounceChargeTimer, &xHigherPriorityTaskWoken); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + return; + } + xTimerStartFromISR(debounceTimer, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } @@ -130,6 +139,11 @@ void vApplicationIdleHook(void) { } } +void DebounceTimerChargeCallback(TimerHandle_t xTimer) { + xTimerStop(xTimer, 0); + systemTask->PushMessage(Pinetime::System::SystemTask::Messages::OnChargingEvent); +} + void DebounceTimerCallback(TimerHandle_t xTimer) { xTimerStop(xTimer, 0); systemTask->OnButtonPushed(); @@ -248,6 +262,7 @@ int main(void) { nrf_drv_clock_init(); debounceTimer = xTimerCreate("debounceTimer", 200, pdFALSE, (void*) 0, DebounceTimerCallback); + debounceChargeTimer = xTimerCreate("debounceTimerCharge", 200, pdFALSE, (void*) 0, DebounceTimerChargeCallback); systemTask = std::make_unique(spi, lcd, -- cgit v1.2.3-70-g09d2 From 7f9cc51b050e1034b573e37484f7afe29c370d81 Mon Sep 17 00:00:00 2001 From: Jean-François Milants Date: Sun, 6 Jun 2021 15:56:03 +0200 Subject: Initialize SystemTask, DisplayApp and HeartRateTask as global static variable instead of variables on the heap. We don't need them on the heap as we know their size at build time, it'll reduce memory fragmentation and it'll make memory analysis easier. --- src/CMakeLists.txt | 4 +- src/FreeRTOSConfig.h | 2 +- src/components/ble/AlertNotificationClient.cpp | 2 +- src/components/ble/AlertNotificationService.cpp | 2 +- src/components/ble/DfuService.cpp | 6 +- src/components/ble/ImmediateAlertService.cpp | 2 +- src/components/ble/NimbleController.cpp | 2 +- src/components/datetime/DateTimeController.cpp | 10 +-- src/components/datetime/DateTimeController.h | 6 +- src/components/heartrate/HeartRateController.cpp | 3 - src/components/heartrate/HeartRateController.h | 4 +- src/components/heartrate/Ppg.cpp | 11 +--- src/components/heartrate/Ppg.h | 3 +- src/components/timer/TimerController.cpp | 29 +++++---- src/components/timer/TimerController.h | 13 ++-- src/displayapp/DisplayApp.cpp | 32 ++++++---- src/displayapp/DisplayApp.h | 7 ++- src/displayapp/screens/FlashLight.cpp | 4 +- src/displayapp/screens/HeartRate.cpp | 8 +-- src/displayapp/screens/ScreenList.h | 13 ++-- src/displayapp/screens/settings/QuickSettings.cpp | 4 +- src/drivers/Bma421.cpp | 2 - src/drivers/SpiMaster.h | 1 - src/heartratetask/HeartRateTask.cpp | 2 +- src/main.cpp | 69 +++++++++++++++------ src/systemtask/Messages.h | 26 ++++++++ src/systemtask/SystemTask.cpp | 75 +++++++++++------------ src/systemtask/SystemTask.h | 53 +++++++--------- 28 files changed, 224 insertions(+), 171 deletions(-) create mode 100644 src/systemtask/Messages.h (limited to 'src/main.cpp') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index cd729921..c72f7c9c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -750,8 +750,8 @@ add_definitions(-DNIMBLE_CFG_CONTROLLER) add_definitions(-DOS_CPUTIME_FREQ) add_definitions(-DNRF52 -DNRF52832 -DNRF52832_XXAA -DNRF52_PAN_74 -DNRF52_PAN_64 -DNRF52_PAN_12 -DNRF52_PAN_58 -DNRF52_PAN_54 -DNRF52_PAN_31 -DNRF52_PAN_51 -DNRF52_PAN_36 -DNRF52_PAN_15 -DNRF52_PAN_20 -DNRF52_PAN_55 -DBOARD_PCA10040) add_definitions(-DFREERTOS) -add_definitions(-D__STACK_SIZE=8192) -add_definitions(-D__HEAP_SIZE=8192) +add_definitions(-D__STACK_SIZE=1024) +add_definitions(-D__HEAP_SIZE=4096) # NOTE : Add the following defines to enable debug mode of the NRF SDK: #add_definitions(-DDEBUG) diff --git a/src/FreeRTOSConfig.h b/src/FreeRTOSConfig.h index 15185766..07c152dc 100644 --- a/src/FreeRTOSConfig.h +++ b/src/FreeRTOSConfig.h @@ -62,7 +62,7 @@ #define configTICK_RATE_HZ 1024 #define configMAX_PRIORITIES (3) #define configMINIMAL_STACK_SIZE (120) -#define configTOTAL_HEAP_SIZE (1024 * 16) +#define configTOTAL_HEAP_SIZE (1024 * 17) #define configMAX_TASK_NAME_LEN (4) #define configUSE_16_BIT_TICKS 0 #define configIDLE_SHOULD_YIELD 1 diff --git a/src/components/ble/AlertNotificationClient.cpp b/src/components/ble/AlertNotificationClient.cpp index 6043a129..c3d1d69a 100644 --- a/src/components/ble/AlertNotificationClient.cpp +++ b/src/components/ble/AlertNotificationClient.cpp @@ -159,7 +159,7 @@ void AlertNotificationClient::OnNotification(ble_gap_event* event) { notif.category = Pinetime::Controllers::NotificationManager::Categories::SimpleAlert; notificationManager.Push(std::move(notif)); - systemTask.PushMessage(Pinetime::System::SystemTask::Messages::OnNewNotification); + systemTask.PushMessage(Pinetime::System::Messages::OnNewNotification); } } diff --git a/src/components/ble/AlertNotificationService.cpp b/src/components/ble/AlertNotificationService.cpp index e9f5941e..d5fc7f65 100644 --- a/src/components/ble/AlertNotificationService.cpp +++ b/src/components/ble/AlertNotificationService.cpp @@ -79,7 +79,7 @@ int AlertNotificationService::OnAlert(uint16_t conn_handle, uint16_t attr_handle break; } - auto event = Pinetime::System::SystemTask::Messages::OnNewNotification; + auto event = Pinetime::System::Messages::OnNewNotification; notificationManager.Push(std::move(notif)); systemTask.PushMessage(event); } diff --git a/src/components/ble/DfuService.cpp b/src/components/ble/DfuService.cpp index 2031668e..cec194cc 100644 --- a/src/components/ble/DfuService.cpp +++ b/src/components/ble/DfuService.cpp @@ -205,7 +205,7 @@ int DfuService::ControlPointHandler(uint16_t connectionHandle, os_mbuf* om) { bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Running); bleController.FirmwareUpdateTotalBytes(0xffffffffu); bleController.FirmwareUpdateCurrentBytes(0); - systemTask.PushMessage(Pinetime::System::SystemTask::Messages::BleFirmwareUpdateStarted); + systemTask.PushMessage(Pinetime::System::Messages::BleFirmwareUpdateStarted); return 0; } else { NRF_LOG_INFO("[DFU] -> Start DFU, mode %d not supported!", imageType); @@ -279,7 +279,7 @@ int DfuService::ControlPointHandler(uint16_t connectionHandle, os_mbuf* om) { } NRF_LOG_INFO("[DFU] -> Activate image and reset!"); bleController.StopFirmwareUpdate(); - systemTask.PushMessage(Pinetime::System::SystemTask::Messages::BleFirmwareUpdateFinished); + systemTask.PushMessage(Pinetime::System::Messages::BleFirmwareUpdateFinished); Reset(); bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated); return 0; @@ -304,7 +304,7 @@ void DfuService::Reset() { notificationManager.Reset(); bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Error); bleController.StopFirmwareUpdate(); - systemTask.PushMessage(Pinetime::System::SystemTask::Messages::BleFirmwareUpdateFinished); + systemTask.PushMessage(Pinetime::System::Messages::BleFirmwareUpdateFinished); } DfuService::NotificationManager::NotificationManager() { diff --git a/src/components/ble/ImmediateAlertService.cpp b/src/components/ble/ImmediateAlertService.cpp index fd6430af..820d3b6e 100644 --- a/src/components/ble/ImmediateAlertService.cpp +++ b/src/components/ble/ImmediateAlertService.cpp @@ -67,7 +67,7 @@ int ImmediateAlertService::OnAlertLevelChanged(uint16_t connectionHandle, uint16 notif.category = Pinetime::Controllers::NotificationManager::Categories::SimpleAlert; notificationManager.Push(std::move(notif)); - systemTask.PushMessage(Pinetime::System::SystemTask::Messages::OnNewNotification); + systemTask.PushMessage(Pinetime::System::Messages::OnNewNotification); } } diff --git a/src/components/ble/NimbleController.cpp b/src/components/ble/NimbleController.cpp index 67a6d691..2c1d0f99 100644 --- a/src/components/ble/NimbleController.cpp +++ b/src/components/ble/NimbleController.cpp @@ -149,7 +149,7 @@ int NimbleController::OnGAPEvent(ble_gap_event* event) { bleController.Disconnect(); } else { bleController.Connect(); - systemTask.PushMessage(Pinetime::System::SystemTask::Messages::BleConnected); + systemTask.PushMessage(Pinetime::System::Messages::BleConnected); connectionHandle = event->connect.conn_handle; // Service discovery is deffered via systemtask } diff --git a/src/components/datetime/DateTimeController.cpp b/src/components/datetime/DateTimeController.cpp index 4f9302eb..28a70abc 100644 --- a/src/components/datetime/DateTimeController.cpp +++ b/src/components/datetime/DateTimeController.cpp @@ -5,9 +5,6 @@ using namespace Pinetime::Controllers; -DateTime::DateTime(System::SystemTask& systemTask) : systemTask {systemTask} { -} - void DateTime::SetTime( uint16_t year, uint8_t month, uint8_t day, uint8_t dayOfWeek, uint8_t hour, uint8_t minute, uint8_t second, uint32_t systickCounter) { std::tm tm = { @@ -70,7 +67,8 @@ void DateTime::UpdateTime(uint32_t systickCounter) { // Notify new day to SystemTask if (hour == 0 and not isMidnightAlreadyNotified) { isMidnightAlreadyNotified = true; - systemTask.PushMessage(System::SystemTask::Messages::OnNewDay); + if(systemTask != nullptr) + systemTask->PushMessage(System::Messages::OnNewDay); } else if (hour != 0) { isMidnightAlreadyNotified = false; } @@ -104,6 +102,10 @@ const char* DateTime::DayOfWeekShortToStringLow() { return DateTime::DaysStringShortLow[(uint8_t) dayOfWeek]; } +void DateTime::Register(Pinetime::System::SystemTask* systemTask) { + this->systemTask = systemTask; +} + char const* DateTime::DaysStringLow[] = {"--", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"}; char const* DateTime::DaysStringShortLow[] = {"--", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"}; diff --git a/src/components/datetime/DateTimeController.h b/src/components/datetime/DateTimeController.h index d0ae727e..265d6e9d 100644 --- a/src/components/datetime/DateTimeController.h +++ b/src/components/datetime/DateTimeController.h @@ -27,8 +27,6 @@ namespace Pinetime { December }; - DateTime(System::SystemTask& systemTask); - void SetTime(uint16_t year, uint8_t month, uint8_t day, @@ -75,8 +73,9 @@ namespace Pinetime { return uptime; } + void Register(System::SystemTask* systemTask); + private: - System::SystemTask& systemTask; uint16_t year = 0; Months month = Months::Unknown; uint8_t day = 0; @@ -90,6 +89,7 @@ namespace Pinetime { std::chrono::seconds uptime {0}; bool isMidnightAlreadyNotified = false; + System::SystemTask* systemTask = nullptr; static char const* DaysString[]; static char const* DaysStringShort[]; diff --git a/src/components/heartrate/HeartRateController.cpp b/src/components/heartrate/HeartRateController.cpp index e84d665a..716813b3 100644 --- a/src/components/heartrate/HeartRateController.cpp +++ b/src/components/heartrate/HeartRateController.cpp @@ -4,9 +4,6 @@ using namespace Pinetime::Controllers; -HeartRateController::HeartRateController(Pinetime::System::SystemTask& systemTask) : systemTask {systemTask} { -} - void HeartRateController::Update(HeartRateController::States newState, uint8_t heartRate) { this->state = newState; if (this->heartRate != heartRate) { diff --git a/src/components/heartrate/HeartRateController.h b/src/components/heartrate/HeartRateController.h index d3a8460d..a63f1a70 100644 --- a/src/components/heartrate/HeartRateController.h +++ b/src/components/heartrate/HeartRateController.h @@ -15,8 +15,7 @@ namespace Pinetime { public: enum class States { Stopped, NotEnoughData, NoTouch, Running }; - explicit HeartRateController(System::SystemTask& systemTask); - + HeartRateController() = default; void Start(); void Stop(); void Update(States newState, uint8_t heartRate); @@ -32,7 +31,6 @@ namespace Pinetime { void SetService(Pinetime::Controllers::HeartRateService* service); private: - System::SystemTask& systemTask; Applications::HeartRateTask* task = nullptr; States state = States::Stopped; uint8_t heartRate = 0; diff --git a/src/components/heartrate/Ppg.cpp b/src/components/heartrate/Ppg.cpp index da0789e0..fcba3815 100644 --- a/src/components/heartrate/Ppg.cpp +++ b/src/components/heartrate/Ppg.cpp @@ -38,9 +38,8 @@ namespace { } } -Ppg::Ppg(float spl) - : offset {spl}, - hpf {0.87033078, -1.74066156, 0.87033078, -1.72377617, 0.75754694}, +Ppg::Ppg() + : hpf {0.87033078, -1.74066156, 0.87033078, -1.72377617, 0.75754694}, agc {20, 0.971, 2}, lpf {0.11595249, 0.23190498, 0.11595249, -0.72168143, 0.18549138} { } @@ -67,13 +66,7 @@ float Ppg::HeartRate() { dataIndex = 0; return hr; } - -int cccount = 0; float Ppg::ProcessHeartRate() { - - if (cccount > 2) - asm("nop"); - cccount++; auto t0 = Trough(data.data(), dataIndex, 7, 48); if (t0 < 0) return 0; diff --git a/src/components/heartrate/Ppg.h b/src/components/heartrate/Ppg.h index ee07dfcf..00014162 100644 --- a/src/components/heartrate/Ppg.h +++ b/src/components/heartrate/Ppg.h @@ -8,8 +8,7 @@ namespace Pinetime { namespace Controllers { class Ppg { public: - explicit Ppg(float spl); - + Ppg(); int8_t Preprocess(float spl); float HeartRate(); diff --git a/src/components/timer/TimerController.cpp b/src/components/timer/TimerController.cpp index 3b25901c..8d5f5c33 100644 --- a/src/components/timer/TimerController.cpp +++ b/src/components/timer/TimerController.cpp @@ -12,14 +12,17 @@ using namespace Pinetime::Controllers; APP_TIMER_DEF(timerAppTimer); - -TimerController::TimerController(System::SystemTask& systemTask) : systemTask{systemTask} { +namespace { + void TimerEnd(void* p_context) { + auto* controller = static_cast (p_context); + if(controller != nullptr) + controller->OnTimerEnd(); + } } void TimerController::Init() { - app_timer_create(&timerAppTimer, APP_TIMER_MODE_SINGLE_SHOT, timerEnd); - + app_timer_create(&timerAppTimer, APP_TIMER_MODE_SINGLE_SHOT, TimerEnd); } void TimerController::StartTimer(uint32_t duration) { @@ -47,13 +50,6 @@ uint32_t TimerController::GetTimeRemaining() { return (static_cast(deltaTicks) / static_cast(configTICK_RATE_HZ)) * 1000; } -void TimerController::timerEnd(void* p_context) { - - auto* controller = static_cast (p_context); - controller->timerRunning = false; - controller->systemTask.PushMessage(System::SystemTask::Messages::OnTimerDone); -} - void TimerController::StopTimer() { app_timer_stop(timerAppTimer); timerRunning = false; @@ -61,4 +57,13 @@ void TimerController::StopTimer() { bool TimerController::IsRunning() { return timerRunning; -} \ No newline at end of file +} +void TimerController::OnTimerEnd() { + timerRunning = false; + if(systemTask != nullptr) + systemTask->PushMessage(System::Messages::OnTimerDone); +} + +void TimerController::Register(Pinetime::System::SystemTask* systemTask) { + this->systemTask = systemTask; +} diff --git a/src/components/timer/TimerController.h b/src/components/timer/TimerController.h index 5a0b293e..fa7bc90d 100644 --- a/src/components/timer/TimerController.h +++ b/src/components/timer/TimerController.h @@ -12,7 +12,7 @@ namespace Pinetime { class TimerController { public: - TimerController(Pinetime::System::SystemTask& systemTask); + TimerController() = default; void Init(); @@ -23,12 +23,13 @@ namespace Pinetime { uint32_t GetTimeRemaining(); bool IsRunning(); - + + void OnTimerEnd(); + + void Register(System::SystemTask* systemTask); + private: - System::SystemTask& systemTask; - - static void timerEnd(void* p_context); - + System::SystemTask* systemTask = nullptr; TickType_t endTicks; bool timerRunning = false; }; diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 7b03d569..ba6dfbd2 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -32,6 +32,7 @@ #include "drivers/St7789.h" #include "drivers/Watchdog.h" #include "systemtask/SystemTask.h" +#include "systemtask/Messages.h" #include "displayapp/screens/settings/QuickSettings.h" #include "displayapp/screens/settings/Settings.h" @@ -51,7 +52,6 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd, Controllers::Ble& bleController, Controllers::DateTime& dateTimeController, Drivers::WatchdogView& watchdog, - System::SystemTask& systemTask, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::HeartRateController& heartRateController, Controllers::Settings& settingsController, @@ -65,7 +65,6 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd, bleController {bleController}, dateTimeController {dateTimeController}, watchdog {watchdog}, - systemTask {systemTask}, notificationManager {notificationManager}, heartRateController {heartRateController}, settingsController {settingsController}, @@ -130,7 +129,7 @@ void DisplayApp::Refresh() { vTaskDelay(100); } lcd.DisplayOff(); - systemTask.PushMessage(System::SystemTask::Messages::OnDisplayTaskSleeping); + PushMessageToSystemTask(Pinetime::System::Messages::OnDisplayTaskSleeping); state = States::Idle; break; case Messages::GoToRunning: @@ -139,7 +138,7 @@ void DisplayApp::Refresh() { state = States::Running; break; case Messages::UpdateTimeOut: - systemTask.PushMessage(System::SystemTask::Messages::UpdateTimeOut); + PushMessageToSystemTask(System::Messages::UpdateTimeOut); break; case Messages::UpdateBleConnection: // clockScreen.SetBleConnectionState(bleController.IsConnected() ? Screens::Clock::BleConnectionStates::Connected : @@ -176,7 +175,7 @@ void DisplayApp::Refresh() { LoadApp(Apps::QuickSettings, DisplayApp::FullRefreshDirections::RightAnim); break; case TouchEvents::DoubleTap: - systemTask.PushMessage(System::SystemTask::Messages::GoToSleep); + PushMessageToSystemTask(System::Messages::GoToSleep); break; default: break; @@ -188,7 +187,7 @@ void DisplayApp::Refresh() { } break; case Messages::ButtonPushed: if (currentApp == Apps::Clock) { - systemTask.PushMessage(System::SystemTask::Messages::GoToSleep); + PushMessageToSystemTask(System::Messages::GoToSleep); } else { if (!currentScreen->OnButtonPushed()) { LoadApp(returnToApp, returnDirection); @@ -267,12 +266,12 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) case Apps::Notifications: currentScreen = std::make_unique( - this, notificationManager, systemTask.nimble().alertService(), Screens::Notifications::Modes::Normal); + this, notificationManager, systemTask->nimble().alertService(), Screens::Notifications::Modes::Normal); ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); break; case Apps::NotificationsPreview: currentScreen = std::make_unique( - this, notificationManager, systemTask.nimble().alertService(), Screens::Notifications::Modes::Preview); + this, notificationManager, systemTask->nimble().alertService(), Screens::Notifications::Modes::Preview); ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); break; case Apps::Timer: @@ -321,7 +320,7 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) // case Apps::FlashLight: - currentScreen = std::make_unique(this, systemTask, brightnessController); + currentScreen = std::make_unique(this, *systemTask, brightnessController); ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::None); break; case Apps::StopWatch: @@ -337,13 +336,13 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) currentScreen = std::make_unique(this, lvgl); break; case Apps::Music: - currentScreen = std::make_unique(this, systemTask.nimble().music()); + currentScreen = std::make_unique(this, systemTask->nimble().music()); break; case Apps::Navigation: - currentScreen = std::make_unique(this, systemTask.nimble().navigation()); + currentScreen = std::make_unique(this, systemTask->nimble().navigation()); break; case Apps::HeartRate: - currentScreen = std::make_unique(this, heartRateController, systemTask); + currentScreen = std::make_unique(this, heartRateController, *systemTask); break; case Apps::Motion: currentScreen = std::make_unique(this, motionController); @@ -425,3 +424,12 @@ void DisplayApp::SetFullRefresh(DisplayApp::FullRefreshDirections direction) { void DisplayApp::SetTouchMode(DisplayApp::TouchModes mode) { touchMode = mode; } + +void DisplayApp::PushMessageToSystemTask(Pinetime::System::Messages message) { + if(systemTask != nullptr) + systemTask->PushMessage(message); +} + +void DisplayApp::Register(Pinetime::System::SystemTask* systemTask) { + this->systemTask = systemTask; +} diff --git a/src/displayapp/DisplayApp.h b/src/displayapp/DisplayApp.h index 0c7bd216..65abd41a 100644 --- a/src/displayapp/DisplayApp.h +++ b/src/displayapp/DisplayApp.h @@ -4,6 +4,7 @@ #include #include #include +#include #include "Apps.h" #include "LittleVgl.h" #include "TouchEvents.h" @@ -49,7 +50,6 @@ namespace Pinetime { Controllers::Ble& bleController, Controllers::DateTime& dateTimeController, Drivers::WatchdogView& watchdog, - System::SystemTask& systemTask, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::HeartRateController& heartRateController, Controllers::Settings& settingsController, @@ -64,6 +64,8 @@ namespace Pinetime { void SetFullRefresh(FullRefreshDirections direction); void SetTouchMode(TouchModes mode); + void Register(Pinetime::System::SystemTask* systemTask); + private: Pinetime::Drivers::St7789& lcd; Pinetime::Components::LittleVgl& lvgl; @@ -72,7 +74,7 @@ namespace Pinetime { Pinetime::Controllers::Ble& bleController; Pinetime::Controllers::DateTime& dateTimeController; Pinetime::Drivers::WatchdogView& watchdog; - Pinetime::System::SystemTask& systemTask; + Pinetime::System::SystemTask* systemTask = nullptr; Pinetime::Controllers::NotificationManager& notificationManager; Pinetime::Controllers::HeartRateController& heartRateController; Pinetime::Controllers::Settings& settingsController; @@ -108,6 +110,7 @@ namespace Pinetime { void Refresh(); void ReturnApp(Apps app, DisplayApp::FullRefreshDirections direction, TouchEvents touchEvent); void LoadApp(Apps app, DisplayApp::FullRefreshDirections direction); + void PushMessageToSystemTask(Pinetime::System::Messages message); }; } } diff --git a/src/displayapp/screens/FlashLight.cpp b/src/displayapp/screens/FlashLight.cpp index 4568db40..7db2c6c8 100644 --- a/src/displayapp/screens/FlashLight.cpp +++ b/src/displayapp/screens/FlashLight.cpp @@ -39,14 +39,14 @@ FlashLight::FlashLight(Pinetime::Applications::DisplayApp* app, backgroundAction->user_data = this; lv_obj_set_event_cb(backgroundAction, event_handler); - systemTask.PushMessage(Pinetime::System::SystemTask::Messages::DisableSleeping); + systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping); } 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_hex(0x000000)); brightness.Restore(); - systemTask.PushMessage(Pinetime::System::SystemTask::Messages::EnableSleeping); + systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping); } void FlashLight::OnClickEvent(lv_obj_t* obj, lv_event_t event) { diff --git a/src/displayapp/screens/HeartRate.cpp b/src/displayapp/screens/HeartRate.cpp index 90f6bc26..5689b63e 100644 --- a/src/displayapp/screens/HeartRate.cpp +++ b/src/displayapp/screens/HeartRate.cpp @@ -63,12 +63,12 @@ HeartRate::HeartRate(Pinetime::Applications::DisplayApp* app, label_startStop = lv_label_create(btn_startStop, nullptr); UpdateStartStopButton(isHrRunning); if (isHrRunning) - systemTask.PushMessage(Pinetime::System::SystemTask::Messages::DisableSleeping); + systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping); } HeartRate::~HeartRate() { lv_obj_clean(lv_scr_act()); - systemTask.PushMessage(Pinetime::System::SystemTask::Messages::EnableSleeping); + systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping); } bool HeartRate::Refresh() { @@ -95,12 +95,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::SystemTask::Messages::DisableSleeping); + systemTask.PushMessage(Pinetime::System::Messages::DisableSleeping); lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GREEN); } else { heartRateController.Stop(); UpdateStartStopButton(heartRateController.State() != Controllers::HeartRateController::States::Stopped); - systemTask.PushMessage(Pinetime::System::SystemTask::Messages::EnableSleeping); + systemTask.PushMessage(Pinetime::System::Messages::EnableSleeping); lv_obj_set_style_local_text_color(label_hr, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); } } diff --git a/src/displayapp/screens/ScreenList.h b/src/displayapp/screens/ScreenList.h index 73ea4610..ea66bfb2 100644 --- a/src/displayapp/screens/ScreenList.h +++ b/src/displayapp/screens/ScreenList.h @@ -15,12 +15,17 @@ namespace Pinetime { public: ScreenList(DisplayApp* app, uint8_t initScreen, - std::array()>, N>&& screens, + const std::array()>, N>&& screens, ScreenListModes mode) - : Screen(app), initScreen {initScreen}, screens {std::move(screens)}, mode {mode}, current {this->screens[initScreen]()} { - screenIndex = initScreen; + : Screen(app), initScreen {initScreen}, screens {std::move(screens)}, mode {mode}, screenIndex{initScreen}, current {this->screens[initScreen]()} { + } + ScreenList(const ScreenList&) = delete; + ScreenList& operator=(const ScreenList&) = delete; + ScreenList(ScreenList&&) = delete; + ScreenList& operator=(ScreenList&&) = delete; + ~ScreenList() override { lv_obj_clean(lv_scr_act()); } @@ -97,7 +102,7 @@ namespace Pinetime { private: uint8_t initScreen = 0; - std::array()>, N> screens; + const std::array()>, N> screens; ScreenListModes mode = ScreenListModes::UpDown; uint8_t screenIndex = 0; diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp index 3994794d..5db7468c 100644 --- a/src/displayapp/screens/settings/QuickSettings.cpp +++ b/src/displayapp/screens/settings/QuickSettings.cpp @@ -7,12 +7,12 @@ using namespace Pinetime::Applications::Screens; namespace { static void ButtonEventHandler(lv_obj_t* obj, lv_event_t event) { - QuickSettings* screen = static_cast(obj->user_data); + auto* screen = static_cast(obj->user_data); screen->OnButtonEvent(obj, event); } static void lv_update_task(struct _lv_task_t* task) { - auto user_data = static_cast(task->user_data); + auto* user_data = static_cast(task->user_data); user_data->UpdateScreen(); } } diff --git a/src/drivers/Bma421.cpp b/src/drivers/Bma421.cpp index 925b66c7..35b2c105 100644 --- a/src/drivers/Bma421.cpp +++ b/src/drivers/Bma421.cpp @@ -103,8 +103,6 @@ Bma421::Values Bma421::Process() { uint8_t activity = 0; bma423_activity_output(&activity, &bma); - NRF_LOG_INFO("MOTION : %d - %d/%d/%d", steps, data.x, data.y, data.z); - // X and Y axis are swapped because of the way the sensor is mounted in the PineTime return {steps, data.y, data.x, data.z}; } diff --git a/src/drivers/SpiMaster.h b/src/drivers/SpiMaster.h index dfc195b7..5045369a 100644 --- a/src/drivers/SpiMaster.h +++ b/src/drivers/SpiMaster.h @@ -10,7 +10,6 @@ namespace Pinetime { namespace Drivers { class SpiMaster { public: - ; enum class SpiModule : uint8_t { SPI0, SPI1 }; enum class BitOrder : uint8_t { Msb_Lsb, Lsb_Msb }; enum class Modes : uint8_t { Mode0, Mode1, Mode2, Mode3 }; diff --git a/src/heartratetask/HeartRateTask.cpp b/src/heartratetask/HeartRateTask.cpp index 36c8cc18..1c21db71 100644 --- a/src/heartratetask/HeartRateTask.cpp +++ b/src/heartratetask/HeartRateTask.cpp @@ -6,7 +6,7 @@ using namespace Pinetime::Applications; HeartRateTask::HeartRateTask(Drivers::Hrs3300& heartRateSensor, Controllers::HeartRateController& controller) - : heartRateSensor {heartRateSensor}, controller {controller}, ppg {static_cast(heartRateSensor.ReadHrs())} { + : heartRateSensor {heartRateSensor}, controller {controller}, ppg{} { messageQueue = xQueueCreate(10, 1); controller.SetHeartRateTask(this); } diff --git a/src/main.cpp b/src/main.cpp index 61194b95..60ed058b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -34,6 +34,7 @@ #include "components/motor/MotorController.h" #include "components/datetime/DateTimeController.h" #include "components/settings/Settings.h" +#include "components/heartrate/HeartRateController.h" #include "drivers/Spi.h" #include "drivers/SpiMaster.h" #include "drivers/SpiNorFlash.h" @@ -50,8 +51,6 @@ Pinetime::Logging::NrfLogger logger; Pinetime::Logging::DummyLogger logger; #endif -#include - static constexpr uint8_t pinSpiSck = 2; static constexpr uint8_t pinSpiMosi = 3; static constexpr uint8_t pinSpiMiso = 4; @@ -108,15 +107,59 @@ void ble_manager_set_ble_connection_callback(void (*connection)()); void ble_manager_set_ble_disconnection_callback(void (*disconnection)()); static constexpr uint8_t pinTouchIrq = 28; static constexpr uint8_t pinPowerPresentIrq = 19; -std::unique_ptr systemTask; Pinetime::Controllers::Settings settingsController {spiNorFlash}; Pinetime::Controllers::MotorController motorController {settingsController}; +Pinetime::Controllers::HeartRateController heartRateController; +Pinetime::Applications::HeartRateTask heartRateApp(heartRateSensor, heartRateController); + +Pinetime::Controllers::DateTime dateTimeController; +Pinetime::Drivers::Watchdog watchdog; +Pinetime::Drivers::WatchdogView watchdogView(watchdog); +Pinetime::Controllers::NotificationManager notificationManager; +Pinetime::Controllers::MotionController motionController; +Pinetime::Controllers::TimerController timerController; + +Pinetime::Applications::DisplayApp displayApp(lcd, + lvgl, + touchPanel, + batteryController, + bleController, + dateTimeController, + watchdogView, + notificationManager, + heartRateController, + settingsController, + motorController, + motionController, + timerController); + +Pinetime::System::SystemTask systemTask(spi, + lcd, + spiNorFlash, + twiMaster, + touchPanel, + lvgl, + batteryController, + bleController, + dateTimeController, + timerController, + watchdog, + notificationManager, + motorController, + heartRateSensor, + motionController, + motionSensor, + settingsController, + heartRateController, + displayApp, + heartRateApp); + void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { if (pin == pinTouchIrq) { - systemTask->OnTouchEvent(); + systemTask.OnTouchEvent(); return; } @@ -141,12 +184,12 @@ void vApplicationIdleHook(void) { void DebounceTimerChargeCallback(TimerHandle_t xTimer) { xTimerStop(xTimer, 0); - systemTask->PushMessage(Pinetime::System::SystemTask::Messages::OnChargingEvent); + systemTask.PushMessage(Pinetime::System::Messages::OnChargingEvent); } void DebounceTimerCallback(TimerHandle_t xTimer) { xTimerStop(xTimer, 0); - systemTask->OnButtonPushed(); + systemTask.OnButtonPushed(); } void SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler(void) { @@ -264,19 +307,7 @@ int main(void) { debounceTimer = xTimerCreate("debounceTimer", 200, pdFALSE, (void*) 0, DebounceTimerCallback); debounceChargeTimer = xTimerCreate("debounceTimerCharge", 200, pdFALSE, (void*) 0, DebounceTimerChargeCallback); - systemTask = std::make_unique(spi, - lcd, - spiNorFlash, - twiMaster, - touchPanel, - lvgl, - batteryController, - bleController, - motorController, - heartRateSensor, - motionSensor, - settingsController); - systemTask->Start(); + systemTask.Start(); nimble_port_init(); vTaskStartScheduler(); diff --git a/src/systemtask/Messages.h b/src/systemtask/Messages.h new file mode 100644 index 00000000..3a195e2d --- /dev/null +++ b/src/systemtask/Messages.h @@ -0,0 +1,26 @@ +#pragma once + +namespace Pinetime { + namespace System { + enum class Messages { + GoToSleep, + GoToRunning, + TouchWakeUp, + OnNewTime, + OnNewNotification, + OnTimerDone, + OnNewCall, + BleConnected, + UpdateTimeOut, + BleFirmwareUpdateStarted, + BleFirmwareUpdateFinished, + OnTouchEvent, + OnButtonEvent, + OnDisplayTaskSleeping, + EnableSleeping, + DisableSleeping, + OnNewDay, + OnChargingEvent + }; + } +} diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 58377764..be484bb4 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -42,10 +42,18 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi, Components::LittleVgl& lvgl, Controllers::Battery& batteryController, Controllers::Ble& bleController, + Controllers::DateTime& dateTimeController, + Controllers::TimerController& timerController, + Drivers::Watchdog& watchdog, + Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::MotorController& motorController, Pinetime::Drivers::Hrs3300& heartRateSensor, + Pinetime::Controllers::MotionController& motionController, Pinetime::Drivers::Bma421& motionSensor, - Controllers::Settings& settingsController) + Controllers::Settings& settingsController, + Pinetime::Controllers::HeartRateController& heartRateController, + Pinetime::Applications::DisplayApp& displayApp, + Pinetime::Applications::HeartRateTask& heartRateApp) : spi {spi}, lcd {lcd}, spiNorFlash {spiNorFlash}, @@ -53,17 +61,20 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi, touchPanel {touchPanel}, lvgl {lvgl}, batteryController {batteryController}, - heartRateController {*this}, bleController {bleController}, - dateTimeController {*this}, - timerController {*this}, - watchdog {}, - watchdogView {watchdog}, + dateTimeController {dateTimeController}, + timerController {timerController}, + watchdog {watchdog}, + notificationManager{notificationManager}, motorController {motorController}, heartRateSensor {heartRateSensor}, motionSensor {motionSensor}, settingsController {settingsController}, - nimbleController(*this, bleController, dateTimeController, notificationManager, batteryController, spiNorFlash, heartRateController) { + heartRateController{heartRateController}, + nimbleController(*this, bleController, dateTimeController, notificationManager, batteryController, spiNorFlash, heartRateController), + motionController{motionController}, + displayApp{displayApp}, + heartRateApp(heartRateApp) { systemTasksMsgQueue = xQueueCreate(10, 1); } @@ -96,9 +107,11 @@ void SystemTask::Work() { twiMaster.Init(); touchPanel.Init(); + dateTimeController.Register(this); batteryController.Init(); motorController.Init(); motionSensor.SoftReset(); + timerController.Register(this); timerController.Init(); // Reset the TWI device because the motion sensor chip most probably crashed it... @@ -108,28 +121,14 @@ void SystemTask::Work() { motionSensor.Init(); settingsController.Init(); - displayApp = std::make_unique(lcd, - lvgl, - touchPanel, - batteryController, - bleController, - dateTimeController, - watchdogView, - *this, - notificationManager, - heartRateController, - settingsController, - motorController, - motionController, - timerController); - displayApp->Start(); - - displayApp->PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel); + displayApp.Register(this); + displayApp.Start(); + + displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel); heartRateSensor.Init(); heartRateSensor.Disable(); - heartRateApp = std::make_unique(heartRateSensor, heartRateController); - heartRateApp->Start(); + heartRateApp.Start(); nrf_gpio_cfg_sense_input(pinButton, (nrf_gpio_pin_pull_t) GPIO_PIN_CNF_PULL_Pulldown, (nrf_gpio_pin_sense_t) GPIO_PIN_CNF_SENSE_High); nrf_gpio_cfg_output(15); @@ -208,9 +207,9 @@ void SystemTask::Work() { spiNorFlash.Wakeup(); lcd.Wakeup(); - displayApp->PushMessage(Pinetime::Applications::Display::Messages::GoToRunning); - displayApp->PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel); - heartRateApp->PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToRunning); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel); + heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::WakeUp); isSleeping = false; isWakingUp = false; @@ -230,26 +229,26 @@ void SystemTask::Work() { isGoingToSleep = true; NRF_LOG_INFO("[systemtask] Going to sleep"); xTimerStop(idleTimer, 0); - displayApp->PushMessage(Pinetime::Applications::Display::Messages::GoToSleep); - heartRateApp->PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::GoToSleep); + heartRateApp.PushMessage(Pinetime::Applications::HeartRateTask::Messages::GoToSleep); break; case Messages::OnNewTime: ReloadIdleTimer(); - displayApp->PushMessage(Pinetime::Applications::Display::Messages::UpdateDateTime); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::UpdateDateTime); break; case Messages::OnNewNotification: if (isSleeping && !isWakingUp) { GoToRunning(); } motorController.SetDuration(35); - displayApp->PushMessage(Pinetime::Applications::Display::Messages::NewNotification); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::NewNotification); break; case Messages::OnTimerDone: if (isSleeping && !isWakingUp) { GoToRunning(); } motorController.SetDuration(35); - displayApp->PushMessage(Pinetime::Applications::Display::Messages::TimerDone); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::TimerDone); break; case Messages::BleConnected: ReloadIdleTimer(); @@ -260,7 +259,7 @@ void SystemTask::Work() { doNotGoToSleep = true; if (isSleeping && !isWakingUp) GoToRunning(); - displayApp->PushMessage(Pinetime::Applications::Display::Messages::BleFirmwareUpdateStarted); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::BleFirmwareUpdateStarted); break; case Messages::BleFirmwareUpdateFinished: doNotGoToSleep = false; @@ -359,7 +358,7 @@ void SystemTask::OnButtonPushed() { if (!isSleeping) { NRF_LOG_INFO("[systemtask] Button pushed"); PushMessage(Messages::OnButtonEvent); - displayApp->PushMessage(Pinetime::Applications::Display::Messages::ButtonPushed); + displayApp.PushMessage(Pinetime::Applications::Display::Messages::ButtonPushed); } else { if (!isWakingUp) { NRF_LOG_INFO("[systemtask] Button pushed, waking up"); @@ -380,7 +379,7 @@ void SystemTask::OnTouchEvent() { return; if (!isSleeping) { PushMessage(Messages::OnTouchEvent); - displayApp->PushMessage(Pinetime::Applications::Display::Messages::TouchEvent); + 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) @@ -389,7 +388,7 @@ void SystemTask::OnTouchEvent() { } } -void SystemTask::PushMessage(SystemTask::Messages msg) { +void SystemTask::PushMessage(System::Messages msg) { if (msg == Messages::GoToSleep) { isGoingToSleep = true; } diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index ea41a69d..fa6a949c 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -6,7 +6,6 @@ #include #include #include -#include #include #include #include @@ -27,6 +26,7 @@ #endif #include "drivers/Watchdog.h" +#include "Messages.h" namespace Pinetime { namespace Drivers { @@ -40,27 +40,6 @@ namespace Pinetime { namespace System { class SystemTask { public: - enum class Messages { - GoToSleep, - GoToRunning, - TouchWakeUp, - OnNewTime, - OnNewNotification, - OnTimerDone, - OnNewCall, - BleConnected, - UpdateTimeOut, - BleFirmwareUpdateStarted, - BleFirmwareUpdateFinished, - OnTouchEvent, - OnButtonEvent, - OnDisplayTaskSleeping, - EnableSleeping, - DisableSleeping, - OnNewDay, - OnChargingEvent - }; - SystemTask(Drivers::SpiMaster& spi, Drivers::St7789& lcd, Pinetime::Drivers::SpiNorFlash& spiNorFlash, @@ -69,10 +48,18 @@ namespace Pinetime { Components::LittleVgl& lvgl, Controllers::Battery& batteryController, Controllers::Ble& bleController, + Controllers::DateTime& dateTimeController, + Controllers::TimerController& timerController, + Drivers::Watchdog& watchdog, + Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::MotorController& motorController, Pinetime::Drivers::Hrs3300& heartRateSensor, + Pinetime::Controllers::MotionController& motionController, Pinetime::Drivers::Bma421& motionSensor, - Controllers::Settings& settingsController); + Controllers::Settings& settingsController, + Pinetime::Controllers::HeartRateController& heartRateController, + Pinetime::Applications::DisplayApp& displayApp, + Pinetime::Applications::HeartRateTask& heartRateApp); void Start(); void PushMessage(Messages msg); @@ -96,27 +83,29 @@ namespace Pinetime { Pinetime::Drivers::Cst816S& touchPanel; Pinetime::Components::LittleVgl& lvgl; Pinetime::Controllers::Battery& batteryController; - std::unique_ptr displayApp; - Pinetime::Controllers::HeartRateController heartRateController; - std::unique_ptr heartRateApp; + Pinetime::Controllers::Ble& bleController; - Pinetime::Controllers::DateTime dateTimeController; - Pinetime::Controllers::TimerController timerController; + Pinetime::Controllers::DateTime& dateTimeController; + Pinetime::Controllers::TimerController& timerController; QueueHandle_t systemTasksMsgQueue; std::atomic isSleeping {false}; std::atomic isGoingToSleep {false}; std::atomic isWakingUp {false}; - Pinetime::Drivers::Watchdog watchdog; - Pinetime::Drivers::WatchdogView watchdogView; - Pinetime::Controllers::NotificationManager notificationManager; + Pinetime::Drivers::Watchdog& watchdog; + Pinetime::Controllers::NotificationManager& notificationManager; Pinetime::Controllers::MotorController& motorController; Pinetime::Drivers::Hrs3300& heartRateSensor; Pinetime::Drivers::Bma421& motionSensor; Pinetime::Controllers::Settings& settingsController; + Pinetime::Controllers::HeartRateController& heartRateController; Pinetime::Controllers::NimbleController nimbleController; Controllers::BrightnessController brightnessController; - Pinetime::Controllers::MotionController motionController; + Pinetime::Controllers::MotionController& motionController; + + Pinetime::Applications::DisplayApp& displayApp; + Pinetime::Applications::HeartRateTask& heartRateApp; + static constexpr uint8_t pinSpiSck = 2; static constexpr uint8_t pinSpiMosi = 3; -- cgit v1.2.3-70-g09d2 From ff00873f974cb1400acf7721251167634e60107a Mon Sep 17 00:00:00 2001 From: Jean-François Milants Date: Sun, 6 Jun 2021 20:20:55 +0200 Subject: Fix build for recovery firmware. --- src/displayapp/DisplayAppRecovery.cpp | 7 +++++-- src/displayapp/DisplayAppRecovery.h | 2 +- src/main.cpp | 1 - 3 files changed, 6 insertions(+), 4 deletions(-) (limited to 'src/main.cpp') diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp index 856eafd8..b73d0a85 100644 --- a/src/displayapp/DisplayAppRecovery.cpp +++ b/src/displayapp/DisplayAppRecovery.cpp @@ -14,7 +14,6 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd, Controllers::Ble& bleController, Controllers::DateTime& dateTimeController, Drivers::WatchdogView& watchdog, - System::SystemTask& systemTask, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::HeartRateController& heartRateController, Controllers::Settings& settingsController, @@ -113,4 +112,8 @@ void DisplayApp::PushMessage(Display::Messages msg) { /* Actual macro used here is port specific. */ // TODO : should I do something here? } -} \ No newline at end of file +} + +void DisplayApp::Register(Pinetime::System::SystemTask* systemTask) { + +} diff --git a/src/displayapp/DisplayAppRecovery.h b/src/displayapp/DisplayAppRecovery.h index 2c5a36fb..638c0071 100644 --- a/src/displayapp/DisplayAppRecovery.h +++ b/src/displayapp/DisplayAppRecovery.h @@ -39,7 +39,6 @@ namespace Pinetime { Controllers::Ble& bleController, Controllers::DateTime& dateTimeController, Drivers::WatchdogView& watchdog, - System::SystemTask& systemTask, Pinetime::Controllers::NotificationManager& notificationManager, Pinetime::Controllers::HeartRateController& heartRateController, Controllers::Settings& settingsController, @@ -48,6 +47,7 @@ namespace Pinetime { Pinetime::Controllers::TimerController& timerController); void Start(); void PushMessage(Pinetime::Applications::Display::Messages msg); + void Register(Pinetime::System::SystemTask* systemTask); private: TaskHandle_t taskHandle; diff --git a/src/main.cpp b/src/main.cpp index 60ed058b..52ec9580 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -33,7 +33,6 @@ #include "components/ble/NotificationManager.h" #include "components/motor/MotorController.h" #include "components/datetime/DateTimeController.h" -#include "components/settings/Settings.h" #include "components/heartrate/HeartRateController.h" #include "drivers/Spi.h" #include "drivers/SpiMaster.h" -- cgit v1.2.3-70-g09d2 From 6d524ebea2c97e309633d5e01c3a1e37c182f27d Mon Sep 17 00:00:00 2001 From: Jean-François Milants Date: Sat, 12 Jun 2021 10:58:28 +0200 Subject: Move most of the code from the constructor of the objects statically initialized in main() into Start()/Init() functions to avoid Static Initialization Order Fiasco (https://en.cppreference.com/w/cpp/language/siof). See https://github.com/JF002/InfiniTime/pull/415#issuecomment-859004238. --- src/displayapp/DisplayApp.cpp | 6 ++++-- src/displayapp/DisplayAppRecovery.cpp | 3 ++- src/displayapp/LittleVgl.cpp | 4 ++++ src/displayapp/LittleVgl.h | 2 ++ src/drivers/SpiMaster.cpp | 7 +++++-- src/drivers/SpiMaster.h | 2 +- src/drivers/TwiMaster.cpp | 4 +++- src/drivers/TwiMaster.h | 2 +- src/heartratetask/HeartRateTask.cpp | 5 +++-- src/main.cpp | 2 ++ src/systemtask/SystemTask.cpp | 3 ++- 11 files changed, 29 insertions(+), 11 deletions(-) (limited to 'src/main.cpp') diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 3bfaf2a2..05f171be 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -77,12 +77,14 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd, motorController {motorController}, motionController {motionController}, timerController {timerController} { +} + +void DisplayApp::Start() { msgQueue = xQueueCreate(queueSize, itemSize); + // Start clock when smartwatch boots LoadApp(Apps::Clock, DisplayApp::FullRefreshDirections::None); -} -void DisplayApp::Start() { if (pdPASS != xTaskCreate(DisplayApp::Process, "displayapp", 800, this, 0, &taskHandle)) { APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); } diff --git a/src/displayapp/DisplayAppRecovery.cpp b/src/displayapp/DisplayAppRecovery.cpp index b73d0a85..fd517b11 100644 --- a/src/displayapp/DisplayAppRecovery.cpp +++ b/src/displayapp/DisplayAppRecovery.cpp @@ -21,10 +21,11 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd, Pinetime::Controllers::MotionController& motionController, Pinetime::Controllers::TimerController& timerController) : lcd {lcd}, bleController {bleController} { - msgQueue = xQueueCreate(queueSize, itemSize); + } void DisplayApp::Start() { + msgQueue = xQueueCreate(queueSize, itemSize); if (pdPASS != xTaskCreate(DisplayApp::Process, "displayapp", 512, this, 0, &taskHandle)) APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); } diff --git a/src/displayapp/LittleVgl.cpp b/src/displayapp/LittleVgl.cpp index 36df51b4..c069afa2 100644 --- a/src/displayapp/LittleVgl.cpp +++ b/src/displayapp/LittleVgl.cpp @@ -23,6 +23,10 @@ bool touchpad_read(lv_indev_drv_t* indev_drv, lv_indev_data_t* data) { LittleVgl::LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel) : lcd {lcd}, touchPanel {touchPanel}, previousClick {0, 0} { + +} + +void LittleVgl::Init() { lv_init(); InitTheme(); InitDisplay(); diff --git a/src/displayapp/LittleVgl.h b/src/displayapp/LittleVgl.h index 7f7b76e0..41f934a7 100644 --- a/src/displayapp/LittleVgl.h +++ b/src/displayapp/LittleVgl.h @@ -19,6 +19,8 @@ namespace Pinetime { LittleVgl(LittleVgl&&) = delete; LittleVgl& operator=(LittleVgl&&) = delete; + void Init(); + void FlushDisplay(const lv_area_t* area, lv_color_t* color_p); bool GetTouchPadInfo(lv_indev_data_t* ptr); void SetFullRefresh(FullRefreshDirections direction); diff --git a/src/drivers/SpiMaster.cpp b/src/drivers/SpiMaster.cpp index e2be5027..0d5bb83c 100644 --- a/src/drivers/SpiMaster.cpp +++ b/src/drivers/SpiMaster.cpp @@ -7,11 +7,14 @@ using namespace Pinetime::Drivers; SpiMaster::SpiMaster(const SpiMaster::SpiModule spi, const SpiMaster::Parameters& params) : spi {spi}, params {params} { - mutex = xSemaphoreCreateBinary(); - ASSERT(mutex != NULL); } bool SpiMaster::Init() { + if(mutex == nullptr) { + mutex = xSemaphoreCreateBinary(); + ASSERT(mutex != nullptr); + } + /* Configure GPIO pins used for pselsck, pselmosi, pselmiso and pselss for SPI0 */ nrf_gpio_pin_set(params.pinSCK); nrf_gpio_cfg_output(params.pinSCK); diff --git a/src/drivers/SpiMaster.h b/src/drivers/SpiMaster.h index 5045369a..5ea624f2 100644 --- a/src/drivers/SpiMaster.h +++ b/src/drivers/SpiMaster.h @@ -59,7 +59,7 @@ namespace Pinetime { volatile uint32_t currentBufferAddr = 0; volatile size_t currentBufferSize = 0; volatile TaskHandle_t taskToNotify; - SemaphoreHandle_t mutex; + SemaphoreHandle_t mutex = nullptr; }; } } diff --git a/src/drivers/TwiMaster.cpp b/src/drivers/TwiMaster.cpp index 7b6582dd..fc9edf81 100644 --- a/src/drivers/TwiMaster.cpp +++ b/src/drivers/TwiMaster.cpp @@ -9,10 +9,12 @@ using namespace Pinetime::Drivers; // TODO use DMA/IRQ TwiMaster::TwiMaster(const Modules module, const Parameters& params) : module {module}, params {params} { - mutex = xSemaphoreCreateBinary(); } void TwiMaster::Init() { + if(mutex == nullptr) + mutex = xSemaphoreCreateBinary(); + NRF_GPIO->PIN_CNF[params.pinScl] = ((uint32_t) GPIO_PIN_CNF_DIR_Input << GPIO_PIN_CNF_DIR_Pos) | ((uint32_t) GPIO_PIN_CNF_INPUT_Connect << GPIO_PIN_CNF_INPUT_Pos) | ((uint32_t) GPIO_PIN_CNF_PULL_Pullup << GPIO_PIN_CNF_PULL_Pos) | ((uint32_t) GPIO_PIN_CNF_DRIVE_S0D1 << GPIO_PIN_CNF_DRIVE_Pos) | diff --git a/src/drivers/TwiMaster.h b/src/drivers/TwiMaster.h index 1c0648a2..6175b99b 100644 --- a/src/drivers/TwiMaster.h +++ b/src/drivers/TwiMaster.h @@ -31,7 +31,7 @@ namespace Pinetime { ErrorCodes Write(uint8_t deviceAddress, const uint8_t* data, size_t size, bool stop); void FixHwFreezed(); NRF_TWIM_Type* twiBaseAddress; - SemaphoreHandle_t mutex; + SemaphoreHandle_t mutex = nullptr; const Modules module; const Parameters params; static constexpr uint8_t maxDataSize {16}; diff --git a/src/heartratetask/HeartRateTask.cpp b/src/heartratetask/HeartRateTask.cpp index 1c21db71..fddc05d7 100644 --- a/src/heartratetask/HeartRateTask.cpp +++ b/src/heartratetask/HeartRateTask.cpp @@ -7,11 +7,12 @@ using namespace Pinetime::Applications; HeartRateTask::HeartRateTask(Drivers::Hrs3300& heartRateSensor, Controllers::HeartRateController& controller) : heartRateSensor {heartRateSensor}, controller {controller}, ppg{} { - messageQueue = xQueueCreate(10, 1); - controller.SetHeartRateTask(this); } void HeartRateTask::Start() { + messageQueue = xQueueCreate(10, 1); + controller.SetHeartRateTask(this); + if (pdPASS != xTaskCreate(HeartRateTask::Process, "Heartrate", 500, this, 0, &taskHandle)) APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); } diff --git a/src/main.cpp b/src/main.cpp index 52ec9580..4c2c5de8 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -306,6 +306,8 @@ int main(void) { debounceTimer = xTimerCreate("debounceTimer", 200, pdFALSE, (void*) 0, DebounceTimerCallback); debounceChargeTimer = xTimerCreate("debounceTimerCharge", 200, pdFALSE, (void*) 0, DebounceTimerChargeCallback); + lvgl.Init(); + systemTask.Start(); nimble_port_init(); diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 4799624a..38e9793c 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -81,10 +81,11 @@ SystemTask::SystemTask(Drivers::SpiMaster& spi, motionController{motionController}, displayApp{displayApp}, heartRateApp(heartRateApp) { - systemTasksMsgQueue = xQueueCreate(10, 1); + } void SystemTask::Start() { + systemTasksMsgQueue = xQueueCreate(10, 1); if (pdPASS != xTaskCreate(SystemTask::Process, "MAIN", 350, this, 0, &taskHandle)) APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); } -- cgit v1.2.3-70-g09d2 From 0045fb16b66b008c13888312b92688dcb7535a0c Mon Sep 17 00:00:00 2001 From: Neil O'Fix <69880003+nlfx@users.noreply.github.com> Date: Sat, 26 Jun 2021 18:53:32 +0000 Subject: SPI flash sleep if bootloader >= 1.0.0 (#322) * Retrieve and display bootloader version - Display bootloader version on System Info screen - Enable SPI flash sleep mode if bootloader version >= 1.0.0 * Wait for SPI flash to wakeup before starting OTA DFU --- src/BootloaderVersion.cpp | 30 ++++++++++++++++++++---------- src/BootloaderVersion.h | 15 ++++++++++----- src/components/ble/DfuService.cpp | 5 +++++ src/displayapp/screens/SystemInfo.cpp | 11 +++++++---- src/main.cpp | 4 ++++ src/systemtask/SystemTask.h | 4 ++++ 6 files changed, 50 insertions(+), 19 deletions(-) (limited to 'src/main.cpp') diff --git a/src/BootloaderVersion.cpp b/src/BootloaderVersion.cpp index 5eba7a1d..07a1da4e 100644 --- a/src/BootloaderVersion.cpp +++ b/src/BootloaderVersion.cpp @@ -1,26 +1,36 @@ #include +#include #include "BootloaderVersion.h" using namespace Pinetime; -// NOTE : current bootloader does not export its version to the application firmware. +// NOTE : version < 1.0.0 of bootloader does not export its version to the application firmware. -uint32_t BootloaderVersion::Major() { - return 0; +uint32_t BootloaderVersion::version = 0; +char BootloaderVersion::versionString[BootloaderVersion::VERSION_STR_LEN] = "0.0.0"; + +const uint32_t BootloaderVersion::Major() { + return (BootloaderVersion::version >> 16u) & 0xff; } -uint32_t BootloaderVersion::Minor() { - return 0; +const uint32_t BootloaderVersion::Minor() { + return (BootloaderVersion::version >> 8u) & 0xff; } -uint32_t BootloaderVersion::Patch() { - return 0; +const uint32_t BootloaderVersion::Patch() { + return BootloaderVersion::version & 0xff; } const char* BootloaderVersion::VersionString() { - return "0.0.0"; + return BootloaderVersion::versionString; +} + +const bool BootloaderVersion::IsValid() { + return BootloaderVersion::version >= 0x00010000; } -bool BootloaderVersion::IsValid() { - return false; +void BootloaderVersion::SetVersion(uint32_t v) { + BootloaderVersion::version = v; + snprintf(BootloaderVersion::versionString, BootloaderVersion::VERSION_STR_LEN, "%ld.%ld.%ld", + BootloaderVersion::Major(), BootloaderVersion::Minor(), BootloaderVersion::Patch()); } diff --git a/src/BootloaderVersion.h b/src/BootloaderVersion.h index c1ede0f5..f8127414 100644 --- a/src/BootloaderVersion.h +++ b/src/BootloaderVersion.h @@ -3,10 +3,15 @@ namespace Pinetime { class BootloaderVersion { public: - static uint32_t Major(); - static uint32_t Minor(); - static uint32_t Patch(); + static const uint32_t Major(); + static const uint32_t Minor(); + static const uint32_t Patch(); static const char* VersionString(); - static bool IsValid(); + static const bool IsValid(); + static void SetVersion(uint32_t v); + private: + static uint32_t version; + static constexpr size_t VERSION_STR_LEN = 12; + static char versionString[VERSION_STR_LEN]; }; -} \ No newline at end of file +} diff --git a/src/components/ble/DfuService.cpp b/src/components/ble/DfuService.cpp index cec194cc..e6bcea81 100644 --- a/src/components/ble/DfuService.cpp +++ b/src/components/ble/DfuService.cpp @@ -121,6 +121,11 @@ int DfuService::WritePacketHandler(uint16_t connectionHandle, os_mbuf* om) { NRF_LOG_INFO( "[DFU] -> Start data received : SD size : %d, BT size : %d, app size : %d", softdeviceSize, bootloaderSize, applicationSize); + // wait until SystemTask has finished waking up all devices + while (systemTask.IsSleeping()) { + vTaskDelay(50); // 50ms + } + dfuImage.Erase(); uint8_t data[] {16, 1, 1}; diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index 1cf895c7..60e53ad6 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -3,6 +3,7 @@ #include "../DisplayApp.h" #include "Label.h" #include "Version.h" +#include "BootloaderVersion.h" #include "components/battery/BatteryController.h" #include "components/ble/BleController.h" #include "components/brightness/BrightnessController.h" @@ -83,17 +84,19 @@ std::unique_ptr SystemInfo::CreateScreen1() { lv_label_set_recolor(label, true); lv_label_set_text_fmt(label, "#FFFF00 InfiniTime#\n\n" - "#444444 Version# %ld.%ld.%ld\n\n" - "#444444 Short Ref# %s\n\n" + "#444444 Version# %ld.%ld.%ld\n" + "#444444 Short Ref# %s\n" "#444444 Build date#\n" "%s\n" - "%s\n", + "%s\n\n" + "#444444 Bootloader# %s", Version::Major(), Version::Minor(), Version::Patch(), Version::GitCommitHash(), __DATE__, - __TIME__); + __TIME__, + BootloaderVersion::VersionString()); lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); return std::make_unique(0, 5, app, label); diff --git a/src/main.cpp b/src/main.cpp index 4c2c5de8..5832a78f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,6 +28,7 @@ #include #include +#include "BootloaderVersion.h" #include "components/battery/BatteryController.h" #include "components/ble/BleController.h" #include "components/ble/NotificationManager.h" @@ -306,6 +307,9 @@ int main(void) { debounceTimer = xTimerCreate("debounceTimer", 200, pdFALSE, (void*) 0, DebounceTimerCallback); debounceChargeTimer = xTimerCreate("debounceTimerCharge", 200, pdFALSE, (void*) 0, DebounceTimerChargeCallback); + // retrieve version stored by bootloader + Pinetime::BootloaderVersion::SetVersion(NRF_TIMER2->CC[0]); + lvgl.Init(); systemTask.Start(); diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h index fa6a949c..f563640c 100644 --- a/src/systemtask/SystemTask.h +++ b/src/systemtask/SystemTask.h @@ -73,6 +73,10 @@ namespace Pinetime { return nimbleController; }; + bool IsSleeping() const { + return isSleeping; + } + private: TaskHandle_t taskHandle; -- cgit v1.2.3-70-g09d2 From 99e26bdd4cbafcdeec815ce6435f1830f1d74816 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Wed, 7 Jul 2021 15:47:47 +0300 Subject: LVGL use system tick --- src/FreeRTOSConfig.h | 2 +- src/displayapp/screens/BatteryInfo.cpp | 38 +++-------------------- src/displayapp/screens/BatteryInfo.h | 3 -- src/displayapp/screens/Tile.cpp | 2 +- src/displayapp/screens/settings/QuickSettings.cpp | 2 +- src/libs/lv_conf.h | 8 ++--- src/main.cpp | 7 ----- 7 files changed, 11 insertions(+), 51 deletions(-) (limited to 'src/main.cpp') diff --git a/src/FreeRTOSConfig.h b/src/FreeRTOSConfig.h index 07c152dc..adbbc8f0 100644 --- a/src/FreeRTOSConfig.h +++ b/src/FreeRTOSConfig.h @@ -77,7 +77,7 @@ #define configENABLE_BACKWARD_COMPATIBILITY 1 /* Hook function related definitions. */ -#define configUSE_IDLE_HOOK 1 +#define configUSE_IDLE_HOOK 0 #define configUSE_TICK_HOOK 0 #define configCHECK_FOR_STACK_OVERFLOW 0 #define configUSE_MALLOC_FAILED_HOOK 0 diff --git a/src/displayapp/screens/BatteryInfo.cpp b/src/displayapp/screens/BatteryInfo.cpp index 87c8b4bb..5ea0b6ff 100644 --- a/src/displayapp/screens/BatteryInfo.cpp +++ b/src/displayapp/screens/BatteryInfo.cpp @@ -9,11 +9,6 @@ static void lv_update_task(struct _lv_task_t* task) { user_data->UpdateScreen(); } -static void lv_anim_task(struct _lv_task_t* task) { - auto user_data = static_cast(task->user_data); - user_data->UpdateAnim(); -} - BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Controllers::Battery& batteryController) : Screen(app), batteryController {batteryController} { @@ -24,12 +19,12 @@ BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Cont lv_obj_set_size(charging_bar, 200, 15); lv_bar_set_range(charging_bar, 0, 100); lv_obj_align(charging_bar, nullptr, LV_ALIGN_CENTER, 0, 10); - lv_bar_set_anim_time(charging_bar, 2000); + lv_bar_set_anim_time(charging_bar, 1000); lv_obj_set_style_local_radius(charging_bar, LV_BAR_PART_BG, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_BG, LV_STATE_DEFAULT, lv_color_hex(0x222222)); lv_obj_set_style_local_bg_opa(charging_bar, LV_BAR_PART_BG, LV_STATE_DEFAULT, LV_OPA_100); lv_obj_set_style_local_bg_color(charging_bar, LV_BAR_PART_INDIC, LV_STATE_DEFAULT, lv_color_hex(0xFF0000)); - lv_bar_set_value(charging_bar, batteryPercent, LV_ANIM_OFF); + lv_bar_set_value(charging_bar, batteryPercent, LV_ANIM_ON); status = lv_label_create(lv_scr_act(), nullptr); lv_label_set_text_static(status, "Reading Battery status"); @@ -58,40 +53,15 @@ BatteryInfo::BatteryInfo(Pinetime::Applications::DisplayApp* app, Pinetime::Cont lv_obj_set_pos(backgroundLabel, 0, 0); lv_label_set_text_static(backgroundLabel, ""); - taskUpdate = lv_task_create(lv_update_task, 500000, LV_TASK_PRIO_LOW, this); - taskAnim = lv_task_create(lv_anim_task, 1000, LV_TASK_PRIO_LOW, this); + taskUpdate = lv_task_create(lv_update_task, 5000, LV_TASK_PRIO_LOW, this); UpdateScreen(); } BatteryInfo::~BatteryInfo() { lv_task_del(taskUpdate); - lv_task_del(taskAnim); lv_obj_clean(lv_scr_act()); } -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++; - } - } - - lv_bar_set_value(charging_bar, animation, LV_ANIM_OFF); - } -} - void BatteryInfo::UpdateScreen() { batteryController.Update(); @@ -123,9 +93,9 @@ void BatteryInfo::UpdateScreen() { 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); + lv_bar_set_value(charging_bar, batteryPercent, LV_ANIM_ON); } bool BatteryInfo::Refresh() { - return running; } diff --git a/src/displayapp/screens/BatteryInfo.h b/src/displayapp/screens/BatteryInfo.h index 346dc571..32115938 100644 --- a/src/displayapp/screens/BatteryInfo.h +++ b/src/displayapp/screens/BatteryInfo.h @@ -22,7 +22,6 @@ namespace Pinetime { bool Refresh() override; void UpdateScreen(); - void UpdateAnim(); private: Pinetime::Controllers::Battery& batteryController; @@ -33,9 +32,7 @@ namespace Pinetime { lv_obj_t* status; lv_task_t* taskUpdate; - lv_task_t* taskAnim; - int8_t animation = 0; int8_t batteryPercent = -1; uint16_t batteryVoltage = 0; }; diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp index ec36af38..3eb127cc 100644 --- a/src/displayapp/screens/Tile.cpp +++ b/src/displayapp/screens/Tile.cpp @@ -107,7 +107,7 @@ Tile::Tile(uint8_t screenID, lv_obj_set_pos(backgroundLabel, 0, 0); lv_label_set_text_static(backgroundLabel, ""); - taskUpdate = lv_task_create(lv_update_task, 500000, LV_TASK_PRIO_MID, this); + taskUpdate = lv_task_create(lv_update_task, 5000, LV_TASK_PRIO_MID, this); } Tile::~Tile() { diff --git a/src/displayapp/screens/settings/QuickSettings.cpp b/src/displayapp/screens/settings/QuickSettings.cpp index 5db7468c..acc2a27a 100644 --- a/src/displayapp/screens/settings/QuickSettings.cpp +++ b/src/displayapp/screens/settings/QuickSettings.cpp @@ -110,7 +110,7 @@ QuickSettings::QuickSettings(Pinetime::Applications::DisplayApp* app, lv_obj_set_pos(backgroundLabel, 0, 0); lv_label_set_text_static(backgroundLabel, ""); - taskUpdate = lv_task_create(lv_update_task, 500000, LV_TASK_PRIO_MID, this); + taskUpdate = lv_task_create(lv_update_task, 5000, LV_TASK_PRIO_MID, this); } QuickSettings::~QuickSettings() { diff --git a/src/libs/lv_conf.h b/src/libs/lv_conf.h index a03a4833..37824bbd 100644 --- a/src/libs/lv_conf.h +++ b/src/libs/lv_conf.h @@ -293,10 +293,10 @@ typedef void* lv_img_decoder_user_data_t; /* 1: use a custom tick source. * It removes the need to manually update the tick with `lv_tick_inc`) */ -#define LV_TICK_CUSTOM 0 +#define LV_TICK_CUSTOM 1 #if LV_TICK_CUSTOM == 1 -#define LV_TICK_CUSTOM_INCLUDE "Arduino.h" /*Header for the system time function*/ -#define LV_TICK_CUSTOM_SYS_TIME_EXPR (millis()) /*Expression evaluating to current system time in ms*/ +#define LV_TICK_CUSTOM_INCLUDE "FreeRTOS.h" /*Header for the system time function*/ +#define LV_TICK_CUSTOM_SYS_TIME_EXPR (xTaskGetTickCount()) /*Expression evaluating to current system time in ms*/ #endif /*LV_TICK_CUSTOM*/ typedef void* lv_disp_drv_user_data_t; /*Type of user data in the display driver*/ @@ -759,4 +759,4 @@ typedef void* lv_obj_user_data_t; /*--END OF LV_CONF_H--*/ -#endif /*LV_CONF_H*/ \ No newline at end of file +#endif /*LV_CONF_H*/ diff --git a/src/main.cpp b/src/main.cpp index 5832a78f..ebdf0175 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -175,13 +175,6 @@ void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } -extern "C" { -void vApplicationIdleHook(void) { - if (!isFactory) - lv_tick_inc(1); -} -} - void DebounceTimerChargeCallback(TimerHandle_t xTimer) { xTimerStop(xTimer, 0); systemTask.PushMessage(Pinetime::System::Messages::OnChargingEvent); -- cgit v1.2.3-70-g09d2 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 --- .gitmodules | 3 + src/CMakeLists.txt | 29 +++++- src/components/fs/FS.cpp | 197 +++++++++++++++++++++++++++++++++++ src/components/fs/FS.h | 71 +++++++++++++ src/components/settings/Settings.cpp | 100 ++++-------------- src/components/settings/Settings.h | 58 +++++------ src/libs/littlefs | 1 + src/libs/lv_conf.h | 4 +- src/main.cpp | 13 ++- src/systemtask/SystemTask.cpp | 11 +- src/systemtask/SystemTask.h | 12 ++- 11 files changed, 369 insertions(+), 130 deletions(-) create mode 100644 src/components/fs/FS.cpp create mode 100644 src/components/fs/FS.h create mode 160000 src/libs/littlefs (limited to 'src/main.cpp') diff --git a/.gitmodules b/.gitmodules index 6f6d0e10..815fc022 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "src/libs/lvgl"] path = src/libs/lvgl url = https://github.com/joaquimorg/lvgl.git +[submodule "src/libs/littlefs"] + path = src/libs/littlefs + url = https://github.com/littlefs-project/littlefs.git diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index aca86543..40e1f2a5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -166,6 +166,13 @@ set(NIMBLE_SRC libs/mynewt-nimble/nimble/host/util/src/addr.c ) +set(LITTLEFS_SRC + libs/littlefs/lfs_util.h + libs/littlefs/lfs.h + libs/littlefs/lfs_util.c + libs/littlefs/lfs.c + ) + set(LVGL_SRC libs/lv_conf.h libs/lvgl/lvgl.h @@ -465,6 +472,7 @@ list(APPEND SOURCE_FILES components/motor/MotorController.cpp components/settings/Settings.cpp components/timer/TimerController.cpp + components/fs/FS.cpp drivers/Cst816s.cpp FreeRTOS/port.c FreeRTOS/port_cmsis_systick.c @@ -543,6 +551,7 @@ list(APPEND RECOVERY_SOURCE_FILES components/heartrate/Biquad.cpp components/heartrate/Ptagc.cpp components/motor/MotorController.cpp + components/fs/FS.cpp ) list(APPEND RECOVERYLOADER_SOURCE_FILES @@ -801,13 +810,25 @@ target_compile_options(lvgl PRIVATE $<$: -MP -MD -x assembler-with-cpp> ) +# LITTLEFS_SRC +add_library(littlefs STATIC ${LITTLEFS_SRC}) +target_include_directories(littlefs SYSTEM PUBLIC . ../) +target_include_directories(littlefs SYSTEM PUBLIC ${INCLUDES_FROM_LIBS}) +target_compile_options(littlefs PRIVATE + $<$,$>: ${COMMON_FLAGS} -Wno-unused-function -Og -g3> + $<$,$>: ${COMMON_FLAGS} -Wno-unused-function -Os> + $<$,$>: ${COMMON_FLAGS} -Wno-unused-function -Og -g3 -fno-rtti> + $<$,$>: ${COMMON_FLAGS} -Wno-unused-function -Os -fno-rtti> + $<$: -MP -MD -x assembler-with-cpp> + ) + # Build autonomous binary (without support for bootloader) set(EXECUTABLE_NAME "pinetime-app") set(EXECUTABLE_FILE_NAME ${EXECUTABLE_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}) set(NRF5_LINKER_SCRIPT "${CMAKE_SOURCE_DIR}/gcc_nrf52.ld") add_executable(${EXECUTABLE_NAME} ${SOURCE_FILES}) set_target_properties(${EXECUTABLE_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_FILE_NAME}) -target_link_libraries(${EXECUTABLE_NAME} nimble nrf-sdk lvgl) +target_link_libraries(${EXECUTABLE_NAME} nimble nrf-sdk lvgl littlefs) target_compile_options(${EXECUTABLE_NAME} PUBLIC $<$,$>: ${COMMON_FLAGS} -Og -g3> $<$,$>: ${COMMON_FLAGS} -Os> @@ -836,7 +857,7 @@ set(IMAGE_MCUBOOT_FILE_NAME ${EXECUTABLE_MCUBOOT_NAME}-image-${pinetime_VERSION_ set(DFU_MCUBOOT_FILE_NAME ${EXECUTABLE_MCUBOOT_NAME}-dfu-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip) set(NRF5_LINKER_SCRIPT_MCUBOOT "${CMAKE_SOURCE_DIR}/gcc_nrf52-mcuboot.ld") add_executable(${EXECUTABLE_MCUBOOT_NAME} ${SOURCE_FILES}) -target_link_libraries(${EXECUTABLE_MCUBOOT_NAME} nimble nrf-sdk lvgl) +target_link_libraries(${EXECUTABLE_MCUBOOT_NAME} nimble nrf-sdk lvgl littlefs) set_target_properties(${EXECUTABLE_MCUBOOT_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_MCUBOOT_FILE_NAME}) target_compile_options(${EXECUTABLE_MCUBOOT_NAME} PUBLIC $<$,$>: ${COMMON_FLAGS} -Og -g3> @@ -872,7 +893,7 @@ endif() set(EXECUTABLE_RECOVERY_NAME "pinetime-recovery") set(EXECUTABLE_RECOVERY_FILE_NAME ${EXECUTABLE_RECOVERY_NAME}-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}) add_executable(${EXECUTABLE_RECOVERY_NAME} ${RECOVERY_SOURCE_FILES}) -target_link_libraries(${EXECUTABLE_RECOVERY_NAME} nimble nrf-sdk) +target_link_libraries(${EXECUTABLE_RECOVERY_NAME} nimble nrf-sdk littlefs) set_target_properties(${EXECUTABLE_RECOVERY_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_RECOVERY_FILE_NAME}) target_compile_definitions(${EXECUTABLE_RECOVERY_NAME} PUBLIC "PINETIME_IS_RECOVERY") target_compile_options(${EXECUTABLE_RECOVERY_NAME} PUBLIC @@ -902,7 +923,7 @@ set(EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-${ set(IMAGE_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-image-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.bin) set(DFU_RECOVERY_MCUBOOT_FILE_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_NAME}-dfu-${pinetime_VERSION_MAJOR}.${pinetime_VERSION_MINOR}.${pinetime_VERSION_PATCH}.zip) add_executable(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} ${RECOVERY_SOURCE_FILES}) -target_link_libraries(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} nimble nrf-sdk) +target_link_libraries(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} nimble nrf-sdk littlefs) set_target_properties(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PROPERTIES OUTPUT_NAME ${EXECUTABLE_RECOVERY_MCUBOOT_FILE_NAME}) target_compile_definitions(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PUBLIC "PINETIME_IS_RECOVERY") target_compile_options(${EXECUTABLE_RECOVERY_MCUBOOT_NAME} PUBLIC diff --git a/src/components/fs/FS.cpp b/src/components/fs/FS.cpp new file mode 100644 index 00000000..857e6bf9 --- /dev/null +++ b/src/components/fs/FS.cpp @@ -0,0 +1,197 @@ +#include "FS.h" +#include +#include +#include + +using namespace Pinetime::Controllers; + +FS::FS(Pinetime::Drivers::SpiNorFlash& driver) : + flashDriver{ driver }, + lfsConfig{ + .context = this, + .read = SectorRead, + .prog = SectorProg, + .erase = SectorErase, + .sync = SectorSync, + + .read_size = 16, + .prog_size = 8, + .block_size = blockSize, + .block_count = size / blockSize, + .block_cycles = 1000u, + + .cache_size = 16, + .lookahead_size = 16, + + .name_max = 50, + .attr_max = 50, + } +{ } + + +void FS::Init() { + + // try mount + int err = lfs_mount(&lfs, &lfsConfig); + + // reformat if we can't mount the filesystem + // this should only happen on the first boot + if (err != LFS_ERR_OK) { + lfs_format(&lfs, &lfsConfig); + err = lfs_mount(&lfs, &lfsConfig); + if (err != LFS_ERR_OK) { + return; + } + } + +#ifndef PINETIME_IS_RECOVERY + VerifyResource(); + LVGLFileSystemInit(); +#endif + +} + +void FS::VerifyResource() { + // validate the resource metadata + resourcesValid = true; +} + +int FS::FileOpen(lfs_file_t* file_p, const char* fileName, const int flags) { + return lfs_file_open(&lfs, file_p, fileName, flags); +} + +int FS::FileClose(lfs_file_t* file_p) { + return lfs_file_close(&lfs, file_p); +} + +int FS::FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size) { + return lfs_file_read(&lfs, file_p, buff, size); +} + +int FS::FileWrite(lfs_file_t* file_p, const uint8_t* buff, uint32_t size) { + return lfs_file_write(&lfs, file_p, buff, size); +} + +int FS::FileSeek(lfs_file_t* file_p, uint32_t pos) { + return lfs_file_seek(&lfs, file_p, pos, LFS_SEEK_SET); +} + +int FS::FileDelete(const char* fileName) { + return lfs_remove(&lfs, fileName); +} + + +int FS::DirCreate(const char* path) { + return lfs_mkdir(&lfs, path); +} + +// Delete directory and all files inside +int FS::DirDelete(const char* path) { + + lfs_dir_t lfs_dir; + lfs_info entryInfo; + + int err; + err = lfs_dir_open(&lfs, &lfs_dir, path); + if (err) { + return err; + } + while (lfs_dir_read(&lfs, &lfs_dir, &entryInfo)) { + lfs_remove(&lfs, entryInfo.name); + } + lfs_dir_close(&lfs, &lfs_dir); + return LFS_ERR_OK; +} + +/* + + ----------- Interface between littlefs and SpiNorFlash ----------- + +*/ +int FS::SectorSync(const struct lfs_config* c) { + return 0; +} + +int FS::SectorErase(const struct lfs_config* c, lfs_block_t block) { + Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); + const size_t address = startAddress + (block * blockSize); + lfs.flashDriver.SectorErase(address); + return lfs.flashDriver.EraseFailed() ? -1 : 0; +} + +int FS::SectorProg(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, const void* buffer, lfs_size_t size) { + Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); + const size_t address = startAddress + (block * blockSize) + off; + lfs.flashDriver.Write(address, (uint8_t*) buffer, size); + return lfs.flashDriver.ProgramFailed() ? -1 : 0; +} + +int FS::SectorRead(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, void* buffer, lfs_size_t size) { + Pinetime::Controllers::FS& lfs = *(static_cast(c->context)); + const size_t address = startAddress + (block * blockSize) + off; + lfs.flashDriver.Read(address, static_cast(buffer), size); + return 0; +} + +/* + + ----------- LVGL filesystem integration ----------- + +*/ + +namespace { + lv_fs_res_t lvglOpen(lv_fs_drv_t* drv, void* file_p, const char* path, lv_fs_mode_t mode) { + + lfs_file_t* file = static_cast(file_p); + FS* filesys = static_cast(drv->user_data); + filesys->FileOpen(file, path, LFS_O_RDONLY); + + if (file->type == 0) { + return LV_FS_RES_FS_ERR; + } + else { + return LV_FS_RES_OK; + } + } + + lv_fs_res_t lvglClose(lv_fs_drv_t* drv, void* file_p) { + FS* filesys = static_cast(drv->user_data); + lfs_file_t* file = static_cast(file_p); + filesys->FileClose(file); + + return LV_FS_RES_OK; + } + + lv_fs_res_t lvglRead(lv_fs_drv_t* drv, void* file_p, void* buf, uint32_t btr, uint32_t* br) { + FS* filesys = static_cast(drv->user_data); + lfs_file_t* file = static_cast(file_p); + filesys->FileRead(file, static_cast(buf), btr); + *br = btr; + return LV_FS_RES_OK; + } + + lv_fs_res_t lvglSeek(lv_fs_drv_t* drv, void* file_p, uint32_t pos) { + FS* filesys = static_cast(drv->user_data); + lfs_file_t* file = static_cast(file_p); + filesys->FileSeek(file, pos); + return LV_FS_RES_OK; + } +} + +void FS::LVGLFileSystemInit() { + + lv_fs_drv_t fs_drv; + lv_fs_drv_init(&fs_drv); + + fs_drv.file_size = sizeof(lfs_file_t); + fs_drv.letter = 'F'; + fs_drv.open_cb = lvglOpen; + fs_drv.close_cb = lvglClose; + fs_drv.read_cb = lvglRead; + fs_drv.seek_cb = lvglSeek; + + fs_drv.user_data = this; + + lv_fs_drv_register(&fs_drv); + +} \ No newline at end of file diff --git a/src/components/fs/FS.h b/src/components/fs/FS.h new file mode 100644 index 00000000..1f2eb7e0 --- /dev/null +++ b/src/components/fs/FS.h @@ -0,0 +1,71 @@ +#pragma once + +#include +#include "drivers/SpiNorFlash.h" +#include + +namespace Pinetime { + namespace Controllers { + class FS { + public: + FS(Pinetime::Drivers::SpiNorFlash&); + + void Init(); + void LVGLFileSystemInit(); + + int FileOpen(lfs_file_t* file_p, const char* fileName, const int flags); + int FileClose(lfs_file_t* file_p); + int FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size); + int FileWrite(lfs_file_t* file_p, const uint8_t* buff, uint32_t size); + int FileSeek(lfs_file_t* file_p, uint32_t pos); + + int FileDelete(const char* fileName); + + int DirCreate(const char* path); + int DirDelete(const char* path); + + void VerifyResource(); + + private: + + Pinetime::Drivers::SpiNorFlash& flashDriver; + + /* + * External Flash MAP (4 MBytes) + * + * 0x000000 +---------------------------------------+ + * | Bootloader Assets | + * | 256 KBytes | + * | | + * 0x040000 +---------------------------------------+ + * | OTA | + * | 464 KBytes | + * | | + * | | + * | | + * 0x0B4000 +---------------------------------------+ + * | File System | + * | | + * | | + * | | + * | | + * 0x400000 +---------------------------------------+ + * + */ + static constexpr size_t startAddress = 0x0B4000; + static constexpr size_t size = 0x3C0000; + static constexpr size_t blockSize = 4096; + + bool resourcesValid = false; + const struct lfs_config lfsConfig; + + lfs_t lfs; + + static int SectorSync(const struct lfs_config* c); + static int SectorErase(const struct lfs_config* c, lfs_block_t block); + static int SectorProg(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, const void* buffer, lfs_size_t size); + static int SectorRead(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, void* buffer, lfs_size_t size); + + }; + } +} diff --git a/src/components/settings/Settings.cpp b/src/components/settings/Settings.cpp index 071940b8..37c09f91 100644 --- a/src/components/settings/Settings.cpp +++ b/src/components/settings/Settings.cpp @@ -4,108 +4,44 @@ using namespace Pinetime::Controllers; -struct SettingsHeader { - uint8_t isActive; // 0xF1 = Block is active, 0xF0 = Block is inactive - uint16_t version; // Current version, to verify if the saved data is for the current Version -}; - -#define HEADER_SIZE sizeof(SettingsHeader) - -Settings::Settings(Pinetime::Drivers::SpiNorFlash& spiNorFlash) : spiNorFlash {spiNorFlash} { +Settings::Settings(Pinetime::Controllers::FS& fs) : fs {fs} { } void Settings::Init() { // Load default settings from Flash - LoadSettingsFromFlash(); + LoadSettingsFromFile(); } void Settings::SaveSettings() { // verify if is necessary to save if (settingsChanged) { - SaveSettingsToFlash(); + SaveSettingsToFile(); } settingsChanged = false; } -bool Settings::FindHeader() { - SettingsHeader settingsHeader; - uint8_t bufferHead[sizeof(settingsHeader)]; - - for (uint8_t block = 0; block < 10; block++) { +void Settings::LoadSettingsFromFile() { + SettingsData bufferSettings; + lfs_file_t settingsFile; - spiNorFlash.Read(settingsBaseAddr + (block * 0x1000), bufferHead, sizeof(settingsHeader)); - std::memcpy(&settingsHeader, bufferHead, sizeof(settingsHeader)); - if (settingsHeader.isActive == 0xF1 && settingsHeader.version == settingsVersion) { - settingsFlashBlock = block; - return true; - } + if ( fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT) != LFS_ERR_OK) { + return; } - return false; -} - -void Settings::ReadSettingsData() { - uint8_t bufferSettings[sizeof(settings)]; - spiNorFlash.Read(settingsBaseAddr + (settingsFlashBlock * 0x1000) + HEADER_SIZE, bufferSettings, sizeof(settings)); - std::memcpy(&settings, bufferSettings, sizeof(settings)); -} - -void Settings::EraseBlock() { - - spiNorFlash.SectorErase(settingsBaseAddr + (settingsFlashBlock * 0x1000)); -} - -void Settings::SetHeader(bool state) { - SettingsHeader settingsHeader; - uint8_t bufferHead[sizeof(settingsHeader)]; - settingsHeader.isActive = state ? 0xF1 : 0xF0; - settingsHeader.version = settingsVersion; - - std::memcpy(bufferHead, &settingsHeader, sizeof(settingsHeader)); - spiNorFlash.Write(settingsBaseAddr + (settingsFlashBlock * 0x1000), bufferHead, sizeof(settingsHeader)); -} - -void Settings::SaveSettingsData() { - uint8_t bufferSettings[sizeof(settings)]; - std::memcpy(bufferSettings, &settings, sizeof(settings)); - spiNorFlash.Write(settingsBaseAddr + (settingsFlashBlock * 0x1000) + HEADER_SIZE, bufferSettings, sizeof(settings)); -} - -void Settings::LoadSettingsFromFlash() { - - if (settingsFlashBlock == 99) { - // Find current Block, if can't find use default settings and set block to 0 ans save ! - if (FindHeader()) { - ReadSettingsData(); - } else { - SaveSettingsToFlash(); - } - } else { - // Read Settings from flash... - // never used :) - ReadSettingsData(); + fs.FileRead(&settingsFile, reinterpret_cast(&bufferSettings), sizeof(settings)); + fs.FileClose(&settingsFile); + if ( bufferSettings.version == settingsVersion ) { + settings = bufferSettings; } } -void Settings::SaveSettingsToFlash() { - - // calculate where to save... - // mark current to inactive - // erase the new location and save - // set settingsFlashBlock - - // if first time hever, only saves to block 0 and set settingsFlashBlock +void Settings::SaveSettingsToFile() { + lfs_file_t settingsFile; - if (settingsFlashBlock != 99) { - SetHeader(false); + if ( fs.FileOpen(&settingsFile, "/settings.dat", LFS_O_RDWR | LFS_O_CREAT) != LFS_ERR_OK) { + return; } - - settingsFlashBlock++; - if (settingsFlashBlock > 9) - settingsFlashBlock = 0; - - EraseBlock(); - SetHeader(true); - SaveSettingsData(); + fs.FileWrite(&settingsFile, reinterpret_cast(&settings), sizeof(settings)); + fs.FileClose(&settingsFile); } diff --git a/src/components/settings/Settings.h b/src/components/settings/Settings.h index 4409425b..577455eb 100644 --- a/src/components/settings/Settings.h +++ b/src/components/settings/Settings.h @@ -2,25 +2,26 @@ #include #include "components/datetime/DateTimeController.h" #include "components/brightness/BrightnessController.h" -#include "drivers/SpiNorFlash.h" +#include "components/fs/FS.h" #include "drivers/Cst816s.h" namespace Pinetime { namespace Controllers { class Settings { public: - enum class ClockType { H24, H12 }; - enum class Vibration { ON, OFF }; - enum class WakeUpMode { None, SingleTap, DoubleTap, RaiseWrist }; + enum class ClockType : uint8_t { H24, H12 }; + enum class Vibration : uint8_t { ON, OFF }; + enum class WakeUpMode : uint8_t { None, SingleTap, DoubleTap, RaiseWrist }; - Settings(Pinetime::Drivers::SpiNorFlash& spiNorFlash); + Settings(Pinetime::Controllers::FS& fs); void Init(); void SaveSettings(); void SetClockFace(uint8_t face) { - if (face != settings.clockFace) + if (face != settings.clockFace) { settingsChanged = true; + } settings.clockFace = face; }; uint8_t GetClockFace() const { @@ -42,8 +43,9 @@ namespace Pinetime { }; void SetClockType(ClockType clocktype) { - if (clocktype != settings.clockType) + if (clocktype != settings.clockType) { settingsChanged = true; + } settings.clockType = clocktype; }; ClockType GetClockType() const { @@ -51,8 +53,9 @@ namespace Pinetime { }; void SetVibrationStatus(Vibration status) { - if (status != settings.vibrationStatus) + if (status != settings.vibrationStatus) { settingsChanged = true; + } settings.vibrationStatus = status; }; Vibration GetVibrationStatus() const { @@ -60,8 +63,9 @@ namespace Pinetime { }; void SetScreenTimeOut(uint32_t timeout) { - if (timeout != settings.screenTimeOut) + if (timeout != settings.screenTimeOut) { settingsChanged = true; + } settings.screenTimeOut = timeout; }; uint32_t GetScreenTimeOut() const { @@ -69,8 +73,9 @@ namespace Pinetime { }; void setWakeUpMode(WakeUpMode wakeUp) { - if (wakeUp != settings.wakeUpMode) + if (wakeUp != settings.wakeUpMode) { settingsChanged = true; + } settings.wakeUpMode = wakeUp; }; WakeUpMode getWakeUpMode() const { @@ -78,8 +83,9 @@ namespace Pinetime { }; void SetBrightness(Controllers::BrightnessController::Levels level) { - if (level != settings.brightLevel) + if (level != settings.brightLevel) { settingsChanged = true; + } settings.brightLevel = level; }; Controllers::BrightnessController::Levels GetBrightness() const { @@ -87,25 +93,29 @@ namespace Pinetime { }; void SetStepsGoal( uint32_t goal ) { - if ( goal != settings.stepsGoal ) + if ( goal != settings.stepsGoal ) { settingsChanged = true; + } settings.stepsGoal = goal; }; uint32_t GetStepsGoal() const { return settings.stepsGoal; }; private: - Pinetime::Drivers::SpiNorFlash& spiNorFlash; + Pinetime::Controllers::FS& fs; + + static constexpr uint32_t settingsVersion = 0x0001; struct SettingsData { + uint32_t version = settingsVersion; + uint32_t stepsGoal = 10000; + uint32_t screenTimeOut = 15000; + ClockType clockType = ClockType::H24; Vibration vibrationStatus = Vibration::ON; uint8_t clockFace = 0; - uint32_t stepsGoal = 10000; - uint32_t screenTimeOut = 15000; - WakeUpMode wakeUpMode = WakeUpMode::None; Controllers::BrightnessController::Levels brightLevel = Controllers::BrightnessController::Levels::Medium; @@ -117,20 +127,8 @@ namespace Pinetime { uint8_t appMenu = 0; uint8_t settingsMenu = 0; - // There are 10 blocks of reserved flash to save settings - // to minimize wear, the recording is done in a rotating way by the 10 blocks - uint8_t settingsFlashBlock = 99; // default to indicate it needs to find the active block - - static constexpr uint32_t settingsBaseAddr = 0x3F6000; // Flash Settings Location - static constexpr uint16_t settingsVersion = 0x0100; // Flash Settings Version - - bool FindHeader(); - void ReadSettingsData(); - void EraseBlock(); - void SetHeader(bool state); - void SaveSettingsData(); - void LoadSettingsFromFlash(); - void SaveSettingsToFlash(); + void LoadSettingsFromFile(); + void SaveSettingsToFile(); }; } } \ No newline at end of file diff --git a/src/libs/littlefs b/src/libs/littlefs new file mode 160000 index 00000000..ead50807 --- /dev/null +++ b/src/libs/littlefs @@ -0,0 +1 @@ +Subproject commit ead50807f1ca3fdf2da00b77a0ce02651ded2d13 diff --git a/src/libs/lv_conf.h b/src/libs/lv_conf.h index a03a4833..e85eeb1f 100644 --- a/src/libs/lv_conf.h +++ b/src/libs/lv_conf.h @@ -204,7 +204,7 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h" */ /* 1: Enable file system (might be required for images */ // TODO: Enable FS -#define LV_USE_FILESYSTEM 0 +#define LV_USE_FILESYSTEM 1 #if LV_USE_FILESYSTEM /*Declare the type of the user data of file system drivers (can be e.g. `void *`, `int`, `struct`)*/ typedef void * lv_fs_drv_user_data_t; @@ -236,7 +236,7 @@ typedef void * lv_fs_drv_user_data_t; * With complex image decoders (e.g. PNG or JPG) caching can save the continuous open/decode of images. * However the opened images might consume additional RAM. * LV_IMG_CACHE_DEF_SIZE must be >= 1 */ -#define LV_IMG_CACHE_DEF_SIZE 1 +#define LV_IMG_CACHE_DEF_SIZE 6 /*Declare the type of the user data of image decoder (can be e.g. `void *`, `int`, `struct`)*/ typedef void* lv_img_decoder_user_data_t; diff --git a/src/main.cpp b/src/main.cpp index 5832a78f..1b7015aa 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -35,6 +35,7 @@ #include "components/motor/MotorController.h" #include "components/datetime/DateTimeController.h" #include "components/heartrate/HeartRateController.h" +#include "components/fs/FS.h" #include "drivers/Spi.h" #include "drivers/SpiMaster.h" #include "drivers/SpiNorFlash.h" @@ -108,10 +109,6 @@ void ble_manager_set_ble_disconnection_callback(void (*disconnection)()); static constexpr uint8_t pinTouchIrq = 28; static constexpr uint8_t pinPowerPresentIrq = 19; -Pinetime::Controllers::Settings settingsController {spiNorFlash}; - -Pinetime::Controllers::MotorController motorController {settingsController}; - Pinetime::Controllers::HeartRateController heartRateController; Pinetime::Applications::HeartRateTask heartRateApp(heartRateSensor, heartRateController); @@ -122,6 +119,11 @@ Pinetime::Controllers::NotificationManager notificationManager; Pinetime::Controllers::MotionController motionController; Pinetime::Controllers::TimerController timerController; +Pinetime::Controllers::FS fs {spiNorFlash}; +Pinetime::Controllers::Settings settingsController {fs}; +Pinetime::Controllers::MotorController motorController {settingsController}; + + Pinetime::Applications::DisplayApp displayApp(lcd, lvgl, touchPanel, @@ -155,7 +157,8 @@ Pinetime::System::SystemTask systemTask(spi, settingsController, heartRateController, displayApp, - heartRateApp); + heartRateApp, + fs); void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { if (pin == pinTouchIrq) { 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