Author: Avamander <avamander@gmail.com>
Renamed SystemTask/ to systemtask/
src/CMakeLists.txt | 6 +++--- | 0 | 10 +++++----- | 0
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f53663140a59101dc60999f7624dda652cf8eada..2026471c5d8a092e1d1ba0f6fe5eab7cb1b93cca 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -374,7 +374,7 @@ DisplayApp/LittleVgl.cpp DisplayApp/Fonts/jetbrains_mono_extrabold_compressed.c DisplayApp/Fonts/jetbrains_mono_bold_20.c - SystemTask/SystemTask.cpp + systemtask/SystemTask.cpp drivers/TwiMaster.cpp ) @@ -451,8 +451,8 @@ libs/date/includes/date/julian.h libs/date/includes/date/ptz.h libs/date/includes/date/tz_private.h DisplayApp/LittleVgl.h - SystemTask/SystemTask.h - SystemTask/SystemMonitor.h + systemtask/SystemTask.h + systemtask/SystemMonitor.h DisplayApp/Screens/Symbols.h drivers/TwiMaster.h ) diff --git a/src/SystemTask/SystemMonitor.h b/src/SystemTask/SystemMonitor.h deleted file mode 100644 index ec1fd817a035ecf3f55cdac3b02ecff686431f82..0000000000000000000000000000000000000000 --- a/src/SystemTask/SystemMonitor.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once -#include <FreeRTOS.h> -#include <task.h> -#include <nrf_log.h> - - -namespace Pinetime { - namespace System { - struct DummyMonitor {}; - struct FreeRtosMonitor {}; - - template<class T> - class SystemMonitor { - public: - SystemMonitor() = delete; - }; - - template<> - class SystemMonitor<DummyMonitor> { - public: - void Process() const {} - }; - - template<> - class SystemMonitor<FreeRtosMonitor> { - public: - void Process() const { - if(xTaskGetTickCount() - lastTick > 10000) { - NRF_LOG_INFO("---------------------------------------\nFree heap : %d", xPortGetFreeHeapSize()); - auto nb = uxTaskGetSystemState(tasksStatus, 10, NULL); - for (uint32_t i = 0; i < nb; i++) { - NRF_LOG_INFO("Task [%s] - %d", tasksStatus[i].pcTaskName, tasksStatus[i].usStackHighWaterMark); - if (tasksStatus[i].usStackHighWaterMark < 20) - NRF_LOG_INFO("WARNING!!! Task %s task is nearly full, only %dB available", tasksStatus[i].pcTaskName, - tasksStatus[i].usStackHighWaterMark * 4); - } - lastTick = xTaskGetTickCount(); - } - } - - private: - mutable TickType_t lastTick = 0; - mutable TaskStatus_t tasksStatus[10]; - }; - } -} \ No newline at end of file diff --git a/src/SystemTask/SystemTask.cpp b/src/SystemTask/SystemTask.cpp deleted file mode 100644 index 2070282b82b6b7cda08f3c5ce240164c0f3079ef..0000000000000000000000000000000000000000 --- a/src/SystemTask/SystemTask.cpp +++ /dev/null @@ -1,247 +0,0 @@ -#include <libraries/log/nrf_log.h> -#include <libraries/gpiote/app_gpiote.h> -#include <drivers/Cst816s.h> -#include <DisplayApp/LittleVgl.h> -#include <hal/nrf_rtc.h> -#include <Components/Ble/NotificationManager.h> -#include <host/ble_gatt.h> -#include <host/ble_hs_adv.h> -#include "SystemTask.h" -#include <nimble/hci_common.h> -#include <host/ble_gap.h> -#include <host/util/util.h> -#include <drivers/InternalFlash.h> -#include "../main.h" -#include "Components/Ble/NimbleController.h" - -using namespace Pinetime::System; - -void IdleTimerCallback(TimerHandle_t xTimer) { - - NRF_LOG_INFO("IdleTimerCallback"); - auto sysTask = static_cast<SystemTask *>(pvTimerGetTimerID(xTimer)); - sysTask->OnIdle(); -} - - -SystemTask::SystemTask(Drivers::SpiMaster &spi, Drivers::St7789 &lcd, - Pinetime::Drivers::SpiNorFlash& spiNorFlash, - Drivers::TwiMaster& twiMaster, Drivers::Cst816S &touchPanel, - Components::LittleVgl &lvgl, - Controllers::Battery &batteryController, Controllers::Ble &bleController, - Controllers::DateTime &dateTimeController, - Pinetime::Controllers::NotificationManager& notificationManager) : - spi{spi}, lcd{lcd}, spiNorFlash{spiNorFlash}, - twiMaster{twiMaster}, touchPanel{touchPanel}, lvgl{lvgl}, batteryController{batteryController}, - bleController{bleController}, dateTimeController{dateTimeController}, - watchdog{}, watchdogView{watchdog}, notificationManager{notificationManager}, - nimbleController(*this, bleController,dateTimeController, notificationManager, batteryController, spiNorFlash) { - systemTaksMsgQueue = xQueueCreate(10, 1); -} - -void SystemTask::Start() { - if (pdPASS != xTaskCreate(SystemTask::Process, "MAIN", 350, this, 0, &taskHandle)) - APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); -} - -void SystemTask::Process(void *instance) { - auto *app = static_cast<SystemTask *>(instance); - NRF_LOG_INFO("SystemTask task started!"); - app->Work(); -} - -void SystemTask::Work() { - watchdog.Setup(7); - watchdog.Start(); - NRF_LOG_INFO("Last reset reason : %s", Pinetime::Drivers::Watchdog::ResetReasonToString(watchdog.ResetReason())); - APP_GPIOTE_INIT(2); - - spi.Init(); - spiNorFlash.Init(); - spiNorFlash.Wakeup(); - nimbleController.Init(); - nimbleController.StartAdvertising(); - lcd.Init(); - - twiMaster.Init(); - touchPanel.Init(); - batteryController.Init(); - - displayApp.reset(new Pinetime::Applications::DisplayApp(lcd, lvgl, touchPanel, batteryController, bleController, - dateTimeController, watchdogView, *this, notificationManager)); - displayApp->Start(); - - batteryController.Update(); - displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateBatteryLevel); - - 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); - - nrfx_gpiote_in_config_t pinConfig; - pinConfig.skip_gpio_setup = true; - pinConfig.hi_accuracy = false; - pinConfig.is_watcher = false; - pinConfig.sense = (nrf_gpiote_polarity_t)NRF_GPIOTE_POLARITY_HITOLO; - pinConfig.pull = (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pulldown; - - nrfx_gpiote_in_init(pinButton, &pinConfig, nrfx_gpiote_evt_handler); - - nrf_gpio_cfg_sense_input(pinTouchIrq, (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup, (nrf_gpio_pin_sense_t)GPIO_PIN_CNF_SENSE_Low); - - pinConfig.skip_gpio_setup = true; - pinConfig.hi_accuracy = false; - pinConfig.is_watcher = false; - pinConfig.sense = (nrf_gpiote_polarity_t)NRF_GPIOTE_POLARITY_HITOLO; - pinConfig.pull = (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup; - - nrfx_gpiote_in_init(pinTouchIrq, &pinConfig, nrfx_gpiote_evt_handler); - - idleTimer = xTimerCreate ("idleTimer", idleTime, pdFALSE, this, IdleTimerCallback); - xTimerStart(idleTimer, 0); - - while(true) { - uint8_t msg; - if (xQueueReceive(systemTaksMsgQueue, &msg, isSleeping?2500 : 1000)) { - Messages message = static_cast<Messages >(msg); - switch(message) { - case Messages::GoToRunning: - spi.Wakeup(); - twiMaster.Wakeup(); - - spiNorFlash.Wakeup(); - lcd.Wakeup(); - touchPanel.Wakeup(); - - displayApp->PushMessage(Applications::DisplayApp::Messages::GoToRunning); - displayApp->PushMessage(Applications::DisplayApp::Messages::UpdateBatteryLevel); - - xTimerStart(idleTimer, 0); - nimbleController.StartAdvertising(); - isSleeping = false; - isWakingUp = false; - break; - case Messages::GoToSleep: - isGoingToSleep = true; - NRF_LOG_INFO("[SystemTask] Going to sleep"); - xTimerStop(idleTimer, 0); - displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep); - break; - case Messages::OnNewTime: - ReloadIdleTimer(); - displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateDateTime); - break; - case Messages::OnNewNotification: - if(isSleeping && !isWakingUp) GoToRunning(); - displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::NewNotification); - break; - case Messages::BleConnected: - ReloadIdleTimer(); - isBleDiscoveryTimerRunning = true; - bleDiscoveryTimer = 5; - break; - case Messages::BleFirmwareUpdateStarted: - doNotGoToSleep = true; - if(isSleeping && !isWakingUp) GoToRunning(); - displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::BleFirmwareUpdateStarted); - break; - case Messages::BleFirmwareUpdateFinished: - doNotGoToSleep = false; - xTimerStart(idleTimer, 0); - if(bleController.State() == Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated) - NVIC_SystemReset(); - break; - case Messages::OnTouchEvent: - ReloadIdleTimer(); - break; - case Messages::OnButtonEvent: - ReloadIdleTimer(); - break; - case Messages::OnDisplayTaskSleeping: - spiNorFlash.Sleep(); - lcd.Sleep(); - touchPanel.Sleep(); - - spi.Sleep(); - twiMaster.Sleep(); - isSleeping = true; - isGoingToSleep = false; - break; - default: break; - } - } - - if(isBleDiscoveryTimerRunning) { - if(bleDiscoveryTimer == 0) { - isBleDiscoveryTimerRunning = false; - // Services discovery is deffered from 3 seconds to avoid the conflicts between the host communicating with the - // tharget and vice-versa. I'm not sure if this is the right way to handle this... - nimbleController.StartDiscovery(); - } else { - bleDiscoveryTimer--; - } - } - - uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG); - dateTimeController.UpdateTime(systick_counter); - batteryController.Update(); - - monitor.Process(); - - if(!nrf_gpio_pin_read(pinButton)) - watchdog.Kick(); - } -} - -void SystemTask::OnButtonPushed() { - if(isGoingToSleep) return; - if(!isSleeping) { - NRF_LOG_INFO("[SystemTask] Button pushed"); - PushMessage(Messages::OnButtonEvent); - displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::ButtonPushed); - } - else { - if(!isWakingUp) { - NRF_LOG_INFO("[SystemTask] Button pushed, waking up"); - GoToRunning(); - } - } -} - -void SystemTask::GoToRunning() { - 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::DisplayApp::Messages::TouchEvent); - } -} - -void SystemTask::PushMessage(SystemTask::Messages msg) { - if(msg == Messages::GoToSleep) { - isGoingToSleep = true; - } - BaseType_t xHigherPriorityTaskWoken; - xHigherPriorityTaskWoken = pdFALSE; - xQueueSendFromISR(systemTaksMsgQueue, &msg, &xHigherPriorityTaskWoken); - if (xHigherPriorityTaskWoken) { - /* Actual macro used here is port specific. */ - // TODO : should I do something here? - } -} - -void SystemTask::OnIdle() { - if(doNotGoToSleep) return; - NRF_LOG_INFO("Idle timeout -> Going to sleep") - PushMessage(Messages::GoToSleep); -} - -void SystemTask::ReloadIdleTimer() const { - if(isSleeping || isGoingToSleep) return; - xTimerReset(idleTimer, 0); -} diff --git a/src/SystemTask/SystemTask.h b/src/SystemTask/SystemTask.h deleted file mode 100644 index 40277cf30694dc3da8db75338416bfff5b000f46..0000000000000000000000000000000000000000 --- a/src/SystemTask/SystemTask.h +++ /dev/null @@ -1,92 +0,0 @@ -#pragma once - -#include <FreeRTOS.h> -#include <task.h> -#include <memory> -#include <drivers/SpiMaster.h> -#include <drivers/St7789.h> -#include <Components/Battery/BatteryController.h> -#include <DisplayApp/DisplayApp.h> -#include <drivers/Watchdog.h> -#include <drivers/SpiNorFlash.h> -#include "SystemMonitor.h" -#include "Components/Ble/NimbleController.h" -#include "timers.h" - -namespace Pinetime { - namespace System { - class SystemTask { - public: - enum class Messages {GoToSleep, GoToRunning, OnNewTime, OnNewNotification, BleConnected, - BleFirmwareUpdateStarted, BleFirmwareUpdateFinished, OnTouchEvent, OnButtonEvent, OnDisplayTaskSleeping - }; - - SystemTask(Drivers::SpiMaster &spi, Drivers::St7789 &lcd, - Pinetime::Drivers::SpiNorFlash& spiNorFlash, - Drivers::TwiMaster& twiMaster, Drivers::Cst816S &touchPanel, - Components::LittleVgl &lvgl, - Controllers::Battery &batteryController, Controllers::Ble &bleController, - Controllers::DateTime &dateTimeController, - Pinetime::Controllers::NotificationManager& manager); - - - void Start(); - void PushMessage(Messages msg); - - void OnButtonPushed(); - void OnTouchEvent(); - - void OnIdle(); - - Pinetime::Controllers::NimbleController& nimble() {return nimbleController;}; - - private: - TaskHandle_t taskHandle; - - Pinetime::Drivers::SpiMaster& spi; - Pinetime::Drivers::St7789& lcd; - Pinetime::Drivers::SpiNorFlash& spiNorFlash; - Pinetime::Drivers::TwiMaster& twiMaster; - Pinetime::Drivers::Cst816S& touchPanel; - Pinetime::Components::LittleVgl& lvgl; - Pinetime::Controllers::Battery& batteryController; - std::unique_ptr<Pinetime::Applications::DisplayApp> displayApp; - Pinetime::Controllers::Ble& bleController; - Pinetime::Controllers::DateTime& dateTimeController; - QueueHandle_t systemTaksMsgQueue; - std::atomic<bool> isSleeping{false}; - std::atomic<bool> isGoingToSleep{false}; - std::atomic<bool> isWakingUp{false}; - Pinetime::Drivers::Watchdog watchdog; - Pinetime::Drivers::WatchdogView watchdogView; - Pinetime::Controllers::NotificationManager& notificationManager; - Pinetime::Controllers::NimbleController nimbleController; - - - static constexpr uint8_t pinSpiSck = 2; - static constexpr uint8_t pinSpiMosi = 3; - static constexpr uint8_t pinSpiMiso = 4; - static constexpr uint8_t pinSpiCsn = 25; - static constexpr uint8_t pinLcdDataCommand = 18; - static constexpr uint8_t pinButton = 13; - static constexpr uint8_t pinTouchIrq = 28; - - static void Process(void* instance); - void Work(); - void ReloadIdleTimer() const; - bool isBleDiscoveryTimerRunning = false; - uint8_t bleDiscoveryTimer = 0; - static constexpr uint32_t idleTime = 15000; - TimerHandle_t idleTimer; - bool doNotGoToSleep = false; - - void GoToRunning(); - -#if configUSE_TRACE_FACILITY == 1 - SystemMonitor<FreeRtosMonitor> monitor; -#else - SystemMonitor<DummyMonitor> monitor; -#endif - }; - } -} diff --git a/src/systemtask/SystemMonitor.h b/src/systemtask/SystemMonitor.h new file mode 100644 index 0000000000000000000000000000000000000000..ec1fd817a035ecf3f55cdac3b02ecff686431f82 --- /dev/null +++ b/src/systemtask/SystemMonitor.h @@ -0,0 +1,46 @@ +#pragma once +#include <FreeRTOS.h> +#include <task.h> +#include <nrf_log.h> + + +namespace Pinetime { + namespace System { + struct DummyMonitor {}; + struct FreeRtosMonitor {}; + + template<class T> + class SystemMonitor { + public: + SystemMonitor() = delete; + }; + + template<> + class SystemMonitor<DummyMonitor> { + public: + void Process() const {} + }; + + template<> + class SystemMonitor<FreeRtosMonitor> { + public: + void Process() const { + if(xTaskGetTickCount() - lastTick > 10000) { + NRF_LOG_INFO("---------------------------------------\nFree heap : %d", xPortGetFreeHeapSize()); + auto nb = uxTaskGetSystemState(tasksStatus, 10, NULL); + for (uint32_t i = 0; i < nb; i++) { + NRF_LOG_INFO("Task [%s] - %d", tasksStatus[i].pcTaskName, tasksStatus[i].usStackHighWaterMark); + if (tasksStatus[i].usStackHighWaterMark < 20) + NRF_LOG_INFO("WARNING!!! Task %s task is nearly full, only %dB available", tasksStatus[i].pcTaskName, + tasksStatus[i].usStackHighWaterMark * 4); + } + lastTick = xTaskGetTickCount(); + } + } + + private: + mutable TickType_t lastTick = 0; + mutable TaskStatus_t tasksStatus[10]; + }; + } +} \ No newline at end of file diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp new file mode 100644 index 0000000000000000000000000000000000000000..24f688e2d9828e057ce245b41c214fe0f2504e32 --- /dev/null +++ b/src/systemtask/SystemTask.cpp @@ -0,0 +1,247 @@ +#include <libraries/log/nrf_log.h> +#include <libraries/gpiote/app_gpiote.h> +#include <drivers/Cst816s.h> +#include <DisplayApp/LittleVgl.h> +#include <hal/nrf_rtc.h> +#include <Components/Ble/NotificationManager.h> +#include <host/ble_gatt.h> +#include <host/ble_hs_adv.h> +#include "SystemTask.h" +#include <nimble/hci_common.h> +#include <host/ble_gap.h> +#include <host/util/util.h> +#include <drivers/InternalFlash.h> +#include "../main.h" +#include "Components/Ble/NimbleController.h" + +using namespace Pinetime::System; + +void IdleTimerCallback(TimerHandle_t xTimer) { + + NRF_LOG_INFO("IdleTimerCallback"); + auto sysTask = static_cast<SystemTask *>(pvTimerGetTimerID(xTimer)); + sysTask->OnIdle(); +} + + +SystemTask::SystemTask(Drivers::SpiMaster &spi, Drivers::St7789 &lcd, + Pinetime::Drivers::SpiNorFlash& spiNorFlash, + Drivers::TwiMaster& twiMaster, Drivers::Cst816S &touchPanel, + Components::LittleVgl &lvgl, + Controllers::Battery &batteryController, Controllers::Ble &bleController, + Controllers::DateTime &dateTimeController, + Pinetime::Controllers::NotificationManager& notificationManager) : + spi{spi}, lcd{lcd}, spiNorFlash{spiNorFlash}, + twiMaster{twiMaster}, touchPanel{touchPanel}, lvgl{lvgl}, batteryController{batteryController}, + bleController{bleController}, dateTimeController{dateTimeController}, + watchdog{}, watchdogView{watchdog}, notificationManager{notificationManager}, + nimbleController(*this, bleController,dateTimeController, notificationManager, batteryController, spiNorFlash) { + systemTaksMsgQueue = xQueueCreate(10, 1); +} + +void SystemTask::Start() { + if (pdPASS != xTaskCreate(SystemTask::Process, "MAIN", 350, this, 0, &taskHandle)) + APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); +} + +void SystemTask::Process(void *instance) { + auto *app = static_cast<SystemTask *>(instance); + NRF_LOG_INFO("systemtask task started!"); + app->Work(); +} + +void SystemTask::Work() { + watchdog.Setup(7); + watchdog.Start(); + NRF_LOG_INFO("Last reset reason : %s", Pinetime::Drivers::Watchdog::ResetReasonToString(watchdog.ResetReason())); + APP_GPIOTE_INIT(2); + + spi.Init(); + spiNorFlash.Init(); + spiNorFlash.Wakeup(); + nimbleController.Init(); + nimbleController.StartAdvertising(); + lcd.Init(); + + twiMaster.Init(); + touchPanel.Init(); + batteryController.Init(); + + displayApp.reset(new Pinetime::Applications::DisplayApp(lcd, lvgl, touchPanel, batteryController, bleController, + dateTimeController, watchdogView, *this, notificationManager)); + displayApp->Start(); + + batteryController.Update(); + displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateBatteryLevel); + + 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); + + nrfx_gpiote_in_config_t pinConfig; + pinConfig.skip_gpio_setup = true; + pinConfig.hi_accuracy = false; + pinConfig.is_watcher = false; + pinConfig.sense = (nrf_gpiote_polarity_t)NRF_GPIOTE_POLARITY_HITOLO; + pinConfig.pull = (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pulldown; + + nrfx_gpiote_in_init(pinButton, &pinConfig, nrfx_gpiote_evt_handler); + + nrf_gpio_cfg_sense_input(pinTouchIrq, (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup, (nrf_gpio_pin_sense_t)GPIO_PIN_CNF_SENSE_Low); + + pinConfig.skip_gpio_setup = true; + pinConfig.hi_accuracy = false; + pinConfig.is_watcher = false; + pinConfig.sense = (nrf_gpiote_polarity_t)NRF_GPIOTE_POLARITY_HITOLO; + pinConfig.pull = (nrf_gpio_pin_pull_t)GPIO_PIN_CNF_PULL_Pullup; + + nrfx_gpiote_in_init(pinTouchIrq, &pinConfig, nrfx_gpiote_evt_handler); + + idleTimer = xTimerCreate ("idleTimer", idleTime, pdFALSE, this, IdleTimerCallback); + xTimerStart(idleTimer, 0); + + while(true) { + uint8_t msg; + if (xQueueReceive(systemTaksMsgQueue, &msg, isSleeping?2500 : 1000)) { + Messages message = static_cast<Messages >(msg); + switch(message) { + case Messages::GoToRunning: + spi.Wakeup(); + twiMaster.Wakeup(); + + spiNorFlash.Wakeup(); + lcd.Wakeup(); + touchPanel.Wakeup(); + + displayApp->PushMessage(Applications::DisplayApp::Messages::GoToRunning); + displayApp->PushMessage(Applications::DisplayApp::Messages::UpdateBatteryLevel); + + xTimerStart(idleTimer, 0); + nimbleController.StartAdvertising(); + isSleeping = false; + isWakingUp = false; + break; + case Messages::GoToSleep: + isGoingToSleep = true; + NRF_LOG_INFO("[systemtask] Going to sleep"); + xTimerStop(idleTimer, 0); + displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep); + break; + case Messages::OnNewTime: + ReloadIdleTimer(); + displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateDateTime); + break; + case Messages::OnNewNotification: + if(isSleeping && !isWakingUp) GoToRunning(); + displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::NewNotification); + break; + case Messages::BleConnected: + ReloadIdleTimer(); + isBleDiscoveryTimerRunning = true; + bleDiscoveryTimer = 5; + break; + case Messages::BleFirmwareUpdateStarted: + doNotGoToSleep = true; + if(isSleeping && !isWakingUp) GoToRunning(); + displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::BleFirmwareUpdateStarted); + break; + case Messages::BleFirmwareUpdateFinished: + doNotGoToSleep = false; + xTimerStart(idleTimer, 0); + if(bleController.State() == Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated) + NVIC_SystemReset(); + break; + case Messages::OnTouchEvent: + ReloadIdleTimer(); + break; + case Messages::OnButtonEvent: + ReloadIdleTimer(); + break; + case Messages::OnDisplayTaskSleeping: + spiNorFlash.Sleep(); + lcd.Sleep(); + touchPanel.Sleep(); + + spi.Sleep(); + twiMaster.Sleep(); + isSleeping = true; + isGoingToSleep = false; + break; + default: break; + } + } + + if(isBleDiscoveryTimerRunning) { + if(bleDiscoveryTimer == 0) { + isBleDiscoveryTimerRunning = false; + // Services discovery is deffered from 3 seconds to avoid the conflicts between the host communicating with the + // tharget and vice-versa. I'm not sure if this is the right way to handle this... + nimbleController.StartDiscovery(); + } else { + bleDiscoveryTimer--; + } + } + + uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG); + dateTimeController.UpdateTime(systick_counter); + batteryController.Update(); + + monitor.Process(); + + if(!nrf_gpio_pin_read(pinButton)) + watchdog.Kick(); + } +} + +void SystemTask::OnButtonPushed() { + if(isGoingToSleep) return; + if(!isSleeping) { + NRF_LOG_INFO("[systemtask] Button pushed"); + PushMessage(Messages::OnButtonEvent); + displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::ButtonPushed); + } + else { + if(!isWakingUp) { + NRF_LOG_INFO("[systemtask] Button pushed, waking up"); + GoToRunning(); + } + } +} + +void SystemTask::GoToRunning() { + 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::DisplayApp::Messages::TouchEvent); + } +} + +void SystemTask::PushMessage(SystemTask::Messages msg) { + if(msg == Messages::GoToSleep) { + isGoingToSleep = true; + } + BaseType_t xHigherPriorityTaskWoken; + xHigherPriorityTaskWoken = pdFALSE; + xQueueSendFromISR(systemTaksMsgQueue, &msg, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken) { + /* Actual macro used here is port specific. */ + // TODO : should I do something here? + } +} + +void SystemTask::OnIdle() { + if(doNotGoToSleep) return; + NRF_LOG_INFO("Idle timeout -> Going to sleep") + PushMessage(Messages::GoToSleep); +} + +void SystemTask::ReloadIdleTimer() const { + if(isSleeping || isGoingToSleep) return; + xTimerReset(idleTimer, 0); +} diff --git a/src/systemtask/SystemTask.h b/src/systemtask/SystemTask.h new file mode 100644 index 0000000000000000000000000000000000000000..40277cf30694dc3da8db75338416bfff5b000f46 --- /dev/null +++ b/src/systemtask/SystemTask.h @@ -0,0 +1,92 @@ +#pragma once + +#include <FreeRTOS.h> +#include <task.h> +#include <memory> +#include <drivers/SpiMaster.h> +#include <drivers/St7789.h> +#include <Components/Battery/BatteryController.h> +#include <DisplayApp/DisplayApp.h> +#include <drivers/Watchdog.h> +#include <drivers/SpiNorFlash.h> +#include "SystemMonitor.h" +#include "Components/Ble/NimbleController.h" +#include "timers.h" + +namespace Pinetime { + namespace System { + class SystemTask { + public: + enum class Messages {GoToSleep, GoToRunning, OnNewTime, OnNewNotification, BleConnected, + BleFirmwareUpdateStarted, BleFirmwareUpdateFinished, OnTouchEvent, OnButtonEvent, OnDisplayTaskSleeping + }; + + SystemTask(Drivers::SpiMaster &spi, Drivers::St7789 &lcd, + Pinetime::Drivers::SpiNorFlash& spiNorFlash, + Drivers::TwiMaster& twiMaster, Drivers::Cst816S &touchPanel, + Components::LittleVgl &lvgl, + Controllers::Battery &batteryController, Controllers::Ble &bleController, + Controllers::DateTime &dateTimeController, + Pinetime::Controllers::NotificationManager& manager); + + + void Start(); + void PushMessage(Messages msg); + + void OnButtonPushed(); + void OnTouchEvent(); + + void OnIdle(); + + Pinetime::Controllers::NimbleController& nimble() {return nimbleController;}; + + private: + TaskHandle_t taskHandle; + + Pinetime::Drivers::SpiMaster& spi; + Pinetime::Drivers::St7789& lcd; + Pinetime::Drivers::SpiNorFlash& spiNorFlash; + Pinetime::Drivers::TwiMaster& twiMaster; + Pinetime::Drivers::Cst816S& touchPanel; + Pinetime::Components::LittleVgl& lvgl; + Pinetime::Controllers::Battery& batteryController; + std::unique_ptr<Pinetime::Applications::DisplayApp> displayApp; + Pinetime::Controllers::Ble& bleController; + Pinetime::Controllers::DateTime& dateTimeController; + QueueHandle_t systemTaksMsgQueue; + std::atomic<bool> isSleeping{false}; + std::atomic<bool> isGoingToSleep{false}; + std::atomic<bool> isWakingUp{false}; + Pinetime::Drivers::Watchdog watchdog; + Pinetime::Drivers::WatchdogView watchdogView; + Pinetime::Controllers::NotificationManager& notificationManager; + Pinetime::Controllers::NimbleController nimbleController; + + + static constexpr uint8_t pinSpiSck = 2; + static constexpr uint8_t pinSpiMosi = 3; + static constexpr uint8_t pinSpiMiso = 4; + static constexpr uint8_t pinSpiCsn = 25; + static constexpr uint8_t pinLcdDataCommand = 18; + static constexpr uint8_t pinButton = 13; + static constexpr uint8_t pinTouchIrq = 28; + + static void Process(void* instance); + void Work(); + void ReloadIdleTimer() const; + bool isBleDiscoveryTimerRunning = false; + uint8_t bleDiscoveryTimer = 0; + static constexpr uint32_t idleTime = 15000; + TimerHandle_t idleTimer; + bool doNotGoToSleep = false; + + void GoToRunning(); + +#if configUSE_TRACE_FACILITY == 1 + SystemMonitor<FreeRtosMonitor> monitor; +#else + SystemMonitor<DummyMonitor> monitor; +#endif + }; + } +}