diff options
Diffstat (limited to 'src/systemtask/SystemTask.cpp')
| -rw-r--r-- | src/systemtask/SystemTask.cpp | 118 |
1 files changed, 101 insertions, 17 deletions
diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index 19a416b..3e315ee 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -23,6 +23,8 @@ #include "drivers/Hrs3300.h" #include "main.h" +#include <memory> + using namespace Pinetime::System; void IdleTimerCallback(TimerHandle_t xTimer) { @@ -38,16 +40,16 @@ SystemTask::SystemTask(Drivers::SpiMaster &spi, Drivers::St7789 &lcd, Drivers::TwiMaster& twiMaster, Drivers::Cst816S &touchPanel, Components::LittleVgl &lvgl, Controllers::Battery &batteryController, Controllers::Ble &bleController, - Controllers::DateTime &dateTimeController, Pinetime::Controllers::MotorController& motorController, Pinetime::Drivers::Hrs3300& heartRateSensor, + Pinetime::Drivers::Bma421& motionSensor, Controllers::Settings &settingsController) : spi{spi}, lcd{lcd}, spiNorFlash{spiNorFlash}, twiMaster{twiMaster}, touchPanel{touchPanel}, lvgl{lvgl}, batteryController{batteryController}, heartRateController{*this}, - bleController{bleController}, dateTimeController{dateTimeController}, + bleController{bleController}, dateTimeController{*this}, watchdog{}, watchdogView{watchdog}, - motorController{motorController}, heartRateSensor{heartRateSensor}, + motorController{motorController}, heartRateSensor{heartRateSensor}, motionSensor{motionSensor}, settingsController{settingsController}, nimbleController(*this, bleController,dateTimeController, notificationManager, batteryController, spiNorFlash, heartRateController) { systemTasksMsgQueue = xQueueCreate(10, 1); @@ -82,24 +84,27 @@ void SystemTask::Work() { touchPanel.Init(); batteryController.Init(); motorController.Init(); + motionSensor.SoftReset(); - settingsController.Init(); + // Reset the TWI device because the motion sensor chip most probably crashed it... + twiMaster.Sleep(); + twiMaster.Init(); + motionSensor.Init(); + settingsController.Init(); - displayApp.reset(new Pinetime::Applications::DisplayApp(lcd, lvgl, touchPanel, batteryController, bleController, + displayApp = std::make_unique<Pinetime::Applications::DisplayApp>(lcd, lvgl, touchPanel, batteryController, bleController, dateTimeController, watchdogView, *this, notificationManager, - heartRateController, settingsController)); + heartRateController, settingsController, motionController); displayApp->Start(); - batteryController.Update(); displayApp->PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel); heartRateSensor.Init(); heartRateSensor.Disable(); - heartRateApp.reset(new Pinetime::Applications::HeartRateTask(heartRateSensor, heartRateController)); + heartRateApp = std::make_unique<Pinetime::Applications::HeartRateTask>(heartRateSensor, heartRateController); 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); nrf_gpio_pin_set(15); @@ -123,26 +128,48 @@ void SystemTask::Work() { nrfx_gpiote_in_init(pinTouchIrq, &pinConfig, nrfx_gpiote_evt_handler); - idleTimer = xTimerCreate ("idleTimer", idleTime, pdFALSE, this, IdleTimerCallback); + idleTimer = xTimerCreate ("idleTimer", pdMS_TO_TICKS(settingsController.GetScreenTimeOut()), pdFALSE, this, IdleTimerCallback); xTimerStart(idleTimer, 0); // Suppress endless loop diagnostic #pragma clang diagnostic push #pragma ide diagnostic ignored "EndlessLoop" while(true) { + UpdateMotion(); + uint8_t msg; - if (xQueueReceive(systemTasksMsgQueue, &msg, isSleeping ? 2500 : 1000)) { + if (xQueueReceive(systemTasksMsgQueue, &msg, 100)) { + + // call the battery controller or use the MSG in DisplayApp to get the battery status ??? + // it is necessary to validate which is the most efficient batteryController.Update(); + //displayApp->PushMessage(Pinetime::Applications::Display::Messages::UpdateBatteryLevel); + // analyze a more efficient way to do this refreshment + // this and the UpdateMotion(); can be called on a timer to be independent of the main process ??? + Messages message = static_cast<Messages >(msg); switch(message) { + case Messages::EnableSleeping: + doNotGoToSleep = false; + break; + case Messages::DisableSleeping: + doNotGoToSleep = true; + break; + case Messages::UpdateTimeOut: + xTimerChangePeriod(idleTimer, pdMS_TO_TICKS(settingsController.GetScreenTimeOut()), 0); + break; case Messages::GoToRunning: spi.Wakeup(); twiMaster.Wakeup(); + // Double Tap needs the touch screen to be in normal mode + if ( settingsController.getWakeUpMode() != Pinetime::Controllers::Settings::WakeUpMode::DoubleTap ) { + touchPanel.Wakeup(); + } + nimbleController.StartAdvertising(); xTimerStart(idleTimer, 0); - spiNorFlash.Wakeup(); - touchPanel.Wakeup(); + spiNorFlash.Wakeup(); lcd.Wakeup(); displayApp->PushMessage(Pinetime::Applications::Display::Messages::GoToRunning); @@ -152,6 +179,23 @@ void SystemTask::Work() { isSleeping = false; isWakingUp = false; break; + case Messages::TouchWakeUp: { + twiMaster.Wakeup(); + auto touchInfo = touchPanel.GetTouchInfo(); + twiMaster.Sleep(); + if( touchInfo.isTouch and + ( + ( touchInfo.gesture == Pinetime::Drivers::Cst816S::Gestures::DoubleTap and + settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::DoubleTap + ) or + ( touchInfo.gesture == Pinetime::Drivers::Cst816S::Gestures::SingleTap and + settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::SingleTap + ) + ) + ) { + GoToRunning(); + } + } break; case Messages::GoToSleep: isGoingToSleep = true; NRF_LOG_INFO("[systemtask] Going to sleep"); @@ -165,7 +209,7 @@ void SystemTask::Work() { break; case Messages::OnNewNotification: if(isSleeping && !isWakingUp) GoToRunning(); - if(notificationManager.IsVibrationEnabled()) motorController.SetDuration(35); + motorController.SetDuration(35); displayApp->PushMessage(Pinetime::Applications::Display::Messages::NewNotification); break; case Messages::BleConnected: @@ -197,13 +241,22 @@ void SystemTask::Work() { spiNorFlash.Sleep(); } lcd.Sleep(); - touchPanel.Sleep(); - spi.Sleep(); + + // Double Tap needs the touch screen to be in normal mode + if ( settingsController.getWakeUpMode() != Pinetime::Controllers::Settings::WakeUpMode::DoubleTap ) { + touchPanel.Sleep(); + } twiMaster.Sleep(); + isSleeping = true; isGoingToSleep = false; break; + case Messages::OnNewDay: + // We might be sleeping (with TWI device disabled. + // Remember we'll have to reset the counter next time we're awake + stepCounterMustBeReset = true; + break; default: break; } } @@ -228,6 +281,33 @@ void SystemTask::Work() { // Clear diagnostic suppression #pragma clang diagnostic pop } +void SystemTask::UpdateMotion() { + if(isGoingToSleep or isWakingUp) return; + + if(isSleeping && settingsController.getWakeUpMode() != Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist) + return; + + if(isSleeping) + twiMaster.Wakeup(); + + if(stepCounterMustBeReset) { + motionSensor.ResetStepCounter(); + stepCounterMustBeReset = false; + } + + auto motionValues = motionSensor.Process(); + if(isSleeping) + twiMaster.Sleep(); + + motionController.IsSensorOk(motionSensor.IsOk()); + motionController.Update(motionValues.x, + motionValues.y, + motionValues.z, + motionValues.steps); + if (motionController.ShouldWakeUp(isSleeping)) { + GoToRunning(); + } +} void SystemTask::OnButtonPushed() { if(isGoingToSleep) return; @@ -245,16 +325,20 @@ void SystemTask::OnButtonPushed() { } void SystemTask::GoToRunning() { + if(isGoingToSleep or (not isSleeping) or isWakingUp) return; isWakingUp = true; PushMessage(Messages::GoToRunning); } void SystemTask::OnTouchEvent() { if(isGoingToSleep) return ; - NRF_LOG_INFO("[systemtask] Touch event"); if(!isSleeping) { PushMessage(Messages::OnTouchEvent); displayApp->PushMessage(Pinetime::Applications::Display::Messages::TouchEvent); + } else if(!isWakingUp) { + if( settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::None or + settingsController.getWakeUpMode() == Pinetime::Controllers::Settings::WakeUpMode::RaiseWrist ) return; + PushMessage(Messages::TouchWakeUp); } } |
