InfiniTime.git

commit bbfc20c3ff4b741cd21b162389905a59a8e22f3f

Author: JF <jf@codingfield.com>

Add new screen that allows the user to manually validate the new firmware he's just OTA'ed.
Still need to find a way to display this screen when needed.

 src/CMakeLists.txt | 6 
 src/Components/FirmwareValidator/FirmwareValidator.cpp | 20 ++
 src/Components/FirmwareValidator/FirmwareValidator.h | 18 ++
 src/DisplayApp/DisplayApp.cpp | 1 
 src/DisplayApp/DisplayApp.h | 2 
 src/DisplayApp/Screens/FirmwareValidation.cpp | 91 ++++++++++++
 src/DisplayApp/Screens/FirmwareValidation.h | 42 +++++
 src/SystemTask/SystemTask.cpp | 8 -


diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2d6d6e8e5bdba88577c22ec6704c6d310e2b7e65..10c28189c83dda3ea6c9606e3c8c5dbeba75f7fb 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -337,6 +337,7 @@   DisplayApp/Screens/ScreenList.cpp
   DisplayApp/Screens/Label.cpp
   DisplayApp/Screens/FirmwareUpdate.cpp
   DisplayApp/Screens/Music.cpp
+  DisplayApp/Screens/FirmwareValidation.cpp
   main.cpp
   drivers/St7789.cpp
   drivers/SpiNorFlash.cpp
@@ -358,6 +359,7 @@   Components/Ble/DfuService.cpp
   Components/Ble/CurrentTimeService.cpp
   Components/Ble/AlertNotificationService.cpp
   Components/Ble/MusicService.cpp
+  Components/FirmwareValidator/FirmwareValidator.cpp
   drivers/Cst816s.cpp
   FreeRTOS/port.c
   FreeRTOS/port_cmsis_systick.c
@@ -415,6 +417,7 @@   DisplayApp/Screens/Brightness.h
   DisplayApp/Screens/ScreenList.h
   DisplayApp/Screens/Label.h
   DisplayApp/Screens/FirmwareUpdate.h
+  DisplayApp/Screens/FirmwareValidation.h
   drivers/St7789.h
   drivers/SpiNorFlash.h
   drivers/SpiMaster.h
@@ -432,7 +435,8 @@   Components/Ble/DeviceInformationService.h
   Components/Ble/CurrentTimeClient.h
   Components/Ble/AlertNotificationClient.h
   Components/Ble/DfuService.h
-    drivers/Cst816s.h
+  Components/FirmwareValidator/FirmwareValidator.h
+  drivers/Cst816s.h
   FreeRTOS/portmacro.h
   FreeRTOS/portmacro_cmsis.h
   libs/date/includes/date/tz.h




diff --git a/src/Components/FirmwareValidator/FirmwareValidator.cpp b/src/Components/FirmwareValidator/FirmwareValidator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..244d5c06bf704afdc9727e02a5248a82c4e381f9
--- /dev/null
+++ b/src/Components/FirmwareValidator/FirmwareValidator.cpp
@@ -0,0 +1,20 @@
+#include <drivers/InternalFlash.h>
+#include <hal/nrf_rtc.h>
+
+#include "FirmwareValidator.h"
+
+using namespace Pinetime::Controllers;
+
+bool FirmwareValidator::IsValidated() const {
+  auto* imageOkPtr = reinterpret_cast<uint32_t *>(validBitAdress);
+  return (*imageOkPtr) == validBitValue;
+}
+
+void FirmwareValidator::Validate() {
+  if(!IsValidated())
+    Pinetime::Drivers::InternalFlash::WriteWord(validBitAdress, validBitValue);
+}
+
+void FirmwareValidator::Reset() {
+  NVIC_SystemReset();
+}




diff --git a/src/Components/FirmwareValidator/FirmwareValidator.h b/src/Components/FirmwareValidator/FirmwareValidator.h
new file mode 100644
index 0000000000000000000000000000000000000000..aa576d8872157563227a112beab9401450a9444f
--- /dev/null
+++ b/src/Components/FirmwareValidator/FirmwareValidator.h
@@ -0,0 +1,18 @@
+#pragma once
+
+#include <cstdint>
+
+namespace Pinetime {
+  namespace Controllers {
+    class FirmwareValidator {
+      public:
+        void Validate();
+        bool IsValidated() const;
+
+        void Reset();
+      private:
+        static constexpr uint32_t validBitAdress {0x7BFE8};
+        static constexpr uint32_t validBitValue {1};
+    };
+  }
+}




diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp
index 46a9638565f065f1b994772d2455f8e055f623b8..a24688b151e8d9681d452773bd3c42e09eb4c285 100644
--- a/src/DisplayApp/DisplayApp.cpp
+++ b/src/DisplayApp/DisplayApp.cpp
@@ -18,6 +18,7 @@ #include 
 #include <DisplayApp/Screens/Music.h>
 #include <Components/Ble/NotificationManager.h>
 #include <DisplayApp/Screens/FirmwareUpdate.h>
+#include <DisplayApp/Screens/FirmwareValidation.h>
 #include "../SystemTask/SystemTask.h"
 
 using namespace Pinetime::Applications;




diff --git a/src/DisplayApp/DisplayApp.h b/src/DisplayApp/DisplayApp.h
index 23f04937b635d1e47d8feb3e3a729a8c8824cbfa..6af9cf2252a3b7fa24d25cad1a37f2aff9a5e7b8 100644
--- a/src/DisplayApp/DisplayApp.h
+++ b/src/DisplayApp/DisplayApp.h
@@ -17,6 +17,7 @@ #include 
 #include <drivers/Watchdog.h>
 #include <DisplayApp/Screens/Modal.h>
 #include <Components/Ble/NotificationManager.h>
+#include <Components/FirmwareValidator/FirmwareValidator.h>
 #include "TouchEvents.h"
 
 
@@ -80,6 +81,7 @@         bool onClockApp = false; // TODO find a better way to know that we should handle gestures and button differently for the Clock app.
         Controllers::BrightnessController brightnessController;
         std::unique_ptr<Screens::Modal> modal;
         Pinetime::Controllers::NotificationManager& notificationManager;
+        Pinetime::Controllers::FirmwareValidator validator;
     };
   }
 }




diff --git a/src/DisplayApp/Screens/FirmwareValidation.cpp b/src/DisplayApp/Screens/FirmwareValidation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..70d325755af6e4323cee5aab1321c049501dfd03
--- /dev/null
+++ b/src/DisplayApp/Screens/FirmwareValidation.cpp
@@ -0,0 +1,91 @@
+#include <libs/lvgl/lvgl.h>
+#include "FirmwareValidation.h"
+#include "../DisplayApp.h"
+#include "../../Version.h"
+#include "../../Components/FirmwareValidator/FirmwareValidator.h"
+
+using namespace Pinetime::Applications::Screens;
+extern lv_font_t jetbrains_mono_extrabold_compressed;
+extern lv_font_t jetbrains_mono_bold_20;
+
+namespace {
+  static void ButtonEventHandler(lv_obj_t * obj, lv_event_t event)
+  {
+    FirmwareValidation* screen = static_cast<FirmwareValidation *>(obj->user_data);
+    screen->OnButtonEvent(obj, event);
+  }
+
+}
+
+FirmwareValidation::FirmwareValidation(Pinetime::Applications::DisplayApp *app,
+                                       Pinetime::Controllers::FirmwareValidator &validator)
+                                       : Screen{app}, validator{validator} {
+  labelVersionInfo = lv_label_create(lv_scr_act(), NULL);
+  lv_obj_align(labelVersionInfo, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0);
+  lv_label_set_text(labelVersionInfo, "Version : ");
+  lv_label_set_align(labelVersionInfo, LV_LABEL_ALIGN_LEFT);
+
+
+  labelVersionValue = lv_label_create(lv_scr_act(), NULL);
+  lv_obj_align(labelVersionValue, labelVersionInfo, LV_ALIGN_OUT_RIGHT_MID, 0, 0);
+  lv_label_set_recolor(labelVersionValue, true);
+  sprintf(version, "%d.%d.%d", Version::Major(), Version::Minor(), Version::Patch());
+  lv_label_set_text(labelVersionValue, version);
+
+  labelIsValidated = lv_label_create(lv_scr_act(), NULL);
+  lv_obj_align(labelIsValidated, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 50);
+  lv_label_set_recolor(labelIsValidated, true);
+  lv_label_set_long_mode(labelIsValidated, LV_LABEL_LONG_BREAK);
+  lv_obj_set_width(labelIsValidated, 240);
+
+  if(validator.IsValidated())
+    lv_label_set_text(labelIsValidated, "You have already\n#00ff00 validated# this firmware#");
+  else {
+    lv_label_set_text(labelIsValidated,
+                      "Please #00ff00 Validate# this version or\n#ff0000 Reset# to rollback to the previous version.");
+
+    buttonValidate = lv_btn_create(lv_scr_act(), NULL);
+    lv_obj_align(buttonValidate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, 0);
+    buttonValidate->user_data = this;
+    lv_obj_set_event_cb(buttonValidate, ButtonEventHandler);
+
+    labelButtonValidate = lv_label_create(buttonValidate, NULL);
+    lv_label_set_recolor(labelButtonValidate, true);
+    lv_label_set_text(labelButtonValidate, "#00ff00 Validate#");
+
+    buttonReset = lv_btn_create(lv_scr_act(), NULL);
+    buttonReset->user_data = this;
+    lv_obj_align(buttonReset, NULL, LV_ALIGN_IN_BOTTOM_RIGHT, 0, 0);
+    lv_obj_set_event_cb(buttonReset, ButtonEventHandler);
+
+    labelButtonReset = lv_label_create(buttonReset, NULL);
+    lv_label_set_recolor(labelButtonReset, true);
+    lv_label_set_text(labelButtonReset, "#ff0000 Reset#");
+  }
+}
+
+
+FirmwareValidation::~FirmwareValidation() {
+  lv_obj_clean(lv_scr_act());
+}
+
+bool FirmwareValidation::Refresh() {
+  return running;
+}
+
+bool FirmwareValidation::OnButtonPushed() {
+  running = false;
+  return true;
+}
+
+void FirmwareValidation::OnButtonEvent(lv_obj_t *object, lv_event_t event) {
+  if(object == buttonValidate && event == LV_EVENT_PRESSED) {
+    validator.Validate();
+    running  = false;
+  } else if(object == buttonReset && event == LV_EVENT_PRESSED) {
+    validator.Reset();
+  }
+
+}
+
+




