From b39310508292b6d5f0d235872fad6b0bf31efb75 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Wed, 26 May 2021 15:15:10 +0300 Subject: improve ui and optimize code --- src/displayapp/screens/StopWatch.cpp | 35 +++++++++++++++++------------------ 1 file changed, 17 insertions(+), 18 deletions(-) (limited to 'src/displayapp') diff --git a/src/displayapp/screens/StopWatch.cpp b/src/displayapp/screens/StopWatch.cpp index d7cd20c3..76c4bfa0 100644 --- a/src/displayapp/screens/StopWatch.cpp +++ b/src/displayapp/screens/StopWatch.cpp @@ -61,22 +61,32 @@ StopWatch::StopWatch(DisplayApp* app) lv_obj_set_style_local_text_font(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_76); lv_obj_set_style_local_text_color(time, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); lv_label_set_text(time, "00:00"); - lv_obj_align(time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, -45); + lv_obj_align(time, lv_scr_act(), LV_ALIGN_CENTER, 0, -45); msecTime = lv_label_create(lv_scr_act(), nullptr); // lv_obj_set_style_local_text_font(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); lv_obj_set_style_local_text_color(msecTime, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); lv_label_set_text(msecTime, "00"); - lv_obj_align(msecTime, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 108, 3); + lv_obj_align(msecTime, lv_scr_act(), LV_ALIGN_CENTER, 0, 3); btnPlayPause = lv_btn_create(lv_scr_act(), nullptr); btnPlayPause->user_data = this; lv_obj_set_event_cb(btnPlayPause, play_pause_event_handler); - lv_obj_align(btnPlayPause, lv_scr_act(), LV_ALIGN_IN_BOTTOM_MID, 0, -10); - lv_obj_set_height(btnPlayPause, 40); + lv_obj_set_height(btnPlayPause, 50); + lv_obj_set_width(btnPlayPause, 115); + lv_obj_align(btnPlayPause, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0); txtPlayPause = lv_label_create(btnPlayPause, nullptr); lv_label_set_text(txtPlayPause, Symbols::play); + btnStopLap = lv_btn_create(lv_scr_act(), nullptr); + btnStopLap->user_data = this; + lv_obj_set_event_cb(btnStopLap, stop_lap_event_handler); + lv_obj_set_height(btnStopLap, 50); + lv_obj_set_width(btnStopLap, 115); + lv_obj_align(btnStopLap, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); + txtStopLap = lv_label_create(btnStopLap, nullptr); + lv_obj_set_hidden(btnStopLap, true); + lapOneText = lv_label_create(lv_scr_act(), nullptr); // lv_obj_set_style_local_text_font(lapOneText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); lv_obj_set_style_local_text_color(lapOneText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW); @@ -88,9 +98,6 @@ StopWatch::StopWatch(DisplayApp* app) lv_obj_set_style_local_text_color(lapTwoText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_YELLOW); lv_obj_align(lapTwoText, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 50, 55); lv_label_set_text(lapTwoText, ""); - - // We don't want this button in the init state - btnStopLap = nullptr; } StopWatch::~StopWatch() { @@ -115,10 +122,6 @@ bool StopWatch::Refresh() { // Init state when an user first opens the app // and when a stop/reset button is pressed case States::Init: { - if (btnStopLap != nullptr) { - lv_obj_del(btnStopLap); - btnStopLap = nullptr; - } // The initial default value lv_label_set_text(time, "00:00"); lv_label_set_text(msecTime, "00"); @@ -129,16 +132,12 @@ bool StopWatch::Refresh() { lapNr = 0; if (currentEvent == Events::Play) { - btnStopLap = lv_btn_create(lv_scr_act(), nullptr); - btnStopLap->user_data = this; - lv_obj_set_event_cb(btnStopLap, stop_lap_event_handler); - lv_obj_align(btnStopLap, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 0); - lv_obj_set_height(btnStopLap, 40); - txtStopLap = lv_label_create(btnStopLap, nullptr); - lv_label_set_text(txtStopLap, Symbols::lapsFlag); + lv_obj_set_hidden(btnStopLap, false); startTime = xTaskGetTickCount(); currentState = States::Running; + } else { + lv_obj_set_hidden(btnStopLap, true); } break; } -- cgit v1.2.3 From c6969268fc162c41dbb37f7a2f061858563ba3c1 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Wed, 26 May 2021 16:13:40 +0300 Subject: Keep button visible, but disabled --- src/displayapp/screens/StopWatch.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'src/displayapp') diff --git a/src/displayapp/screens/StopWatch.cpp b/src/displayapp/screens/StopWatch.cpp index 76c4bfa0..7c128d1b 100644 --- a/src/displayapp/screens/StopWatch.cpp +++ b/src/displayapp/screens/StopWatch.cpp @@ -84,8 +84,12 @@ StopWatch::StopWatch(DisplayApp* app) lv_obj_set_height(btnStopLap, 50); lv_obj_set_width(btnStopLap, 115); lv_obj_align(btnStopLap, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 0, 0); + lv_obj_set_style_local_bg_color(btnStopLap, LV_BTN_PART_MAIN, LV_STATE_DISABLED, lv_color_hex(0x080808)); txtStopLap = lv_label_create(btnStopLap, nullptr); - lv_obj_set_hidden(btnStopLap, true); + lv_obj_set_style_local_text_color(txtStopLap, LV_BTN_PART_MAIN, LV_STATE_DISABLED, lv_color_hex(0x888888)); + lv_label_set_text(txtStopLap, Symbols::stop); + lv_obj_set_state(btnStopLap, LV_STATE_DISABLED); + lv_obj_set_state(txtStopLap, LV_STATE_DISABLED); lapOneText = lv_label_create(lv_scr_act(), nullptr); // lv_obj_set_style_local_text_font(lapOneText, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, &jetbrains_mono_bold_20); @@ -132,12 +136,14 @@ bool StopWatch::Refresh() { lapNr = 0; if (currentEvent == Events::Play) { - lv_obj_set_hidden(btnStopLap, false); + lv_obj_set_state(btnStopLap, LV_STATE_DEFAULT); + lv_obj_set_state(txtStopLap, LV_STATE_DEFAULT); startTime = xTaskGetTickCount(); currentState = States::Running; } else { - lv_obj_set_hidden(btnStopLap, true); + lv_obj_set_state(btnStopLap, LV_STATE_DISABLED); + lv_obj_set_state(txtStopLap, LV_STATE_DISABLED); } break; } -- cgit v1.2.3 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/displayapp') 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 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/displayapp') 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 From caca6a5cff0025df80241a09baab28e49720ddf8 Mon Sep 17 00:00:00 2001 From: Jean-François Milants Date: Thu, 10 Jun 2021 21:19:11 +0200 Subject: Fix stack corruption when exiting an app (the app was destroyed while it was executing the button handler). --- src/displayapp/DisplayApp.cpp | 8 +++++++- src/displayapp/DisplayApp.h | 3 +++ 2 files changed, 10 insertions(+), 1 deletion(-) (limited to 'src/displayapp') diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index ba6dfbd2..99758c92 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -205,6 +205,11 @@ void DisplayApp::Refresh() { } } + if(nextApp != Apps::None) { + LoadApp(nextApp, nextDirection); + nextApp = Apps::None; + } + if (state != States::Idle && touchMode == TouchModes::Polling) { auto info = touchPanel.GetTouchInfo(); if (info.action == 2) { // 2 = contact @@ -223,7 +228,8 @@ void DisplayApp::RunningState() { } void DisplayApp::StartApp(Apps app, DisplayApp::FullRefreshDirections direction) { - LoadApp(app, direction); + nextApp = app; + nextDirection = direction; } void DisplayApp::ReturnApp(Apps app, DisplayApp::FullRefreshDirections direction, TouchEvents touchEvent) { diff --git a/src/displayapp/DisplayApp.h b/src/displayapp/DisplayApp.h index 65abd41a..73a7cc36 100644 --- a/src/displayapp/DisplayApp.h +++ b/src/displayapp/DisplayApp.h @@ -111,6 +111,9 @@ namespace Pinetime { void ReturnApp(Apps app, DisplayApp::FullRefreshDirections direction, TouchEvents touchEvent); void LoadApp(Apps app, DisplayApp::FullRefreshDirections direction); void PushMessageToSystemTask(Pinetime::System::Messages message); + + Apps nextApp = Apps::None; + DisplayApp::FullRefreshDirections nextDirection; }; } } -- cgit v1.2.3 From b1925ff28638dd4b8400c4d0c49d796d8990b1af Mon Sep 17 00:00:00 2001 From: Jean-François Milants Date: Thu, 10 Jun 2021 21:20:27 +0200 Subject: Minor improvements: use std::make_unique when creating unique_ptr, check the code is running from an IRQ before calling xQueueSendFromISR or xQueueSend) --- src/displayapp/DisplayApp.cpp | 21 +++++++++++++++------ src/displayapp/screens/SystemInfo.cpp | 10 +++++----- src/displayapp/screens/settings/Settings.cpp | 4 ++-- src/displayapp/screens/settings/Settings.h | 1 - src/drivers/SpiMaster.cpp | 8 ++++---- src/systemtask/SystemTask.cpp | 24 ++++++++++++++++++------ 6 files changed, 44 insertions(+), 24 deletions(-) (limited to 'src/displayapp') diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 99758c92..3bfaf2a2 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -45,6 +45,12 @@ using namespace Pinetime::Applications; using namespace Pinetime::Applications::Display; +namespace { + static inline bool in_isr(void) { + return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0; + } +} + DisplayApp::DisplayApp(Drivers::St7789& lcd, Components::LittleVgl& lvgl, Drivers::Cst816S& touchPanel, @@ -364,12 +370,15 @@ void DisplayApp::IdleState() { } void DisplayApp::PushMessage(Messages msg) { - BaseType_t xHigherPriorityTaskWoken; - xHigherPriorityTaskWoken = pdFALSE; - xQueueSendFromISR(msgQueue, &msg, &xHigherPriorityTaskWoken); - if (xHigherPriorityTaskWoken) { - /* Actual macro used here is port specific. */ - // TODO : should I do something here? + if(in_isr()) { + BaseType_t xHigherPriorityTaskWoken; + xHigherPriorityTaskWoken = pdFALSE; + xQueueSendFromISR(msgQueue, &msg, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken) { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + } + } else { + xQueueSend(msgQueue, &msg, portMAX_DELAY); } } diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index f61d2ff1..a7387dac 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -81,7 +81,7 @@ std::unique_ptr SystemInfo::CreateScreen1() { __TIME__); lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); - return std::unique_ptr(new Screens::Label(0, 5, app, label)); + return std::make_unique(0, 5, app, label); } std::unique_ptr SystemInfo::CreateScreen2() { @@ -161,7 +161,7 @@ std::unique_ptr SystemInfo::CreateScreen2() { brightnessController.ToString(), resetReason); lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); - return std::unique_ptr(new Screens::Label(1, 4, app, label)); + return std::make_unique(1, 4, app, label); } std::unique_ptr SystemInfo::CreateScreen3() { @@ -195,7 +195,7 @@ std::unique_ptr SystemInfo::CreateScreen3() { (int) mon.free_biggest_size, 0); lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); - return std::unique_ptr(new Screens::Label(2, 5, app, label)); + return std::make_unique(2, 5, app, label); } bool sortById(const TaskStatus_t& lhs, const TaskStatus_t& rhs) { @@ -229,7 +229,7 @@ std::unique_ptr SystemInfo::CreateScreen4() { lv_table_set_cell_value(infoTask, i + 1, 2, std::to_string(tasksStatus[i].usStackHighWaterMark).c_str()); } } - return std::unique_ptr(new Screens::Label(3, 5, app, infoTask)); + return std::make_unique(3, 5, app, infoTask); } std::unique_ptr SystemInfo::CreateScreen5() { @@ -245,5 +245,5 @@ std::unique_ptr SystemInfo::CreateScreen5() { "#FFFF00 JF002/InfiniTime#"); lv_label_set_align(label, LV_LABEL_ALIGN_CENTER); lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); - return std::unique_ptr(new Screens::Label(4, 5, app, label)); + return std::make_unique(4, 5, app, label); } diff --git a/src/displayapp/screens/settings/Settings.cpp b/src/displayapp/screens/settings/Settings.cpp index 2c72c832..e63a3584 100644 --- a/src/displayapp/screens/settings/Settings.cpp +++ b/src/displayapp/screens/settings/Settings.cpp @@ -46,7 +46,7 @@ std::unique_ptr Settings::CreateScreen1() { {Symbols::clock, "Watch face", Apps::SettingWatchFace}, }}; - return std::unique_ptr(new Screens::List(0, 2, app, settingsController, applications)); + return std::make_unique(0, 2, app, settingsController, applications); } std::unique_ptr Settings::CreateScreen2() { @@ -58,5 +58,5 @@ std::unique_ptr Settings::CreateScreen2() { {Symbols::list, "About", Apps::SysInfo}, }}; - return std::unique_ptr(new Screens::List(1, 2, app, settingsController, applications)); + return std::make_unique(1, 2, app, settingsController, applications); } diff --git a/src/displayapp/screens/settings/Settings.h b/src/displayapp/screens/settings/Settings.h index 7e332dfe..711a6be6 100644 --- a/src/displayapp/screens/settings/Settings.h +++ b/src/displayapp/screens/settings/Settings.h @@ -16,7 +16,6 @@ namespace Pinetime { bool Refresh() override; - void OnButtonEvent(lv_obj_t* object, lv_event_t event); bool OnTouchEvent(Pinetime::Applications::TouchEvents event) override; private: diff --git a/src/drivers/SpiMaster.cpp b/src/drivers/SpiMaster.cpp index 34fcc08a..e2be5027 100644 --- a/src/drivers/SpiMaster.cpp +++ b/src/drivers/SpiMaster.cpp @@ -132,17 +132,17 @@ void SpiMaster::OnEndEvent() { spiBaseAddress->TASKS_START = 1; } else { + BaseType_t xHigherPriorityTaskWoken = pdFALSE; if (taskToNotify != nullptr) { - BaseType_t xHigherPriorityTaskWoken = pdFALSE; vTaskNotifyGiveFromISR(taskToNotify, &xHigherPriorityTaskWoken); portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } nrf_gpio_pin_set(this->pinCsn); currentBufferAddr = 0; - BaseType_t xHigherPriorityTaskWoken = pdFALSE; - xSemaphoreGiveFromISR(mutex, &xHigherPriorityTaskWoken); - portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + BaseType_t xHigherPriorityTaskWoken2 = pdFALSE; + xSemaphoreGiveFromISR(mutex, &xHigherPriorityTaskWoken2); + portYIELD_FROM_ISR(xHigherPriorityTaskWoken | xHigherPriorityTaskWoken2); } } diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index be484bb4..4799624a 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -27,6 +27,12 @@ using namespace Pinetime::System; +namespace { + static inline bool in_isr(void) { + return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0; + } +} + void IdleTimerCallback(TimerHandle_t xTimer) { NRF_LOG_INFO("IdleTimerCallback"); @@ -392,12 +398,18 @@ void SystemTask::PushMessage(System::Messages msg) { if (msg == Messages::GoToSleep) { isGoingToSleep = true; } - BaseType_t xHigherPriorityTaskWoken; - xHigherPriorityTaskWoken = pdFALSE; - xQueueSendFromISR(systemTasksMsgQueue, &msg, &xHigherPriorityTaskWoken); - if (xHigherPriorityTaskWoken) { - /* Actual macro used here is port specific. */ - // TODO: should I do something here? + + if(in_isr()) { + BaseType_t xHigherPriorityTaskWoken; + xHigherPriorityTaskWoken = pdFALSE; + xQueueSendFromISR(systemTasksMsgQueue, &msg, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken) { + /* Actual macro used here is port specific. */ + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); + + } + } else { + xQueueSend(systemTasksMsgQueue, &msg, portMAX_DELAY); } } -- cgit v1.2.3 From 049174bd3535d980a2744cbf035e1e33d33b5e39 Mon Sep 17 00:00:00 2001 From: Florian Date: Fri, 11 Jun 2021 01:15:32 +0200 Subject: replace ScreenList with a single screen in Clock. This removes the tap to switch feature --- src/displayapp/screens/Clock.cpp | 39 +++++++++++++++++++++------------------ src/displayapp/screens/Clock.h | 4 ++-- 2 files changed, 23 insertions(+), 20 deletions(-) (limited to 'src/displayapp') diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp index 14299840..9962a9f4 100644 --- a/src/displayapp/screens/Clock.cpp +++ b/src/displayapp/screens/Clock.cpp @@ -32,22 +32,25 @@ Clock::Clock(DisplayApp* app, notificatioManager {notificatioManager}, settingsController {settingsController}, heartRateController {heartRateController}, - motionController {motionController}, - screens {app, - settingsController.GetClockFace(), - { - [this]() -> std::unique_ptr { - return WatchFaceDigitalScreen(); - }, - [this]() -> std::unique_ptr { - return WatchFaceAnalogScreen(); - }, - // Examples for more watch faces - //[this]() -> std::unique_ptr { return WatchFaceMinimalScreen(); }, - //[this]() -> std::unique_ptr { return WatchFaceCustomScreen(); } - }, - Screens::ScreenListModes::LongPress} { - + motionController {motionController} { + + switch (settingsController.GetClockFace()) { + case 0: + screen = WatchFaceDigitalScreen(); + break; + case 1: + screen = WatchFaceAnalogScreen(); + break; + /* + // Examples for more watch faces + case 2: + screen = WatchFaceMinimalScreen(); + break; + case 3: + screen = WatchFaceCustomScreen(); + break; + */ + } settingsController.SetAppMenu(0); } @@ -56,12 +59,12 @@ Clock::~Clock() { } bool Clock::Refresh() { - screens.Refresh(); + screen->Refresh(); return running; } bool Clock::OnTouchEvent(Pinetime::Applications::TouchEvents event) { - return screens.OnTouchEvent(event); + return screen->OnTouchEvent(event); } std::unique_ptr Clock::WatchFaceDigitalScreen() { diff --git a/src/displayapp/screens/Clock.h b/src/displayapp/screens/Clock.h index 9879985f..174c73b7 100644 --- a/src/displayapp/screens/Clock.h +++ b/src/displayapp/screens/Clock.h @@ -4,8 +4,8 @@ #include #include #include +#include #include "Screen.h" -#include "ScreenList.h" #include "components/datetime/DateTimeController.h" namespace Pinetime { @@ -47,7 +47,7 @@ namespace Pinetime { Controllers::HeartRateController& heartRateController; Controllers::MotionController& motionController; - ScreenList<2> screens; + std::unique_ptr screen; std::unique_ptr WatchFaceDigitalScreen(); std::unique_ptr WatchFaceAnalogScreen(); -- cgit v1.2.3 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/displayapp') 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 From bf906bd573b37e0bb592221dae6b5f156836a6b6 Mon Sep 17 00:00:00 2001 From: Riku Isokoski Date: Sat, 12 Jun 2021 12:12:39 +0300 Subject: Fix scrollbar (#382) --- src/displayapp/screens/SystemInfo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/displayapp') diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index a7387dac..a0b626e9 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -161,7 +161,7 @@ std::unique_ptr SystemInfo::CreateScreen2() { brightnessController.ToString(), resetReason); lv_obj_align(label, lv_scr_act(), LV_ALIGN_CENTER, 0, 0); - return std::make_unique(1, 4, app, label); + return std::make_unique(1, 5, app, label); } std::unique_ptr SystemInfo::CreateScreen3() { -- cgit v1.2.3 From 314a8ebba070bd935c795cea2955d494f002797f Mon Sep 17 00:00:00 2001 From: Avamander Date: Sat, 12 Jun 2021 12:18:19 +0300 Subject: Changed the namespace of SystemInfo::sortById to avoid a name conflict (#360) --- src/displayapp/DisplayApp.cpp | 2 -- src/displayapp/screens/SystemInfo.cpp | 2 +- src/displayapp/screens/SystemInfo.h | 3 +++ 3 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/displayapp') diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 05f171be..01e26e22 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -331,8 +331,6 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) std::make_unique(this, dateTimeController, batteryController, brightnessController, bleController, watchdog); ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; - // - case Apps::FlashLight: currentScreen = std::make_unique(this, *systemTask, brightnessController); ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::None); diff --git a/src/displayapp/screens/SystemInfo.cpp b/src/displayapp/screens/SystemInfo.cpp index a0b626e9..9ff28288 100644 --- a/src/displayapp/screens/SystemInfo.cpp +++ b/src/displayapp/screens/SystemInfo.cpp @@ -198,7 +198,7 @@ std::unique_ptr SystemInfo::CreateScreen3() { return std::make_unique(2, 5, app, label); } -bool sortById(const TaskStatus_t& lhs, const TaskStatus_t& rhs) { +bool SystemInfo::sortById(const TaskStatus_t& lhs, const TaskStatus_t& rhs) { return lhs.xTaskNumber < rhs.xTaskNumber; } diff --git a/src/displayapp/screens/SystemInfo.h b/src/displayapp/screens/SystemInfo.h index c0c65554..c61a07a2 100644 --- a/src/displayapp/screens/SystemInfo.h +++ b/src/displayapp/screens/SystemInfo.h @@ -43,6 +43,9 @@ namespace Pinetime { Pinetime::Drivers::WatchdogView& watchdog; ScreenList<5> screens; + + static bool sortById(const TaskStatus_t& lhs, const TaskStatus_t& rhs); + std::unique_ptr CreateScreen1(); std::unique_ptr CreateScreen2(); std::unique_ptr CreateScreen3(); -- cgit v1.2.3 From d7962617e47c221b6274af53b9488e5280c8d2d8 Mon Sep 17 00:00:00 2001 From: Jean-François Milants Date: Sat, 12 Jun 2021 14:21:29 +0200 Subject: Clock : initialize the actual clockface in initialization list instead of in the core of the ctro(). --- src/displayapp/screens/Clock.cpp | 31 ++++++++++++------------------- 1 file changed, 12 insertions(+), 19 deletions(-) (limited to 'src/displayapp') diff --git a/src/displayapp/screens/Clock.cpp b/src/displayapp/screens/Clock.cpp index 9962a9f4..05e47a39 100644 --- a/src/displayapp/screens/Clock.cpp +++ b/src/displayapp/screens/Clock.cpp @@ -32,25 +32,18 @@ Clock::Clock(DisplayApp* app, notificatioManager {notificatioManager}, settingsController {settingsController}, heartRateController {heartRateController}, - motionController {motionController} { - - switch (settingsController.GetClockFace()) { - case 0: - screen = WatchFaceDigitalScreen(); - break; - case 1: - screen = WatchFaceAnalogScreen(); - break; - /* - // Examples for more watch faces - case 2: - screen = WatchFaceMinimalScreen(); - break; - case 3: - screen = WatchFaceCustomScreen(); - break; - */ - } + motionController {motionController}, + screen {[this, &settingsController]() { + switch (settingsController.GetClockFace()) { + case 0: + return WatchFaceDigitalScreen(); + break; + case 1: + return WatchFaceAnalogScreen(); + break; + } + return WatchFaceDigitalScreen(); + }()} { settingsController.SetAppMenu(0); } -- cgit v1.2.3 From c575754b4283ab1e8a2b1320a97992db6712ac58 Mon Sep 17 00:00:00 2001 From: Bryton Hall Date: Sat, 12 Jun 2021 09:06:58 -0400 Subject: add basic metronome app (#409) * add basic metronome app * add bpb, tap to bpm, update widgets * use event pressed for bpm tap * move case statement break to the right place * narrow bpm selection range, override touch events * fix arc knob style * re-enable sleeping in destructor --- src/CMakeLists.txt | 2 + src/displayapp/Apps.h | 1 + src/displayapp/DisplayApp.cpp | 8 +- src/displayapp/lv_pinetime_theme.c | 13 +++ src/displayapp/screens/ApplicationList.cpp | 2 +- src/displayapp/screens/Metronome.cpp | 169 +++++++++++++++++++++++++++++ src/displayapp/screens/Metronome.h | 34 ++++++ 7 files changed, 226 insertions(+), 3 deletions(-) create mode 100644 src/displayapp/screens/Metronome.cpp create mode 100644 src/displayapp/screens/Metronome.h (limited to 'src/displayapp') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c72f7c9c..71909d7d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -396,6 +396,7 @@ list(APPEND SOURCE_FILES displayapp/screens/FirmwareUpdate.cpp displayapp/screens/Music.cpp displayapp/screens/Navigation.cpp + displayapp/screens/Metronome.cpp displayapp/screens/Motion.cpp displayapp/screens/FirmwareValidation.cpp displayapp/screens/ApplicationList.cpp @@ -592,6 +593,7 @@ set(INCLUDE_FILES displayapp/Apps.h displayapp/screens/Notifications.h displayapp/screens/HeartRate.h + displayapp/screens/Metronome.h displayapp/screens/Motion.h displayapp/screens/Timer.h drivers/St7789.h diff --git a/src/displayapp/Apps.h b/src/displayapp/Apps.h index 2df517f8..684e3a46 100644 --- a/src/displayapp/Apps.h +++ b/src/displayapp/Apps.h @@ -21,6 +21,7 @@ namespace Pinetime { HeartRate, Navigation, StopWatch, + Metronome, Motion, Steps, QuickSettings, diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 01e26e22..cd25c979 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -18,6 +18,7 @@ #include "displayapp/screens/Paddle.h" #include "displayapp/screens/StopWatch.h" #include "displayapp/screens/Meter.h" +#include "displayapp/screens/Metronome.h" #include "displayapp/screens/Music.h" #include "displayapp/screens/Navigation.h" #include "displayapp/screens/Notifications.h" @@ -318,7 +319,7 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) currentScreen = std::make_unique(this, settingsController); ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; - case Apps::SettingSteps: + case Apps::SettingSteps: currentScreen = std::make_unique(this, settingsController); ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; @@ -356,10 +357,13 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) case Apps::HeartRate: currentScreen = std::make_unique(this, heartRateController, *systemTask); break; + case Apps::Metronome: + currentScreen = std::make_unique(this, motorController, systemTask); + break; case Apps::Motion: currentScreen = std::make_unique(this, motionController); break; - case Apps::Steps: + case Apps::Steps: currentScreen = std::make_unique(this, motionController, settingsController); break; } diff --git a/src/displayapp/lv_pinetime_theme.c b/src/displayapp/lv_pinetime_theme.c index b003a411..1b8b1980 100644 --- a/src/displayapp/lv_pinetime_theme.c +++ b/src/displayapp/lv_pinetime_theme.c @@ -48,6 +48,7 @@ static lv_style_t style_sw_bg; static lv_style_t style_sw_indic; static lv_style_t style_sw_knob; static lv_style_t style_arc_bg; +static lv_style_t style_arc_knob; static lv_style_t style_arc_indic; static lv_style_t style_table_cell; static lv_style_t style_pad_small; @@ -191,6 +192,7 @@ static void basic_init(void) { lv_style_set_text_line_space(&style_ddlist_list, LV_STATE_DEFAULT, LV_VER_RES / 25); lv_style_set_shadow_width(&style_ddlist_list, LV_STATE_DEFAULT, LV_VER_RES / 20); lv_style_set_shadow_color(&style_ddlist_list, LV_STATE_DEFAULT, LV_PINETIME_GRAY); + lv_style_set_bg_color(&style_ddlist_list, LV_STATE_DEFAULT, LV_PINETIME_GRAY); style_init_reset(&style_ddlist_selected); lv_style_set_bg_opa(&style_ddlist_selected, LV_STATE_DEFAULT, LV_OPA_COVER); @@ -239,6 +241,13 @@ static void basic_init(void) { lv_style_set_line_color(&style_arc_bg, LV_STATE_DEFAULT, LV_PINETIME_GRAY); lv_style_set_line_width(&style_arc_bg, LV_STATE_DEFAULT, LV_DPX(25)); lv_style_set_line_rounded(&style_arc_bg, LV_STATE_DEFAULT, true); + lv_style_set_pad_all(&style_arc_bg, LV_STATE_DEFAULT, LV_DPX(5)); + + lv_style_reset(&style_arc_knob); + lv_style_set_radius(&style_arc_knob, LV_STATE_DEFAULT, LV_RADIUS_CIRCLE); + lv_style_set_bg_opa(&style_arc_knob, LV_STATE_DEFAULT, LV_OPA_COVER); + lv_style_set_bg_color(&style_arc_knob, LV_STATE_DEFAULT, LV_PINETIME_LIGHT_GRAY); + lv_style_set_pad_all(&style_arc_knob, LV_STATE_DEFAULT, LV_DPX(5)); style_init_reset(&style_table_cell); lv_style_set_border_color(&style_table_cell, LV_STATE_DEFAULT, LV_PINETIME_GRAY); @@ -447,6 +456,10 @@ static void theme_apply(lv_obj_t* obj, lv_theme_style_t name) { lv_obj_clean_style_list(obj, LV_ARC_PART_INDIC); list = lv_obj_get_style_list(obj, LV_ARC_PART_INDIC); _lv_style_list_add_style(list, &style_arc_indic); + + lv_obj_clean_style_list(obj, LV_ARC_PART_KNOB); + list = lv_obj_get_style_list(obj, LV_ARC_PART_KNOB); + _lv_style_list_add_style(list, &style_arc_knob); break; case LV_THEME_SWITCH: diff --git a/src/displayapp/screens/ApplicationList.cpp b/src/displayapp/screens/ApplicationList.cpp index d599f5cc..d434c177 100644 --- a/src/displayapp/screens/ApplicationList.cpp +++ b/src/displayapp/screens/ApplicationList.cpp @@ -63,7 +63,7 @@ std::unique_ptr ApplicationList::CreateScreen2() { {Symbols::paddle, Apps::Paddle}, {"2", Apps::Twos}, {"M", Apps::Motion}, - {"", Apps::None}, + {"b", Apps::Metronome}, {"", Apps::None}, }}; diff --git a/src/displayapp/screens/Metronome.cpp b/src/displayapp/screens/Metronome.cpp new file mode 100644 index 00000000..c536e301 --- /dev/null +++ b/src/displayapp/screens/Metronome.cpp @@ -0,0 +1,169 @@ +#include "Metronome.h" + +#include "Screen.h" +#include "Symbols.h" +#include "lvgl/lvgl.h" +#include "FreeRTOSConfig.h" +#include "task.h" + +#include +#include + +using namespace Pinetime::Applications::Screens; + +namespace { + float calculateDelta(const TickType_t startTime, const TickType_t currentTime) { + TickType_t delta = 0; + // Take care of overflow + if (startTime > currentTime) { + delta = 0xffffffff - startTime; + delta += (currentTime + 1); + } else { + delta = currentTime - startTime; + } + return static_cast(delta) / static_cast(configTICK_RATE_HZ); + } + + static void eventHandler(lv_obj_t* obj, lv_event_t event) { + Metronome* screen = static_cast(obj->user_data); + screen->OnEvent(obj, event); + } + + lv_obj_t* createLabel(const char* name, lv_obj_t* reference, lv_align_t align, lv_font_t* font, uint8_t x = 0, uint8_t y = 0) { + lv_obj_t* label = lv_label_create(lv_scr_act(), nullptr); + lv_obj_set_style_local_text_font(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, font); + lv_obj_set_style_local_text_color(label, LV_LABEL_PART_MAIN, LV_STATE_DEFAULT, LV_COLOR_GRAY); + lv_label_set_text(label, name); + lv_obj_align(label, reference, align, x, y); + + return label; + } +} + +Metronome::Metronome(DisplayApp* app, Controllers::MotorController& motorController, System::SystemTask& systemTask) + : Screen(app), running {true}, currentState {States::Stopped}, startTime {}, motorController {motorController}, systemTask {systemTask} { + + bpmArc = lv_arc_create(lv_scr_act(), nullptr); + bpmArc->user_data = this; + lv_obj_set_event_cb(bpmArc, eventHandler); + lv_arc_set_bg_angles(bpmArc, 0, 270); + lv_arc_set_rotation(bpmArc, 135); + lv_arc_set_range(bpmArc, 40, 220); + lv_arc_set_value(bpmArc, bpm); + lv_obj_set_size(bpmArc, 210, 210); + lv_arc_set_adjustable(bpmArc, true); + lv_obj_align(bpmArc, lv_scr_act(), LV_ALIGN_IN_TOP_MID, 0, 7); + + bpmValue = createLabel(std::to_string(lv_arc_get_value(bpmArc)).c_str(), bpmArc, LV_ALIGN_IN_TOP_MID, &jetbrains_mono_76, 0, 55); + bpmLegend = createLabel("bpm", bpmValue, LV_ALIGN_OUT_BOTTOM_MID, &jetbrains_mono_bold_20, 0, 0); + + bpmTap = lv_btn_create(lv_scr_act(), nullptr); + bpmTap->user_data = this; + lv_obj_set_event_cb(bpmTap, eventHandler); + lv_obj_set_style_local_bg_opa(bpmTap, LV_BTN_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_TRANSP); + lv_obj_set_height(bpmTap, 80); + lv_obj_align(bpmTap, bpmValue, LV_ALIGN_IN_TOP_MID, 0, 0); + + bpbDropdown = lv_dropdown_create(lv_scr_act(), nullptr); + bpbDropdown->user_data = this; + lv_obj_set_event_cb(bpbDropdown, eventHandler); + lv_obj_set_style_local_pad_left(bpbDropdown, LV_DROPDOWN_PART_MAIN, LV_STATE_DEFAULT, 20); + lv_obj_set_style_local_pad_left(bpbDropdown, LV_DROPDOWN_PART_LIST, LV_STATE_DEFAULT, 20); + lv_obj_align(bpbDropdown, lv_scr_act(), LV_ALIGN_IN_BOTTOM_LEFT, 15, -4); + lv_dropdown_set_options(bpbDropdown, "1\n2\n3\n4\n5\n6\n7\n8\n9"); + lv_dropdown_set_selected(bpbDropdown, bpb - 1); + bpbLegend = lv_label_create(bpbDropdown, nullptr); + lv_label_set_text(bpbLegend, "bpb"); + lv_obj_align(bpbLegend, bpbDropdown, LV_ALIGN_IN_RIGHT_MID, -15, 0); + + playPause = lv_btn_create(lv_scr_act(), nullptr); + playPause->user_data = this; + lv_obj_set_event_cb(playPause, eventHandler); + lv_obj_align(playPause, lv_scr_act(), LV_ALIGN_IN_BOTTOM_RIGHT, -15, -10); + lv_obj_set_height(playPause, 39); + playPauseLabel = lv_label_create(playPause, nullptr); + lv_label_set_text(playPauseLabel, Symbols::play); + + app->SetTouchMode(DisplayApp::TouchModes::Polling); +} + +Metronome::~Metronome() { + app->SetTouchMode(DisplayApp::TouchModes::Gestures); + systemTask.PushMessage(Pinetime::System::SystemTask::Messages::EnableSleeping); + lv_obj_clean(lv_scr_act()); +} + +bool Metronome::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + return true; +} + +bool Metronome::Refresh() { + switch (currentState) { + case States::Stopped: { + break; + } + case States::Running: { + if (calculateDelta(startTime, xTaskGetTickCount()) >= (60.0 / bpm)) { + counter--; + startTime -= 60.0 / bpm; + startTime = xTaskGetTickCount(); + if (counter == 0) { + counter = bpb; + motorController.SetDuration(90); + } else { + motorController.SetDuration(30); + } + } + break; + } + } + return running; +} + +void Metronome::OnEvent(lv_obj_t* obj, lv_event_t event) { + switch (event) { + case LV_EVENT_VALUE_CHANGED: { + if (obj == bpmArc) { + bpm = lv_arc_get_value(bpmArc); + lv_label_set_text_fmt(bpmValue, "%03d", bpm); + } else if (obj == bpbDropdown) { + bpb = lv_dropdown_get_selected(obj) + 1; + } + break; + } + case LV_EVENT_PRESSED: { + if (obj == bpmTap) { + float timeDelta = calculateDelta(tappedTime, xTaskGetTickCount()); + if (tappedTime == 0 || timeDelta > 3) { + tappedTime = xTaskGetTickCount(); + } else { + bpm = ceil(60.0 / timeDelta); + lv_arc_set_value(bpmArc, bpm); + lv_label_set_text_fmt(bpmValue, "%03d", bpm); + tappedTime = xTaskGetTickCount(); + } + } + break; + } + case LV_EVENT_CLICKED: { + if (obj == playPause) { + currentState = (currentState == States::Stopped ? States::Running : States::Stopped); + switch (currentState) { + case States::Stopped: { + lv_label_set_text(playPauseLabel, Symbols::play); + systemTask.PushMessage(Pinetime::System::SystemTask::Messages::EnableSleeping); + break; + } + case States::Running: { + lv_label_set_text(playPauseLabel, Symbols::pause); + systemTask.PushMessage(Pinetime::System::SystemTask::Messages::DisableSleeping); + startTime = xTaskGetTickCount(); + counter = 1; + break; + } + } + } + break; + } + } +} diff --git a/src/displayapp/screens/Metronome.h b/src/displayapp/screens/Metronome.h new file mode 100644 index 00000000..3a1f1084 --- /dev/null +++ b/src/displayapp/screens/Metronome.h @@ -0,0 +1,34 @@ +#pragma once + +#include "systemtask/SystemTask.h" +#include "components/motor/MotorController.h" + +#include + +namespace Pinetime::Applications::Screens { + + class Metronome : public Screen { + public: + Metronome(DisplayApp* app, Controllers::MotorController& motorController, System::SystemTask& systemTask); + ~Metronome() override; + bool Refresh() override; + bool OnTouchEvent(TouchEvents event) override; + void OnEvent(lv_obj_t* obj, lv_event_t event); + enum class States { Running, Stopped }; + + private: + bool running; + States currentState; + TickType_t startTime; + TickType_t tappedTime = 0; + Controllers::MotorController& motorController; + System::SystemTask& systemTask; + uint16_t bpm = 120; + uint8_t bpb = 4; + uint8_t counter = 1; + + lv_obj_t *bpmArc, *bpmTap, *bpmValue, *bpmLegend; + lv_obj_t *bpbDropdown, *bpbLegend; + lv_obj_t *playPause, *playPauseLabel; + }; +} -- cgit v1.2.3 From d6fcbe960e595e53e3f24cbaae0cbb0505ad6dc2 Mon Sep 17 00:00:00 2001 From: Jean-François Milants Date: Sat, 12 Jun 2021 15:14:14 +0200 Subject: Fix build issues since Metronome app has been merged. --- src/displayapp/DisplayApp.cpp | 2 +- src/displayapp/screens/Metronome.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'src/displayapp') diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index cd25c979..ab73969d 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -358,7 +358,7 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) currentScreen = std::make_unique(this, heartRateController, *systemTask); break; case Apps::Metronome: - currentScreen = std::make_unique(this, motorController, systemTask); + currentScreen = std::make_unique(this, motorController, *systemTask); break; case Apps::Motion: currentScreen = std::make_unique(this, motionController); diff --git a/src/displayapp/screens/Metronome.cpp b/src/displayapp/screens/Metronome.cpp index c536e301..7bfbccb7 100644 --- a/src/displayapp/screens/Metronome.cpp +++ b/src/displayapp/screens/Metronome.cpp @@ -89,7 +89,7 @@ Metronome::Metronome(DisplayApp* app, Controllers::MotorController& motorControl Metronome::~Metronome() { app->SetTouchMode(DisplayApp::TouchModes::Gestures); - systemTask.PushMessage(Pinetime::System::SystemTask::Messages::EnableSleeping); + systemTask.PushMessage(System::Messages::EnableSleeping); lv_obj_clean(lv_scr_act()); } @@ -151,12 +151,12 @@ void Metronome::OnEvent(lv_obj_t* obj, lv_event_t event) { switch (currentState) { case States::Stopped: { lv_label_set_text(playPauseLabel, Symbols::play); - systemTask.PushMessage(Pinetime::System::SystemTask::Messages::EnableSleeping); + systemTask.PushMessage(System::Messages::EnableSleeping); break; } case States::Running: { lv_label_set_text(playPauseLabel, Symbols::pause); - systemTask.PushMessage(Pinetime::System::SystemTask::Messages::DisableSleeping); + systemTask.PushMessage(System::Messages::DisableSleeping); startTime = xTaskGetTickCount(); counter = 1; break; -- cgit v1.2.3 From dbc2d234058226c42b79e35cb8f6576ac3bf709f Mon Sep 17 00:00:00 2001 From: Jean-François Milants Date: Sat, 12 Jun 2021 18:00:42 +0200 Subject: Add Init() in DummyuLittleVgl to fix recovery firmware --- src/displayapp/DummyLittleVgl.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/displayapp') diff --git a/src/displayapp/DummyLittleVgl.h b/src/displayapp/DummyLittleVgl.h index 96cf153f..016165b8 100644 --- a/src/displayapp/DummyLittleVgl.h +++ b/src/displayapp/DummyLittleVgl.h @@ -19,6 +19,10 @@ 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) { -- cgit v1.2.3