diff --git a/src/components/ble/DfuService.cpp b/src/components/ble/DfuService.cpp index e6bcea81..4179994d 100644 --- a/src/components/ble/DfuService.cpp +++ b/src/components/ble/DfuService.cpp @@ -266,13 +266,14 @@ int DfuService::ControlPointHandler(uint16_t connectionHandle, os_mbuf* om) { static_cast(ErrorCodes::NoError)}; notificationManager.AsyncSend(connectionHandle, controlPointCharacteristicHandle, data, 3); } else { - bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Error); NRF_LOG_INFO("Image Error : bad CRC"); uint8_t data[3] {static_cast(Opcodes::Response), static_cast(Opcodes::ValidateFirmware), static_cast(ErrorCodes::CrcError)}; notificationManager.AsyncSend(connectionHandle, controlPointCharacteristicHandle, data, 3); + bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Error); + Reset(); } return 0; @@ -283,10 +284,8 @@ int DfuService::ControlPointHandler(uint16_t connectionHandle, os_mbuf* om) { return 0; } NRF_LOG_INFO("[DFU] -> Activate image and reset!"); - bleController.StopFirmwareUpdate(); - systemTask.PushMessage(Pinetime::System::Messages::BleFirmwareUpdateFinished); - Reset(); bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated); + Reset(); return 0; default: return 0; @@ -294,6 +293,7 @@ int DfuService::ControlPointHandler(uint16_t connectionHandle, os_mbuf* om) { } void DfuService::OnTimeout() { + bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Error); Reset(); } @@ -307,7 +307,6 @@ void DfuService::Reset() { applicationSize = 0; expectedCrc = 0; notificationManager.Reset(); - bleController.State(Pinetime::Controllers::Ble::FirmwareUpdateStates::Error); bleController.StopFirmwareUpdate(); systemTask.PushMessage(Pinetime::System::Messages::BleFirmwareUpdateFinished); } diff --git a/src/displayapp/DisplayApp.cpp b/src/displayapp/DisplayApp.cpp index 071af0c8..4d32a7e5 100644 --- a/src/displayapp/DisplayApp.cpp +++ b/src/displayapp/DisplayApp.cpp @@ -177,9 +177,13 @@ void DisplayApp::Refresh() { } break; case Messages::TouchEvent: { - if (state != States::Running) + if (state != States::Running) { break; + } auto gesture = OnTouchEvent(); + if (gesture == TouchEvents::None) { + break; + } if (!currentScreen->OnTouchEvent(gesture)) { if (currentApp == Apps::Clock) { switch (gesture) { @@ -286,6 +290,7 @@ void DisplayApp::LoadApp(Apps app, DisplayApp::FullRefreshDirections direction) break; case Apps::FirmwareUpdate: currentScreen = std::make_unique(this, bleController); + ReturnApp(Apps::Clock, FullRefreshDirections::Down, TouchEvents::None); break; case Apps::Notifications: diff --git a/src/displayapp/screens/FirmwareUpdate.cpp b/src/displayapp/screens/FirmwareUpdate.cpp index 4086b152..edb2e49d 100644 --- a/src/displayapp/screens/FirmwareUpdate.cpp +++ b/src/displayapp/screens/FirmwareUpdate.cpp @@ -27,9 +27,10 @@ FirmwareUpdate::FirmwareUpdate(Pinetime::Applications::DisplayApp* app, Pinetime lv_bar_set_value(bar1, 0, LV_ANIM_OFF); percentLabel = lv_label_create(lv_scr_act(), nullptr); - lv_label_set_text(percentLabel, ""); + lv_label_set_text(percentLabel, "Waiting..."); lv_obj_set_auto_realign(percentLabel, true); lv_obj_align(percentLabel, bar1, LV_ALIGN_OUT_TOP_MID, 0, 60); + startTime = xTaskGetTickCount(); } FirmwareUpdate::~FirmwareUpdate() { @@ -40,26 +41,42 @@ bool FirmwareUpdate::Refresh() { switch (bleController.State()) { default: case Pinetime::Controllers::Ble::FirmwareUpdateStates::Idle: + // This condition makes sure that the app is exited if somehow it got + // launched without a firmware update. This should never happen. + if (state != States::Error) { + if (xTaskGetTickCount() - startTime > (60 * 1024)) { + UpdateError(); + state = States::Error; + } + } else if (xTaskGetTickCount() - startTime > (5 * 1024)) { + running = false; + } + break; case Pinetime::Controllers::Ble::FirmwareUpdateStates::Running: if (state != States::Running) state = States::Running; - return DisplayProgression(); + DisplayProgression(); + break; case Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated: if (state != States::Validated) { UpdateValidated(); state = States::Validated; } - return running; + break; case Pinetime::Controllers::Ble::FirmwareUpdateStates::Error: if (state != States::Error) { UpdateError(); state = States::Error; } - return running; + if (xTaskGetTickCount() - startTime > (5 * 1024)) { + running = false; + } + break; } + return running; } -bool FirmwareUpdate::DisplayProgression() const { +void FirmwareUpdate::DisplayProgression() const { float current = bleController.FirmwareUpdateCurrentBytes() / 1024.0f; float total = bleController.FirmwareUpdateTotalBytes() / 1024.0f; int16_t pc = (current / total) * 100.0f; @@ -67,7 +84,6 @@ bool FirmwareUpdate::DisplayProgression() const { lv_label_set_text(percentLabel, percentStr); lv_bar_set_value(bar1, pc, LV_ANIM_OFF); - return running; } void FirmwareUpdate::UpdateValidated() { @@ -78,4 +94,9 @@ void FirmwareUpdate::UpdateValidated() { void FirmwareUpdate::UpdateError() { lv_label_set_recolor(percentLabel, true); lv_label_set_text(percentLabel, "#ff0000 Error!#"); + startTime = xTaskGetTickCount(); +} + +bool FirmwareUpdate::OnButtonPushed() { + return true; } diff --git a/src/displayapp/screens/FirmwareUpdate.h b/src/displayapp/screens/FirmwareUpdate.h index f4d34df0..90c99f4c 100644 --- a/src/displayapp/screens/FirmwareUpdate.h +++ b/src/displayapp/screens/FirmwareUpdate.h @@ -2,6 +2,7 @@ #include "Screen.h" #include +#include "FreeRTOS.h" namespace Pinetime { namespace Controllers { @@ -25,13 +26,17 @@ namespace Pinetime { lv_obj_t* titleLabel; mutable char percentStr[10]; - States state; + States state = States::Idle; - bool DisplayProgression() const; + void DisplayProgression() const; + + bool OnButtonPushed() override; void UpdateValidated(); void UpdateError(); + + TickType_t startTime; }; } } diff --git a/src/systemtask/SystemTask.cpp b/src/systemtask/SystemTask.cpp index d8b965b1..7efd1d6b 100644 --- a/src/systemtask/SystemTask.cpp +++ b/src/systemtask/SystemTask.cpp @@ -198,7 +198,11 @@ void SystemTask::Work() { Messages message = static_cast(msg); switch (message) { case Messages::EnableSleeping: - doNotGoToSleep = false; + // Make sure that exiting an app doesn't enable sleeping, + // if the exiting was caused by a firmware update + if (!bleController.IsFirmwareUpdating()) { + doNotGoToSleep = false; + } break; case Messages::DisableSleeping: doNotGoToSleep = true; @@ -275,10 +279,11 @@ void SystemTask::Work() { displayApp.PushMessage(Pinetime::Applications::Display::Messages::BleFirmwareUpdateStarted); break; case Messages::BleFirmwareUpdateFinished: + if (bleController.State() == Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated) { + NVIC_SystemReset(); + } doNotGoToSleep = false; xTimerStart(idleTimer, 0); - if (bleController.State() == Pinetime::Controllers::Ble::FirmwareUpdateStates::Validated) - NVIC_SystemReset(); break; case Messages::OnTouchEvent: ReloadIdleTimer();