diff --git a/src/DisplayApp/Screens/FirmwareValidation.h b/src/DisplayApp/Screens/FirmwareValidation.h
new file mode 100644
index 0000000000000000000000000000000000000000..947f5575ba0fa5a4eed356e7c26781b1d9049dda
--- /dev/null
+++ b/src/DisplayApp/Screens/FirmwareValidation.h
@@ -0,0 +1,42 @@
+#pragma once
+
+#include <cstdint>
+#include "Screen.h"
+#include <bits/unique_ptr.h>
+#include <libs/lvgl/src/lv_core/lv_style.h>
+#include <libs/lvgl/src/lv_core/lv_obj.h>
+
+namespace Pinetime {
+  namespace Controllers {
+    class FirmwareValidator;
+  }
+
+  namespace Applications {
+    namespace Screens {
+
+      class FirmwareValidation : public Screen{
+        public:
+          FirmwareValidation(DisplayApp* app, Pinetime::Controllers::FirmwareValidator& validator);
+          ~FirmwareValidation() override;
+
+          bool Refresh() override;
+          bool OnButtonPushed() override;
+
+          void OnButtonEvent(lv_obj_t *object, lv_event_t event);
+
+        private:
+          Pinetime::Controllers::FirmwareValidator& validator;
+
+          lv_obj_t* labelVersionInfo;
+          lv_obj_t* labelVersionValue;
+          char version[9];
+          lv_obj_t* labelIsValidated;
+          lv_obj_t* buttonValidate;
+          lv_obj_t* labelButtonValidate;
+          lv_obj_t* buttonReset;
+          lv_obj_t* labelButtonReset;
+          bool running = true;
+      };
+    }
+  }
+}




diff --git a/src/SystemTask/SystemTask.cpp b/src/SystemTask/SystemTask.cpp
index 9f57f6f6356b0d14a99dadd076f6454a7e15ba40..d4b78187d959ee03a28e4862297b0669e3e0c89a 100644
--- a/src/SystemTask/SystemTask.cpp
+++ b/src/SystemTask/SystemTask.cpp
@@ -58,14 +58,6 @@   APP_GPIOTE_INIT(2);
 
   spi.Init();
   spiNorFlash.Init();
-
-  // Write the 'image OK' flag if it's not already done
-  // TODO implement a better verification mecanism for the image (ask for user confirmation via UI/BLE ?)
-  uint32_t* imageOkPtr = reinterpret_cast<uint32_t *>(0x7BFE8);
-  uint32_t imageOk = *imageOkPtr;
-  if(imageOk != 1)
-    Pinetime::Drivers::InternalFlash::WriteWord(0x7BFE8, 1);
-
   nimbleController.Init();
   nimbleController.StartAdvertising();
   lcd.Init();