From 4d2aacf8639f565b822020cdb43c011e1a72dc7b Mon Sep 17 00:00:00 2001 From: JF Date: Sat, 14 Mar 2020 16:33:47 +0100 Subject: Display battery level and BLE connection status using icon on Clock screen. --- src/CMakeLists.txt | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'src/CMakeLists.txt') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index c93feb38..a957e104 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -163,6 +163,37 @@ set(LVGL_SRC ) +list(APPEND IMAGE_FILES + DisplayApp/Icons/battery/os_battery_error.c + + DisplayApp/Icons/battery/os_battery_100.c + DisplayApp/Icons/battery/os_battery_090.c + DisplayApp/Icons/battery/os_battery_080.c + DisplayApp/Icons/battery/os_battery_070.c + DisplayApp/Icons/battery/os_battery_060.c + DisplayApp/Icons/battery/os_battery_050.c + DisplayApp/Icons/battery/os_battery_040.c + DisplayApp/Icons/battery/os_battery_030.c + DisplayApp/Icons/battery/os_battery_020.c + DisplayApp/Icons/battery/os_battery_010.c + DisplayApp/Icons/battery/os_battery_005.c + + DisplayApp/Icons/battery/os_batterycharging_100.c + DisplayApp/Icons/battery/os_batterycharging_090.c + DisplayApp/Icons/battery/os_batterycharging_080.c + DisplayApp/Icons/battery/os_batterycharging_070.c + DisplayApp/Icons/battery/os_batterycharging_060.c + DisplayApp/Icons/battery/os_batterycharging_050.c + DisplayApp/Icons/battery/os_batterycharging_040.c + DisplayApp/Icons/battery/os_batterycharging_030.c + DisplayApp/Icons/battery/os_batterycharging_020.c + DisplayApp/Icons/battery/os_batterycharging_010.c + DisplayApp/Icons/battery/os_batterycharging_005.c + + DisplayApp/Icons/bluetooth/os_bt_connected.c + DisplayApp/Icons/bluetooth/os_bt_disconnected.c + ) + list(APPEND SOURCE_FILES Logging/NrfLogger.cpp BlinkApp/BlinkApp.cpp @@ -174,6 +205,9 @@ list(APPEND SOURCE_FILES DisplayApp/Screens/Meter.cpp DisplayApp/Screens/Gauge.cpp DisplayApp/Screens/Modal.cpp + DisplayApp/Screens/BatteryIcon.cpp + DisplayApp/Screens/BleIcon.cpp + main.cpp drivers/St7789.cpp drivers/SpiMaster.cpp @@ -188,6 +222,7 @@ list(APPEND SOURCE_FILES FreeRTOS/port_cmsis_systick.c FreeRTOS/port_cmsis.c ${LVGL_SRC} + ${IMAGE_FILES} DisplayApp/LittleVgl.cpp DisplayApp/Fonts/jetbrains_mono_extrabold_compressed.c @@ -208,6 +243,8 @@ set(INCLUDE_FILES DisplayApp/Screens/Meter.h DisplayApp/Screens/Gauge.h DisplayApp/Screens/Modal.h + DisplayApp/Screens/BatteryIcon.h + DisplayApp/Screens/BleIcon.cpp # DisplayApp/Screens/Tab.h drivers/St7789.h drivers/SpiMaster.h -- cgit v1.2.3-70-g09d2 From 2ed76ac55615a720dbcbf2ac828ad3060a252273 Mon Sep 17 00:00:00 2001 From: JF Date: Sun, 15 Mar 2020 18:03:11 +0100 Subject: Encapsulate brightness controll into the class BrightnessController. Add a new app to configure the brightness. --- src/CMakeLists.txt | 10 ++- src/Components/Brightness/BrightnessController.cpp | 70 +++++++++++++++++++++ src/Components/Brightness/BrightnessController.h | 28 +++++++++ src/DisplayApp/DisplayApp.cpp | 23 +++---- src/DisplayApp/DisplayApp.h | 7 +-- src/DisplayApp/Screens/Brightness.cpp | 72 ++++++++++++++++++++++ src/DisplayApp/Screens/Brightness.h | 31 ++++++++++ src/DisplayApp/Screens/Tile.cpp | 11 +++- src/DisplayApp/Screens/Tile.h | 1 + 9 files changed, 232 insertions(+), 21 deletions(-) create mode 100644 src/Components/Brightness/BrightnessController.cpp create mode 100644 src/Components/Brightness/BrightnessController.h create mode 100644 src/DisplayApp/Screens/Brightness.cpp create mode 100644 src/DisplayApp/Screens/Brightness.h (limited to 'src/CMakeLists.txt') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a957e104..670f0630 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -161,6 +161,11 @@ set(LVGL_SRC libs/lvgl/src/lv_objx/lv_mbox.c libs/lvgl/src/lv_objx/lv_mbox.h + libs/lvgl/src/lv_objx/lv_bar.c + libs/lvgl/src/lv_objx/lv_bar.h + libs/lvgl/src/lv_objx/lv_slider.h + libs/lvgl/src/lv_objx/lv_slider.c + ) list(APPEND IMAGE_FILES @@ -207,7 +212,7 @@ list(APPEND SOURCE_FILES DisplayApp/Screens/Modal.cpp DisplayApp/Screens/BatteryIcon.cpp DisplayApp/Screens/BleIcon.cpp - + DisplayApp/Screens/Brightness.cpp main.cpp drivers/St7789.cpp drivers/SpiMaster.cpp @@ -217,6 +222,7 @@ list(APPEND SOURCE_FILES Components/Battery/BatteryController.cpp Components/Ble/BleController.cpp Components/DateTime/DateTimeController.cpp + Components/Brightness/BrightnessController.cpp drivers/Cst816s.cpp FreeRTOS/port.c FreeRTOS/port_cmsis_systick.c @@ -245,6 +251,7 @@ set(INCLUDE_FILES DisplayApp/Screens/Modal.h DisplayApp/Screens/BatteryIcon.h DisplayApp/Screens/BleIcon.cpp + DisplayApp/Screens/Brightness.h # DisplayApp/Screens/Tab.h drivers/St7789.h drivers/SpiMaster.h @@ -254,6 +261,7 @@ set(INCLUDE_FILES Components/Battery/BatteryController.h Components/Ble/BleController.h Components/DateTime/DateTimeController.h + Components/Brightness/BrightnessController.h drivers/Cst816s.h FreeRTOS/portmacro.h FreeRTOS/portmacro_cmsis.h diff --git a/src/Components/Brightness/BrightnessController.cpp b/src/Components/Brightness/BrightnessController.cpp new file mode 100644 index 00000000..c8825d68 --- /dev/null +++ b/src/Components/Brightness/BrightnessController.cpp @@ -0,0 +1,70 @@ +#include +#include "BrightnessController.h" + +using namespace Pinetime::Controllers; + + +void BrightnessController::Init() { + nrf_gpio_cfg_output(pinLcdBacklight1); + nrf_gpio_cfg_output(pinLcdBacklight2); + nrf_gpio_cfg_output(pinLcdBacklight3); + Set(level); +} + +void BrightnessController::Set(BrightnessController::Levels level) { + this->level = level; + switch(level) { + default: + case Levels::High: + nrf_gpio_pin_clear(pinLcdBacklight1); + nrf_gpio_pin_clear(pinLcdBacklight2); + nrf_gpio_pin_clear(pinLcdBacklight3); + break; + case Levels::Medium: + nrf_gpio_pin_clear(pinLcdBacklight1); + nrf_gpio_pin_clear(pinLcdBacklight2); + nrf_gpio_pin_set(pinLcdBacklight3); + break; + case Levels::Low: + nrf_gpio_pin_clear(pinLcdBacklight1); + nrf_gpio_pin_set(pinLcdBacklight2); + nrf_gpio_pin_set(pinLcdBacklight3); + break; + case Levels::Off: + nrf_gpio_pin_set(pinLcdBacklight1); + nrf_gpio_pin_set(pinLcdBacklight2); + nrf_gpio_pin_set(pinLcdBacklight3); + break; + } +} + +void BrightnessController::Lower() { + switch(level) { + case Levels::High: Set(Levels::Medium); break; + case Levels::Medium: Set(Levels::Low); break; + case Levels::Low: Set(Levels::Off); break; + default: break; + } +} + +void BrightnessController::Higher() { + switch(level) { + case Levels::Off: Set(Levels::Low); break; + case Levels::Low: Set(Levels::Medium); break; + case Levels::Medium: Set(Levels::High); break; + default: break; + } +} + +BrightnessController::Levels BrightnessController::Level() const { + return level; +} + +void BrightnessController::Backup() { + backupLevel = level; +} + +void BrightnessController::Restore() { + Set(backupLevel); +} + diff --git a/src/Components/Brightness/BrightnessController.h b/src/Components/Brightness/BrightnessController.h new file mode 100644 index 00000000..b8354ec0 --- /dev/null +++ b/src/Components/Brightness/BrightnessController.h @@ -0,0 +1,28 @@ +#pragma once + +#include + +namespace Pinetime { + namespace Controllers { + class BrightnessController { + public: + enum class Levels {Off, Low, Medium, High}; + void Init(); + + void Set(Levels level); + Levels Level() const; + void Lower(); + void Higher(); + + void Backup(); + void Restore(); + + private: + static constexpr uint8_t pinLcdBacklight1 = 14; + static constexpr uint8_t pinLcdBacklight2 = 22; + static constexpr uint8_t pinLcdBacklight3 = 23; + Levels level = Levels::High; + Levels backupLevel = Levels::High; + }; + } +} diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp index 7464175e..3f58e4b3 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/DisplayApp/DisplayApp.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include "../SystemTask/SystemTask.h" using namespace Pinetime::Applications; @@ -57,12 +58,7 @@ void DisplayApp::Process(void *instance) { } void DisplayApp::InitHw() { - nrf_gpio_cfg_output(pinLcdBacklight1); - nrf_gpio_cfg_output(pinLcdBacklight2); - nrf_gpio_cfg_output(pinLcdBacklight3); - nrf_gpio_pin_clear(pinLcdBacklight1); - nrf_gpio_pin_clear(pinLcdBacklight2); - nrf_gpio_pin_clear(pinLcdBacklight3); + brightnessController.Init(); } uint32_t acc = 0; @@ -85,11 +81,11 @@ void DisplayApp::Refresh() { if (xQueueReceive(msgQueue, &msg, queueTimeout)) { switch (msg) { case Messages::GoToSleep: - nrf_gpio_pin_set(pinLcdBacklight3); - vTaskDelay(100); - nrf_gpio_pin_set(pinLcdBacklight2); - vTaskDelay(100); - nrf_gpio_pin_set(pinLcdBacklight1); + brightnessController.Backup(); + while(brightnessController.Level() != Controllers::BrightnessController::Levels::Off) { + brightnessController.Lower(); + vTaskDelay(100); + } lcd.DisplayOff(); lcd.Sleep(); touchPanel.Sleep(); @@ -100,9 +96,7 @@ void DisplayApp::Refresh() { touchPanel.Wakeup(); lcd.DisplayOn(); - nrf_gpio_pin_clear(pinLcdBacklight3); - nrf_gpio_pin_clear(pinLcdBacklight2); - nrf_gpio_pin_clear(pinLcdBacklight1); + brightnessController.Restore(); state = States::Running; break; case Messages::UpdateDateTime: @@ -174,6 +168,7 @@ void DisplayApp::RunningState() { case Apps::Test: currentScreen.reset(new Screens::Message(this)); break; case Apps::Meter: currentScreen.reset(new Screens::Meter(this)); break; case Apps::Gauge: currentScreen.reset(new Screens::Gauge(this)); break; + case Apps::Brightness : currentScreen.reset(new Screens::Brightness(this, brightnessController)); break; } nextApp = Apps::None; } diff --git a/src/DisplayApp/DisplayApp.h b/src/DisplayApp/DisplayApp.h index eaad1baa..ccbca4c3 100644 --- a/src/DisplayApp/DisplayApp.h +++ b/src/DisplayApp/DisplayApp.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include "Fonts/lcdfont14.h" @@ -37,7 +38,7 @@ namespace Pinetime { void Start(); void PushMessage(Messages msg); - enum class Apps {None, Launcher, Clock, Test, Meter, Gauge}; + enum class Apps {None, Launcher, Clock, Test, Meter, Gauge, Brightness}; void StartApp(Apps app); private: @@ -64,15 +65,13 @@ namespace Pinetime { TouchEvents OnTouchEvent(); std::unique_ptr currentScreen; - static constexpr uint8_t pinLcdBacklight1 = 14; - static constexpr uint8_t pinLcdBacklight2 = 22; - static constexpr uint8_t pinLcdBacklight3 = 23; bool isClock = true; Pinetime::System::SystemTask& systemTask; Apps nextApp = Apps::None; 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; }; } } diff --git a/src/DisplayApp/Screens/Brightness.cpp b/src/DisplayApp/Screens/Brightness.cpp new file mode 100644 index 00000000..a87a62a8 --- /dev/null +++ b/src/DisplayApp/Screens/Brightness.cpp @@ -0,0 +1,72 @@ +#include +#include "Brightness.h" + +using namespace Pinetime::Applications::Screens; + +void slider_event_cb(lv_obj_t * slider, lv_event_t event) { + if(event == LV_EVENT_VALUE_CHANGED) { + auto* brightnessSlider = static_cast(slider->user_data); + brightnessSlider->OnValueChanged(); + } +} + +Brightness::Brightness(Pinetime::Applications::DisplayApp *app, Controllers::BrightnessController& brightness) : Screen(app), brightness{brightness} { + slider = lv_slider_create(lv_scr_act(), NULL); + lv_obj_set_user_data(slider, this); + lv_obj_set_width(slider, LV_DPI * 2); + lv_obj_align(slider, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_event_cb(slider, slider_event_cb); + lv_slider_set_range(slider, 0, 2); + lv_slider_set_value(slider, LevelToInt(brightness.Level()), LV_ANIM_OFF); + + slider_label = lv_label_create(lv_scr_act(), NULL); + lv_label_set_text(slider_label, LevelToString(brightness.Level())); + lv_obj_set_auto_realign(slider_label, true); + lv_obj_align(slider_label, slider, LV_ALIGN_OUT_BOTTOM_MID, 0, 10); +} + +Brightness::~Brightness() { + lv_obj_clean(lv_scr_act()); +} + +bool Brightness::Refresh() { + return running; +} + +bool Brightness::OnButtonPushed() { + running = false; + return true; +} + +const char *Brightness::LevelToString(Pinetime::Controllers::BrightnessController::Levels level) { + switch(level) { + case Pinetime::Controllers::BrightnessController::Levels::Off: return "Off"; + case Pinetime::Controllers::BrightnessController::Levels::Low: return "Low"; + case Pinetime::Controllers::BrightnessController::Levels::Medium: return "Medium"; + case Pinetime::Controllers::BrightnessController::Levels::High: return "High"; + default : return "???"; + } +} + +void Brightness::OnValueChanged() { + SetValue(lv_slider_get_value(slider)); +} + +void Brightness::SetValue(uint8_t value) { + switch(value) { + case 0: brightness.Set(Controllers::BrightnessController::Levels::Low); break; + case 1: brightness.Set(Controllers::BrightnessController::Levels::Medium); break; + case 2: brightness.Set(Controllers::BrightnessController::Levels::High); break; + } + lv_label_set_text(slider_label, LevelToString(brightness.Level())); +} + +uint8_t Brightness::LevelToInt(Pinetime::Controllers::BrightnessController::Levels level) { + switch(level) { + case Pinetime::Controllers::BrightnessController::Levels::Off: return 0; + case Pinetime::Controllers::BrightnessController::Levels::Low: return 0; + case Pinetime::Controllers::BrightnessController::Levels::Medium: return 1; + case Pinetime::Controllers::BrightnessController::Levels::High: return 2; + default : return 0; + } +} diff --git a/src/DisplayApp/Screens/Brightness.h b/src/DisplayApp/Screens/Brightness.h new file mode 100644 index 00000000..31861f8a --- /dev/null +++ b/src/DisplayApp/Screens/Brightness.h @@ -0,0 +1,31 @@ +#pragma once + +#include +#include +#include "Screen.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + class Brightness : public Screen { + public: + Brightness(DisplayApp* app, Controllers::BrightnessController& brightness); + ~Brightness() override; + bool Refresh() override; + bool OnButtonPushed() override; + + void OnValueChanged(); + private: + bool running = true; + Controllers::BrightnessController& brightness; + + lv_obj_t * slider_label; + lv_obj_t * slider; + + const char* LevelToString(Controllers::BrightnessController::Levels level); + uint8_t LevelToInt(Controllers::BrightnessController::Levels level); + void SetValue(uint8_t value); + }; + } + } +} \ No newline at end of file diff --git a/src/DisplayApp/Screens/Tile.cpp b/src/DisplayApp/Screens/Tile.cpp index 004c8d31..5dc1fce4 100644 --- a/src/DisplayApp/Screens/Tile.cpp +++ b/src/DisplayApp/Screens/Tile.cpp @@ -16,7 +16,7 @@ static void event_handler(lv_obj_t * obj, lv_event_t event) { screen->OnObjectEvent(obj, event, eventData); } -static const char * btnm_map1[] = {"Meter", "Gauge", "Clock", "\n", "Soft\nversion", "App2", "App3", ""}; +static const char * btnm_map1[] = {"Meter", "Gauge", "Clock", "\n", "Soft\nversion", "App2", "Brightness", ""}; Tile::Tile(DisplayApp* app) : Screen(app) { modal.reset(new Modal(app)); @@ -126,8 +126,10 @@ void Tile::OnObjectEvent(lv_obj_t *obj, lv_event_t event, uint32_t buttonId) { modal->Show(); break; case 4: - case 5: tile->StartTestApp(); + break; + case 5: + tile->StartBrightnessApp(); break; } @@ -151,6 +153,11 @@ void Tile::StartTestApp() { running = false; } +void Tile::StartBrightnessApp() { + app->StartApp(DisplayApp::Apps::Brightness); + running = false; +} + void Tile::StartMeterApp() { app->StartApp(DisplayApp::Apps::Meter); running = false; diff --git a/src/DisplayApp/Screens/Tile.h b/src/DisplayApp/Screens/Tile.h index eb253435..cfd9b01f 100644 --- a/src/DisplayApp/Screens/Tile.h +++ b/src/DisplayApp/Screens/Tile.h @@ -58,6 +58,7 @@ namespace Pinetime { bool running = true; std::unique_ptr modal; + void StartBrightnessApp(); }; } } -- cgit v1.2.3-70-g09d2 From 8ed6ffaaf8d0ad681c4f84b89e4a72792edb5a8f Mon Sep 17 00:00:00 2001 From: JF Date: Sun, 15 Mar 2020 21:01:24 +0100 Subject: Add the possibility to the screen to handle a touch gesture. A default action is taken if the current screen doesn't handle it. --- src/CMakeLists.txt | 3 ++- src/DisplayApp/DisplayApp.cpp | 45 ++++++++++++++++++----------------- src/DisplayApp/DisplayApp.h | 4 ++-- src/DisplayApp/Screens/Brightness.cpp | 20 ++++++++++++++++ src/DisplayApp/Screens/Brightness.h | 2 ++ src/DisplayApp/Screens/Screen.h | 4 ++++ src/DisplayApp/TouchEvents.h | 8 +++++++ 7 files changed, 61 insertions(+), 25 deletions(-) create mode 100644 src/DisplayApp/TouchEvents.h (limited to 'src/CMakeLists.txt') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 670f0630..34a7e250 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -242,6 +242,7 @@ set(INCLUDE_FILES Logging/NrfLogger.h BlinkApp/BlinkApp.h DisplayApp/DisplayApp.h + DisplayApp/TouchEvents.h DisplayApp/Screens/Screen.h DisplayApp/Screens/Clock.h DisplayApp/Screens/Message.h @@ -288,4 +289,4 @@ link_directories( ../ ) -nRF5x_addExecutable(pinetime-app "${SOURCE_FILES}") +nRF5x_addExecutable(pinetime-app "${SOURCE_FILES}" ${INCLUDE_FILES}) diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp index 3f58e4b3..14545d2e 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/DisplayApp/DisplayApp.cpp @@ -110,17 +110,19 @@ void DisplayApp::Refresh() { case Messages::TouchEvent: { if (state != States::Running) break; auto gesture = OnTouchEvent(); - switch (gesture) { - case DisplayApp::TouchEvents::SwipeUp: - currentScreen->OnButtonPushed(); - lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::Up); - break; - case DisplayApp::TouchEvents::SwipeDown: - currentScreen->OnButtonPushed(); - lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::Down); - break; - default: - break; + if(!currentScreen->OnTouchEvent(gesture)) { + switch (gesture) { + case TouchEvents::SwipeUp: + currentScreen->OnButtonPushed(); + lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::Up); + break; + case TouchEvents::SwipeDown: + currentScreen->OnButtonPushed(); + lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::Down); + break; + default: + break; + } } } break; @@ -189,32 +191,31 @@ void DisplayApp::PushMessage(DisplayApp::Messages msg) { } } -DisplayApp::TouchEvents DisplayApp::OnTouchEvent() { +TouchEvents DisplayApp::OnTouchEvent() { auto info = touchPanel.GetTouchInfo(); if(info.isTouch) { switch(info.gesture) { case Pinetime::Drivers::Cst816S::Gestures::SingleTap: - // TODO set x,y to LittleVgl lvgl.SetNewTapEvent(info.x, info.y); - return DisplayApp::TouchEvents::Tap; + return TouchEvents::Tap; case Pinetime::Drivers::Cst816S::Gestures::LongPress: - return DisplayApp::TouchEvents::LongTap; + return TouchEvents::LongTap; case Pinetime::Drivers::Cst816S::Gestures::DoubleTap: - return DisplayApp::TouchEvents::DoubleTap; + return TouchEvents::DoubleTap; case Pinetime::Drivers::Cst816S::Gestures::SlideRight: - return DisplayApp::TouchEvents::SwipeRight; + return TouchEvents::SwipeRight; case Pinetime::Drivers::Cst816S::Gestures::SlideLeft: - return DisplayApp::TouchEvents::SwipeLeft; + return TouchEvents::SwipeLeft; case Pinetime::Drivers::Cst816S::Gestures::SlideDown: - return DisplayApp::TouchEvents::SwipeDown; + return TouchEvents::SwipeDown; case Pinetime::Drivers::Cst816S::Gestures::SlideUp: - return DisplayApp::TouchEvents::SwipeUp; + return TouchEvents::SwipeUp; case Pinetime::Drivers::Cst816S::Gestures::None: default: - return DisplayApp::TouchEvents::None; + return TouchEvents::None; } } - return DisplayApp::TouchEvents::None; + return TouchEvents::None; } void DisplayApp::StartApp(DisplayApp::Apps app) { diff --git a/src/DisplayApp/DisplayApp.h b/src/DisplayApp/DisplayApp.h index ccbca4c3..38edd056 100644 --- a/src/DisplayApp/DisplayApp.h +++ b/src/DisplayApp/DisplayApp.h @@ -15,6 +15,7 @@ #include "LittleVgl.h" #include #include +#include "TouchEvents.h" namespace Pinetime { @@ -26,8 +27,7 @@ namespace Pinetime { public: enum class States {Idle, Running}; enum class Messages : uint8_t {GoToSleep, GoToRunning, UpdateDateTime, UpdateBleConnection, UpdateBatteryLevel, TouchEvent, SwitchScreen,ButtonPushed} ; - enum class TouchEvents { None, Tap, SwipeLeft, SwipeRight, SwipeUp, SwipeDown, LongTap, DoubleTap - }; + DisplayApp(Pinetime::Drivers::St7789& lcd, Pinetime::Components::LittleVgl& lvgl, Pinetime::Drivers::Cst816S&, diff --git a/src/DisplayApp/Screens/Brightness.cpp b/src/DisplayApp/Screens/Brightness.cpp index a87a62a8..9e3416c0 100644 --- a/src/DisplayApp/Screens/Brightness.cpp +++ b/src/DisplayApp/Screens/Brightness.cpp @@ -70,3 +70,23 @@ uint8_t Brightness::LevelToInt(Pinetime::Controllers::BrightnessController::Leve default : return 0; } } + +bool Brightness::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + switch(event) { + case TouchEvents::SwipeLeft: + brightness.Lower(); + SetValue(); + return true; + case TouchEvents::SwipeRight: + brightness.Higher(); + SetValue(); + return true; + default: + return false; + } +} + +void Brightness::SetValue() { + lv_slider_set_value(slider, LevelToInt(brightness.Level()), LV_ANIM_OFF); + lv_label_set_text(slider_label, LevelToString(brightness.Level())); +} diff --git a/src/DisplayApp/Screens/Brightness.h b/src/DisplayApp/Screens/Brightness.h index 31861f8a..37cbcd7e 100644 --- a/src/DisplayApp/Screens/Brightness.h +++ b/src/DisplayApp/Screens/Brightness.h @@ -13,6 +13,7 @@ namespace Pinetime { ~Brightness() override; bool Refresh() override; bool OnButtonPushed() override; + bool OnTouchEvent(TouchEvents event) override; void OnValueChanged(); private: @@ -25,6 +26,7 @@ namespace Pinetime { const char* LevelToString(Controllers::BrightnessController::Levels level); uint8_t LevelToInt(Controllers::BrightnessController::Levels level); void SetValue(uint8_t value); + void SetValue(); }; } } diff --git a/src/DisplayApp/Screens/Screen.h b/src/DisplayApp/Screens/Screen.h index 6cbd41ad..d8902317 100644 --- a/src/DisplayApp/Screens/Screen.h +++ b/src/DisplayApp/Screens/Screen.h @@ -1,4 +1,5 @@ #pragma once +#include "../TouchEvents.h" namespace Pinetime { namespace Applications { @@ -15,6 +16,9 @@ namespace Pinetime { // Return false if the button hasn't been handled by the app, true if it has been handled virtual bool OnButtonPushed() { return false; } + // Return false if the event hasn't been handled by the app, true if it has been handled + virtual bool OnTouchEvent(TouchEvents event) { return false; } + protected: DisplayApp* app; }; diff --git a/src/DisplayApp/TouchEvents.h b/src/DisplayApp/TouchEvents.h new file mode 100644 index 00000000..cf2f88dd --- /dev/null +++ b/src/DisplayApp/TouchEvents.h @@ -0,0 +1,8 @@ +#pragma once + +namespace Pinetime { + namespace Applications { + + enum class TouchEvents { None, Tap, SwipeLeft, SwipeRight, SwipeUp, SwipeDown, LongTap, DoubleTap}; + } +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From fb64ba8fb6953fe7e98db6874207a687d0d57bac Mon Sep 17 00:00:00 2001 From: JF Date: Sun, 22 Mar 2020 12:03:17 +0100 Subject: Add new App : Sysinfo. It displays various info about the running system : version, date/time, battery, brightness and resetreason. It contains placeholder for future use (like mac address, uptime,...). --- src/CMakeLists.txt | 5 +- src/Components/Battery/BatteryController.cpp | 4 +- src/DisplayApp/DisplayApp.cpp | 21 ++++- src/DisplayApp/DisplayApp.h | 10 ++- src/DisplayApp/Screens/Clock.cpp | 17 ---- src/DisplayApp/Screens/Label.cpp | 28 ++++++ src/DisplayApp/Screens/Label.h | 24 +++++ src/DisplayApp/Screens/ScreenList.cpp | 125 +++++++++++++++++++++++++++ src/DisplayApp/Screens/ScreenList.h | 34 ++++++++ src/DisplayApp/Screens/Tile.cpp | 6 +- src/DisplayApp/Screens/Tile.h | 2 +- src/SystemTask/SystemTask.cpp | 6 +- src/SystemTask/SystemTask.h | 1 + src/drivers/Watchdog.cpp | 20 +++-- src/drivers/Watchdog.h | 14 ++- 15 files changed, 276 insertions(+), 41 deletions(-) create mode 100644 src/DisplayApp/Screens/Label.cpp create mode 100644 src/DisplayApp/Screens/Label.h create mode 100644 src/DisplayApp/Screens/ScreenList.cpp create mode 100644 src/DisplayApp/Screens/ScreenList.h (limited to 'src/CMakeLists.txt') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 34a7e250..5c521b33 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -213,6 +213,8 @@ list(APPEND SOURCE_FILES DisplayApp/Screens/BatteryIcon.cpp DisplayApp/Screens/BleIcon.cpp DisplayApp/Screens/Brightness.cpp + DisplayApp/Screens/ScreenList.cpp + DisplayApp/Screens/Label.cpp main.cpp drivers/St7789.cpp drivers/SpiMaster.cpp @@ -253,7 +255,8 @@ set(INCLUDE_FILES DisplayApp/Screens/BatteryIcon.h DisplayApp/Screens/BleIcon.cpp DisplayApp/Screens/Brightness.h -# DisplayApp/Screens/Tab.h + DisplayApp/Screens/ScreenList.h + DisplayApp/Screens/Label.h drivers/St7789.h drivers/SpiMaster.h drivers/Watchdog.h diff --git a/src/Components/Battery/BatteryController.cpp b/src/Components/Battery/BatteryController.cpp index 7719bcbb..198ce5aa 100644 --- a/src/Components/Battery/BatteryController.cpp +++ b/src/Components/Battery/BatteryController.cpp @@ -36,8 +36,8 @@ void Battery::Update() { voltage = (value * 2.0f) / (1024/3.0f); percentRemaining = ((voltage - 3.55)*100)*3.9; - NRF_LOG_INFO("BATTERY " NRF_LOG_FLOAT_MARKER " %% - " NRF_LOG_FLOAT_MARKER " v", NRF_LOG_FLOAT(percentRemaining), NRF_LOG_FLOAT(voltage)); - NRF_LOG_INFO("POWER Charging : %d - Power : %d", isCharging, isPowerPresent); +// NRF_LOG_INFO("BATTERY " NRF_LOG_FLOAT_MARKER " %% - " NRF_LOG_FLOAT_MARKER " v", NRF_LOG_FLOAT(percentRemaining), NRF_LOG_FLOAT(voltage)); +// NRF_LOG_INFO("POWER Charging : %d - Power : %d", isCharging, isPowerPresent); } void Battery::SaadcEventHandler(nrfx_saadc_evt_t const * event) { diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp index 14545d2e..e7187f1d 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/DisplayApp/DisplayApp.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include "../SystemTask/SystemTask.h" using namespace Pinetime::Applications; @@ -24,13 +25,15 @@ DisplayApp::DisplayApp(Pinetime::Drivers::St7789& lcd, Controllers::Battery &batteryController, Controllers::Ble &bleController, Controllers::DateTime &dateTimeController, + Pinetime::Drivers::WatchdogView& watchdog, Pinetime::System::SystemTask& systemTask) : lcd{lcd}, lvgl{lvgl}, - touchPanel{touchPanel}, batteryController{batteryController}, bleController{bleController}, dateTimeController{dateTimeController}, + watchdog{watchdog}, + touchPanel{touchPanel}, currentScreen{new Screens::Clock(this, dateTimeController, batteryController, bleController) }, systemTask{systemTask} { msgQueue = xQueueCreate(queueSize, itemSize); @@ -167,7 +170,8 @@ void DisplayApp::RunningState() { currentScreen.reset(new Screens::Clock(this, dateTimeController, batteryController, bleController)); onClockApp = true; break; - case Apps::Test: currentScreen.reset(new Screens::Message(this)); break; +// case Apps::Test: currentScreen.reset(new Screens::Message(this)); break; + case Apps::SysInfo: currentScreen.reset(new Screens::ScreenList(this, dateTimeController, batteryController, brightnessController, watchdog)); break; case Apps::Meter: currentScreen.reset(new Screens::Meter(this)); break; case Apps::Gauge: currentScreen.reset(new Screens::Gauge(this)); break; case Apps::Brightness : currentScreen.reset(new Screens::Brightness(this, brightnessController)); break; @@ -221,3 +225,16 @@ TouchEvents DisplayApp::OnTouchEvent() { void DisplayApp::StartApp(DisplayApp::Apps app) { nextApp = app; } + +void DisplayApp::SetFullRefresh(DisplayApp::FullRefreshDirections direction) { + switch(direction){ + case DisplayApp::FullRefreshDirections::Down: + lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::Down); + break; + case DisplayApp::FullRefreshDirections::Up: + lvgl.SetFullRefresh(Components::LittleVgl::FullRefreshDirections::Up); + break; + default: break; + } + +} diff --git a/src/DisplayApp/DisplayApp.h b/src/DisplayApp/DisplayApp.h index 38edd056..04c82fee 100644 --- a/src/DisplayApp/DisplayApp.h +++ b/src/DisplayApp/DisplayApp.h @@ -15,6 +15,7 @@ #include "LittleVgl.h" #include #include +#include #include "TouchEvents.h" @@ -26,7 +27,9 @@ namespace Pinetime { class DisplayApp { public: enum class States {Idle, Running}; - enum class Messages : uint8_t {GoToSleep, GoToRunning, UpdateDateTime, UpdateBleConnection, UpdateBatteryLevel, TouchEvent, SwitchScreen,ButtonPushed} ; + enum class Messages : uint8_t {GoToSleep, GoToRunning, UpdateDateTime, UpdateBleConnection, UpdateBatteryLevel, TouchEvent, SwitchScreen,ButtonPushed}; + enum class FullRefreshDirections { None, Up, Down }; + DisplayApp(Pinetime::Drivers::St7789& lcd, Pinetime::Components::LittleVgl& lvgl, @@ -34,13 +37,15 @@ namespace Pinetime { Controllers::Battery &batteryController, Controllers::Ble &bleController, Controllers::DateTime& dateTimeController, + Pinetime::Drivers::WatchdogView& watchdog, Pinetime::System::SystemTask& systemTask); void Start(); void PushMessage(Messages msg); - enum class Apps {None, Launcher, Clock, Test, Meter, Gauge, Brightness}; + enum class Apps {None, Launcher, Clock, SysInfo, Meter, Gauge, Brightness}; void StartApp(Apps app); + void SetFullRefresh(FullRefreshDirections direction); private: TaskHandle_t taskHandle; static void Process(void* instance); @@ -60,6 +65,7 @@ namespace Pinetime { Pinetime::Controllers::Battery &batteryController; Pinetime::Controllers::Ble &bleController; Pinetime::Controllers::DateTime& dateTimeController; + Pinetime::Drivers::WatchdogView& watchdog; Pinetime::Drivers::Cst816S& touchPanel; TouchEvents OnTouchEvent(); diff --git a/src/DisplayApp/Screens/Clock.cpp b/src/DisplayApp/Screens/Clock.cpp index 00590777..07db83ee 100644 --- a/src/DisplayApp/Screens/Clock.cpp +++ b/src/DisplayApp/Screens/Clock.cpp @@ -37,23 +37,6 @@ Clock::Clock(DisplayApp* app, lv_img_set_src(bleIcon, BleIcon::GetIcon(false)); lv_obj_align(bleIcon, batteryIcon, LV_ALIGN_OUT_LEFT_MID, 0, 0); -// label_battery = lv_label_create(lv_scr_act(), NULL); -// lv_obj_align(label_battery, lv_scr_act(), LV_ALIGN_IN_TOP_RIGHT, -80, 0); - -// labelStyle = const_cast(lv_label_get_style(label_battery, LV_LABEL_STYLE_MAIN)); -// labelStyle->text.font = &jetbrains_mono_bold_20; -// -// lv_style_copy(&labelBigStyle, labelStyle); -// labelBigStyle.text.font = &jetbrains_mono_extrabold_compressed; -// -// lv_label_set_style(label_battery, LV_LABEL_STYLE_MAIN, labelStyle); - -// label_ble = lv_label_create(lv_scr_act(), NULL); - - -// lv_label_set_style(label_ble, LV_LABEL_STYLE_MAIN, labelStyle); -// lv_obj_align(label_ble, lv_scr_act(), LV_ALIGN_IN_TOP_LEFT, 10, 0); - label_date = lv_label_create(lv_scr_act(), NULL); lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 60); diff --git a/src/DisplayApp/Screens/Label.cpp b/src/DisplayApp/Screens/Label.cpp new file mode 100644 index 00000000..ba35279d --- /dev/null +++ b/src/DisplayApp/Screens/Label.cpp @@ -0,0 +1,28 @@ +#include +#include "Label.h" + +using namespace Pinetime::Applications::Screens; + + +Label::Label(const char* text) : text{text} { + +} + +Label::~Label() { + +} + +void Label::Refresh() { + +} + +void Label::Show() { + label = lv_label_create(lv_scr_act(), NULL); + lv_label_set_align(label, LV_LABEL_ALIGN_LEFT); + lv_obj_set_size(label, 240, 240); + lv_label_set_text(label, text); +} + +void Label::Hide() { + lv_obj_clean(lv_scr_act()); +} diff --git a/src/DisplayApp/Screens/Label.h b/src/DisplayApp/Screens/Label.h new file mode 100644 index 00000000..b73540f4 --- /dev/null +++ b/src/DisplayApp/Screens/Label.h @@ -0,0 +1,24 @@ +#pragma once + +#include +#include "Screen.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + class Label { + public: + Label() = default; + explicit Label(const char* text); + ~Label(); + void Refresh(); + + void Hide(); + void Show(); + private: + lv_obj_t * label = nullptr; + const char* text = nullptr; + }; + } + } +} \ No newline at end of file diff --git a/src/DisplayApp/Screens/ScreenList.cpp b/src/DisplayApp/Screens/ScreenList.cpp new file mode 100644 index 00000000..bea335ff --- /dev/null +++ b/src/DisplayApp/Screens/ScreenList.cpp @@ -0,0 +1,125 @@ +#include +#include +#include "ScreenList.h" + +using namespace Pinetime::Applications::Screens; + +// TODO this class must be improved to receive the list of "sub screens" via pointer or +// move operation. +// It should accept many type of "sub screen" (it only supports Label for now). +// The number of sub screen it supports must be dynamic. +ScreenList::ScreenList(Pinetime::Applications::DisplayApp *app, Pinetime::Controllers::DateTime &dateTimeController, + Pinetime::Controllers::Battery& batteryController, Pinetime::Controllers::BrightnessController& brightnessController, Pinetime::Drivers::WatchdogView& watchdog) : + Screen(app), + dateTimeController{dateTimeController}, batteryController{batteryController}, brightnessController{brightnessController}, watchdog{watchdog} { + screens.reserve(3); + + // TODO all of this is far too heavy (string processing). This should be improved. + // TODO the info (battery, time,...) should be updated in the Refresh method. + char t1[200]; + + auto batteryPercent = static_cast(batteryController.PercentRemaining()); + if(batteryPercent > 100) batteryPercent = 100; + else if(batteryPercent < 0) batteryPercent = 0; + + uint8_t brightness = 0; + switch(brightnessController.Level()) { + case Controllers::BrightnessController::Levels::Low: brightness = 1; break; + case Controllers::BrightnessController::Levels::Medium: brightness = 2; break; + case Controllers::BrightnessController::Levels::High: brightness = 3; break; + } + auto resetReason = [&watchdog]() { + switch (watchdog.ResetReason()) { + case Drivers::Watchdog::ResetReasons::Watchdog: return "wtdg"; + case Drivers::Watchdog::ResetReasons::HardReset: return "hardr"; + case Drivers::Watchdog::ResetReasons::NFC: return "nfc"; + case Drivers::Watchdog::ResetReasons::SoftReset: return "softr"; + case Drivers::Watchdog::ResetReasons::CpuLockup: return "cpulock"; + case Drivers::Watchdog::ResetReasons::SystemOff: return "off"; + case Drivers::Watchdog::ResetReasons::LpComp: return "lpcomp"; + case Drivers::Watchdog::ResetReasons::DebugInterface: return "dbg"; + case Drivers::Watchdog::ResetReasons::ResetPin: return "rst"; + default: return "?"; + } + }(); + + + sprintf(t1, "Pinetime\n" + "Version:%d.%d.%d\n" + "Build: xx/xx/xxxx\n" + "Time: %02d:%02d:%02d\n" + "date: %02d/%02d/%04d\n" + "Uptime: xd xxhxx:xx\n" + "Battery: %d%%\n" + "Backlight: %d/3\n" + "Last reset: %s\n" + "BLE MAC: \n AA:BB:CC:DD:EE:FF", Version::Major(), Version::Minor(), Version::Patch(), + dateTimeController.Hours(), dateTimeController.Minutes(), dateTimeController.Seconds(), + dateTimeController.Day(), dateTimeController.Month(), dateTimeController.Year(), + batteryPercent, brightness, resetReason); +/* + auto t1 = "Pinetime\n" + "Version:\n" + "Build: 23/03/2020\n" + "Time: 17:23:12\n" + "date: 23/03/2020\n" + "Uptime: 2d 13h52:21\n" + "Battery: 3.56v/82%\n" + "Backlight: 2/3\n" + "Last reset: wtdg\n" + "BLE MAC: \n AA:BB:CC:DD:EE:FF";*/ + screens.emplace_back(t1); + + auto t2 = "Hello from\nthe developper!"; + screens.emplace_back(t2); + + auto t3 = "Place holder\nin case we need\nmore room!"; + screens.emplace_back(t3); + + auto &screen = screens[screenIndex]; + screen.Show(); +} + +ScreenList::~ScreenList() { + lv_obj_clean(lv_scr_act()); +} + +bool ScreenList::Refresh() { + auto &screen = screens[screenIndex]; + screen.Refresh(); + + return running; +} + +bool ScreenList::OnButtonPushed() { + running = false; + return true; +} + +bool ScreenList::OnTouchEvent(Pinetime::Applications::TouchEvents event) { + switch (event) { + case TouchEvents::SwipeDown: + if (screenIndex > 0) { + app->SetFullRefresh(DisplayApp::FullRefreshDirections::Down); + auto &oldScreen = screens[screenIndex]; + oldScreen.Hide(); + screenIndex--; + auto &newScreen = screens[screenIndex]; + newScreen.Show(); + } + return true; + case TouchEvents::SwipeUp: + app->SetFullRefresh(DisplayApp::FullRefreshDirections::Up); + if (screenIndex < screens.size() - 1) { + auto &oldScreen = screens[screenIndex]; + oldScreen.Hide(); + screenIndex++; + auto &newScreen = screens[screenIndex]; + newScreen.Show(); + } + return true; + default: + return false; + } + return false; +} diff --git a/src/DisplayApp/Screens/ScreenList.h b/src/DisplayApp/Screens/ScreenList.h new file mode 100644 index 00000000..ba8e7700 --- /dev/null +++ b/src/DisplayApp/Screens/ScreenList.h @@ -0,0 +1,34 @@ +#pragma once + +#include +#include "Screen.h" +#include "Label.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + class ScreenList : public Screen { + public: + explicit ScreenList(DisplayApp* app, + Pinetime::Controllers::DateTime& dateTimeController, + Pinetime::Controllers::Battery& batteryController, + Pinetime::Controllers::BrightnessController& brightnessController, + Pinetime::Drivers::WatchdogView& watchdog); + ~ScreenList() override; + bool Refresh() override; + bool OnButtonPushed() override; + bool OnTouchEvent(TouchEvents event) override; + private: + bool running = true; + uint8_t screenIndex = 0; + + // TODO choose another container without dynamic alloc + std::vector screens; + Pinetime::Controllers::DateTime& dateTimeController; + Pinetime::Controllers::Battery& batteryController; + Pinetime::Controllers::BrightnessController& brightnessController; + Pinetime::Drivers::WatchdogView& watchdog; + }; + } + } +} \ No newline at end of file diff --git a/src/DisplayApp/Screens/Tile.cpp b/src/DisplayApp/Screens/Tile.cpp index 5dc1fce4..7eb1018c 100644 --- a/src/DisplayApp/Screens/Tile.cpp +++ b/src/DisplayApp/Screens/Tile.cpp @@ -126,7 +126,7 @@ void Tile::OnObjectEvent(lv_obj_t *obj, lv_event_t event, uint32_t buttonId) { modal->Show(); break; case 4: - tile->StartTestApp(); + tile->StartSysInfoApp(); break; case 5: tile->StartBrightnessApp(); @@ -148,8 +148,8 @@ void Tile::StartClockApp() { running = false; } -void Tile::StartTestApp() { - app->StartApp(DisplayApp::Apps::Test); +void Tile::StartSysInfoApp() { + app->StartApp(DisplayApp::Apps::SysInfo); running = false; } diff --git a/src/DisplayApp/Screens/Tile.h b/src/DisplayApp/Screens/Tile.h index cfd9b01f..fa2d6db0 100644 --- a/src/DisplayApp/Screens/Tile.h +++ b/src/DisplayApp/Screens/Tile.h @@ -52,7 +52,7 @@ namespace Pinetime { uint32_t clickCount = 0 ; uint32_t previousClickCount = 0; void StartClockApp(); - void StartTestApp(); + void StartSysInfoApp(); void StartMeterApp(); void StartGaugeApp(); bool running = true; diff --git a/src/SystemTask/SystemTask.cpp b/src/SystemTask/SystemTask.cpp index 00fad002..c4e1386c 100644 --- a/src/SystemTask/SystemTask.cpp +++ b/src/SystemTask/SystemTask.cpp @@ -13,7 +13,9 @@ SystemTask::SystemTask(Pinetime::Drivers::SpiMaster &spi, Pinetime::Drivers::St7 Pinetime::Drivers::Cst816S &touchPanel, Pinetime::Components::LittleVgl &lvgl, Pinetime::Controllers::Battery &batteryController, Pinetime::Controllers::Ble &bleController, Pinetime::Controllers::DateTime& dateTimeController) : - spi{spi}, lcd{lcd}, touchPanel{touchPanel}, lvgl{lvgl}, batteryController{batteryController}, bleController{bleController}, dateTimeController{dateTimeController} { + spi{spi}, lcd{lcd}, touchPanel{touchPanel}, lvgl{lvgl}, batteryController{batteryController}, + bleController{bleController}, dateTimeController{dateTimeController}, + watchdog{}, watchdogView{watchdog}{ systemTaksMsgQueue = xQueueCreate(10, 1); } @@ -42,7 +44,7 @@ void SystemTask::Work() { touchPanel.Init(); batteryController.Init(); - displayApp.reset(new Pinetime::Applications::DisplayApp(lcd, lvgl, touchPanel, batteryController, bleController, dateTimeController, *this)); + displayApp.reset(new Pinetime::Applications::DisplayApp(lcd, lvgl, touchPanel, batteryController, bleController, dateTimeController, watchdogView, *this)); displayApp->Start(); batteryController.Update(); diff --git a/src/SystemTask/SystemTask.h b/src/SystemTask/SystemTask.h index f5ba2d75..a2775d9d 100644 --- a/src/SystemTask/SystemTask.h +++ b/src/SystemTask/SystemTask.h @@ -43,6 +43,7 @@ namespace Pinetime { QueueHandle_t systemTaksMsgQueue; bool isSleeping = false; Pinetime::Drivers::Watchdog watchdog; + Pinetime::Drivers::WatchdogView watchdogView; static constexpr uint8_t pinSpiSck = 2; diff --git a/src/drivers/Watchdog.cpp b/src/drivers/Watchdog.cpp index b0dc12e5..55b6de73 100644 --- a/src/drivers/Watchdog.cpp +++ b/src/drivers/Watchdog.cpp @@ -19,6 +19,8 @@ void Watchdog::Setup(uint8_t timeoutSeconds) { /* Enable reload requests */ NRF_WDT->RREN = (WDT_RREN_RR0_Enabled << WDT_RREN_RR0_Pos); + + resetReason = ActualResetReason(); } void Watchdog::Start() { @@ -29,18 +31,18 @@ void Watchdog::Kick() { NRF_WDT->RR[0] = WDT_RR_RR_Reload; } -Watchdog::ResetReasons Watchdog::ResetReason() { +Watchdog::ResetReasons Watchdog::ActualResetReason() const { uint32_t resetReason; sd_power_reset_reason_get(&resetReason); sd_power_reset_reason_clr(0xFFFFFFFF); - if(resetReason & 0x01) return ResetReasons::ResetPin; - if((resetReason >> 1) & 0x01) return ResetReasons::Watchdog; - if((resetReason >> 2) & 0x01) return ResetReasons::SoftReset; - if((resetReason >> 3) & 0x01) return ResetReasons::CpuLockup; - if((resetReason >> 16) & 0x01) return ResetReasons::SystemOff; - if((resetReason >> 17) & 0x01) return ResetReasons::LpComp; - if((resetReason >> 18) & 0x01) return ResetReasons::DebugInterface; - if((resetReason >> 19) & 0x01) return ResetReasons::NFC; + if(resetReason & 0x01u) return ResetReasons::ResetPin; + if((resetReason >> 1u) & 0x01u) return ResetReasons::Watchdog; + if((resetReason >> 2u) & 0x01u) return ResetReasons::SoftReset; + if((resetReason >> 3u) & 0x01u) return ResetReasons::CpuLockup; + if((resetReason >> 16u) & 0x01u) return ResetReasons::SystemOff; + if((resetReason >> 17u) & 0x01u) return ResetReasons::LpComp; + if((resetReason >> 18u) & 0x01u) return ResetReasons::DebugInterface; + if((resetReason >> 19u) & 0x01u) return ResetReasons::NFC; return ResetReasons::HardReset; } diff --git a/src/drivers/Watchdog.h b/src/drivers/Watchdog.h index da192d9e..73f99ea1 100644 --- a/src/drivers/Watchdog.h +++ b/src/drivers/Watchdog.h @@ -8,10 +8,20 @@ namespace Pinetime { void Setup(uint8_t timeoutSeconds); void Start(); void Kick(); - - ResetReasons ResetReason(); + ResetReasons ResetReason() const { return resetReason; } static const char* ResetReasonToString(ResetReasons reason); + private: + ResetReasons resetReason; + ResetReasons ActualResetReason() const; + }; + + class WatchdogView { + public: + WatchdogView(const Watchdog& watchdog) : watchdog{watchdog} { } + Watchdog::ResetReasons ResetReason() const { return watchdog.ResetReason();} + private: + const Watchdog& watchdog; }; } } -- cgit v1.2.3-70-g09d2 From baca0fc3e59e88420d6c7983ad133fe63c794ec0 Mon Sep 17 00:00:00 2001 From: JF Date: Sat, 28 Mar 2020 19:05:28 +0100 Subject: Encapsulate Notification management in NotificationManager. It implement a static array of notifications to avoid dynamic allocation. --- src/CMakeLists.txt | 2 ++ src/Components/Ble/BleController.cpp | 24 ----------------- src/Components/Ble/BleController.h | 11 +------- src/Components/Ble/NotificationManager.cpp | 29 +++++++++++++++++++++ src/Components/Ble/NotificationManager.h | 29 +++++++++++++++++++++ src/DisplayApp/DisplayApp.cpp | 25 ++++++++---------- src/DisplayApp/DisplayApp.h | 16 +++++------- src/DisplayApp/Screens/Modal.cpp | 41 ++---------------------------- src/DisplayApp/Screens/Modal.h | 4 +-- src/DisplayApp/Screens/Tile.cpp | 4 ++- src/SystemTask/SystemTask.cpp | 15 ++++++----- src/SystemTask/SystemTask.h | 13 +++++----- src/main.cpp | 8 ++++-- 13 files changed, 105 insertions(+), 116 deletions(-) create mode 100644 src/Components/Ble/NotificationManager.cpp create mode 100644 src/Components/Ble/NotificationManager.h (limited to 'src/CMakeLists.txt') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 5c521b33..e92e3998 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -223,6 +223,7 @@ list(APPEND SOURCE_FILES BLE/BleManager.c Components/Battery/BatteryController.cpp Components/Ble/BleController.cpp + Components/Ble/NotificationManager.cpp Components/DateTime/DateTimeController.cpp Components/Brightness/BrightnessController.cpp drivers/Cst816s.cpp @@ -264,6 +265,7 @@ set(INCLUDE_FILES BLE/BleManager.h Components/Battery/BatteryController.h Components/Ble/BleController.h + Components/Ble/NotificationManager.h Components/DateTime/DateTimeController.h Components/Brightness/BrightnessController.h drivers/Cst816s.h diff --git a/src/Components/Ble/BleController.cpp b/src/Components/Ble/BleController.cpp index fd405896..5fa51688 100644 --- a/src/Components/Ble/BleController.cpp +++ b/src/Components/Ble/BleController.cpp @@ -4,10 +4,6 @@ using namespace Pinetime::Controllers; -Ble::Ble() { - notificationQueue = xQueueCreate(10, sizeof(NotificationMessage)); -} - void Ble::Connect() { isConnected = true; } @@ -16,24 +12,4 @@ void Ble::Disconnect() { isConnected = false; } -void Ble::PushNotification(const char *message, uint8_t size) { - char* messageCopy = static_cast(malloc(sizeof(char) * size)); - std::memcpy(messageCopy, message, size); - NotificationMessage msg; - msg.size = size; - msg.message = messageCopy; - - BaseType_t xHigherPriorityTaskWoken; - xHigherPriorityTaskWoken = pdFALSE; - xQueueSendFromISR(notificationQueue, &msg, &xHigherPriorityTaskWoken); - if (xHigherPriorityTaskWoken) { - /* Actual macro used here is port specific. */ - // TODO : should I do something here? - } -} - -bool Ble::PopNotification(Ble::NotificationMessage& msg) { - return xQueueReceive(notificationQueue, &msg, 0) != 0; -} - diff --git a/src/Components/Ble/BleController.h b/src/Components/Ble/BleController.h index 4f037fc1..31d66986 100644 --- a/src/Components/Ble/BleController.h +++ b/src/Components/Ble/BleController.h @@ -7,22 +7,13 @@ namespace Pinetime { namespace Controllers { class Ble { public: - struct NotificationMessage { - uint8_t size = 0; - const char* message = nullptr; - }; - Ble(); + Ble() = default; bool IsConnected() const {return isConnected;} void Connect(); void Disconnect(); - - void PushNotification(const char* message, uint8_t size); - bool PopNotification(NotificationMessage& msg); - private: bool isConnected = false; - QueueHandle_t notificationQueue; }; } diff --git a/src/Components/Ble/NotificationManager.cpp b/src/Components/Ble/NotificationManager.cpp new file mode 100644 index 00000000..2e02cb15 --- /dev/null +++ b/src/Components/Ble/NotificationManager.cpp @@ -0,0 +1,29 @@ +#include +#include "NotificationManager.h" + +using namespace Pinetime::Controllers; + +void NotificationManager::Push(Pinetime::Controllers::NotificationManager::Categories category, + const char *message, uint8_t messageSize) { + // TODO handle edge cases on read/write index + auto& notif = notifications[writeIndex]; + std::memcpy(notif.message.data(), message, messageSize); + notif.message[messageSize] = '\0'; + notif.category = category; + + writeIndex = (writeIndex + 1 < TotalNbNotifications) ? writeIndex + 1 : 0; + if(!empty && writeIndex == readIndex) + readIndex = writeIndex + 1; +} + +NotificationManager::Notification Pinetime::Controllers::NotificationManager::Pop() { +// TODO handle edge cases on read/write index + NotificationManager::Notification notification = notifications[readIndex]; + + if(readIndex != writeIndex) { + readIndex = (readIndex + 1 < TotalNbNotifications) ? readIndex + 1 : 0; + } + + // TODO Check move optimization on return + return notification; +} diff --git a/src/Components/Ble/NotificationManager.h b/src/Components/Ble/NotificationManager.h new file mode 100644 index 00000000..8edd6828 --- /dev/null +++ b/src/Components/Ble/NotificationManager.h @@ -0,0 +1,29 @@ +#pragma once + +#include + +namespace Pinetime { + namespace Controllers { + class NotificationManager { + public: + enum class Categories {Unknown, SimpleAlert, Email, News, IncomingCall, MissedCall, Sms, VoiceMail, Schedule, HighProriotyAlert, InstantMessage }; + static constexpr uint8_t MessageSize = 18; + + struct Notification { + std::array message; + Categories category = Categories::Unknown; + }; + + void Push(Categories category, const char* message, uint8_t messageSize); + Notification Pop(); + + + private: + static constexpr uint8_t TotalNbNotifications = 5; + std::array notifications; + uint8_t readIndex = 0; + uint8_t writeIndex = 0; + bool empty = true; + }; + } +} \ No newline at end of file diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp index 2e07cbc5..1b4515e0 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/DisplayApp/DisplayApp.cpp @@ -15,18 +15,16 @@ #include #include #include +#include #include "../SystemTask/SystemTask.h" using namespace Pinetime::Applications; -DisplayApp::DisplayApp(Pinetime::Drivers::St7789& lcd, - Pinetime::Components::LittleVgl& lvgl, - Pinetime::Drivers::Cst816S& touchPanel, - Controllers::Battery &batteryController, - Controllers::Ble &bleController, - Controllers::DateTime &dateTimeController, - Pinetime::Drivers::WatchdogView& watchdog, - Pinetime::System::SystemTask& systemTask) : +DisplayApp::DisplayApp(Drivers::St7789 &lcd, Components::LittleVgl &lvgl, Drivers::Cst816S &touchPanel, + Controllers::Battery &batteryController, Controllers::Ble &bleController, + Controllers::DateTime &dateTimeController, Drivers::WatchdogView &watchdog, + System::SystemTask &systemTask, + Pinetime::Controllers::NotificationManager& notificationManager) : lcd{lcd}, lvgl{lvgl}, batteryController{batteryController}, @@ -35,7 +33,8 @@ DisplayApp::DisplayApp(Pinetime::Drivers::St7789& lcd, watchdog{watchdog}, touchPanel{touchPanel}, currentScreen{new Screens::Clock(this, dateTimeController, batteryController, bleController) }, - systemTask{systemTask} { + systemTask{systemTask}, + notificationManager{notificationManager} { msgQueue = xQueueCreate(queueSize, itemSize); onClockApp = true; modal.reset(new Screens::Modal(this)); @@ -113,12 +112,8 @@ void DisplayApp::Refresh() { // clockScreen.SetBatteryPercentRemaining(batteryController.PercentRemaining()); break; case Messages::NewNotification: { - Pinetime::Controllers::Ble::NotificationMessage notificationMessage; - if (bleController.PopNotification(notificationMessage)) { - std::string m {notificationMessage.message, notificationMessage.size}; - modal->Show(m); - // TODO delete message - } + auto notification = notificationManager.Pop(); + modal->Show(notification.message.data()); } break; case Messages::TouchEvent: { diff --git a/src/DisplayApp/DisplayApp.h b/src/DisplayApp/DisplayApp.h index ad817331..09f0d1cd 100644 --- a/src/DisplayApp/DisplayApp.h +++ b/src/DisplayApp/DisplayApp.h @@ -17,6 +17,7 @@ #include #include #include +#include #include "TouchEvents.h" @@ -34,14 +35,11 @@ namespace Pinetime { enum class FullRefreshDirections { None, Up, Down }; - DisplayApp(Pinetime::Drivers::St7789& lcd, - Pinetime::Components::LittleVgl& lvgl, - Pinetime::Drivers::Cst816S&, - Controllers::Battery &batteryController, - Controllers::Ble &bleController, - Controllers::DateTime& dateTimeController, - Pinetime::Drivers::WatchdogView& watchdog, - Pinetime::System::SystemTask& systemTask); + DisplayApp(Drivers::St7789 &lcd, Components::LittleVgl &lvgl, Drivers::Cst816S &, + Controllers::Battery &batteryController, Controllers::Ble &bleController, + Controllers::DateTime &dateTimeController, Drivers::WatchdogView &watchdog, + System::SystemTask &systemTask, + Pinetime::Controllers::NotificationManager& notificationManager); void Start(); void PushMessage(Messages msg); @@ -82,7 +80,7 @@ namespace Pinetime { 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 modal; - + Pinetime::Controllers::NotificationManager& notificationManager; }; } } diff --git a/src/DisplayApp/Screens/Modal.cpp b/src/DisplayApp/Screens/Modal.cpp index ec477b6e..63ae70c0 100644 --- a/src/DisplayApp/Screens/Modal.cpp +++ b/src/DisplayApp/Screens/Modal.cpp @@ -25,42 +25,6 @@ bool Modal::OnButtonPushed() { return true; } -void Modal::Show() { - if(isVisible) return; - isVisible = true; - lv_style_copy(&modal_style, &lv_style_plain_color); - modal_style.body.main_color = modal_style.body.grad_color = LV_COLOR_BLACK; - modal_style.body.opa = LV_OPA_50; - - obj = lv_obj_create(lv_scr_act(), NULL); - lv_obj_set_style(obj, &modal_style); - lv_obj_set_pos(obj, 0, 0); - lv_obj_set_size(obj, LV_HOR_RES, LV_VER_RES); - lv_obj_set_opa_scale_enable(obj, true); /* Enable opacity scaling for the animation */ - - static const char * btns2[] = {"Ok", ""}; - - /* Create the message box as a child of the modal background */ - mbox = lv_mbox_create(obj, NULL); - lv_mbox_add_btns(mbox, btns2); - char versionStr[20]; - sprintf(versionStr, "VERSION: %d.%d.%d", Version::Major(), Version::Minor(), Version::Patch()); - lv_mbox_set_text(mbox, versionStr); -// lv_mbox_set_text(mbox, "Hello world!"); - lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); - lv_obj_set_event_cb(mbox, Modal::mbox_event_cb); - - mbox->user_data = this; - - /* Fade the message box in with an animation */ - lv_anim_t a; - lv_anim_init(&a); - lv_anim_set_time(&a, 500, 0); - lv_anim_set_values(&a, LV_OPA_TRANSP, LV_OPA_COVER); - lv_anim_set_exec_cb(&a, obj, (lv_anim_exec_xcb_t)lv_obj_set_opa_scale); - lv_anim_create(&a); -} - void Modal::Hide() { /* Delete the parent modal background */ lv_obj_del_async(lv_obj_get_parent(mbox)); @@ -83,9 +47,8 @@ void Modal::OnEvent(lv_obj_t *event_obj, lv_event_t evt) { } } -void Modal::Show(const std::string& message) { +void Modal::Show(const char* msg) { if(isVisible) return; - this->message = message; isVisible = true; lv_style_copy(&modal_style, &lv_style_plain_color); modal_style.body.main_color = modal_style.body.grad_color = LV_COLOR_BLACK; @@ -102,7 +65,7 @@ void Modal::Show(const std::string& message) { /* Create the message box as a child of the modal background */ mbox = lv_mbox_create(obj, NULL); lv_mbox_add_btns(mbox, btns2); - lv_mbox_set_text(mbox, message.data()); + lv_mbox_set_text(mbox, msg); lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); lv_obj_set_event_cb(mbox, Modal::mbox_event_cb); diff --git a/src/DisplayApp/Screens/Modal.h b/src/DisplayApp/Screens/Modal.h index b13b5c60..b5425906 100644 --- a/src/DisplayApp/Screens/Modal.h +++ b/src/DisplayApp/Screens/Modal.h @@ -22,8 +22,7 @@ namespace Pinetime { Modal(DisplayApp* app); ~Modal() override; - void Show(); - void Show(const std::string& message); + void Show(const char* msg); void Hide(); bool Refresh() override; @@ -39,7 +38,6 @@ namespace Pinetime { lv_obj_t *info; bool running = true; bool isVisible = false; - std::string message; }; } diff --git a/src/DisplayApp/Screens/Tile.cpp b/src/DisplayApp/Screens/Tile.cpp index 7eb1018c..6c225c9d 100644 --- a/src/DisplayApp/Screens/Tile.cpp +++ b/src/DisplayApp/Screens/Tile.cpp @@ -123,7 +123,9 @@ void Tile::OnObjectEvent(lv_obj_t *obj, lv_event_t event, uint32_t buttonId) { tile->StartClockApp(); break; case 3: - modal->Show(); + char versionStr[20]; + sprintf(versionStr, "VERSION: %d.%d.%d", Version::Major(), Version::Minor(), Version::Patch()); + modal->Show(versionStr); break; case 4: tile->StartSysInfoApp(); diff --git a/src/SystemTask/SystemTask.cpp b/src/SystemTask/SystemTask.cpp index 0080c6b6..e65abb61 100644 --- a/src/SystemTask/SystemTask.cpp +++ b/src/SystemTask/SystemTask.cpp @@ -5,17 +5,19 @@ #include #include #include +#include #include "SystemTask.h" #include "../main.h" using namespace Pinetime::System; -SystemTask::SystemTask(Pinetime::Drivers::SpiMaster &spi, Pinetime::Drivers::St7789 &lcd, - Pinetime::Drivers::Cst816S &touchPanel, Pinetime::Components::LittleVgl &lvgl, - Pinetime::Controllers::Battery &batteryController, Pinetime::Controllers::Ble &bleController, - Pinetime::Controllers::DateTime& dateTimeController) : +SystemTask::SystemTask(Drivers::SpiMaster &spi, Drivers::St7789 &lcd, Drivers::Cst816S &touchPanel, + Components::LittleVgl &lvgl, + Controllers::Battery &batteryController, Controllers::Ble &bleController, + Controllers::DateTime &dateTimeController, + Pinetime::Controllers::NotificationManager& notificationManager) : spi{spi}, lcd{lcd}, touchPanel{touchPanel}, lvgl{lvgl}, batteryController{batteryController}, bleController{bleController}, dateTimeController{dateTimeController}, - watchdog{}, watchdogView{watchdog}{ + watchdog{}, watchdogView{watchdog}, notificationManager{notificationManager} { systemTaksMsgQueue = xQueueCreate(10, 1); } @@ -44,7 +46,8 @@ void SystemTask::Work() { touchPanel.Init(); batteryController.Init(); - displayApp.reset(new Pinetime::Applications::DisplayApp(lcd, lvgl, touchPanel, batteryController, bleController, dateTimeController, watchdogView, *this)); + displayApp.reset(new Pinetime::Applications::DisplayApp(lcd, lvgl, touchPanel, batteryController, bleController, + dateTimeController, watchdogView, *this, notificationManager)); displayApp->Start(); batteryController.Update(); diff --git a/src/SystemTask/SystemTask.h b/src/SystemTask/SystemTask.h index b64fda65..a1ba277a 100644 --- a/src/SystemTask/SystemTask.h +++ b/src/SystemTask/SystemTask.h @@ -16,13 +16,11 @@ namespace Pinetime { enum class Messages {GoToSleep, GoToRunning, OnNewTime, OnNewNotification }; - SystemTask(Pinetime::Drivers::SpiMaster& spi, - Pinetime::Drivers::St7789& lcd, - Pinetime::Drivers::Cst816S& touchPanel, - Pinetime::Components::LittleVgl& lvgl, - Pinetime::Controllers::Battery& batteryController, - Pinetime::Controllers::Ble& bleController, - Pinetime::Controllers::DateTime& dateTimeController); + SystemTask(Drivers::SpiMaster &spi, Drivers::St7789 &lcd, Drivers::Cst816S &touchPanel, + Components::LittleVgl &lvgl, + Controllers::Battery &batteryController, Controllers::Ble &bleController, + Controllers::DateTime &dateTimeController, + Pinetime::Controllers::NotificationManager& manager); void Start(); @@ -45,6 +43,7 @@ namespace Pinetime { bool isSleeping = false; Pinetime::Drivers::Watchdog watchdog; Pinetime::Drivers::WatchdogView watchdogView; + Pinetime::Controllers::NotificationManager& notificationManager; static constexpr uint8_t pinSpiSck = 2; diff --git a/src/main.cpp b/src/main.cpp index a4a759d9..106d19eb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #if NRF_LOG_ENABLED #include "Logging/NrfLogger.h" @@ -55,6 +56,8 @@ void ble_manager_set_ble_disconnection_callback(void (*disconnection)()); static constexpr uint8_t pinTouchIrq = 28; std::unique_ptr systemTask; +Pinetime::Controllers::NotificationManager notificationManager; + void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { if(pin == pinTouchIrq) { systemTask->OnTouchEvent(); @@ -86,7 +89,7 @@ void OnBleDisconnection() { } void OnNewNotification(const char* message, uint8_t size) { - bleController.PushNotification(message, size); + notificationManager.Push(Pinetime::Controllers::NotificationManager::Categories::SimpleAlert, message, size); systemTask->PushMessage(Pinetime::System::SystemTask::Messages::OnNewNotification); } @@ -128,7 +131,8 @@ int main(void) { debounceTimer = xTimerCreate ("debounceTimer", 200, pdFALSE, (void *) 0, DebounceTimerCallback); - systemTask.reset(new Pinetime::System::SystemTask(spi, lcd, touchPanel, lvgl, batteryController, bleController, dateTimeController)); + systemTask.reset(new Pinetime::System::SystemTask(spi, lcd, touchPanel, lvgl, batteryController, bleController, + dateTimeController, notificationManager)); systemTask->Start(); ble_manager_init(); -- cgit v1.2.3-70-g09d2