From 02772b996fb26146cf38fc6deccff7f43a49dfd6 Mon Sep 17 00:00:00 2001 From: JF Date: Sun, 23 Feb 2020 13:44:39 +0100 Subject: Do not compile GFX and older fonts anymore. Refactor SystemTask in its own class. Refactor Screen to be able to close current screen and open a new one. Re-enable sleep/wake up and propagate button event to Screens. --- src/SystemTask/SystemTask.cpp | 115 ++++++++++++++++++++++++++++++++++++++++++ src/SystemTask/SystemTask.h | 60 ++++++++++++++++++++++ 2 files changed, 175 insertions(+) create mode 100644 src/SystemTask/SystemTask.cpp create mode 100644 src/SystemTask/SystemTask.h (limited to 'src/SystemTask') diff --git a/src/SystemTask/SystemTask.cpp b/src/SystemTask/SystemTask.cpp new file mode 100644 index 00000000..642e36a2 --- /dev/null +++ b/src/SystemTask/SystemTask.cpp @@ -0,0 +1,115 @@ +#include +#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) : + spi{spi}, lcd{lcd}, touchPanel{touchPanel}, lvgl{lvgl}, batteryController{batteryController}, bleController{bleController}, dateTimeController{dateTimeController} { + systemTaksMsgQueue = xQueueCreate(10, 1); +} + +void SystemTask::Start() { + if (pdPASS != xTaskCreate(SystemTask::Process, "MAIN", 256, this, 0, &taskHandle)) + APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); +} + +void SystemTask::Process(void *instance) { + auto *app = static_cast(instance); + NRF_LOG_INFO("SystemTask task started!"); + app->Work(); +} + +void SystemTask::Work() { + APP_GPIOTE_INIT(2); + bool erase_bonds=false; +// nrf_sdh_freertos_init(ble_manager_start_advertising, &erase_bonds); + + spi.Init(); + lcd.Init(); + touchPanel.Init(); + batteryController.Init(); + + displayApp.reset(new Pinetime::Applications::DisplayApp(lcd, lvgl, touchPanel, batteryController, bleController, dateTimeController, *this)); + 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); + + + while(true) { + uint8_t msg; + if (xQueueReceive(systemTaksMsgQueue, &msg, isSleeping?3600000 : 1000)) { + Messages message = static_cast(msg); + switch(message) { + case Messages::GoToRunning: isSleeping = false; break; + case Messages::GoToSleep: + NRF_LOG_INFO("[SystemTask] Going to sleep"); + displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep); + isSleeping = true; break; + default: break; + } + } + uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG); + dateTimeController.UpdateTime(systick_counter); + } +} + +void SystemTask::OnButtonPushed() { + + if(!isSleeping) { + NRF_LOG_INFO("[SystemTask] Button pushed"); + displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::ButtonPushed); + } + else { + NRF_LOG_INFO("[SystemTask] Button pushed, waking up"); + displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToRunning); + isSleeping = false; + batteryController.Update(); + displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateBatteryLevel); + } +} + +void SystemTask::OnTouchEvent() { + NRF_LOG_INFO("[SystemTask] Touch event"); + displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::TouchEvent); +} + +void SystemTask::PushMessage(SystemTask::Messages msg) { + BaseType_t xHigherPriorityTaskWoken; + xHigherPriorityTaskWoken = pdFALSE; + xQueueSendFromISR(systemTaksMsgQueue, &msg, &xHigherPriorityTaskWoken); + if (xHigherPriorityTaskWoken) { + /* Actual macro used here is port specific. */ + // TODO : should I do something here? + } +} diff --git a/src/SystemTask/SystemTask.h b/src/SystemTask/SystemTask.h new file mode 100644 index 00000000..cb913545 --- /dev/null +++ b/src/SystemTask/SystemTask.h @@ -0,0 +1,60 @@ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace Pinetime { + namespace System { + class SystemTask { + public: + enum class Messages {GoToSleep, GoToRunning}; + + 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); + + + void Start(); + void PushMessage(Messages msg); + + void OnButtonPushed(); + void OnTouchEvent(); + private: + TaskHandle_t taskHandle; + + Pinetime::Drivers::SpiMaster& spi; + Pinetime::Drivers::St7789& lcd; + Pinetime::Drivers::Cst816S& touchPanel; + Pinetime::Components::LittleVgl& lvgl; + Pinetime::Controllers::Battery& batteryController; + std::unique_ptr displayApp; + Pinetime::Controllers::Ble& bleController; + Pinetime::Controllers::DateTime& dateTimeController; + QueueHandle_t systemTaksMsgQueue; + bool isSleeping = false; + + + 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(); + + + }; + } +} \ No newline at end of file -- cgit v1.2.3-70-g09d2 From f07ffab4c1fa876e8da9a1bcc895ecf0dfa75acf Mon Sep 17 00:00:00 2001 From: JF Date: Sun, 23 Feb 2020 16:14:03 +0100 Subject: Re-enable BLE, BLE status on display and battery level on display. --- doc/SPI-LCD-driver.md | 46 ++++++++++++++++++++++++++++++++++++++ src/BLE/BleManager.h | 1 + src/CMakeLists.txt | 4 ++-- src/DisplayApp/DisplayApp.cpp | 15 +++++-------- src/DisplayApp/DisplayApp.h | 1 - src/DisplayApp/Screens/Clock.cpp | 24 +++++++++++--------- src/DisplayApp/Screens/Clock.h | 24 +++++++++++--------- src/DisplayApp/Screens/Message.cpp | 11 +++++++-- src/DisplayApp/Screens/Message.h | 9 ++++---- src/DisplayApp/Screens/Screen.h | 6 +---- src/DisplayApp/Screens/Tile.cpp | 40 ++++++++++++++++++++------------- src/DisplayApp/Screens/Tile.h | 7 +++--- src/SystemTask/SystemTask.cpp | 6 +++-- src/main.cpp | 9 +------- 14 files changed, 130 insertions(+), 73 deletions(-) create mode 100644 doc/SPI-LCD-driver.md (limited to 'src/SystemTask') diff --git a/doc/SPI-LCD-driver.md b/doc/SPI-LCD-driver.md new file mode 100644 index 00000000..3c33c258 --- /dev/null +++ b/doc/SPI-LCD-driver.md @@ -0,0 +1,46 @@ +# The SPI LCD driver +## Introduction +The LCD controller that drive the display of the Pinetime is the Sitronix ST7789V. This controller is easy to integrate with an MCU thanks to its SPI interface, and has some interesting features like: +- an on-chip display data RAM that can store the whole framebuffer +- partial screen update +- hardware assisted vertical scrolling +- interrupt pin, allowing to drive the display with DMA and IRQ +- ... + +When you want to write a device driver for a specific component, its datasheet is your holy bible. This document contains a lot of information about the chip, its specification, characteristics, features and functionalities. +Luckily for us, the datasheet of the ST7789 is great! It contains everything we need to write a nice driver for our beloved Pinetime. + +In this document, I'll try to explain the process I've followed to write a device driver for the LCD. There were multiple iterations: +- First, I tried to find the correct initialization sequence so that the controller is configured correctly according to the hardware configuration; +- Then, I tried to display some pixels on the screen; +- Next, I wanted to display squares, colors and text; +- Following, there was a need to make that faster and faster again; +- And finally, I wanted to draw beautiful and useful UIs + +I'll describe all these steps in the following chapters. + +## The datasheet +As I said in the introduction, the datasheet will be your bedside book during your journey as a device driver designer. You'll read it from the beginning to the end once, twice, maybe ten times. Then, each time you'll want to do something new, you'll reopen the file and search for that specific paragraph or diagram than explains how the controller works so that you can figure out how to use it. + +The schematic of your board (the Pinetime schematics in this case) will also be very important, as you'll need to know how the LCD controller is physically connected to the MCU. + +How to read the datasheet? I recommand to read it from the beginning to the end (no joke) at least once. You certainly do not need to read everything in details, but it's good to know what information is available and where in the document. It'll be very useful during the developpment phase. +You'll want to read some part with more attention : +- Data color coding in 4-Line Serial Interface : how to send the pixel to be display to the controller +- Display Data Ram : how is the memory organised +- Power On/Off sequence +- System function commands : all the commands you can send to the controller. + +## One Pixel at a time + + +## Bulk transfert + +## DMA + +## IRQ + +## Bare metal integration +Integration customisée dans la lib GFX que j'ai écrite + +## Integration with LittleVGL \ No newline at end of file diff --git a/src/BLE/BleManager.h b/src/BLE/BleManager.h index 13b12a62..68fdff9a 100644 --- a/src/BLE/BleManager.h +++ b/src/BLE/BleManager.h @@ -1,4 +1,5 @@ #pragma once +#include #ifdef __cplusplus extern "C" { diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index efbb3861..3fb4dd6e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -158,7 +158,7 @@ list(APPEND SOURCE_FILES DisplayApp/DisplayApp.cpp DisplayApp/Screens/Screen.cpp DisplayApp/Screens/Clock.cpp -# DisplayApp/Screens/Message.cpp + DisplayApp/Screens/Message.cpp DisplayApp/Screens/Tile.cpp # DisplayApp/Screens/Tab.cpp main.cpp @@ -189,7 +189,7 @@ set(INCLUDE_FILES DisplayApp/DisplayApp.h DisplayApp/Screens/Screen.h DisplayApp/Screens/Clock.h -# DisplayApp/Screens/Message.h + DisplayApp/Screens/Message.h DisplayApp/Screens/Tile.h # DisplayApp/Screens/Tab.h drivers/St7789.h diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp index d70726dd..1a794e04 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/DisplayApp/DisplayApp.cpp @@ -4,17 +4,14 @@ #include #include #include -#include -#include "Components/Gfx/Gfx.h" #include #include #include -#include #include #include #include +#include #include "../SystemTask/SystemTask.h" -//#include using namespace Pinetime::Applications; @@ -31,7 +28,7 @@ DisplayApp::DisplayApp(Pinetime::Drivers::St7789& lcd, batteryController{batteryController}, bleController{bleController}, dateTimeController{dateTimeController}, - currentScreen{new Screens::Clock(this, dateTimeController) }, + currentScreen{new Screens::Clock(this, dateTimeController, batteryController, bleController) }, systemTask{systemTask} { msgQueue = xQueueCreate(queueSize, itemSize); } @@ -126,13 +123,13 @@ void DisplayApp::Refresh() { void DisplayApp::RunningState() { // clockScreen.SetCurrentDateTime(dateTimeController.CurrentDateTime()); - if(!currentScreen->Refresh(true)) { + if(!currentScreen->Refresh()) { currentScreen.reset(nullptr); switch(nextApp) { case Apps::None: case Apps::Launcher: currentScreen.reset(new Screens::Tile(this)); break; - case Apps::Clock: currentScreen.reset(new Screens::Clock(this, dateTimeController)); break; -// case Apps::Test: currentScreen.reset(new Screens::Message(this)); break; + case Apps::Clock: currentScreen.reset(new Screens::Clock(this, dateTimeController, batteryController, bleController)); break; + case Apps::Test: currentScreen.reset(new Screens::Message(this)); break; } nextApp = Apps::None; } @@ -158,7 +155,7 @@ void DisplayApp::OnTouchEvent() { // auto info = touchPanel.GetTouchInfo(); // // if(info.isTouch) { -// gfx.FillRectangle(info.x-10, info.y-10, 20,20, pointColor); +// lcd.DrawPixel(info.x, info.y, pointColor); // pointColor+=10; // } } diff --git a/src/DisplayApp/DisplayApp.h b/src/DisplayApp/DisplayApp.h index 656dd4ed..cb5e9f3b 100644 --- a/src/DisplayApp/DisplayApp.h +++ b/src/DisplayApp/DisplayApp.h @@ -14,7 +14,6 @@ #include "LittleVgl.h" #include #include -//#include namespace Pinetime { diff --git a/src/DisplayApp/Screens/Clock.cpp b/src/DisplayApp/Screens/Clock.cpp index 3b849150..f0bd8338 100644 --- a/src/DisplayApp/Screens/Clock.cpp +++ b/src/DisplayApp/Screens/Clock.cpp @@ -15,7 +15,11 @@ static void event_handler(lv_obj_t * obj, lv_event_t event) { screen->OnObjectEvent(obj, event); } -Clock::Clock(DisplayApp* app, Controllers::DateTime& dateTimeController) : Screen(app), currentDateTime{{}}, version {{}}, dateTimeController{dateTimeController} { +Clock::Clock(DisplayApp* app, + Controllers::DateTime& dateTimeController, + Controllers::Battery& batteryController, + Controllers::Ble& bleController) : Screen(app), currentDateTime{{}}, version {{}}, + dateTimeController{dateTimeController}, batteryController{batteryController}, bleController{bleController} { displayedChar[0] = 0; displayedChar[1] = 0; displayedChar[2] = 0; @@ -65,12 +69,9 @@ Clock::~Clock() { lv_obj_clean(lv_scr_act()); } -bool Clock::Refresh(bool fullRefresh) { - if(fullRefresh) { - auto currentDateTime = dateTimeController.CurrentDateTime(); - } - - if (fullRefresh || batteryPercentRemaining.IsUpdated()) { +bool Clock::Refresh() { + batteryPercentRemaining = batteryController.PercentRemaining(); + if (batteryPercentRemaining.IsUpdated()) { char batteryChar[11]; auto newBatteryValue = batteryPercentRemaining.Get(); newBatteryValue = (newBatteryValue > 100) ? 100 : newBatteryValue; @@ -80,8 +81,9 @@ bool Clock::Refresh(bool fullRefresh) { lv_label_set_text(label_battery, batteryChar); } - if (fullRefresh || bleState.IsUpdated()) { - if(bleState.Get() == BleConnectionStates::Connected) { + bleState = bleController.IsConnected(); + if (bleState.IsUpdated()) { + if(bleState.Get() == true) { lv_obj_set_hidden(label_ble, false); lv_label_set_text(label_ble, "BLE"); } else { @@ -91,7 +93,7 @@ bool Clock::Refresh(bool fullRefresh) { currentDateTime = dateTimeController.CurrentDateTime(); - if(fullRefresh || currentDateTime.IsUpdated()) { + if(currentDateTime.IsUpdated()) { auto newDateTime = currentDateTime.Get(); auto dp = date::floor(newDateTime); @@ -138,7 +140,7 @@ bool Clock::Refresh(bool fullRefresh) { } } - if(fullRefresh || version.IsUpdated()) { + if(version.IsUpdated()) { auto dummy = version.Get(); char versionStr[20]; sprintf(versionStr, "VERSION: %d.%d.%d", Version::Major(), Version::Minor(), Version::Patch()); diff --git a/src/DisplayApp/Screens/Clock.h b/src/DisplayApp/Screens/Clock.h index a358e41b..d6e44fda 100644 --- a/src/DisplayApp/Screens/Clock.h +++ b/src/DisplayApp/Screens/Clock.h @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include "../Fonts/lcdfont14.h" #include "../Fonts/lcdfont70.h" #include "../../Version.h" @@ -24,8 +26,10 @@ namespace Pinetime { T& Get() { this->isUpdated = false; return value; } DirtyValue& operator=(const T& other) { - this->value = other; - this->isUpdated = true; + if (this->value != other) { + this->value = other; + this->isUpdated = true; + } return *this; } private: @@ -34,17 +38,15 @@ namespace Pinetime { }; class Clock : public Screen{ public: - enum class BleConnectionStates{ NotConnected, Connected}; - Clock(DisplayApp* app, Controllers::DateTime& dateTimeController); + Clock(DisplayApp* app, + Controllers::DateTime& dateTimeController, + Controllers::Battery& batteryController, + Controllers::Ble& bleController); ~Clock() override; - bool Refresh(bool fullRefresh) override; + bool Refresh() override; bool OnButtonPushed() override; - void SetBatteryPercentRemaining(uint8_t percent) { batteryPercentRemaining = percent; } - void SetBleConnectionState(BleConnectionStates state) { bleState = state; } - void SetCurrentDateTime(const std::chrono::time_point& tp) { currentDateTime = tp;} - void OnObjectEvent(lv_obj_t *pObj, lv_event_t i); private: static const char* MonthToString(Pinetime::Controllers::DateTime::Months month); @@ -60,7 +62,7 @@ namespace Pinetime { uint8_t currentDay = 0; DirtyValue batteryPercentRemaining {0}; - DirtyValue bleState {BleConnectionStates::NotConnected}; + DirtyValue bleState {false}; DirtyValue> currentDateTime; DirtyValue version; @@ -75,6 +77,8 @@ namespace Pinetime { lv_obj_t* backgroundLabel; Controllers::DateTime& dateTimeController; + Controllers::Battery& batteryController; + Controllers::Ble& bleController; bool running = true; diff --git a/src/DisplayApp/Screens/Message.cpp b/src/DisplayApp/Screens/Message.cpp index c9e0938f..c8a4ea1f 100644 --- a/src/DisplayApp/Screens/Message.cpp +++ b/src/DisplayApp/Screens/Message.cpp @@ -19,7 +19,7 @@ static void event_handler(lv_obj_t * obj, lv_event_t event) { screen->OnObjectEvent(obj, event); } -Message::Message(DisplayApp* app, Pinetime::Components::Gfx &gfx) : Screen(app, gfx) { +Message::Message(DisplayApp* app) : Screen(app) { backgroundLabel = lv_label_create(lv_scr_act(), NULL); backgroundLabel->user_data = this; @@ -55,11 +55,13 @@ Message::~Message() { lv_obj_clean(lv_scr_act()); } -void Message::Refresh(bool fullRefresh) { +bool Message::Refresh() { if(previousClickCount != clickCount) { lv_label_set_text_fmt(labelClick, "%d", clickCount); previousClickCount = clickCount; } + + return running; } void Message::OnObjectEvent(lv_obj_t *obj, lv_event_t event) { @@ -79,3 +81,8 @@ void Message::OnObjectEvent(lv_obj_t *obj, lv_event_t event) { NRF_LOG_INFO("Toggled"); } } + +bool Message::OnButtonPushed() { + running = false; + return true; +} diff --git a/src/DisplayApp/Screens/Message.h b/src/DisplayApp/Screens/Message.h index 2f1da942..4e87bba4 100644 --- a/src/DisplayApp/Screens/Message.h +++ b/src/DisplayApp/Screens/Message.h @@ -15,15 +15,13 @@ namespace Pinetime { namespace Screens { class Message : public Screen{ public: - explicit Message(DisplayApp* app, Components::Gfx& gfx); + explicit Message(DisplayApp* app); ~Message() override; - void Refresh(bool fullRefresh) override; + bool Refresh() override; + bool OnButtonPushed(); void OnObjectEvent(lv_obj_t* obj, lv_event_t event); - void OnButtonPushed() override { nextScreen = Screen::NextScreen::Menu; } private: - const FONT_INFO largeFont {lCD_70ptFontInfo.height, lCD_70ptFontInfo.startChar, lCD_70ptFontInfo.endChar, lCD_70ptFontInfo.spacePixels, lCD_70ptFontInfo.charInfo, lCD_70ptFontInfo.data}; - const FONT_INFO smallFont {lCD_14ptFontInfo.height, lCD_14ptFontInfo.startChar, lCD_14ptFontInfo.endChar, lCD_14ptFontInfo.spacePixels, lCD_14ptFontInfo.charInfo, lCD_14ptFontInfo.data}; lv_style_t* labelStyle; lv_obj_t * label; @@ -33,6 +31,7 @@ namespace Pinetime { uint32_t clickCount = 0 ; uint32_t previousClickCount = 0; + bool running = true; }; } } diff --git a/src/DisplayApp/Screens/Screen.h b/src/DisplayApp/Screens/Screen.h index 625daada..6cbd41ad 100644 --- a/src/DisplayApp/Screens/Screen.h +++ b/src/DisplayApp/Screens/Screen.h @@ -1,20 +1,16 @@ #pragma once -#include - namespace Pinetime { namespace Applications { class DisplayApp; namespace Screens { class Screen { public: - enum class NextScreen {None, Clock, Menu, App}; - Screen(DisplayApp* app) : app{app} {} virtual ~Screen() = default; // Return false if the app can be closed, true if it must continue to run - virtual bool Refresh(bool fullRefresh) = 0; + virtual bool Refresh() = 0; // Return false if the button hasn't been handled by the app, true if it has been handled virtual bool OnButtonPushed() { return false; } diff --git a/src/DisplayApp/Screens/Tile.cpp b/src/DisplayApp/Screens/Tile.cpp index c9e33544..6ee677dc 100644 --- a/src/DisplayApp/Screens/Tile.cpp +++ b/src/DisplayApp/Screens/Tile.cpp @@ -1,14 +1,8 @@ -#include -#include -#include -#include #include #include #include -#include #include "Tile.h" #include -#include using namespace Pinetime::Applications::Screens; @@ -17,7 +11,9 @@ extern lv_font_t jetbrains_mono_bold_20; static void event_handler(lv_obj_t * obj, lv_event_t event) { Tile* screen = static_cast(obj->user_data); - screen->OnObjectEvent(obj, event); + uint32_t* eventDataPtr = (uint32_t*) lv_event_get_data(); + uint32_t eventData = *eventDataPtr; + screen->OnObjectEvent(obj, event, eventData); } static const char * btnm_map1[] = {"App1", "App2", "App3", "\n", "App4", "App5", "App11", ""}; @@ -104,19 +100,28 @@ Tile::~Tile() { lv_obj_clean(lv_scr_act()); } -bool Tile::Refresh(bool fullRefresh) { +bool Tile::Refresh() { return running; } -void Tile::OnObjectEvent(lv_obj_t *obj, lv_event_t event) { +void Tile::OnObjectEvent(lv_obj_t *obj, lv_event_t event, uint32_t buttonId) { auto* tile = static_cast(obj->user_data); - if(event == LV_EVENT_CLICKED) { - - tile->StartApp(); + if(event == LV_EVENT_VALUE_CHANGED) { + switch(buttonId) { + case 0: + case 1: + case 2: + tile->StartClockApp(); + break; + case 3: + case 4: + case 5: + tile->StartTestApp(); + + break; + } clickCount++; } - else if(event == LV_EVENT_VALUE_CHANGED) { - } } bool Tile::OnButtonPushed() { @@ -125,7 +130,12 @@ bool Tile::OnButtonPushed() { return true; } -void Tile::StartApp() { +void Tile::StartClockApp() { app->StartApp(DisplayApp::Apps::Clock); running = false; } + +void Tile::StartTestApp() { + app->StartApp(DisplayApp::Apps::Test); + running = false; +} diff --git a/src/DisplayApp/Screens/Tile.h b/src/DisplayApp/Screens/Tile.h index 03cfb6d2..630fc666 100644 --- a/src/DisplayApp/Screens/Tile.h +++ b/src/DisplayApp/Screens/Tile.h @@ -18,10 +18,10 @@ namespace Pinetime { explicit Tile(DisplayApp* app); ~Tile() override; - bool Refresh(bool fullRefresh) override; + bool Refresh() override; bool OnButtonPushed() override; - void OnObjectEvent(lv_obj_t* obj, lv_event_t event); + void OnObjectEvent(lv_obj_t* obj, lv_event_t event, uint32_t buttonId); private: @@ -50,7 +50,8 @@ namespace Pinetime { uint32_t clickCount = 0 ; uint32_t previousClickCount = 0; - void StartApp(); + void StartClockApp(); + void StartTestApp(); bool running = true; }; } diff --git a/src/SystemTask/SystemTask.cpp b/src/SystemTask/SystemTask.cpp index 642e36a2..91822fa2 100644 --- a/src/SystemTask/SystemTask.cpp +++ b/src/SystemTask/SystemTask.cpp @@ -3,6 +3,8 @@ #include #include #include +#include +#include #include "SystemTask.h" #include "../main.h" using namespace Pinetime::System; @@ -16,7 +18,7 @@ SystemTask::SystemTask(Pinetime::Drivers::SpiMaster &spi, Pinetime::Drivers::St7 } void SystemTask::Start() { - if (pdPASS != xTaskCreate(SystemTask::Process, "MAIN", 256, this, 0, &taskHandle)) + if (pdPASS != xTaskCreate(SystemTask::Process, "MAIN", 350, this, 0, &taskHandle)) APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); } @@ -29,7 +31,7 @@ void SystemTask::Process(void *instance) { void SystemTask::Work() { APP_GPIOTE_INIT(2); bool erase_bonds=false; -// nrf_sdh_freertos_init(ble_manager_start_advertising, &erase_bonds); + nrf_sdh_freertos_init(ble_manager_start_advertising, &erase_bonds); spi.Init(); lcd.Init(); diff --git a/src/main.cpp b/src/main.cpp index 08b15f62..6a271a49 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,25 +1,19 @@ #include #include -#include #include #include #include #include #include -#include #include #include -#include #include #include #include "BLE/BleManager.h" #include "Components/Battery/BatteryController.h" #include "Components/Ble/BleController.h" -#include "../drivers/Cst816s.h" #include #include - -#include #include #include @@ -134,12 +128,11 @@ int main(void) { systemTask.reset(new Pinetime::System::SystemTask(*spi, *lcd, *touchPanel, *lvgl, batteryController, bleController, dateTimeController)); systemTask->Start(); -/* ble_manager_init(); ble_manager_set_new_time_callback(OnNewTime); ble_manager_set_ble_connection_callback(OnBleConnection); ble_manager_set_ble_disconnection_callback(OnBleDisconnection); -*/ + vTaskStartScheduler(); for (;;) { -- cgit v1.2.3-70-g09d2 From 0aa1803ea22b119401bcd2e4d9d5278e8386f151 Mon Sep 17 00:00:00 2001 From: JF Date: Sun, 23 Feb 2020 21:09:11 +0100 Subject: Enable watchdog, and issue a WDT reset when the button is pushed for more than 7s. --- src/CMakeLists.txt | 4 +-- src/SystemTask/SystemTask.cpp | 8 +++++- src/SystemTask/SystemTask.h | 2 ++ src/drivers/Watchdog.cpp | 60 +++++++++++++++++++++++++++++++++++++++++++ src/drivers/Watchdog.h | 17 ++++++++++++ src/libs/lvgl | 2 +- 6 files changed, 89 insertions(+), 4 deletions(-) create mode 100644 src/drivers/Watchdog.cpp create mode 100644 src/drivers/Watchdog.h (limited to 'src/SystemTask') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 3fb4dd6e..6b5c5741 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -160,11 +160,10 @@ list(APPEND SOURCE_FILES DisplayApp/Screens/Clock.cpp DisplayApp/Screens/Message.cpp DisplayApp/Screens/Tile.cpp -# DisplayApp/Screens/Tab.cpp main.cpp drivers/St7789.cpp drivers/SpiMaster.cpp -# Components/Gfx/Gfx.cpp + drivers/Watchdog.cpp BLE/BleManager.c Components/Battery/BatteryController.cpp Components/Ble/BleController.cpp @@ -194,6 +193,7 @@ set(INCLUDE_FILES # DisplayApp/Screens/Tab.h drivers/St7789.h drivers/SpiMaster.h + drivers/Watchdog.h BLE/BleManager.h Components/Battery/BatteryController.h Components/Ble/BleController.h diff --git a/src/SystemTask/SystemTask.cpp b/src/SystemTask/SystemTask.cpp index 91822fa2..e15846da 100644 --- a/src/SystemTask/SystemTask.cpp +++ b/src/SystemTask/SystemTask.cpp @@ -29,6 +29,9 @@ void SystemTask::Process(void *instance) { } 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); bool erase_bonds=false; nrf_sdh_freertos_init(ble_manager_start_advertising, &erase_bonds); @@ -70,7 +73,7 @@ void SystemTask::Work() { while(true) { uint8_t msg; - if (xQueueReceive(systemTaksMsgQueue, &msg, isSleeping?3600000 : 1000)) { + if (xQueueReceive(systemTaksMsgQueue, &msg, isSleeping?2500 : 1000)) { Messages message = static_cast(msg); switch(message) { case Messages::GoToRunning: isSleeping = false; break; @@ -83,6 +86,9 @@ void SystemTask::Work() { } uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG); dateTimeController.UpdateTime(systick_counter); + + if(!nrf_gpio_pin_read(pinButton)) + watchdog.Kick(); } } diff --git a/src/SystemTask/SystemTask.h b/src/SystemTask/SystemTask.h index cb913545..f5ba2d75 100644 --- a/src/SystemTask/SystemTask.h +++ b/src/SystemTask/SystemTask.h @@ -7,6 +7,7 @@ #include #include #include +#include namespace Pinetime { namespace System { @@ -41,6 +42,7 @@ namespace Pinetime { Pinetime::Controllers::DateTime& dateTimeController; QueueHandle_t systemTaksMsgQueue; bool isSleeping = false; + Pinetime::Drivers::Watchdog watchdog; static constexpr uint8_t pinSpiSck = 2; diff --git a/src/drivers/Watchdog.cpp b/src/drivers/Watchdog.cpp new file mode 100644 index 00000000..b0dc12e5 --- /dev/null +++ b/src/drivers/Watchdog.cpp @@ -0,0 +1,60 @@ +#include +#include +#include +#include "Watchdog.h" +using namespace Pinetime::Drivers; + + +void Watchdog::Setup(uint8_t timeoutSeconds) { + NRF_WDT->CONFIG &= ~(WDT_CONFIG_SLEEP_Msk << WDT_CONFIG_SLEEP_Pos); + NRF_WDT->CONFIG |= (WDT_CONFIG_HALT_Run << WDT_CONFIG_SLEEP_Pos); + + NRF_WDT->CONFIG &= ~(WDT_CONFIG_HALT_Msk << WDT_CONFIG_HALT_Pos); + NRF_WDT->CONFIG |= (WDT_CONFIG_HALT_Pause << WDT_CONFIG_HALT_Pos); + + /* timeout (s) = (CRV + 1) / 32768 */ + // JF : 7500 = 7.5s + uint32_t crv = (((timeoutSeconds*1000u) << 15u) / 1000) - 1; + NRF_WDT->CRV = crv; + + /* Enable reload requests */ + NRF_WDT->RREN = (WDT_RREN_RR0_Enabled << WDT_RREN_RR0_Pos); +} + +void Watchdog::Start() { + NRF_WDT->TASKS_START = 1; +} + +void Watchdog::Kick() { + NRF_WDT->RR[0] = WDT_RR_RR_Reload; +} + +Watchdog::ResetReasons Watchdog::ResetReason() { + 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; + return ResetReasons::HardReset; +} + +const char *Watchdog::ResetReasonToString(Watchdog::ResetReasons reason) { + switch(reason) { + case ResetReasons::ResetPin: return "Reset pin"; + case ResetReasons::Watchdog: return "Watchdog"; + case ResetReasons::DebugInterface: return "Debug interface"; + case ResetReasons::LpComp: return "LPCOMP"; + case ResetReasons::SystemOff: return "System OFF"; + case ResetReasons::CpuLockup: return "CPU Lock-up"; + case ResetReasons::SoftReset: return "Soft reset"; + case ResetReasons::NFC: return "NFC"; + case ResetReasons::HardReset: return "Hard reset"; + default: return "Unknown"; + } +} diff --git a/src/drivers/Watchdog.h b/src/drivers/Watchdog.h new file mode 100644 index 00000000..da192d9e --- /dev/null +++ b/src/drivers/Watchdog.h @@ -0,0 +1,17 @@ +#pragma once + +namespace Pinetime { + namespace Drivers { + class Watchdog { + public: + enum class ResetReasons { ResetPin, Watchdog, SoftReset, CpuLockup, SystemOff, LpComp, DebugInterface, NFC, HardReset }; + void Setup(uint8_t timeoutSeconds); + void Start(); + void Kick(); + + ResetReasons ResetReason(); + static const char* ResetReasonToString(ResetReasons reason); + + }; + } +} diff --git a/src/libs/lvgl b/src/libs/lvgl index 10b9c9b2..ee95d1c9 160000 --- a/src/libs/lvgl +++ b/src/libs/lvgl @@ -1 +1 @@ -Subproject commit 10b9c9b2f5344e7b2f5cc00a19ed86ed56ae9866 +Subproject commit ee95d1c9cf74899585f9165458911f2d54ca7500 -- cgit v1.2.3-70-g09d2 From 179b14f48c2c7506d1a7832899e134cc3868a41c Mon Sep 17 00:00:00 2001 From: JF Date: Wed, 26 Feb 2020 20:49:26 +0100 Subject: Add new Screens (gauge, meter,...) --- src/CMakeLists.txt | 17 +++++++++ src/DisplayApp/DisplayApp.cpp | 4 +++ src/DisplayApp/DisplayApp.h | 2 +- src/DisplayApp/Screens/Gauge.cpp | 57 +++++++++++++++++++++++++++++ src/DisplayApp/Screens/Gauge.h | 39 ++++++++++++++++++++ src/DisplayApp/Screens/Meter.cpp | 47 ++++++++++++++++++++++++ src/DisplayApp/Screens/Meter.h | 38 ++++++++++++++++++++ src/DisplayApp/Screens/Modal.cpp | 77 ++++++++++++++++++++++++++++++++++++++++ src/DisplayApp/Screens/Modal.h | 44 +++++++++++++++++++++++ src/DisplayApp/Screens/Tile.cpp | 21 ++++++++++- src/DisplayApp/Screens/Tile.h | 5 +++ src/SystemTask/SystemTask.cpp | 2 +- src/main.cpp | 8 ++--- 13 files changed, 354 insertions(+), 7 deletions(-) create mode 100644 src/DisplayApp/Screens/Gauge.cpp create mode 100644 src/DisplayApp/Screens/Gauge.h create mode 100644 src/DisplayApp/Screens/Meter.cpp create mode 100644 src/DisplayApp/Screens/Meter.h create mode 100644 src/DisplayApp/Screens/Modal.cpp create mode 100644 src/DisplayApp/Screens/Modal.h (limited to 'src/SystemTask') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6b5c5741..ac19cf09 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,6 +48,8 @@ set(LVGL_SRC libs/lvgl/src/lv_misc/lv_anim.c libs/lvgl/src/lv_misc/lv_anim.h + libs/lvgl/src/lv_misc/lv_async.h + libs/lvgl/src/lv_misc/lv_async.c libs/lvgl/src/lv_misc/lv_fs.c libs/lvgl/src/lv_misc/lv_fs.h libs/lvgl/src/lv_misc/lv_task.c @@ -149,6 +151,15 @@ set(LVGL_SRC libs/lvgl/src/lv_objx/lv_page.h libs/lvgl/src/lv_objx/lv_img.c libs/lvgl/src/lv_objx/lv_img.h + libs/lvgl/src/lv_objx/lv_lmeter.c + libs/lvgl/src/lv_objx/lv_lmeter.h + libs/lvgl/src/lv_objx/lv_arc.c + libs/lvgl/src/lv_objx/lv_arc.h + libs/lvgl/src/lv_objx/lv_gauge.c + libs/lvgl/src/lv_objx/lv_gauge.h + + libs/lvgl/src/lv_objx/lv_mbox.c + libs/lvgl/src/lv_objx/lv_mbox.h ) @@ -160,6 +171,9 @@ list(APPEND SOURCE_FILES DisplayApp/Screens/Clock.cpp DisplayApp/Screens/Message.cpp DisplayApp/Screens/Tile.cpp + DisplayApp/Screens/Meter.cpp + DisplayApp/Screens/Gauge.cpp + DisplayApp/Screens/Modal.cpp main.cpp drivers/St7789.cpp drivers/SpiMaster.cpp @@ -190,6 +204,9 @@ set(INCLUDE_FILES DisplayApp/Screens/Clock.h DisplayApp/Screens/Message.h DisplayApp/Screens/Tile.h + DisplayApp/Screens/Meter.h + DisplayApp/Screens/Gauge.h + DisplayApp/Screens/Modal.h # DisplayApp/Screens/Tab.h drivers/St7789.h drivers/SpiMaster.h diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp index 1a794e04..2519f40e 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/DisplayApp/DisplayApp.cpp @@ -11,6 +11,8 @@ #include #include #include +#include +#include #include "../SystemTask/SystemTask.h" using namespace Pinetime::Applications; @@ -130,6 +132,8 @@ void DisplayApp::RunningState() { case Apps::Launcher: currentScreen.reset(new Screens::Tile(this)); break; case Apps::Clock: currentScreen.reset(new Screens::Clock(this, dateTimeController, batteryController, bleController)); break; 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; } nextApp = Apps::None; } diff --git a/src/DisplayApp/DisplayApp.h b/src/DisplayApp/DisplayApp.h index cb5e9f3b..348fd5bf 100644 --- a/src/DisplayApp/DisplayApp.h +++ b/src/DisplayApp/DisplayApp.h @@ -35,7 +35,7 @@ namespace Pinetime { void Start(); void PushMessage(Messages msg); - enum class Apps {None, Launcher, Clock, Test}; + enum class Apps {None, Launcher, Clock, Test, Meter, Gauge}; void StartApp(Apps app); private: diff --git a/src/DisplayApp/Screens/Gauge.cpp b/src/DisplayApp/Screens/Gauge.cpp new file mode 100644 index 00000000..33f76a74 --- /dev/null +++ b/src/DisplayApp/Screens/Gauge.cpp @@ -0,0 +1,57 @@ +#include +#include "Gauge.h" +#include "../DisplayApp.h" + +using namespace Pinetime::Applications::Screens; +extern lv_font_t jetbrains_mono_extrabold_compressedextrabold_compressed; +extern lv_font_t jetbrains_mono_bold_20; + + +Gauge::Gauge(Pinetime::Applications::DisplayApp *app) : Screen(app) { + /*Create a style*/ + lv_style_copy(&style, &lv_style_pretty_color); + style.body.main_color = LV_COLOR_CYAN; /*Line color at the beginning*/ + style.body.grad_color = LV_COLOR_RED; /*Line color at the end*/ + style.body.padding.left = 10; /*Scale line length*/ + style.body.padding.inner = 8 ; /*Scale label padding*/ + style.body.border.color = lv_color_hex3(0x333); /*Needle middle circle color*/ + style.line.width = 3; + style.text.color = LV_COLOR_WHITE; + style.line.color = LV_COLOR_RED; /*Line color after the critical value*/ + + /*Describe the color for the needles*/ + + needle_colors[0] = LV_COLOR_ORANGE; + + /*Create a gauge*/ + gauge1 = lv_gauge_create(lv_scr_act(), NULL); + lv_gauge_set_style(gauge1, LV_GAUGE_STYLE_MAIN, &style); + lv_gauge_set_needle_count(gauge1, 1, needle_colors); + lv_obj_set_size(gauge1, 180, 180); + lv_obj_align(gauge1, NULL, LV_ALIGN_CENTER, 0, 0); + lv_gauge_set_scale(gauge1, 360, 60, 0); + lv_gauge_set_range(gauge1, 0, 59); + + /*Set the values*/ + lv_gauge_set_value(gauge1, 0, value); +} + +Gauge::~Gauge() { + + + lv_obj_clean(lv_scr_act()); +} + +bool Gauge::Refresh() { +// lv_lmeter_set_value(lmeter, value++); /*Set the current value*/ +// if(value>=60) value = 0; + + lv_gauge_set_value(gauge1, 0, value++); + if(value == 59) value = 0; + return running; +} + +bool Gauge::OnButtonPushed() { + running = false; + return true; +} diff --git a/src/DisplayApp/Screens/Gauge.h b/src/DisplayApp/Screens/Gauge.h new file mode 100644 index 00000000..463654ee --- /dev/null +++ b/src/DisplayApp/Screens/Gauge.h @@ -0,0 +1,39 @@ +#pragma once + +#include +#include +#include +#include "Screen.h" +#include +#include +#include +#include +#include +#include "../Fonts/lcdfont14.h" +#include "../Fonts/lcdfont70.h" +#include "../../Version.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + + class Gauge : public Screen{ + public: + Gauge(DisplayApp* app); + ~Gauge() override; + + bool Refresh() override; + bool OnButtonPushed() override; + + private: + lv_style_t style; + lv_color_t needle_colors[3]; + lv_obj_t * gauge1; + + uint32_t value=30; + bool running = true; + + }; + } + } +} diff --git a/src/DisplayApp/Screens/Meter.cpp b/src/DisplayApp/Screens/Meter.cpp new file mode 100644 index 00000000..9daafad3 --- /dev/null +++ b/src/DisplayApp/Screens/Meter.cpp @@ -0,0 +1,47 @@ +#include +#include "Meter.h" +#include "../DisplayApp.h" + +using namespace Pinetime::Applications::Screens; +extern lv_font_t jetbrains_mono_extrabold_compressedextrabold_compressed; +extern lv_font_t jetbrains_mono_bold_20; + + +Meter::Meter(Pinetime::Applications::DisplayApp *app) : Screen(app) { + + lv_style_copy(&style_lmeter, &lv_style_pretty_color); + style_lmeter.line.width = 2; + style_lmeter.line.color = LV_COLOR_SILVER; + style_lmeter.body.main_color = lv_color_make(255,0,0); + style_lmeter.body.grad_color = lv_color_make(160,0,0); + style_lmeter.body.padding.left = 16; /*Line length*/ + + /*Create a line meter */ + lmeter = lv_lmeter_create(lv_scr_act(), NULL); + lv_lmeter_set_range(lmeter, 0, 60); /*Set the range*/ + lv_lmeter_set_value(lmeter, value); /*Set the current value*/ + lv_lmeter_set_angle_offset(lmeter, 180); + lv_lmeter_set_scale(lmeter, 360, 60); /*Set the angle and number of lines*/ + lv_lmeter_set_style(lmeter, LV_LMETER_STYLE_MAIN, &style_lmeter); /*Apply the new style*/ + lv_obj_set_size(lmeter, 150, 150); + lv_obj_align(lmeter, NULL, LV_ALIGN_CENTER, 0, 0); + +} + +Meter::~Meter() { + + + lv_obj_clean(lv_scr_act()); +} + +bool Meter::Refresh() { + lv_lmeter_set_value(lmeter, value++); /*Set the current value*/ + if(value>=60) value = 0; + + return running; +} + +bool Meter::OnButtonPushed() { + running = false; + return true; +} diff --git a/src/DisplayApp/Screens/Meter.h b/src/DisplayApp/Screens/Meter.h new file mode 100644 index 00000000..1a08b46c --- /dev/null +++ b/src/DisplayApp/Screens/Meter.h @@ -0,0 +1,38 @@ +#pragma once + +#include +#include +#include +#include "Screen.h" +#include +#include +#include +#include +#include +#include "../Fonts/lcdfont14.h" +#include "../Fonts/lcdfont70.h" +#include "../../Version.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + + class Meter : public Screen{ + public: + Meter(DisplayApp* app); + ~Meter() override; + + bool Refresh() override; + bool OnButtonPushed() override; + + private: + lv_style_t style_lmeter; + lv_obj_t * lmeter; + + uint32_t value=0; + bool running = true; + + }; + } + } +} diff --git a/src/DisplayApp/Screens/Modal.cpp b/src/DisplayApp/Screens/Modal.cpp new file mode 100644 index 00000000..a1b955cf --- /dev/null +++ b/src/DisplayApp/Screens/Modal.cpp @@ -0,0 +1,77 @@ +#include +#include "Modal.h" +#include "../DisplayApp.h" + +using namespace Pinetime::Applications::Screens; +extern lv_font_t jetbrains_mono_extrabold_compressedextrabold_compressed; +extern lv_font_t jetbrains_mono_bold_20; + +Modal::Modal(Pinetime::Applications::DisplayApp *app) : Screen(app) { + + +} + +Modal::~Modal() { + lv_obj_clean(lv_scr_act()); +} + +bool Modal::Refresh() { + + return running; +} + +bool Modal::OnButtonPushed() { + running = false; + return true; +} + +void Modal::Show() { + 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", "Cancel", ""}; + + /* 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, "Hello world!"); + lv_obj_align(mbox, NULL, LV_ALIGN_CENTER, 0, 0); + lv_obj_set_event_cb(mbox, Modal::mbox_event_cb); + + /* 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)); + mbox = NULL; /* happens before object is actually deleted! */ +} + +void Modal::mbox_event_cb(lv_obj_t *obj, lv_event_t evt) { + auto* m = static_cast(obj->user_data); + m->OnEvent(obj, evt); +} + +void Modal::OnEvent(lv_obj_t *event_obj, lv_event_t evt) { + if(evt == LV_EVENT_DELETE && event_obj == mbox) { + /* Delete the parent modal background */ + lv_obj_del_async(lv_obj_get_parent(mbox)); + mbox = NULL; /* happens before object is actually deleted! */ + } else if(evt == LV_EVENT_VALUE_CHANGED) { + /* A button was clicked */ + lv_mbox_start_auto_close(mbox, 100); + } +} diff --git a/src/DisplayApp/Screens/Modal.h b/src/DisplayApp/Screens/Modal.h new file mode 100644 index 00000000..de287293 --- /dev/null +++ b/src/DisplayApp/Screens/Modal.h @@ -0,0 +1,44 @@ +#pragma once + +#include +#include +#include +#include "Screen.h" +#include +#include +#include +#include +#include +#include "../Fonts/lcdfont14.h" +#include "../Fonts/lcdfont70.h" +#include "../../Version.h" + +namespace Pinetime { + namespace Applications { + namespace Screens { + + class Modal : public Screen{ + public: + Modal(DisplayApp* app); + ~Modal() override; + + void Show(); + void Hide(); + + bool Refresh() override; + bool OnButtonPushed() override; + + static void mbox_event_cb(lv_obj_t *obj, lv_event_t evt); + private: + void OnEvent(lv_obj_t *event_obj, lv_event_t evt); + + lv_style_t modal_style; + lv_obj_t *obj; + lv_obj_t *mbox; + lv_obj_t *info; + bool running = true; + + }; + } + } +} diff --git a/src/DisplayApp/Screens/Tile.cpp b/src/DisplayApp/Screens/Tile.cpp index 6ee677dc..1c85aa1d 100644 --- a/src/DisplayApp/Screens/Tile.cpp +++ b/src/DisplayApp/Screens/Tile.cpp @@ -16,9 +16,11 @@ static void event_handler(lv_obj_t * obj, lv_event_t event) { screen->OnObjectEvent(obj, event, eventData); } -static const char * btnm_map1[] = {"App1", "App2", "App3", "\n", "App4", "App5", "App11", ""}; +static const char * btnm_map1[] = {"Meter", "Gauge", "Clock", "\n", "App4", "App5", "App11", ""}; Tile::Tile(DisplayApp* app) : Screen(app) { + modal.reset(new Modal(app)); + static lv_point_t valid_pos[] = {{0,0}, {LV_COORD_MIN, LV_COORD_MIN}}; tileview = lv_tileview_create(lv_scr_act(), NULL); lv_tileview_set_valid_positions(tileview, valid_pos, 1); @@ -109,11 +111,17 @@ void Tile::OnObjectEvent(lv_obj_t *obj, lv_event_t event, uint32_t buttonId) { if(event == LV_EVENT_VALUE_CHANGED) { switch(buttonId) { case 0: + tile->StartMeterApp(); + break; case 1: + tile->StartGaugeApp(); + break; case 2: tile->StartClockApp(); break; case 3: + modal->Show(); + break; case 4: case 5: tile->StartTestApp(); @@ -139,3 +147,14 @@ void Tile::StartTestApp() { app->StartApp(DisplayApp::Apps::Test); running = false; } + +void Tile::StartMeterApp() { + app->StartApp(DisplayApp::Apps::Meter); + running = false; +} + +void Tile::StartGaugeApp() { + app->StartApp(DisplayApp::Apps::Gauge); + running = false; +} + diff --git a/src/DisplayApp/Screens/Tile.h b/src/DisplayApp/Screens/Tile.h index 630fc666..eb253435 100644 --- a/src/DisplayApp/Screens/Tile.h +++ b/src/DisplayApp/Screens/Tile.h @@ -8,6 +8,7 @@ #include "../Fonts/lcdfont14.h" #include "../Fonts/lcdfont70.h" #include "../../Version.h" +#include "Modal.h" #include namespace Pinetime { @@ -52,7 +53,11 @@ namespace Pinetime { uint32_t previousClickCount = 0; void StartClockApp(); void StartTestApp(); + void StartMeterApp(); + void StartGaugeApp(); bool running = true; + + std::unique_ptr modal; }; } } diff --git a/src/SystemTask/SystemTask.cpp b/src/SystemTask/SystemTask.cpp index e15846da..5a3d9ca6 100644 --- a/src/SystemTask/SystemTask.cpp +++ b/src/SystemTask/SystemTask.cpp @@ -34,7 +34,7 @@ void SystemTask::Work() { NRF_LOG_INFO("Last reset reason : %s", Pinetime::Drivers::Watchdog::ResetReasonToString(watchdog.ResetReason())); APP_GPIOTE_INIT(2); bool erase_bonds=false; - nrf_sdh_freertos_init(ble_manager_start_advertising, &erase_bonds); +// nrf_sdh_freertos_init(ble_manager_start_advertising, &erase_bonds); spi.Init(); lcd.Init(); diff --git a/src/main.cpp b/src/main.cpp index 6a271a49..5a9df6cb 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -128,10 +128,10 @@ int main(void) { systemTask.reset(new Pinetime::System::SystemTask(*spi, *lcd, *touchPanel, *lvgl, batteryController, bleController, dateTimeController)); systemTask->Start(); - ble_manager_init(); - ble_manager_set_new_time_callback(OnNewTime); - ble_manager_set_ble_connection_callback(OnBleConnection); - ble_manager_set_ble_disconnection_callback(OnBleDisconnection); +// ble_manager_init(); +// ble_manager_set_new_time_callback(OnNewTime); +// ble_manager_set_ble_connection_callback(OnBleConnection); +// ble_manager_set_ble_disconnection_callback(OnBleDisconnection); vTaskStartScheduler(); -- cgit v1.2.3-70-g09d2 From 6b5b0112e3bb9ba325be803018380ab429120cbc Mon Sep 17 00:00:00 2001 From: JF Date: Mon, 2 Mar 2020 20:13:42 +0100 Subject: Re-Enable BLE --- src/SystemTask/SystemTask.cpp | 2 +- src/main.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'src/SystemTask') diff --git a/src/SystemTask/SystemTask.cpp b/src/SystemTask/SystemTask.cpp index 5a3d9ca6..e15846da 100644 --- a/src/SystemTask/SystemTask.cpp +++ b/src/SystemTask/SystemTask.cpp @@ -34,7 +34,7 @@ void SystemTask::Work() { NRF_LOG_INFO("Last reset reason : %s", Pinetime::Drivers::Watchdog::ResetReasonToString(watchdog.ResetReason())); APP_GPIOTE_INIT(2); bool erase_bonds=false; -// nrf_sdh_freertos_init(ble_manager_start_advertising, &erase_bonds); + nrf_sdh_freertos_init(ble_manager_start_advertising, &erase_bonds); spi.Init(); lcd.Init(); diff --git a/src/main.cpp b/src/main.cpp index 72db6ea8..32ceb843 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -142,10 +142,10 @@ int main(void) { systemTask.reset(new Pinetime::System::SystemTask(spi, lcd, touchPanel, lvgl, batteryController, bleController, dateTimeController)); systemTask->Start(); -// ble_manager_init(); -// ble_manager_set_new_time_callback(OnNewTime); -// ble_manager_set_ble_connection_callback(OnBleConnection); -// ble_manager_set_ble_disconnection_callback(OnBleDisconnection); + ble_manager_init(); + ble_manager_set_new_time_callback(OnNewTime); + ble_manager_set_ble_connection_callback(OnBleConnection); + ble_manager_set_ble_disconnection_callback(OnBleDisconnection); vTaskStartScheduler(); -- cgit v1.2.3-70-g09d2