diff options
| author | Riku Isokoski <riksu9000@gmail.com> | 2021-08-01 08:47:26 (GMT) |
|---|---|---|
| committer | Riku Isokoski <riksu9000@gmail.com> | 2021-08-01 08:47:26 (GMT) |
| commit | 5bdef365f2b8f8e0ba06d04216749205a5bba50d (patch) | |
| tree | b0260cd863c37ca1cee57fd813647706e2d07f77 /src/displayapp/DisplayApp.cpp | |
| parent | 9e8dd9a1e63523f4e3ed322978e5b5e079c50375 (diff) | |
| parent | 514481ef7f9c71ad816b31d979c6ab39ce9380dd (diff) | |
Merge branch 'develop' into HEAD
Diffstat (limited to 'src/displayapp/DisplayApp.cpp')
| -rw-r--r-- | src/displayapp/DisplayApp.cpp | 193 |
1 files changed, 130 insertions, 63 deletions
diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 731f3d0..bdd703e 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -2,6 +2,7 @@ #include <libraries/log/nrf_log.h> #include <displayapp/screens/HeartRate.h> #include <displayapp/screens/Motion.h> +#include <displayapp/screens/Timer.h> #include "components/battery/BatteryController.h" #include "components/ble/BleController.h" #include "components/datetime/DateTimeController.h" @@ -17,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" @@ -31,6 +33,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" @@ -40,9 +43,42 @@ #include "displayapp/screens/settings/SettingDisplay.h" #include "displayapp/screens/settings/SettingSteps.h" +#include "libs/lv_conf.h" + using namespace Pinetime::Applications; using namespace Pinetime::Applications::Display; +namespace { + static inline bool in_isr(void) { + return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0; + } + + TouchEvents Convert(Pinetime::Drivers::Cst816S::TouchInfos info) { + if (info.isTouch) { + switch (info.gesture) { + case Pinetime::Drivers::Cst816S::Gestures::SingleTap: + return TouchEvents::Tap; + case Pinetime::Drivers::Cst816S::Gestures::LongPress: + return TouchEvents::LongTap; + case Pinetime::Drivers::Cst816S::Gestures::DoubleTap: + return TouchEvents::DoubleTap; + case Pinetime::Drivers::Cst816S::Gestures::SlideRight: + return TouchEvents::SwipeRight; + case Pinetime::Drivers::Cst816S::Gestures::SlideLeft: + return TouchEvents::SwipeLeft; + case Pinetime::Drivers::Cst816S::Gestures::SlideDown: + return TouchEvents::SwipeDown; + case Pinetime::Drivers::Cst816S::Gestures::SlideUp: + return TouchEvents::SwipeUp; + case Pinetime::Drivers::Cst816S::Gestures::None: + default: + return TouchEvents::None; + } + } + return TouchEvents::None; + } +} + DisplayApp::DisplayApp(Drivers::St7789& lcd, Components::LittleVgl& lvgl, Drivers::Cst816S& touchPanel, @@ -50,12 +86,12 @@ 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, Pinetime::Controllers::MotorController& motorController, - Pinetime::Controllers::MotionController& motionController) + Pinetime::Controllers::MotionController& motionController, + Pinetime::Controllers::TimerController& timerController) : lcd {lcd}, lvgl {lvgl}, touchPanel {touchPanel}, @@ -63,18 +99,20 @@ DisplayApp::DisplayApp(Drivers::St7789& lcd, bleController {bleController}, dateTimeController {dateTimeController}, watchdog {watchdog}, - systemTask {systemTask}, notificationManager {notificationManager}, heartRateController {heartRateController}, settingsController {settingsController}, motorController {motorController}, - motionController {motionController} { + 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); } @@ -103,6 +141,7 @@ uint32_t count = 0; bool toggle = true; void DisplayApp::Refresh() { TickType_t queueTimeout; + TickType_t delta; switch (state) { case States::Idle: IdleState(); @@ -110,7 +149,11 @@ void DisplayApp::Refresh() { break; case States::Running: RunningState(); - queueTimeout = 20; + delta = xTaskGetTickCount() - lastWakeTime; + if (delta > LV_DISP_DEF_REFR_PERIOD) { + delta = LV_DISP_DEF_REFR_PERIOD; + } + queueTimeout = LV_DISP_DEF_REFR_PERIOD - delta; break; default: queueTimeout = portMAX_DELAY; @@ -118,16 +161,25 @@ void DisplayApp::Refresh() { } Messages msg; - if (xQueueReceive(msgQueue, &msg, queueTimeout)) { + bool messageReceived = xQueueReceive(msgQueue, &msg, queueTimeout); + lastWakeTime = xTaskGetTickCount(); + if (messageReceived) { switch (msg) { - case Messages::GoToSleep: + case Messages::DimScreen: + // Backup brightness is the brightness to return to after dimming or sleeping brightnessController.Backup(); + brightnessController.Set(Controllers::BrightnessController::Levels::Low); + break; + case Messages::RestoreBrightness: + brightnessController.Restore(); + break; + case Messages::GoToSleep: while (brightnessController.Level() != Controllers::BrightnessController::Levels::Off) { brightnessController.Lower(); vTaskDelay(100); } lcd.DisplayOff(); - systemTask.PushMessage(System::SystemTask::Messages::OnDisplayTaskSleeping); + PushMessageToSystemTask(Pinetime::System::Messages::OnDisplayTaskSleeping); state = States::Idle; break; case Messages::GoToRunning: @@ -136,7 +188,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 : @@ -148,10 +200,23 @@ void DisplayApp::Refresh() { case Messages::NewNotification: LoadApp(Apps::NotificationsPreview, DisplayApp::FullRefreshDirections::Down); break; + case Messages::TimerDone: + if (currentApp == Apps::Timer) { + auto* timer = static_cast<Screens::Timer*>(currentScreen.get()); + timer->setDone(); + } else { + LoadApp(Apps::Timer, DisplayApp::FullRefreshDirections::Down); + } + break; case Messages::TouchEvent: { - if (state != States::Running) + if (state != States::Running) { break; - auto gesture = OnTouchEvent(); + } + auto info = touchPanel.GetTouchInfo(); + auto gesture = Convert(info); + if (gesture == TouchEvents::None) { + break; + } if (!currentScreen->OnTouchEvent(gesture)) { if (currentApp == Apps::Clock) { switch (gesture) { @@ -165,22 +230,30 @@ 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; } } else if (returnTouchEvent == gesture) { LoadApp(returnToApp, returnDirection); + brightnessController.Set(settingsController.GetBrightness()); + brightnessController.Backup(); + } else if (touchMode == TouchModes::Gestures) { + if (gesture == TouchEvents::Tap) { + lvgl.SetNewTapEvent(info.x, info.y); + } } } } 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); + brightnessController.Set(settingsController.GetBrightness()); + brightnessController.Backup(); } } break; @@ -195,6 +268,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 @@ -213,7 +291,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) { @@ -252,18 +331,22 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) break; case Apps::FirmwareUpdate: currentScreen = std::make_unique<Screens::FirmwareUpdate>(this, bleController); + ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::None); break; case Apps::Notifications: currentScreen = std::make_unique<Screens::Notifications>( - this, notificationManager, systemTask.nimble().alertService(), motorController, Screens::Notifications::Modes::Normal); + this, notificationManager, systemTask->nimble().alertService(), motorController, Screens::Notifications::Modes::Normal); ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); break; case Apps::NotificationsPreview: currentScreen = std::make_unique<Screens::Notifications>( - this, notificationManager, systemTask.nimble().alertService(), motorController, Screens::Notifications::Modes::Preview); + this, notificationManager, systemTask->nimble().alertService(), motorController, Screens::Notifications::Modes::Preview); ReturnApp(Apps::Clock, FullRefreshDirections::Up, TouchEvents::SwipeUp); break; + case Apps::Timer: + currentScreen = std::make_unique<Screens::Timer>(this, timerController); + break; // Settings case Apps::QuickSettings: @@ -291,7 +374,7 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) currentScreen = std::make_unique<Screens::SettingDisplay>(this, settingsController); ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; - case Apps::SettingSteps: + case Apps::SettingSteps: currentScreen = std::make_unique<Screens::SettingSteps>(this, settingsController); ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; @@ -300,18 +383,16 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; case Apps::SysInfo: - currentScreen = - std::make_unique<Screens::SystemInfo>(this, dateTimeController, batteryController, brightnessController, bleController, watchdog); + currentScreen = std::make_unique<Screens::SystemInfo>( + this, dateTimeController, batteryController, brightnessController, bleController, watchdog, motionController); ReturnApp(Apps::Settings, FullRefreshDirections::Down, TouchEvents::SwipeDown); break; - // - case Apps::FlashLight: - currentScreen = std::make_unique<Screens::FlashLight>(this, systemTask, brightnessController); + currentScreen = std::make_unique<Screens::FlashLight>(this, *systemTask, brightnessController); ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::None); break; case Apps::StopWatch: - currentScreen = std::make_unique<Screens::StopWatch>(this); + currentScreen = std::make_unique<Screens::StopWatch>(this, *systemTask); break; case Apps::Twos: currentScreen = std::make_unique<Screens::Twos>(this); @@ -323,18 +404,21 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) currentScreen = std::make_unique<Screens::Paddle>(this, lvgl); break; case Apps::Music: - currentScreen = std::make_unique<Screens::Music>(this, systemTask.nimble().music()); + currentScreen = std::make_unique<Screens::Music>(this, systemTask->nimble().music()); break; case Apps::Navigation: - currentScreen = std::make_unique<Screens::Navigation>(this, systemTask.nimble().navigation()); + currentScreen = std::make_unique<Screens::Navigation>(this, systemTask->nimble().navigation()); break; case Apps::HeartRate: - currentScreen = std::make_unique<Screens::HeartRate>(this, heartRateController, systemTask); + currentScreen = std::make_unique<Screens::HeartRate>(this, heartRateController, *systemTask); + break; + case Apps::Metronome: + currentScreen = std::make_unique<Screens::Metronome>(this, motorController, *systemTask); break; case Apps::Motion: currentScreen = std::make_unique<Screens::Motion>(this, motionController); break; - case Apps::Steps: + case Apps::Steps: currentScreen = std::make_unique<Screens::Steps>(this, motionController, settingsController); break; } @@ -345,42 +429,16 @@ 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? - } -} - -TouchEvents DisplayApp::OnTouchEvent() { - auto info = touchPanel.GetTouchInfo(); - if (info.isTouch) { - switch (info.gesture) { - case Pinetime::Drivers::Cst816S::Gestures::SingleTap: - if (touchMode == TouchModes::Gestures) { - lvgl.SetNewTapEvent(info.x, info.y); - } - return TouchEvents::Tap; - case Pinetime::Drivers::Cst816S::Gestures::LongPress: - return TouchEvents::LongTap; - case Pinetime::Drivers::Cst816S::Gestures::DoubleTap: - return TouchEvents::DoubleTap; - case Pinetime::Drivers::Cst816S::Gestures::SlideRight: - return TouchEvents::SwipeRight; - case Pinetime::Drivers::Cst816S::Gestures::SlideLeft: - return TouchEvents::SwipeLeft; - case Pinetime::Drivers::Cst816S::Gestures::SlideDown: - return TouchEvents::SwipeDown; - case Pinetime::Drivers::Cst816S::Gestures::SlideUp: - return TouchEvents::SwipeUp; - case Pinetime::Drivers::Cst816S::Gestures::None: - default: - return TouchEvents::None; + if (in_isr()) { + BaseType_t xHigherPriorityTaskWoken; + xHigherPriorityTaskWoken = pdFALSE; + xQueueSendFromISR(msgQueue, &msg, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken) { + portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } + } else { + xQueueSend(msgQueue, &msg, portMAX_DELAY); } - return TouchEvents::None; } void DisplayApp::SetFullRefresh(DisplayApp::FullRefreshDirections direction) { @@ -411,3 +469,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; +} |
