From 63e0c4f4efb047f4f15601f7b08640c4b589de93 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jean-Fran=C3=A7ois=20Milants?= Date: Mon, 23 Oct 2023 20:12:34 +0200 Subject: [PATCH] Application selection at build time A list of "user applications" is built at compile time. It contains all the info needed to create the application at runtime (ptr to a create() function) and to display the app in the application menu. All applications declare a TypeTrait with these information. When a new app must be loaded, DisplayApp first check if this app is a System app (in which case it creates it like it did before). If it's not a System app, it looks for the app in the list of User applications and creates it if it found it. Those changes allow to more easily add new app and to select which app must be built into the firmware. Switch to C++20 (and fix a few issues in SpiMaster.cpp and Watchdog.cpp. --- CMakeLists.txt | 2 +- src/CMakeLists.txt | 1 - src/displayapp/Apps.h | 29 +++++- src/displayapp/Controllers.h | 51 +++++++++++ src/displayapp/DisplayApp.cpp | 102 +++++++++++---------- src/displayapp/DisplayApp.h | 5 + src/displayapp/UserApps.h | 36 ++++++++ src/displayapp/screens/Alarm.cpp | 4 + src/displayapp/screens/Alarm.h | 26 ++++-- src/displayapp/screens/ApplicationList.cpp | 24 +++-- src/displayapp/screens/ApplicationList.h | 38 ++------ src/displayapp/screens/Clock.h | 11 ++- src/displayapp/screens/HeartRate.h | 9 ++ src/displayapp/screens/InfiniPaint.h | 11 +++ src/displayapp/screens/Metronome.h | 9 ++ src/displayapp/screens/Motion.h | 10 ++ src/displayapp/screens/Music.h | 11 +++ src/displayapp/screens/Navigation.h | 11 +++ src/displayapp/screens/Paddle.h | 11 +++ src/displayapp/screens/Steps.h | 11 +++ src/displayapp/screens/StopWatch.h | 89 ++++++++++-------- src/displayapp/screens/Tile.cpp | 1 - src/displayapp/screens/Timer.cpp | 2 +- src/displayapp/screens/Timer.h | 64 +++++++------ src/displayapp/screens/Twos.h | 9 +- src/displayapp/screens/Weather.h | 13 ++- src/drivers/SpiMaster.cpp | 12 +-- src/drivers/Watchdog.cpp | 2 +- src/systemtask/SystemTask.cpp | 3 + 29 files changed, 431 insertions(+), 176 deletions(-) create mode 100644 src/displayapp/Controllers.h create mode 100644 src/displayapp/UserApps.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 83c6e98d..41989489 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose Debug or Release") project(pinetime VERSION 1.13.0 LANGUAGES C CXX ASM) set(CMAKE_C_STANDARD 99) -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 20) # set(CMAKE_GENERATOR "Unix Makefiles") set(CMAKE_C_EXTENSIONS OFF) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8e8e9686..dc718bab 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -394,7 +394,6 @@ list(APPEND SOURCE_FILES displayapp/screens/Notifications.cpp displayapp/screens/Twos.cpp displayapp/screens/HeartRate.cpp - displayapp/screens/Motion.cpp displayapp/screens/FlashLight.cpp displayapp/screens/List.cpp displayapp/screens/CheckboxList.cpp diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h index f253bc03..d96e6ea7 100644 --- a/src/displayapp/Apps.h +++ b/src/displayapp/Apps.h @@ -1,5 +1,5 @@ #pragma once - +#include namespace Pinetime { namespace Applications { enum class Apps { @@ -37,7 +37,32 @@ namespace Pinetime { SettingChimes, SettingShakeThreshold, SettingBluetooth, - Error + Error, + Weather }; + template + struct AppTraits {}; + + template + struct TypeList { + static constexpr size_t Count = sizeof...(As); + }; + + using UserAppTypes = TypeList; } } diff --git a/src/displayapp/Controllers.h b/src/displayapp/Controllers.h new file mode 100644 index 00000000..cef98986 --- /dev/null +++ b/src/displayapp/Controllers.h @@ -0,0 +1,51 @@ +#pragma once +namespace Pinetime { + namespace Applications { + class DisplayApp; + } + namespace Components { + class LittleVgl; + } + namespace Controllers { + class Battery; + class Ble; + class DateTime; + class NotificationManager; + class HeartRateController; + class Settings; + class MotorController; + class MotionController; + class AlarmController; + class BrightnessController; + class WeatherService; + class FS; + class Timer; + class MusicService; + class NavigationService; + } + namespace System { + class SystemTask; + } + namespace Applications { + struct AppControllers { + const Pinetime::Controllers::Battery& batteryController; + const Pinetime::Controllers::Ble& bleController; + Pinetime::Controllers::DateTime& dateTimeController; + Pinetime::Controllers::NotificationManager& notificationManager; + Pinetime::Controllers::HeartRateController& heartRateController; + Pinetime::Controllers::Settings& settingsController; + Pinetime::Controllers::MotorController& motorController; + Pinetime::Controllers::MotionController& motionController; + Pinetime::Controllers::AlarmController& alarmController; + Pinetime::Controllers::BrightnessController& brightnessController; + Pinetime::Controllers::WeatherService* weatherController; + Pinetime::Controllers::FS& filesystem; + Pinetime::Controllers::Timer& timer; + Pinetime::System::SystemTask* systemTask; + Pinetime::Applications::DisplayApp* displayApp; + Pinetime::Components::LittleVgl& lvgl; + Pinetime::Controllers::MusicService* musicService; + Pinetime::Controllers::NavigationService* navigationService; + }; + } +} \ No newline at end of file diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 682ea12c..a195361d 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -50,6 +50,7 @@ #include "displayapp/screens/settings/SettingBluetooth.h" #include "libs/lv_conf.h" +#include "UserApps.h" using namespace Pinetime::Applications; using namespace Pinetime::Applications::Display; @@ -96,7 +97,12 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd, touchHandler {touchHandler}, filesystem {filesystem}, lvgl {lcd, filesystem}, - timer(this, TimerCallback) { + timer(this, TimerCallback), + controllers{ + batteryController, bleController, dateTimeController, notificationManager, heartRateController, + settingsController, motorController, motionController, alarmController, brightnessController, + nullptr, filesystem, timer, nullptr, this, lvgl, nullptr, nullptr} + { } void DisplayApp::Start(System::BootErrors error) { @@ -402,14 +408,21 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio SetFullRefresh(direction); switch (app) { - case Apps::Launcher: - currentScreen = - std::make_unique(this, settingsController, batteryController, bleController, dateTimeController, filesystem); - break; - case Apps::Motion: - // currentScreen = std::make_unique(motionController); - // break; - case Apps::None: + case Apps::Launcher: { + std::array apps; + int i = 0; + for (const auto& userApp : userApps) { + apps[i++] = Screens::Tile::Applications {userApp.icon, userApp.app, true}; + } + currentScreen = std::make_unique(this, + settingsController, + batteryController, + bleController, + dateTimeController, + filesystem, + std::move(apps)); + } + break; case Apps::Clock: currentScreen = std::make_unique(dateTimeController, batteryController, @@ -421,7 +434,6 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio systemTask->nimble().weather(), filesystem); break; - case Apps::Error: currentScreen = std::make_unique(bootError); break; @@ -453,14 +465,6 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio *systemTask, Screens::Notifications::Modes::Preview); break; - case Apps::Timer: - currentScreen = std::make_unique(timer); - break; - case Apps::Alarm: - currentScreen = std::make_unique(alarmController, settingsController.GetClockType(), *systemTask, motorController); - break; - - // Settings case Apps::QuickSettings: currentScreen = std::make_unique(this, batteryController, @@ -516,38 +520,25 @@ void DisplayApp::LoadScreen(Apps app, DisplayApp::FullRefreshDirections directio case Apps::FlashLight: currentScreen = std::make_unique(*systemTask, brightnessController); break; - case Apps::StopWatch: - currentScreen = std::make_unique(*systemTask); - break; - case Apps::Twos: - currentScreen = std::make_unique(); - break; - case Apps::Paint: - currentScreen = std::make_unique(lvgl, motorController); - break; - case Apps::Paddle: - currentScreen = std::make_unique(lvgl); - break; - case Apps::Music: - currentScreen = std::make_unique(systemTask->nimble().music()); - break; - case Apps::Navigation: - currentScreen = std::make_unique(systemTask->nimble().navigation()); - break; - case Apps::HeartRate: - currentScreen = std::make_unique(heartRateController, *systemTask); - break; - case Apps::Metronome: - currentScreen = std::make_unique(motorController, *systemTask); - break; - /* Weather debug app - case Apps::Weather: - currentScreen = std::make_unique(this, systemTask->nimble().weather()); - break; - */ - case Apps::Steps: - currentScreen = std::make_unique(motionController, settingsController); + default: { + const auto* d = std::find_if(userApps.begin(), userApps.end(), [app](const AppDescription& appDescription) { + return appDescription.app == app; + }); + if (d != userApps.end()) + currentScreen.reset(d->create(controllers)); + else { + currentScreen = std::make_unique(dateTimeController, + batteryController, + bleController, + notificationManager, + settingsController, + heartRateController, + motionController, + systemTask->nimble().weather(), + filesystem); + } break; + } } currentApp = app; } @@ -605,6 +596,19 @@ void DisplayApp::PushMessageToSystemTask(Pinetime::System::Messages message) { void DisplayApp::Register(Pinetime::System::SystemTask* systemTask) { this->systemTask = systemTask; + this->controllers.systemTask = systemTask; +} + +void DisplayApp::Register(Pinetime::Controllers::WeatherService* weatherService) { + this->controllers.weatherController = weatherService; +} + +void DisplayApp::Register(Pinetime::Controllers::MusicService* musicService) { + this->controllers.musicService = musicService; +} + +void DisplayApp::Register(Pinetime::Controllers::NavigationService* NavigationService) { + this->controllers.navigationService = NavigationService; } void DisplayApp::ApplyBrightness() { diff --git a/src/displayapp/DisplayApp.h b/src/displayapp/DisplayApp.h index f537651d..7dbac850 100644 --- a/src/displayapp/DisplayApp.h +++ b/src/displayapp/DisplayApp.h @@ -20,6 +20,7 @@ #include "BootErrors.h" #include "utility/StaticStack.h" +#include "displayapp/Controllers.h" namespace Pinetime { @@ -73,6 +74,9 @@ namespace Pinetime { void SetFullRefresh(FullRefreshDirections direction); void Register(Pinetime::System::SystemTask* systemTask); + void Register(Pinetime::Controllers::WeatherService* weatherService); + void Register(Pinetime::Controllers::MusicService* musicService); + void Register(Pinetime::Controllers::NavigationService* NavigationService); private: Pinetime::Drivers::St7789& lcd; @@ -96,6 +100,7 @@ namespace Pinetime { Pinetime::Components::LittleVgl lvgl; Pinetime::Controllers::Timer timer; + AppControllers controllers; TaskHandle_t taskHandle; States state = States::Running; diff --git a/src/displayapp/UserApps.h b/src/displayapp/UserApps.h new file mode 100644 index 00000000..d0165cf9 --- /dev/null +++ b/src/displayapp/UserApps.h @@ -0,0 +1,36 @@ +#pragma once +#include "Apps.h" +#include "Controllers.h" + +#include "displayapp/screens/Alarm.h" +#include "displayapp/screens/Timer.h" +#include "displayapp/screens/Twos.h" +#include "displayapp/screens/Tile.h" +#include "displayapp/screens/ApplicationList.h" +#include "displayapp/screens/Clock.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + class Screen; + } + + struct AppDescription { + Apps app; + const char* icon; + Screens::Screen* (*create)(AppControllers& controllers); + }; + + template + consteval AppDescription CreateAppDescription() { + return {AppTraits::app, AppTraits::icon, &AppTraits::Create}; + } + + template typename T, Apps ...ts> + consteval std::array CreateAppDescriptions(T) { + return {CreateAppDescription()...}; + } + + constexpr auto userApps = CreateAppDescriptions(UserAppTypes {}); + } +} diff --git a/src/displayapp/screens/Alarm.cpp b/src/displayapp/screens/Alarm.cpp index 4e6ce797..cbc702f3 100644 --- a/src/displayapp/screens/Alarm.cpp +++ b/src/displayapp/screens/Alarm.cpp @@ -19,6 +19,10 @@ #include "displayapp/screens/Screen.h" #include "displayapp/screens/Symbols.h" #include "displayapp/InfiniTimeTheme.h" +#include "components/settings/Settings.h" +#include "components/alarm/AlarmController.h" +#include "components/motor/MotorController.h" +#include "systemtask/SystemTask.h" using namespace Pinetime::Applications::Screens; using Pinetime::Controllers::AlarmController; diff --git a/src/displayapp/screens/Alarm.h b/src/displayapp/screens/Alarm.h index 91177366..efa38eb7 100644 --- a/src/displayapp/screens/Alarm.h +++ b/src/displayapp/screens/Alarm.h @@ -17,21 +17,22 @@ */ #pragma once +#include "displayapp/Apps.h" +#include "components/settings/Settings.h" #include "displayapp/screens/Screen.h" -#include "systemtask/SystemTask.h" -#include "displayapp/LittleVgl.h" -#include "components/alarm/AlarmController.h" #include "displayapp/widgets/Counter.h" +#include "displayapp/Controllers.h" +#include "Symbols.h" namespace Pinetime { namespace Applications { namespace Screens { class Alarm : public Screen { public: - Alarm(Controllers::AlarmController& alarmController, - Controllers::Settings::ClockType clockType, - System::SystemTask& systemTask, - Controllers::MotorController& motorController); + explicit Alarm(Controllers::AlarmController& alarmController, + Controllers::Settings::ClockType clockType, + System::SystemTask& systemTask, + Controllers::MotorController& motorController); ~Alarm() override; void SetAlerting(); void OnButtonEvent(lv_obj_t* obj, lv_event_t event); @@ -63,6 +64,15 @@ namespace Pinetime { Widgets::Counter hourCounter = Widgets::Counter(0, 23, jetbrains_mono_76); Widgets::Counter minuteCounter = Widgets::Counter(0, 59, jetbrains_mono_76); }; + } + template<> + struct AppTraits { + static constexpr Apps app = Apps::Alarm; + static constexpr const char* icon = Screens::Symbols::clock; + static Screens::Screen *Create(AppControllers& controllers) { return new Screens::Alarm(controllers.alarmController, + controllers.settingsController.GetClockType(), + *controllers.systemTask, + controllers.motorController); }; }; - }; + } } diff --git a/src/displayapp/screens/ApplicationList.cpp b/src/displayapp/screens/ApplicationList.cpp index 6014cf53..e5e26098 100644 --- a/src/displayapp/screens/ApplicationList.cpp +++ b/src/displayapp/screens/ApplicationList.cpp @@ -1,8 +1,9 @@ #include "displayapp/screens/ApplicationList.h" +#include "displayapp/screens/Tile.h" #include #include -#include "displayapp/Apps.h" -#include "displayapp/DisplayApp.h" +#include +#include "components/settings/Settings.h" using namespace Pinetime::Applications::Screens; @@ -16,18 +17,20 @@ auto ApplicationList::CreateScreenList() const { return screens; } -ApplicationList::ApplicationList(Pinetime::Applications::DisplayApp* app, +ApplicationList::ApplicationList(DisplayApp* app, Pinetime::Controllers::Settings& settingsController, const Pinetime::Controllers::Battery& batteryController, const Pinetime::Controllers::Ble& bleController, Controllers::DateTime& dateTimeController, - Pinetime::Controllers::FS& filesystem) + Pinetime::Controllers::FS& filesystem, + std::array&& apps) : app {app}, settingsController {settingsController}, batteryController {batteryController}, bleController {bleController}, dateTimeController {dateTimeController}, filesystem{filesystem}, + apps{std::move(apps)}, screens {app, settingsController.GetAppMenu(), CreateScreenList(), Screens::ScreenListModes::UpDown} { } @@ -40,9 +43,14 @@ bool ApplicationList::OnTouchEvent(Pinetime::Applications::TouchEvents event) { } std::unique_ptr ApplicationList::CreateScreen(unsigned int screenNum) const { - std::array apps; - for (int i = 0; i < appsPerScreen; i++) { - apps[i] = applications[screenNum * appsPerScreen + i]; + std::array pageApps; + + for(int i = 0; i < appsPerScreen; i++) { + if(i+(screenNum * appsPerScreen) >= apps.size()) { + pageApps[i] = {"", Pinetime::Applications::Apps::None, false}; + } else { + pageApps[i] = apps[i + (screenNum * appsPerScreen)]; + } } return std::make_unique(screenNum, @@ -52,5 +60,5 @@ std::unique_ptr ApplicationList::CreateScreen(unsigned int screenNum) co batteryController, bleController, dateTimeController, - apps); + pageApps); } diff --git a/src/displayapp/screens/ApplicationList.h b/src/displayapp/screens/ApplicationList.h index 371ee710..2ad9c7c7 100644 --- a/src/displayapp/screens/ApplicationList.h +++ b/src/displayapp/screens/ApplicationList.h @@ -2,15 +2,12 @@ #include #include - -#include "displayapp/screens/Screen.h" -#include "displayapp/screens/ScreenList.h" -#include "components/datetime/DateTimeController.h" -#include "components/settings/Settings.h" -#include "components/battery/BatteryController.h" -#include "displayapp/screens/Symbols.h" -#include "displayapp/screens/Tile.h" -#include "displayapp/screens/Navigation.h" +#include "displayapp/Apps.h" +#include "Screen.h" +#include "ScreenList.h" +#include "displayapp/Controllers.h" +#include "Symbols.h" +#include "Tile.h" namespace Pinetime { namespace Applications { @@ -22,7 +19,8 @@ namespace Pinetime { const Pinetime::Controllers::Battery& batteryController, const Pinetime::Controllers::Ble& bleController, Controllers::DateTime& dateTimeController, - Pinetime::Controllers::FS& filesystem); + Pinetime::Controllers::FS& filesystem, + std::array&& apps); ~ApplicationList() override; bool OnTouchEvent(TouchEvents event) override; @@ -36,29 +34,13 @@ namespace Pinetime { const Pinetime::Controllers::Ble& bleController; Controllers::DateTime& dateTimeController; Pinetime::Controllers::FS& filesystem; + std::array apps; static constexpr int appsPerScreen = 6; // Increment this when more space is needed - static constexpr int nScreens = 2; + static constexpr int nScreens = (UserAppTypes::Count/appsPerScreen)+1; - std::array applications {{ - {Symbols::stopWatch, Apps::StopWatch, true}, - {Symbols::clock, Apps::Alarm, true}, - {Symbols::hourGlass, Apps::Timer, true}, - {Symbols::shoe, Apps::Steps, true}, - {Symbols::heartBeat, Apps::HeartRate, true}, - {Symbols::music, Apps::Music, true}, - - {Symbols::paintbrush, Apps::Paint, true}, - {Symbols::paddle, Apps::Paddle, true}, - {"2", Apps::Twos, true}, - {Symbols::drum, Apps::Metronome, true}, - {Symbols::map, Apps::Navigation, Applications::Screens::Navigation::IsAvailable(filesystem)}, - {Symbols::none, Apps::None, false}, - - // {"M", Apps::Motion}, - }}; ScreenList screens; }; } diff --git a/src/displayapp/screens/Clock.h b/src/displayapp/screens/Clock.h index f3591f43..e67c0260 100644 --- a/src/displayapp/screens/Clock.h +++ b/src/displayapp/screens/Clock.h @@ -1,13 +1,12 @@ #pragma once -#include #include #include #include -#include +#include "displayapp/Controllers.h" #include "displayapp/screens/Screen.h" -#include "components/datetime/DateTimeController.h" -#include "components/ble/weather/WeatherService.h" +#include "displayapp/Apps.h" +#include "Symbols.h" namespace Pinetime { namespace Controllers { @@ -16,6 +15,10 @@ namespace Pinetime { class Ble; class NotificationManager; class MotionController; + class DateTime; + class HeartRateController; + class WeatherService; + class FS; } namespace Applications { diff --git a/src/displayapp/screens/HeartRate.h b/src/displayapp/screens/HeartRate.h index 78ae63db..85da8dee 100644 --- a/src/displayapp/screens/HeartRate.h +++ b/src/displayapp/screens/HeartRate.h @@ -4,6 +4,7 @@ #include #include "displayapp/screens/Screen.h" #include "systemtask/SystemTask.h" +#include "Symbols.h" #include #include @@ -37,5 +38,13 @@ namespace Pinetime { lv_task_t* taskRefresh; }; } + template <> + struct AppTraits { + static constexpr Apps app = Apps::HeartRate; + static constexpr const char* icon = Screens::Symbols::heartBeat; + static Screens::Screen* Create(AppControllers& controllers) { + return new Screens::HeartRate(controllers.heartRateController, *controllers.systemTask); + }; + }; } } diff --git a/src/displayapp/screens/InfiniPaint.h b/src/displayapp/screens/InfiniPaint.h index ec184c44..a25ace55 100644 --- a/src/displayapp/screens/InfiniPaint.h +++ b/src/displayapp/screens/InfiniPaint.h @@ -5,6 +5,9 @@ #include // std::fill #include "displayapp/screens/Screen.h" #include "components/motor/MotorController.h" +#include "Symbols.h" +#include +#include namespace Pinetime { namespace Components { @@ -35,5 +38,13 @@ namespace Pinetime { uint8_t color = 2; }; } + template <> + struct AppTraits { + static constexpr Apps app = Apps::Paint; + static constexpr const char* icon = Screens::Symbols::paintbrush; + static Screens::Screen* Create(AppControllers& controllers) { + return new Screens::InfiniPaint(controllers.lvgl, controllers.motorController); + }; + }; } } diff --git a/src/displayapp/screens/Metronome.h b/src/displayapp/screens/Metronome.h index 13b0d664..8820962d 100644 --- a/src/displayapp/screens/Metronome.h +++ b/src/displayapp/screens/Metronome.h @@ -3,6 +3,7 @@ #include "systemtask/SystemTask.h" #include "components/motor/MotorController.h" #include "displayapp/screens/Screen.h" +#include "Symbols.h" namespace Pinetime { namespace Applications { @@ -36,5 +37,13 @@ namespace Pinetime { lv_task_t* taskRefresh; }; } + template <> + struct AppTraits { + static constexpr Apps app = Apps::Metronome; + static constexpr const char* icon = Screens::Symbols::drum; + static Screens::Screen* Create(AppControllers& controllers) { + return new Screens::Metronome(controllers.motorController, *controllers.systemTask); + }; + }; } } diff --git a/src/displayapp/screens/Motion.h b/src/displayapp/screens/Motion.h index e4cbe483..3ef570d6 100644 --- a/src/displayapp/screens/Motion.h +++ b/src/displayapp/screens/Motion.h @@ -6,6 +6,8 @@ #include #include #include +#include "displayapp/Controllers.h" +#include "displayapp/Apps.h" namespace Pinetime { namespace Applications { @@ -30,5 +32,13 @@ namespace Pinetime { lv_task_t* taskRefresh; }; } + template <> + struct AppTraits { + static constexpr Apps app = Apps::Motion; + static constexpr const char* icon = "M"; + static Screens::Screen* Create(AppControllers& controllers) { + return new Screens::Motion(controllers.motionController); + }; + }; } } diff --git a/src/displayapp/screens/Music.h b/src/displayapp/screens/Music.h index 847c6e74..acbb6312 100644 --- a/src/displayapp/screens/Music.h +++ b/src/displayapp/screens/Music.h @@ -21,6 +21,9 @@ #include #include #include "displayapp/screens/Screen.h" +#include "displayapp/Apps.h" +#include "displayapp/Controllers.h" +#include "Symbols.h" namespace Pinetime { namespace Controllers { @@ -82,5 +85,13 @@ namespace Pinetime { /** Watchapp */ }; } + template <> + struct AppTraits { + static constexpr Apps app = Apps::Music; + static constexpr const char* icon = Screens::Symbols::music; + static Screens::Screen* Create(AppControllers& controllers) { + return new Screens::Music(*controllers.musicService); + }; + }; } } diff --git a/src/displayapp/screens/Navigation.h b/src/displayapp/screens/Navigation.h index eb243b01..d54df13c 100644 --- a/src/displayapp/screens/Navigation.h +++ b/src/displayapp/screens/Navigation.h @@ -22,6 +22,9 @@ #include #include "displayapp/screens/Screen.h" #include +#include "displayapp/Apps.h" +#include "displayapp/Controllers.h" +#include "Symbols.h" namespace Pinetime { namespace Controllers { @@ -55,5 +58,13 @@ namespace Pinetime { lv_task_t* taskRefresh; }; } + template <> + struct AppTraits { + static constexpr Apps app = Apps::Navigation; + static constexpr const char* icon = Screens::Symbols::map; + static Screens::Screen* Create(AppControllers& controllers) { + return new Screens::Navigation(*controllers.navigationService); + }; + }; } } diff --git a/src/displayapp/screens/Paddle.h b/src/displayapp/screens/Paddle.h index 33dac191..0670e5b1 100644 --- a/src/displayapp/screens/Paddle.h +++ b/src/displayapp/screens/Paddle.h @@ -3,6 +3,9 @@ #include #include #include "displayapp/screens/Screen.h" +#include "displayapp/Apps.h" +#include "displayapp/Controllers.h" +#include "Symbols.h" namespace Pinetime { namespace Components { @@ -45,5 +48,13 @@ namespace Pinetime { lv_task_t* taskRefresh; }; } + template <> + struct AppTraits { + static constexpr Apps app = Apps::Paddle; + static constexpr const char* icon = Screens::Symbols::paddle; + static Screens::Screen* Create(AppControllers& controllers) { + return new Screens::Paddle(controllers.lvgl); + }; + }; } } diff --git a/src/displayapp/screens/Steps.h b/src/displayapp/screens/Steps.h index 5dc07eff..5299d67f 100644 --- a/src/displayapp/screens/Steps.h +++ b/src/displayapp/screens/Steps.h @@ -4,6 +4,9 @@ #include #include "displayapp/screens/Screen.h" #include +#include "displayapp/Apps.h" +#include "displayapp/Controllers.h" +#include "Symbols.h" namespace Pinetime { @@ -39,5 +42,13 @@ namespace Pinetime { lv_task_t* taskRefresh; }; } + template <> + struct AppTraits { + static constexpr Apps app = Apps::Steps; + static constexpr const char* icon = Screens::Symbols::shoe; + static Screens::Screen* Create(AppControllers& controllers) { + return new Screens::Steps(controllers.motionController, controllers.settingsController); + }; + }; } } diff --git a/src/displayapp/screens/StopWatch.h b/src/displayapp/screens/StopWatch.h index d1acd162..c3550fc4 100644 --- a/src/displayapp/screens/StopWatch.h +++ b/src/displayapp/screens/StopWatch.h @@ -7,50 +7,65 @@ #include "portmacro_cmsis.h" #include "systemtask/SystemTask.h" +#include "displayapp/Apps.h" +#include "displayapp/Controllers.h" +#include "Symbols.h" -namespace Pinetime::Applications::Screens { +namespace Pinetime { + namespace Applications { + namespace Screens { - enum class States { Init, Running, Halted }; + enum class States { Init, Running, Halted }; - struct TimeSeparated_t { - int hours; - int mins; - int secs; - int hundredths; - }; + struct TimeSeparated_t { + int hours; + int mins; + int secs; + int hundredths; + }; - class StopWatch : public Screen { - public: - explicit StopWatch(System::SystemTask& systemTask); - ~StopWatch() override; - void Refresh() override; + class StopWatch : public Screen { + public: + explicit StopWatch(System::SystemTask& systemTask); + ~StopWatch() override; + void Refresh() override; - void playPauseBtnEventHandler(); - void stopLapBtnEventHandler(); - bool OnButtonPushed() override; + void playPauseBtnEventHandler(); + void stopLapBtnEventHandler(); + bool OnButtonPushed() override; - private: - void SetInterfacePaused(); - void SetInterfaceRunning(); - void SetInterfaceStopped(); + private: + void SetInterfacePaused(); + void SetInterfaceRunning(); + void SetInterfaceStopped(); - void Reset(); - void Start(); - void Pause(); + void Reset(); + void Start(); + void Pause(); - Pinetime::System::SystemTask& systemTask; - States currentState = States::Init; - TickType_t startTime; - TickType_t oldTimeElapsed = 0; - TickType_t blinkTime = 0; - static constexpr int maxLapCount = 20; - TickType_t laps[maxLapCount + 1]; - static constexpr int displayedLaps = 2; - int lapsDone = 0; - lv_obj_t *time, *msecTime, *btnPlayPause, *btnStopLap, *txtPlayPause, *txtStopLap; - lv_obj_t* lapText; - bool isHoursLabelUpdated = false; + Pinetime::System::SystemTask& systemTask; + States currentState = States::Init; + TickType_t startTime; + TickType_t oldTimeElapsed = 0; + TickType_t blinkTime = 0; + static constexpr int maxLapCount = 20; + TickType_t laps[maxLapCount + 1]; + static constexpr int displayedLaps = 2; + int lapsDone = 0; + lv_obj_t *time, *msecTime, *btnPlayPause, *btnStopLap, *txtPlayPause, *txtStopLap; + lv_obj_t* lapText; + bool isHoursLabelUpdated = false; - lv_task_t* taskRefresh; - }; + lv_task_t* taskRefresh; + }; + } + template <> + struct AppTraits { + static constexpr Apps app = Apps::StopWatch; + static constexpr const char* icon = Screens::Symbols::stopWatch; + static Screens::Screen* Create(AppControllers& controllers) { + return new Screens::StopWatch(*controllers.systemTask); + }; + }; + } } diff --git a/src/displayapp/screens/Tile.cpp b/src/displayapp/screens/Tile.cpp index 343755e3..7c392c59 100644 --- a/src/displayapp/screens/Tile.cpp +++ b/src/displayapp/screens/Tile.cpp @@ -1,5 +1,4 @@ #include "displayapp/screens/Tile.h" -#include "displayapp/DisplayApp.h" #include "displayapp/screens/BatteryIcon.h" #include "components/ble/BleController.h" #include "displayapp/InfiniTimeTheme.h" diff --git a/src/displayapp/screens/Timer.cpp b/src/displayapp/screens/Timer.cpp index d9488740..a1ede6be 100644 --- a/src/displayapp/screens/Timer.cpp +++ b/src/displayapp/screens/Timer.cpp @@ -62,7 +62,7 @@ Timer::Timer(Controllers::Timer& timerController) : timer {timerController} { txtPlayPause = lv_label_create(lv_scr_act(), nullptr); lv_obj_align(txtPlayPause, btnPlayPause, LV_ALIGN_CENTER, 0, 0); - if (timerController.IsRunning()) { + if (timer.IsRunning()) { SetTimerRunning(); } else { SetTimerStopped(); diff --git a/src/displayapp/screens/Timer.h b/src/displayapp/screens/Timer.h index e452a9d9..f8e337c2 100644 --- a/src/displayapp/screens/Timer.h +++ b/src/displayapp/screens/Timer.h @@ -8,38 +8,48 @@ #include #include "components/timer/Timer.h" +#include "Symbols.h" -namespace Pinetime::Applications::Screens { - class Timer : public Screen { - public: - Timer(Controllers::Timer& timerController); - ~Timer() override; - void Refresh() override; - void Reset(); - void ToggleRunning(); - void ButtonPressed(); - void MaskReset(); +namespace Pinetime::Applications{ + namespace Screens { + class Timer : public Screen { + public: + Timer(Controllers::Timer& timerController); + ~Timer() override; + void Refresh() override; + void Reset(); + void ToggleRunning(); + void ButtonPressed(); + void MaskReset(); - private: - void SetTimerRunning(); - void SetTimerStopped(); - void UpdateMask(); - Controllers::Timer& timer; + private: + void SetTimerRunning(); + void SetTimerStopped(); + void UpdateMask(); + Pinetime::Controllers::Timer& timer; - lv_obj_t* btnPlayPause; - lv_obj_t* txtPlayPause; + lv_obj_t* btnPlayPause; + lv_obj_t* txtPlayPause; - lv_obj_t* btnObjectMask; - lv_obj_t* highlightObjectMask; - lv_objmask_mask_t* btnMask; - lv_objmask_mask_t* highlightMask; + lv_obj_t* btnObjectMask; + lv_obj_t* highlightObjectMask; + lv_objmask_mask_t* btnMask; + lv_objmask_mask_t* highlightMask; - lv_task_t* taskRefresh; - Widgets::Counter minuteCounter = Widgets::Counter(0, 59, jetbrains_mono_76); - Widgets::Counter secondCounter = Widgets::Counter(0, 59, jetbrains_mono_76); + lv_task_t* taskRefresh; + Widgets::Counter minuteCounter = Widgets::Counter(0, 59, jetbrains_mono_76); + Widgets::Counter secondCounter = Widgets::Counter(0, 59, jetbrains_mono_76); - bool buttonPressing = false; - lv_coord_t maskPosition = 0; - TickType_t pressTime = 0; + bool buttonPressing = false; + lv_coord_t maskPosition = 0; + TickType_t pressTime = 0; + }; + } + + template<> + struct AppTraits { + static constexpr Apps app = Apps::Timer; + static constexpr const char* icon = Screens::Symbols::hourGlass; + static Screens::Screen *Create(AppControllers& controllers) { return new Screens::Timer(controllers.timer); }; }; } diff --git a/src/displayapp/screens/Twos.h b/src/displayapp/screens/Twos.h index e731eae6..4e6980f5 100644 --- a/src/displayapp/screens/Twos.h +++ b/src/displayapp/screens/Twos.h @@ -1,7 +1,8 @@ #pragma once -#include +#include "displayapp/Apps.h" #include "displayapp/screens/Screen.h" +#include "displayapp/Controllers.h" namespace Pinetime { namespace Applications { @@ -35,5 +36,11 @@ namespace Pinetime { bool placeNewTile(); }; } + template<> + struct AppTraits { + static constexpr Apps app = Apps::Twos; + static constexpr const char* icon = "2"; + static Screens::Screen *Create(AppControllers& /*controllers*/) { return new Screens::Twos(); }; + }; } } diff --git a/src/displayapp/screens/Weather.h b/src/displayapp/screens/Weather.h index 459534aa..888dc257 100644 --- a/src/displayapp/screens/Weather.h +++ b/src/displayapp/screens/Weather.h @@ -1,9 +1,12 @@ #pragma once #include -#include +#include "components/ble/weather/WeatherService.h" #include "Screen.h" #include "ScreenList.h" +#include "displayapp/Apps.h" +#include "displayapp/Controllers.h" +#include "Symbols.h" namespace Pinetime { namespace Applications { @@ -41,5 +44,13 @@ namespace Pinetime { std::unique_ptr CreateScreenHumidity(); }; } + template <> + struct AppTraits { + static constexpr Apps app = Apps::Weather; + static constexpr const char* icon = Screens::Symbols::sun; + static Screens::Screen* Create(AppControllers& controllers) { + return new Screens::Weather(controllers.displayApp, *controllers.weatherController); + }; + }; } } diff --git a/src/drivers/SpiMaster.cpp b/src/drivers/SpiMaster.cpp index 1a2fab9c..3446d639 100644 --- a/src/drivers/SpiMaster.cpp +++ b/src/drivers/SpiMaster.cpp @@ -131,8 +131,8 @@ void SpiMaster::OnEndEvent() { if (s > 0) { auto currentSize = std::min((size_t) 255, s); PrepareTx(currentBufferAddr, currentSize); - currentBufferAddr += currentSize; - currentBufferSize -= currentSize; + currentBufferAddr = currentBufferAddr + currentSize; + currentBufferSize = currentBufferSize - currentSize; spiBaseAddress->TASKS_START = 1; } else { @@ -153,7 +153,7 @@ void SpiMaster::OnEndEvent() { void SpiMaster::OnStartedEvent() { } -void SpiMaster::PrepareTx(const volatile uint32_t bufferAddress, const volatile size_t size) { +void SpiMaster::PrepareTx(const uint32_t bufferAddress, const size_t size) { spiBaseAddress->TXD.PTR = bufferAddress; spiBaseAddress->TXD.MAXCNT = size; spiBaseAddress->TXD.LIST = 0; @@ -163,7 +163,7 @@ void SpiMaster::PrepareTx(const volatile uint32_t bufferAddress, const volatile spiBaseAddress->EVENTS_END = 0; } -void SpiMaster::PrepareRx(const volatile uint32_t bufferAddress, const volatile size_t size) { +void SpiMaster::PrepareRx(const uint32_t bufferAddress, const size_t size) { spiBaseAddress->TXD.PTR = 0; spiBaseAddress->TXD.MAXCNT = 0; spiBaseAddress->TXD.LIST = 0; @@ -195,8 +195,8 @@ bool SpiMaster::Write(uint8_t pinCsn, const uint8_t* data, size_t size) { auto currentSize = std::min((size_t) 255, (size_t) currentBufferSize); PrepareTx(currentBufferAddr, currentSize); - currentBufferSize -= currentSize; - currentBufferAddr += currentSize; + currentBufferSize = currentBufferSize - currentSize; + currentBufferAddr = currentBufferAddr + currentSize; spiBaseAddress->TASKS_START = 1; if (size == 1) { diff --git a/src/drivers/Watchdog.cpp b/src/drivers/Watchdog.cpp index 6c2c963b..eeeb6cfd 100644 --- a/src/drivers/Watchdog.cpp +++ b/src/drivers/Watchdog.cpp @@ -41,7 +41,7 @@ namespace { // RRED (Reload Register Enable) is a bitfield of 8 bits. Each bit represent // one of the eight reload registers available. // In this case, we enable only the first one. - NRF_WDT->RREN |= 1; + NRF_WDT->RREN = NRF_WDT->RREN | 1; } /// Returns the reset reason provided by the POWER subsystem diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index e59a0ff7..b245e392 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -136,6 +136,9 @@ void SystemTask::Work() { settingsController.Init(); displayApp.Register(this); + displayApp.Register(&nimbleController.weather()); + displayApp.Register(&nimbleController.music()); + displayApp.Register(&nimbleController.navigation()); displayApp.Start(bootError); heartRateSensor.Init();