From e65c9fa18138e8623d5f8e5e8f25fcf0e3d3cf67 Mon Sep 17 00:00:00 2001 From: JF Date: Mon, 10 Feb 2020 21:05:33 +0100 Subject: Integration of lvgl : continued... --- src/DisplayApp/Screens/Clock.cpp | 77 ++++++++++++++++++++++++---------------- 1 file changed, 46 insertions(+), 31 deletions(-) (limited to 'src/DisplayApp/Screens/Clock.cpp') diff --git a/src/DisplayApp/Screens/Clock.cpp b/src/DisplayApp/Screens/Clock.cpp index 155cb581..a413476a 100644 --- a/src/DisplayApp/Screens/Clock.cpp +++ b/src/DisplayApp/Screens/Clock.cpp @@ -2,17 +2,46 @@ #include #include #include +#include #include "Clock.h" using namespace Pinetime::Applications::Screens; +extern lv_font_t jetbrains_mono_extrabold_compressedextrabold_compressed; +extern lv_font_t jetbrains_mono_bold_20; + +Clock::Clock(Pinetime::Components::Gfx &gfx) : Screen(gfx), currentDateTime{{}}, version {{}} { + 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_compressedextrabold_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_time = lv_label_create(lv_scr_act(), NULL); + lv_label_set_style(label_time, LV_LABEL_STYLE_MAIN, &labelBigStyle); + lv_obj_align(label_time, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 0); + + + label_date = lv_label_create(lv_scr_act(), NULL); + lv_label_set_style(label_date, LV_LABEL_STYLE_MAIN, labelStyle); + lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 80); + + label_version = lv_label_create(lv_scr_act(), NULL); + lv_label_set_style(label_version, LV_LABEL_STYLE_MAIN, labelStyle); + lv_obj_align(label_version, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 100); + +} void Clock::Refresh(bool fullRefresh) { if(fullRefresh) { - gfx.FillRectangle(0,0,240,240,0x0000); - currentChar[0] = 1; - currentChar[1] = 2; - currentChar[2] = 3; - currentChar[3] = 4; auto dummy = currentDateTime.Get(); } @@ -23,12 +52,14 @@ void Clock::Refresh(bool fullRefresh) { newBatteryValue = (newBatteryValue < 0) ? 0 : newBatteryValue; sprintf(batteryChar, "BAT: %d%%", newBatteryValue); - gfx.DrawString((240 - 108), 0, 0xffff, batteryChar, &smallFont, false); + lv_label_set_text(label_battery, batteryChar); } if (fullRefresh || bleState.IsUpdated()) { uint16_t color = (bleState.Get() == BleConnectionStates::Connected) ? 0xffff : 0x0000; gfx.DrawString(10, 0, color, "BLE", &smallFont, false); + lv_label_set_text(label_ble, "BLE"); + // TODO color } if(fullRefresh || currentDateTime.IsUpdated()) { @@ -53,35 +84,16 @@ void Clock::Refresh(bool fullRefresh) { char hoursChar[3]; sprintf(hoursChar, "%02d", hour); - uint8_t x = 7; - if (hoursChar[0] != currentChar[0]) { - gfx.DrawChar(&largeFont, hoursChar[0], &x, 78, 0xffff); - currentChar[0] = hoursChar[0]; - } - - x = 61; - if (hoursChar[1] != currentChar[1]) { - gfx.DrawChar(&largeFont, hoursChar[1], &x, 78, 0xffff); - currentChar[1] = hoursChar[1]; - } - - x = 127; - if (minutesChar[0] != currentChar[2]) { - gfx.DrawChar(&largeFont, minutesChar[0], &x, 78, 0xffff); - currentChar[2] = minutesChar[0]; - } - - x = 181; - if (minutesChar[1] != currentChar[3]) { - gfx.DrawChar(&largeFont, minutesChar[1], &x, 78, 0xffff); - currentChar[3] = minutesChar[1]; - } + char timeStr[6]; + sprintf(timeStr, "%c%c:%c%c", hoursChar[0],hoursChar[1],minutesChar[0], minutesChar[1]); + lv_label_set_text(label_time, timeStr); if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) { gfx.FillRectangle(0,180, 240, 15, 0x0000); char dateStr[22]; sprintf(dateStr, "%s %d %s %d", DayOfWeekToString(dayOfWeek), day, MonthToString(month), year); - gfx.DrawString(10, 180, 0xffff, dateStr, &smallFont, false); + lv_label_set_text(label_date, dateStr); + currentYear = year; currentMonth = month; @@ -93,8 +105,9 @@ void Clock::Refresh(bool fullRefresh) { if(fullRefresh || version.IsUpdated()) { char version[20]; sprintf(version, "VERSION: %d.%d.%d", Version::Major(), Version::Minor(), Version::Patch()); - gfx.DrawString(20, 220, 0xffff, version, &smallFont, false); + lv_label_set_text(label_version, version); } + } const char *Clock::MonthToString(Pinetime::Controllers::DateTime::Months month) { @@ -131,3 +144,5 @@ char const *Clock::MonthsString[] = { "NOV", "DEC" }; + + -- cgit v1.2.3-70-g09d2 From 167a0ffc873a2442af43d0347efd00f84932b8cc Mon Sep 17 00:00:00 2001 From: JF Date: Sun, 16 Feb 2020 18:32:36 +0100 Subject: Add touch panel port to lvgl. PoC of user interaction with 3 screen (clock, menu and app). --- src/CMakeLists.txt | 17 ++++ src/Components/DateTime/DateTimeController.cpp | 2 +- src/DisplayApp/DisplayApp.cpp | 46 +++++++--- src/DisplayApp/DisplayApp.h | 8 +- src/DisplayApp/LittleVgl.cpp | 38 +++++++- src/DisplayApp/LittleVgl.h | 12 ++- src/DisplayApp/Screens/Clock.cpp | 57 ++++++++++-- src/DisplayApp/Screens/Clock.h | 11 ++- src/DisplayApp/Screens/Message.cpp | 77 +++++++++++++--- src/DisplayApp/Screens/Message.h | 12 ++- src/DisplayApp/Screens/Screen.h | 9 +- src/DisplayApp/Screens/Tab.cpp | 67 ++++++++++++++ src/DisplayApp/Screens/Tab.h | 28 ++++++ src/DisplayApp/Screens/Tile.cpp | 118 +++++++++++++++++++++++++ src/DisplayApp/Screens/Tile.h | 56 ++++++++++++ src/drivers/Cst816s.cpp | 40 ++++----- src/libs/lv_conf.h | 2 +- src/main.cpp | 8 +- 18 files changed, 540 insertions(+), 68 deletions(-) create mode 100644 src/DisplayApp/Screens/Tab.cpp create mode 100644 src/DisplayApp/Screens/Tab.h create mode 100644 src/DisplayApp/Screens/Tile.cpp create mode 100644 src/DisplayApp/Screens/Tile.h (limited to 'src/DisplayApp/Screens/Clock.cpp') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0b220423..a5971f27 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -137,6 +137,19 @@ set(LVGL_SRC libs/lvgl/src/lv_themes/lv_theme_night.h libs/lvgl/src/lv_themes/lv_theme_night.c + libs/lvgl/src/lv_objx/lv_list.c + libs/lvgl/src/lv_objx/lv_list.h + libs/lvgl/src/lv_objx/lv_tileview.c + libs/lvgl/src/lv_objx/lv_tileview.h + libs/lvgl/src/lv_objx/lv_tabview.c + libs/lvgl/src/lv_objx/lv_tabview.h + libs/lvgl/src/lv_objx/lv_btnm.c + libs/lvgl/src/lv_objx/lv_btnm.h + libs/lvgl/src/lv_objx/lv_page.c + libs/lvgl/src/lv_objx/lv_page.h + libs/lvgl/src/lv_objx/lv_img.c + libs/lvgl/src/lv_objx/lv_img.h + ) list(APPEND SOURCE_FILES @@ -148,6 +161,8 @@ list(APPEND SOURCE_FILES DisplayApp/Screens/Screen.cpp DisplayApp/Screens/Clock.cpp DisplayApp/Screens/Message.cpp + DisplayApp/Screens/Tile.cpp + DisplayApp/Screens/Tab.cpp main.cpp drivers/St7789.cpp drivers/SpiMaster.cpp @@ -177,6 +192,8 @@ set(INCLUDE_FILES DisplayApp/Screens/Screen.h DisplayApp/Screens/Clock.h DisplayApp/Screens/Message.h + DisplayApp/Screens/Tile.h + DisplayApp/Screens/Tab.h drivers/St7789.h drivers/SpiMaster.h Components/Gfx/Gfx.h diff --git a/src/Components/DateTime/DateTimeController.cpp b/src/Components/DateTime/DateTimeController.cpp index 81d45416..ed6d70fb 100644 --- a/src/Components/DateTime/DateTimeController.cpp +++ b/src/Components/DateTime/DateTimeController.cpp @@ -49,7 +49,7 @@ void DateTime::UpdateTime(uint32_t systickCounter) { previousSystickCounter = 0xffffff - (rest - systickCounter); } - currentDateTime += std::chrono::milliseconds (systickDelta*10); + currentDateTime += std::chrono::seconds (correctedDelta); auto dp = date::floor(currentDateTime); auto time = date::make_time(currentDateTime-dp); diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp index 365855ed..959c84a0 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/DisplayApp/DisplayApp.cpp @@ -12,6 +12,8 @@ #include #include #include +#include +#include using namespace Pinetime::Applications; @@ -29,14 +31,12 @@ DisplayApp::DisplayApp(Pinetime::Drivers::St7789& lcd, batteryController{batteryController}, bleController{bleController}, dateTimeController{dateTimeController}, - clockScreen{gfx}, - messageScreen{gfx}{ + currentScreen{new Screens::Tile(this, gfx) } { msgQueue = xQueueCreate(queueSize, itemSize); - currentScreen = &clockScreen; } void DisplayApp::Start() { - if (pdPASS != xTaskCreate(DisplayApp::Process, "DisplayApp", 1024, this, 0, &taskHandle)) + if (pdPASS != xTaskCreate(DisplayApp::Process, "DisplayApp", 512, this, 0, &taskHandle)) APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); } @@ -73,7 +73,7 @@ void DisplayApp::Refresh() { break; case States::Running: RunningState(); - queueTimeout = 1000; + queueTimeout = 20; break; } @@ -104,15 +104,17 @@ void DisplayApp::Refresh() { case Messages::UpdateDateTime: break; case Messages::UpdateBleConnection: - clockScreen.SetBleConnectionState(bleController.IsConnected() ? Screens::Clock::BleConnectionStates::Connected : Screens::Clock::BleConnectionStates::NotConnected); +// clockScreen.SetBleConnectionState(bleController.IsConnected() ? Screens::Clock::BleConnectionStates::Connected : Screens::Clock::BleConnectionStates::NotConnected); break; case Messages::UpdateBatteryLevel: - clockScreen.SetBatteryPercentRemaining(batteryController.PercentRemaining()); +// clockScreen.SetBatteryPercentRemaining(batteryController.PercentRemaining()); break; case Messages::TouchEvent: if(state != States::Running) break; OnTouchEvent(); break; + case Messages::ButtonPushed: + currentScreen->OnButtonPushed(); } } } @@ -120,10 +122,26 @@ void DisplayApp::Refresh() { bool first = true; void DisplayApp::RunningState() { - clockScreen.SetCurrentDateTime(dateTimeController.CurrentDateTime()); +// clockScreen.SetCurrentDateTime(dateTimeController.CurrentDateTime()); if(currentScreen != nullptr) { currentScreen->Refresh(first); + if(currentScreen->GetNextScreen() != Screens::Screen::NextScreen::None) { + switch(currentScreen->GetNextScreen()) { + case Screens::Screen::NextScreen::Clock: + currentScreen.reset(nullptr); + currentScreen.reset(new Screens::Clock(this, gfx, dateTimeController)); + break; + case Screens::Screen::NextScreen::Menu: + currentScreen.reset(nullptr); + currentScreen.reset(new Screens::Tile(this, gfx)); + break; + case Screens::Screen::NextScreen::App: + currentScreen.reset(nullptr); + currentScreen.reset(new Screens::Message(this, gfx)); + break; + } + } first = false; } } @@ -144,10 +162,10 @@ void DisplayApp::PushMessage(DisplayApp::Messages msg) { static uint16_t pointColor = 0x07e0; void DisplayApp::OnTouchEvent() { - auto info = touchPanel.GetTouchInfo(); - - if(info.isTouch) { - gfx.FillRectangle(info.x-10, info.y-10, 20,20, pointColor); - pointColor+=10; - } +// auto info = touchPanel.GetTouchInfo(); +// +// if(info.isTouch) { +// gfx.FillRectangle(info.x-10, info.y-10, 20,20, pointColor); +// pointColor+=10; +// } } diff --git a/src/DisplayApp/DisplayApp.h b/src/DisplayApp/DisplayApp.h index 8cd26ce8..f8101536 100644 --- a/src/DisplayApp/DisplayApp.h +++ b/src/DisplayApp/DisplayApp.h @@ -23,7 +23,7 @@ namespace Pinetime { class DisplayApp { public: enum class States {Idle, Running}; - enum class Messages : uint8_t {GoToSleep, GoToRunning, UpdateDateTime, UpdateBleConnection, UpdateBatteryLevel, TouchEvent} ; + enum class Messages : uint8_t {GoToSleep, GoToRunning, UpdateDateTime, UpdateBleConnection, UpdateBatteryLevel, TouchEvent, SwitchScreen,ButtonPushed} ; DisplayApp(Pinetime::Drivers::St7789& lcd, Pinetime::Components::Gfx& gfx, Pinetime::Components::LittleVgl& lvgl, @@ -60,12 +60,12 @@ namespace Pinetime { Pinetime::Drivers::Cst816S& touchPanel; void OnTouchEvent(); - Screens::Clock clockScreen; - Screens::Message messageScreen; - Screens::Screen* currentScreen = nullptr; + 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; }; } } diff --git a/src/DisplayApp/LittleVgl.cpp b/src/DisplayApp/LittleVgl.cpp index 7830953a..50744acc 100644 --- a/src/DisplayApp/LittleVgl.cpp +++ b/src/DisplayApp/LittleVgl.cpp @@ -17,8 +17,18 @@ static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_colo lvgl->FlushDisplay(area, color_p); } -LittleVgl::LittleVgl(Pinetime::Drivers::St7789& lcd) : lcd{lcd} { +bool touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) { + auto* lvgl = static_cast(indev_drv->user_data); + return lvgl->GetTouchPadInfo(data); +} + +LittleVgl::LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel) : lcd{lcd}, touchPanel{touchPanel} { lv_init(); + InitDisplay(); + InitTouchpad(); +} + +void LittleVgl::InitDisplay() { lv_theme_t* theme = lv_theme_night_init(10, NULL); lv_theme_set_current(theme); @@ -39,8 +49,16 @@ LittleVgl::LittleVgl(Pinetime::Drivers::St7789& lcd) : lcd{lcd} { /*Finally register the driver*/ lv_disp_drv_register(&disp_drv); +} +void LittleVgl::InitTouchpad() { + lv_indev_drv_t indev_drv; + lv_indev_drv_init(&indev_drv); + indev_drv.type = LV_INDEV_TYPE_POINTER; + indev_drv.read_cb = touchpad_read; + indev_drv.user_data = this; + lv_indev_drv_register(&indev_drv); } void LittleVgl::FlushDisplay(const lv_area_t *area, lv_color_t *color_p) { @@ -57,3 +75,21 @@ void LittleVgl::FlushDisplay(const lv_area_t *area, lv_color_t *color_p) { * Inform the graphics library that you are ready with the flushing*/ lv_disp_flush_ready(&disp_drv); } + +bool LittleVgl::GetTouchPadInfo(lv_indev_data_t *ptr) { + auto info = touchPanel.GetTouchInfo(); + + if((previousClick.x != info.x || previousClick.y != info.y) && + (info.gesture == Drivers::Cst816S::Gestures::SingleTap)) { + ptr->state = LV_INDEV_STATE_PR; + previousClick.x = ptr->point.x; + previousClick.y = ptr->point.y; + } + else { + ptr->state = LV_INDEV_STATE_REL; + } + + ptr->point.x = info.x; + ptr->point.y = info.y; + return false; +} diff --git a/src/DisplayApp/LittleVgl.h b/src/DisplayApp/LittleVgl.h index cff1c3b1..ef104969 100644 --- a/src/DisplayApp/LittleVgl.h +++ b/src/DisplayApp/LittleVgl.h @@ -2,26 +2,36 @@ #include #include +#include static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p); +static bool touchpad_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); namespace Pinetime { namespace Components { class LittleVgl { public: - LittleVgl(Pinetime::Drivers::St7789& lcd); + LittleVgl(Pinetime::Drivers::St7789& lcd, Pinetime::Drivers::Cst816S& touchPanel); void FlushDisplay(const lv_area_t * area, lv_color_t * color_p); + bool GetTouchPadInfo(lv_indev_data_t *ptr); private: + void InitDisplay(); + void InitTouchpad(); + Pinetime::Drivers::St7789& lcd; + Pinetime::Drivers::Cst816S& touchPanel; + lv_disp_buf_t disp_buf_2; lv_color_t buf2_1[LV_HOR_RES_MAX * 2]; lv_color_t buf2_2[LV_HOR_RES_MAX * 2]; lv_disp_drv_t disp_drv; + lv_point_t previousClick; + }; } diff --git a/src/DisplayApp/Screens/Clock.cpp b/src/DisplayApp/Screens/Clock.cpp index a413476a..8513d3ed 100644 --- a/src/DisplayApp/Screens/Clock.cpp +++ b/src/DisplayApp/Screens/Clock.cpp @@ -4,12 +4,24 @@ #include #include #include "Clock.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; -Clock::Clock(Pinetime::Components::Gfx &gfx) : Screen(gfx), currentDateTime{{}}, version {{}} { +static void event_handler(lv_obj_t * obj, lv_event_t event) { + Clock* screen = static_cast(obj->user_data); + screen->OnObjectEvent(obj, event); +} + +Clock::Clock(DisplayApp* app, Pinetime::Components::Gfx &gfx, Controllers::DateTime& dateTimeController) : Screen(app, gfx), currentDateTime{{}}, version {{}}, dateTimeController{dateTimeController} { + displayedChar[0] = 0; + displayedChar[1] = 0; + displayedChar[2] = 0; + displayedChar[3] = 0; + displayedChar[4] = 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); @@ -38,11 +50,24 @@ Clock::Clock(Pinetime::Components::Gfx &gfx) : Screen(gfx), currentDateTime{{}}, lv_label_set_style(label_version, LV_LABEL_STYLE_MAIN, labelStyle); lv_obj_align(label_version, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 100); + backgroundLabel = lv_label_create(lv_scr_act(), NULL); + backgroundLabel->user_data = this; + lv_label_set_style(backgroundLabel, LV_LABEL_STYLE_MAIN, labelStyle); + lv_obj_set_click(backgroundLabel, true); + lv_obj_set_event_cb(backgroundLabel, event_handler); + lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); + lv_obj_set_size(backgroundLabel, 240, 240); + lv_obj_set_pos(backgroundLabel, 0, 0); + lv_label_set_text(backgroundLabel, ""); +} + +Clock::~Clock() { + lv_obj_clean(lv_scr_act()); } void Clock::Refresh(bool fullRefresh) { if(fullRefresh) { - auto dummy = currentDateTime.Get(); + auto currentDateTime = dateTimeController.CurrentDateTime(); } if (fullRefresh || batteryPercentRemaining.IsUpdated()) { @@ -62,6 +87,8 @@ void Clock::Refresh(bool fullRefresh) { // TODO color } + currentDateTime = dateTimeController.CurrentDateTime(); + if(fullRefresh || currentDateTime.IsUpdated()) { auto newDateTime = currentDateTime.Get(); @@ -86,10 +113,17 @@ void Clock::Refresh(bool fullRefresh) { char timeStr[6]; sprintf(timeStr, "%c%c:%c%c", hoursChar[0],hoursChar[1],minutesChar[0], minutesChar[1]); - lv_label_set_text(label_time, timeStr); + + if(hoursChar[0] != displayedChar[0] || hoursChar[1] != displayedChar[1] || minutesChar[0] != displayedChar[2] || minutesChar[1] != displayedChar[3]) { + displayedChar[0] = hoursChar[0]; + displayedChar[1] = hoursChar[1]; + displayedChar[2] = minutesChar[0]; + displayedChar[3] = minutesChar[1]; + + lv_label_set_text(label_time, timeStr); + } if ((year != currentYear) || (month != currentMonth) || (dayOfWeek != currentDayOfWeek) || (day != currentDay)) { - gfx.FillRectangle(0,180, 240, 15, 0x0000); char dateStr[22]; sprintf(dateStr, "%s %d %s %d", DayOfWeekToString(dayOfWeek), day, MonthToString(month), year); lv_label_set_text(label_date, dateStr); @@ -103,9 +137,10 @@ void Clock::Refresh(bool fullRefresh) { } if(fullRefresh || version.IsUpdated()) { - char version[20]; - sprintf(version, "VERSION: %d.%d.%d", Version::Major(), Version::Minor(), Version::Patch()); - lv_label_set_text(label_version, version); + auto dummy = version.Get(); + char versionStr[20]; + sprintf(versionStr, "VERSION: %d.%d.%d", Version::Major(), Version::Minor(), Version::Patch()); + lv_label_set_text(label_version, versionStr); } } @@ -145,4 +180,12 @@ char const *Clock::MonthsString[] = { "DEC" }; +void Clock::OnObjectEvent(lv_obj_t *obj, lv_event_t event) { + if(obj == backgroundLabel) { + if (event == LV_EVENT_CLICKED) { + nextScreen = NextScreen::Menu; + } + } +} + diff --git a/src/DisplayApp/Screens/Clock.h b/src/DisplayApp/Screens/Clock.h index f5328535..d6e5a288 100644 --- a/src/DisplayApp/Screens/Clock.h +++ b/src/DisplayApp/Screens/Clock.h @@ -21,7 +21,7 @@ namespace Pinetime { explicit DirtyValue(T v) { value = v; } explicit DirtyValue(T& v) { value = v; } bool IsUpdated() const { return isUpdated; } - T& Get() { return value; this->isUpdated = false;} + T& Get() { this->isUpdated = false; return value; } DirtyValue& operator=(const T& other) { this->value = other; @@ -35,19 +35,23 @@ namespace Pinetime { class Clock : public Screen{ public: enum class BleConnectionStates{ NotConnected, Connected}; - Clock(Components::Gfx& gfx); + Clock(DisplayApp* app, Components::Gfx& gfx, Controllers::DateTime& dateTimeController); + ~Clock() override; void Refresh(bool fullRefresh) 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); static const char* DayOfWeekToString(Pinetime::Controllers::DateTime::Days dayOfWeek); static char const *DaysString[]; static char const *MonthsString[]; + char displayedChar[5]; + 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}; @@ -69,6 +73,9 @@ namespace Pinetime { lv_obj_t* label_time; lv_obj_t* label_date; lv_obj_t* label_version; + lv_obj_t* backgroundLabel; + + Controllers::DateTime& dateTimeController; }; } diff --git a/src/DisplayApp/Screens/Message.cpp b/src/DisplayApp/Screens/Message.cpp index 8ffad413..c9e0938f 100644 --- a/src/DisplayApp/Screens/Message.cpp +++ b/src/DisplayApp/Screens/Message.cpp @@ -5,24 +5,77 @@ #include #include #include +#include #include "Message.h" +#include + using namespace Pinetime::Applications::Screens; -extern lv_font_t jetbrains_mono_extrabold_compressedextrabold_compressed; +extern lv_font_t jetbrains_mono_bold_20; + +static void event_handler(lv_obj_t * obj, lv_event_t event) { + Message* screen = static_cast(obj->user_data); + screen->OnObjectEvent(obj, event); +} + +Message::Message(DisplayApp* app, Pinetime::Components::Gfx &gfx) : Screen(app, gfx) { + + backgroundLabel = lv_label_create(lv_scr_act(), NULL); + backgroundLabel->user_data = this; + + labelStyle = const_cast(lv_label_get_style(backgroundLabel, LV_LABEL_STYLE_MAIN)); + labelStyle->text.font = &jetbrains_mono_bold_20; + + lv_label_set_style(backgroundLabel, LV_LABEL_STYLE_MAIN, labelStyle); + lv_obj_set_click(backgroundLabel, true); + lv_obj_set_event_cb(backgroundLabel, event_handler); + lv_label_set_long_mode(backgroundLabel, LV_LABEL_LONG_CROP); + lv_obj_set_size(backgroundLabel, 240, 240); + lv_obj_set_pos(backgroundLabel, 0, 0); + lv_label_set_text(backgroundLabel, ""); +// lv_obj_align(backgroundLabel, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0); + + button = lv_btn_create(lv_scr_act(), NULL); + lv_obj_set_event_cb(button, event_handler); + lv_obj_align(button, NULL, LV_ALIGN_CENTER, 0, -40); + button->user_data = this; + + label = lv_label_create(button, NULL); + lv_label_set_style(label, LV_LABEL_STYLE_MAIN, labelStyle); + lv_label_set_text(label, "Hello!"); + + labelClick = lv_label_create(lv_scr_act(), NULL); + lv_label_set_style(labelClick, LV_LABEL_STYLE_MAIN, labelStyle); + lv_obj_align(labelClick, button, LV_ALIGN_OUT_BOTTOM_MID, 0, 30); + lv_label_set_text(labelClick, "0"); +} + +Message::~Message() { + lv_obj_clean(lv_scr_act()); +} -lv_obj_t * label; -int x = 0; void Message::Refresh(bool fullRefresh) { - if(fullRefresh) { - label = lv_label_create(lv_scr_act(), NULL); /*Add a label to the button*/ - labelStyle = const_cast(lv_label_get_style(label, LV_LABEL_STYLE_MAIN)); - labelStyle->text.font = &jetbrains_mono_extrabold_compressedextrabold_compressed; - lv_label_set_style(label, LV_LABEL_STYLE_MAIN, labelStyle); - lv_label_set_text(label, "01:23"); /*Set the labels text*/ - } else { - lv_obj_set_pos(label, 0, x++); - if(x > 200) x = 0; + if(previousClickCount != clickCount) { + lv_label_set_text_fmt(labelClick, "%d", clickCount); + previousClickCount = clickCount; } +} +void Message::OnObjectEvent(lv_obj_t *obj, lv_event_t event) { + if(obj == backgroundLabel) { + if(event == LV_EVENT_CLICKED) { + app->PushMessage(DisplayApp::Messages::SwitchScreen); + NRF_LOG_INFO("SCREEN"); + } + return ; + } + + if(event == LV_EVENT_CLICKED) { + NRF_LOG_INFO("Clicked"); + clickCount++; + } + else if(event == LV_EVENT_VALUE_CHANGED) { + NRF_LOG_INFO("Toggled"); + } } diff --git a/src/DisplayApp/Screens/Message.h b/src/DisplayApp/Screens/Message.h index 419c2e62..2f1da942 100644 --- a/src/DisplayApp/Screens/Message.h +++ b/src/DisplayApp/Screens/Message.h @@ -15,14 +15,24 @@ namespace Pinetime { namespace Screens { class Message : public Screen{ public: - Message(Components::Gfx& gfx) : Screen(gfx) {} + explicit Message(DisplayApp* app, Components::Gfx& gfx); + ~Message() override; void Refresh(bool fullRefresh) override; + 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; + lv_obj_t* backgroundLabel; + lv_obj_t * button; + lv_obj_t * labelClick; + + uint32_t clickCount = 0 ; + uint32_t previousClickCount = 0; }; } } diff --git a/src/DisplayApp/Screens/Screen.h b/src/DisplayApp/Screens/Screen.h index 5e2fa43e..57b8ea2a 100644 --- a/src/DisplayApp/Screens/Screen.h +++ b/src/DisplayApp/Screens/Screen.h @@ -4,14 +4,21 @@ namespace Pinetime { namespace Applications { + class DisplayApp; namespace Screens { class Screen { public: - Screen(Components::Gfx& gfx) : gfx{gfx} {} + enum class NextScreen {None, Clock, Menu, App}; + Screen(DisplayApp* app, Components::Gfx& gfx) : app{app}, gfx{gfx} {} + virtual ~Screen() = default; virtual void Refresh(bool fullRefresh) = 0; + NextScreen GetNextScreen() {return nextScreen;} + virtual void OnButtonPushed() {}; protected: + DisplayApp* app; Components::Gfx& gfx; + NextScreen nextScreen = NextScreen::None; }; } } diff --git a/src/DisplayApp/Screens/Tab.cpp b/src/DisplayApp/Screens/Tab.cpp new file mode 100644 index 00000000..adc32578 --- /dev/null +++ b/src/DisplayApp/Screens/Tab.cpp @@ -0,0 +1,67 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "Tab.h" +#include + + +using namespace Pinetime::Applications::Screens; + +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); +//} + +Tab::Tab(DisplayApp* app, Pinetime::Components::Gfx &gfx) : Screen(app, gfx) { +/*Create a Tab view object*/ + lv_obj_t *tabview; + tabview = lv_tabview_create(lv_scr_act(), NULL); + + /*Add 3 tabs (the tabs are page (lv_page) and can be scrolled*/ + lv_obj_t *tab1 = lv_tabview_add_tab(tabview, "Tab 1"); + lv_obj_t *tab2 = lv_tabview_add_tab(tabview, "Tab 2"); + lv_obj_t *tab3 = lv_tabview_add_tab(tabview, "Tab 3"); + + + /*Add content to the tabs*/ + lv_obj_t * label = lv_label_create(tab1, NULL); + lv_label_set_text(label, "This the first tab\n\n" + "If the content\n" + "of a tab\n" + "become too long\n" + "the it \n" + "automatically\n" + "become\n" + "scrollable."); + + label = lv_label_create(tab2, NULL); + lv_label_set_text(label, "Second tab"); + + label = lv_label_create(tab3, NULL); + lv_label_set_text(label, "Third tab"); + +} + +Tab::~Tab() { + lv_obj_clean(lv_scr_act()); +} + +void Tab::Refresh(bool fullRefresh) { + +} + +void Tab::OnObjectEvent(lv_obj_t *obj, lv_event_t event) { + if(event == LV_EVENT_CLICKED) { + NRF_LOG_INFO("Clicked"); + } + else if(event == LV_EVENT_VALUE_CHANGED) { + NRF_LOG_INFO("Toggled"); + } +} diff --git a/src/DisplayApp/Screens/Tab.h b/src/DisplayApp/Screens/Tab.h new file mode 100644 index 00000000..1af956f4 --- /dev/null +++ b/src/DisplayApp/Screens/Tab.h @@ -0,0 +1,28 @@ +#pragma once + +#include +#include +#include +#include "Screen.h" +#include +#include "../Fonts/lcdfont14.h" +#include "../Fonts/lcdfont70.h" +#include "../../Version.h" +#include + +namespace Pinetime { + namespace Applications { + namespace Screens { + class Tab : public Screen { + public: + explicit Tab(DisplayApp* app, Components::Gfx& gfx); + ~Tab() override; + void Refresh(bool fullRefresh) override; + void OnObjectEvent(lv_obj_t* obj, lv_event_t event); + + private: + + }; + } + } +} diff --git a/src/DisplayApp/Screens/Tile.cpp b/src/DisplayApp/Screens/Tile.cpp new file mode 100644 index 00000000..d89562c7 --- /dev/null +++ b/src/DisplayApp/Screens/Tile.cpp @@ -0,0 +1,118 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include "Tile.h" +#include +#include + + +using namespace Pinetime::Applications::Screens; + +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); +} + +//static const char * btnm_map1[] = {"App1", "App2", "App3", "\n", "App4", "App5", "App11", ""}; +//static const char * btnm_map2[] = {"App6", "App7", "App8", "\n", "App9", "App10", "App22",""}; +static const char * btnm_map1[] = {"App1", ""}; + +Tile::Tile(DisplayApp* app, Pinetime::Components::Gfx &gfx) : Screen(app, gfx) { + + 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); + lv_tileview_set_edge_flash(tileview, false); + + tile1 = lv_obj_create(tileview, NULL); + lv_obj_set_pos(tile1, 0, 0); + lv_obj_set_size(tile1, LV_HOR_RES, LV_VER_RES); + lv_tileview_add_element(tileview, tile1); + + btnm1 = lv_btnm_create(tile1, NULL); + lv_btnm_set_map(btnm1, btnm_map1); + lv_obj_set_size(btnm1, LV_HOR_RES, LV_VER_RES); + + labelStyle = const_cast(lv_label_get_style(btnm1, LV_BTNM_STYLE_BTN_REL)); + labelStyle->text.font = &jetbrains_mono_bold_20; + labelStyle->body.grad_color = labelStyle->body.main_color; + lv_btnm_set_style(btnm1, LV_BTNM_STYLE_BTN_REL, labelStyle); + lv_btnm_set_style(btnm1, LV_BTNM_STYLE_BTN_PR, labelStyle); + + lv_obj_align(btnm1, tile1, LV_ALIGN_CENTER, 0, 0); + btnm1->user_data = this; + lv_obj_set_event_cb(btnm1, event_handler); +/* + tile2 = lv_obj_create(tileview, NULL); + lv_obj_set_pos(tile2, 0, LV_VER_RES); + lv_obj_set_size(tile2, LV_HOR_RES, LV_VER_RES); + lv_tileview_add_element(tileview, tile2); + + btnm2 = lv_btnm_create(tileview, NULL); + lv_btnm_set_map(btnm2, btnm_map2); + lv_obj_align(btnm2, tile2, LV_ALIGN_CENTER, 0, 0); +*/ +/* + tile1 = lv_obj_create(tileview, NULL); + lv_obj_set_pos(tile1, 0, 0); + lv_obj_set_size(tile1, LV_HOR_RES, LV_VER_RES); + lv_tileview_add_element(tileview, tile1); + + btn1 = lv_btn_create(tile1, NULL); + lv_obj_align(btn1, tile1, LV_ALIGN_CENTER, 0, 0); + + label1 = lv_label_create(btn1, NULL); + lv_label_set_text(label1, "Button1"); +*/ +/* + tile2 = lv_obj_create(tileview, NULL); + lv_obj_set_pos(tile2, 0, LV_VER_RES); + lv_obj_set_size(tile2, LV_HOR_RES, LV_VER_RES); + lv_tileview_add_element(tileview, tile2); + + btn2 = lv_btn_create(tile2, NULL); + lv_obj_align(btn2, tile2, LV_ALIGN_CENTER, 0, 0); + + + label2 = lv_label_create(btn2, NULL); + lv_label_set_text(label2, "Button2"); + + tile3 = lv_obj_create(tileview, NULL); + lv_obj_set_pos(tile3, 0, LV_VER_RES*2); + lv_obj_set_size(tile3, LV_HOR_RES, LV_VER_RES); + lv_tileview_add_element(tileview, tile3); + + btn3 = lv_btn_create(tile3, NULL); + lv_obj_align(btn3, tile3, LV_ALIGN_CENTER, 0, 0); + + + label3 = lv_label_create(btn3, NULL); + lv_label_set_text(label3, "Button3"); +*/ +} + +Tile::~Tile() { + lv_obj_clean(lv_scr_act()); +} + +void Tile::Refresh(bool fullRefresh) { + +} + +void Tile::OnObjectEvent(lv_obj_t *obj, lv_event_t event) { + if(event == LV_EVENT_CLICKED) { + NRF_LOG_INFO("Clicked"); + nextScreen = Screen::NextScreen::App; + clickCount++; + } + else if(event == LV_EVENT_VALUE_CHANGED) { + NRF_LOG_INFO("Toggled"); + } +} diff --git a/src/DisplayApp/Screens/Tile.h b/src/DisplayApp/Screens/Tile.h new file mode 100644 index 00000000..c9de2c5c --- /dev/null +++ b/src/DisplayApp/Screens/Tile.h @@ -0,0 +1,56 @@ +#pragma once + +#include +#include +#include +#include "Screen.h" +#include +#include "../Fonts/lcdfont14.h" +#include "../Fonts/lcdfont70.h" +#include "../../Version.h" +#include + +namespace Pinetime { + namespace Applications { + namespace Screens { + class Tile : public Screen { + public: + explicit Tile(DisplayApp* app, Components::Gfx& gfx); + ~Tile() override; + void Refresh(bool fullRefresh) override; + void OnObjectEvent(lv_obj_t* obj, lv_event_t event); + + void OnButtonPushed() override {nextScreen = NextScreen::Clock;} + + 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 * label1; + lv_obj_t * label2; + lv_obj_t * label3; + + lv_obj_t* backgroundLabel; + lv_obj_t * button; + lv_obj_t * labelClick; + + lv_obj_t *tileview; + lv_obj_t * tile1; + lv_obj_t * tile2; + lv_obj_t * list; + lv_obj_t * list_btn; + lv_obj_t * tile3; + lv_obj_t * btn1; + lv_obj_t * btn2; + lv_obj_t * btn3; + + lv_obj_t * btnm1; + lv_obj_t * btnm2; + + uint32_t clickCount = 0 ; + uint32_t previousClickCount = 0; + }; + } + } +} diff --git a/src/drivers/Cst816s.cpp b/src/drivers/Cst816s.cpp index b1af12d4..61bce94c 100644 --- a/src/drivers/Cst816s.cpp +++ b/src/drivers/Cst816s.cpp @@ -78,26 +78,26 @@ Cst816S::TouchInfos Cst816S::GetTouchInfo() { info.action = action; info.gesture = static_cast(touchData[gestureIndex]); - NRF_LOG_INFO("---------------") - NRF_LOG_INFO("ID : %d", pointId); - NRF_LOG_INFO("NB : %d", nbTouchPoints); - NRF_LOG_INFO("X/Y :%d / %d", info.x, info.y); - NRF_LOG_INFO("Action : %d", action); - NRF_LOG_INFO("Finger : %d", finger); - NRF_LOG_INFO("Pressure : %d", pressure); - NRF_LOG_INFO("area : %d", area); - NRF_LOG_INFO("Touch : %s", info.isTouch?"Yes" : "No"); - switch(info.gesture) {// gesture - case Gestures::None: NRF_LOG_INFO("Gesture : None"); break; - case Gestures::SlideDown: NRF_LOG_INFO("Gesture : Slide Down"); break; - case Gestures::SlideUp: NRF_LOG_INFO("Gesture : Slide Up"); break; - case Gestures::SlideLeft: NRF_LOG_INFO("Gesture : Slide Left"); break; - case Gestures::SlideRight: NRF_LOG_INFO("Gesture : Slide Right"); break; - case Gestures::SingleTap: NRF_LOG_INFO("Gesture : Single click"); break; - case Gestures::DoubleTap: NRF_LOG_INFO("Gesture : Double click"); break; - case Gestures::LongPress: NRF_LOG_INFO("Gesture : Long press"); break; - default : NRF_LOG_INFO("Unknown"); break; - } +// NRF_LOG_INFO("---------------") +// NRF_LOG_INFO("ID : %d", pointId); +// NRF_LOG_INFO("NB : %d", nbTouchPoints); +// NRF_LOG_INFO("X/Y :%d / %d", info.x, info.y); +// NRF_LOG_INFO("Action : %d", action); +// NRF_LOG_INFO("Finger : %d", finger); +// NRF_LOG_INFO("Pressure : %d", pressure); +// NRF_LOG_INFO("area : %d", area); +// NRF_LOG_INFO("Touch : %s", info.isTouch?"Yes" : "No"); +// switch(info.gesture) {// gesture +// case Gestures::None: NRF_LOG_INFO("Gesture : None"); break; +// case Gestures::SlideDown: NRF_LOG_INFO("Gesture : Slide Down"); break; +// case Gestures::SlideUp: NRF_LOG_INFO("Gesture : Slide Up"); break; +// case Gestures::SlideLeft: NRF_LOG_INFO("Gesture : Slide Left"); break; +// case Gestures::SlideRight: NRF_LOG_INFO("Gesture : Slide Right"); break; +// case Gestures::SingleTap: NRF_LOG_INFO("Gesture : Single click"); break; +// case Gestures::DoubleTap: NRF_LOG_INFO("Gesture : Double click"); break; +// case Gestures::LongPress: NRF_LOG_INFO("Gesture : Long press"); break; +// default : NRF_LOG_INFO("Unknown"); break; +// } } diff --git a/src/libs/lv_conf.h b/src/libs/lv_conf.h index 603339ee..8d7a6f7e 100644 --- a/src/libs/lv_conf.h +++ b/src/libs/lv_conf.h @@ -563,7 +563,7 @@ typedef void * lv_obj_user_data_t; #define LV_USE_TILEVIEW 1 #if LV_USE_TILEVIEW /*Time of slide animation [ms] (0: no animation)*/ -# define LV_TILEVIEW_DEF_ANIM_TIME 300 +# define LV_TILEVIEW_DEF_ANIM_TIME 0 #endif /*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/ diff --git a/src/main.cpp b/src/main.cpp index 0d374c6b..2a272677 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -82,7 +82,7 @@ extern "C" { void DebounceTimerCallback(TimerHandle_t xTimer) { xTimerStop(xTimer, 0); - if(isSleeping) { + /*if(isSleeping) { SystemTask_PushMessage(SystemTaskMessages::GoToRunning); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToRunning); isSleeping = false; @@ -93,7 +93,8 @@ void DebounceTimerCallback(TimerHandle_t xTimer) { SystemTask_PushMessage(SystemTaskMessages::GoToSleep); displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep); isSleeping = true; - } + }*/ + displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::ButtonPushed); } void SystemTask_PushMessage(SystemTaskMessages message) { @@ -126,8 +127,9 @@ void SystemTask(void *) { lcd.reset(new Pinetime::Drivers::St7789(*spi, pinLcdDataCommand)); gfx.reset(new Pinetime::Components::Gfx(*lcd)); - lvgl.reset(new Pinetime::Components::LittleVgl(*lcd)); touchPanel.reset(new Pinetime::Drivers::Cst816S()); + + lvgl.reset(new Pinetime::Components::LittleVgl(*lcd, *touchPanel)); ptrLcd = lcd.get(); spi->Init(); -- cgit v1.2.3-70-g09d2 From 2bdff7ed2b490cb8ce5599341e12d707c0ba7fd0 Mon Sep 17 00:00:00 2001 From: JF Date: Thu, 20 Feb 2020 18:17:53 +0100 Subject: Re-enable BLE display on Clock screen --- src/DisplayApp/DisplayApp.cpp | 2 +- src/DisplayApp/Screens/Clock.cpp | 10 ++++++---- src/DisplayApp/Screens/Tile.cpp | 4 +--- 3 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src/DisplayApp/Screens/Clock.cpp') diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp index 959c84a0..34d81ddc 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/DisplayApp/DisplayApp.cpp @@ -31,7 +31,7 @@ DisplayApp::DisplayApp(Pinetime::Drivers::St7789& lcd, batteryController{batteryController}, bleController{bleController}, dateTimeController{dateTimeController}, - currentScreen{new Screens::Tile(this, gfx) } { + currentScreen{new Screens::Clock(this, gfx, dateTimeController) } { msgQueue = xQueueCreate(queueSize, itemSize); } diff --git a/src/DisplayApp/Screens/Clock.cpp b/src/DisplayApp/Screens/Clock.cpp index 8513d3ed..806a1c2c 100644 --- a/src/DisplayApp/Screens/Clock.cpp +++ b/src/DisplayApp/Screens/Clock.cpp @@ -81,10 +81,12 @@ void Clock::Refresh(bool fullRefresh) { } if (fullRefresh || bleState.IsUpdated()) { - uint16_t color = (bleState.Get() == BleConnectionStates::Connected) ? 0xffff : 0x0000; - gfx.DrawString(10, 0, color, "BLE", &smallFont, false); - lv_label_set_text(label_ble, "BLE"); - // TODO color + if(bleState.Get() == BleConnectionStates::Connected) { + lv_obj_set_hidden(label_ble, false); + lv_label_set_text(label_ble, "BLE"); + } else { + lv_obj_set_hidden(label_ble, true); + } } currentDateTime = dateTimeController.CurrentDateTime(); diff --git a/src/DisplayApp/Screens/Tile.cpp b/src/DisplayApp/Screens/Tile.cpp index d89562c7..ac930ba7 100644 --- a/src/DisplayApp/Screens/Tile.cpp +++ b/src/DisplayApp/Screens/Tile.cpp @@ -20,9 +20,7 @@ static void event_handler(lv_obj_t * obj, lv_event_t event) { screen->OnObjectEvent(obj, event); } -//static const char * btnm_map1[] = {"App1", "App2", "App3", "\n", "App4", "App5", "App11", ""}; -//static const char * btnm_map2[] = {"App6", "App7", "App8", "\n", "App9", "App10", "App22",""}; -static const char * btnm_map1[] = {"App1", ""}; +static const char * btnm_map1[] = {"App1", "App2", "App3", "\n", "App4", "App5", "App11", ""}; Tile::Tile(DisplayApp* app, Pinetime::Components::Gfx &gfx) : Screen(app, gfx) { -- cgit v1.2.3-70-g09d2 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/CMakeLists.txt | 19 +++-- src/DisplayApp/DisplayApp.cpp | 51 +++++++------- src/DisplayApp/DisplayApp.h | 19 +++-- src/DisplayApp/Screens/Clock.cpp | 12 +++- src/DisplayApp/Screens/Clock.h | 11 +-- src/DisplayApp/Screens/Screen.h | 14 ++-- src/DisplayApp/Screens/Tile.cpp | 39 +++++++---- src/DisplayApp/Screens/Tile.h | 16 +++-- src/SystemTask/SystemTask.cpp | 115 ++++++++++++++++++++++++++++++ src/SystemTask/SystemTask.h | 60 ++++++++++++++++ src/libs/lv_conf.h | 4 +- src/main.cpp | 146 +++++++-------------------------------- src/main.h | 7 ++ 13 files changed, 313 insertions(+), 200 deletions(-) create mode 100644 src/SystemTask/SystemTask.cpp create mode 100644 src/SystemTask/SystemTask.h create mode 100644 src/main.h (limited to 'src/DisplayApp/Screens/Clock.cpp') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a5971f27..efbb3861 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -156,17 +156,15 @@ list(APPEND SOURCE_FILES Logging/NrfLogger.cpp BlinkApp/BlinkApp.cpp DisplayApp/DisplayApp.cpp - DisplayApp/Fonts/lcdfont70.c - DisplayApp/Fonts/lcdfont14.c DisplayApp/Screens/Screen.cpp DisplayApp/Screens/Clock.cpp - DisplayApp/Screens/Message.cpp +# DisplayApp/Screens/Message.cpp DisplayApp/Screens/Tile.cpp - DisplayApp/Screens/Tab.cpp +# DisplayApp/Screens/Tab.cpp main.cpp drivers/St7789.cpp drivers/SpiMaster.cpp - Components/Gfx/Gfx.cpp +# Components/Gfx/Gfx.cpp BLE/BleManager.c Components/Battery/BatteryController.cpp Components/Ble/BleController.cpp @@ -180,6 +178,8 @@ list(APPEND SOURCE_FILES DisplayApp/LittleVgl.cpp DisplayApp/Fonts/jetbrains_mono_extrabold_compressed.c DisplayApp/Fonts/jetbrains_mono_bold_20.c + + SystemTask/SystemTask.cpp ) set(INCLUDE_FILES @@ -187,16 +187,13 @@ set(INCLUDE_FILES Logging/NrfLogger.h BlinkApp/BlinkApp.h DisplayApp/DisplayApp.h - DisplayApp/Fonts/lcdfont70.h - DisplayApp/Fonts/lcdfont14.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 +# DisplayApp/Screens/Tab.h drivers/St7789.h drivers/SpiMaster.h - Components/Gfx/Gfx.h BLE/BleManager.h Components/Battery/BatteryController.h Components/Ble/BleController.h @@ -214,6 +211,8 @@ set(INCLUDE_FILES libs/date/includes/date/tz_private.h DisplayApp/LittleVgl.h + + SystemTask/SystemTask.h ) include_directories( diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp index 34d81ddc..d70726dd 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/DisplayApp/DisplayApp.cpp @@ -13,25 +13,26 @@ #include #include #include -#include +#include "../SystemTask/SystemTask.h" +//#include using namespace Pinetime::Applications; DisplayApp::DisplayApp(Pinetime::Drivers::St7789& lcd, - Pinetime::Components::Gfx& gfx, Pinetime::Components::LittleVgl& lvgl, Pinetime::Drivers::Cst816S& touchPanel, Controllers::Battery &batteryController, Controllers::Ble &bleController, - Controllers::DateTime &dateTimeController) : + Controllers::DateTime &dateTimeController, + Pinetime::System::SystemTask& systemTask) : lcd{lcd}, - gfx{gfx}, lvgl{lvgl}, touchPanel{touchPanel}, batteryController{batteryController}, bleController{bleController}, dateTimeController{dateTimeController}, - currentScreen{new Screens::Clock(this, gfx, dateTimeController) } { + currentScreen{new Screens::Clock(this, dateTimeController) }, + systemTask{systemTask} { msgQueue = xQueueCreate(queueSize, itemSize); } @@ -48,7 +49,7 @@ void DisplayApp::Process(void *instance) { while (1) { app->Refresh(); - lv_task_handler(); + } } @@ -114,36 +115,28 @@ void DisplayApp::Refresh() { OnTouchEvent(); break; case Messages::ButtonPushed: - currentScreen->OnButtonPushed(); + if(!currentScreen->OnButtonPushed()) { + systemTask.PushMessage(System::SystemTask::Messages::GoToSleep); + } + break; } } } -bool first = true; - void DisplayApp::RunningState() { // clockScreen.SetCurrentDateTime(dateTimeController.CurrentDateTime()); - if(currentScreen != nullptr) { - currentScreen->Refresh(first); - if(currentScreen->GetNextScreen() != Screens::Screen::NextScreen::None) { - switch(currentScreen->GetNextScreen()) { - case Screens::Screen::NextScreen::Clock: - currentScreen.reset(nullptr); - currentScreen.reset(new Screens::Clock(this, gfx, dateTimeController)); - break; - case Screens::Screen::NextScreen::Menu: - currentScreen.reset(nullptr); - currentScreen.reset(new Screens::Tile(this, gfx)); - break; - case Screens::Screen::NextScreen::App: - currentScreen.reset(nullptr); - currentScreen.reset(new Screens::Message(this, gfx)); - break; - } + if(!currentScreen->Refresh(true)) { + 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; } - first = false; + nextApp = Apps::None; } + lv_task_handler(); } void DisplayApp::IdleState() { @@ -169,3 +162,7 @@ void DisplayApp::OnTouchEvent() { // pointColor+=10; // } } + +void DisplayApp::StartApp(DisplayApp::Apps app) { + nextApp = app; +} diff --git a/src/DisplayApp/DisplayApp.h b/src/DisplayApp/DisplayApp.h index f8101536..656dd4ed 100644 --- a/src/DisplayApp/DisplayApp.h +++ b/src/DisplayApp/DisplayApp.h @@ -14,35 +14,37 @@ #include "LittleVgl.h" #include #include -#include +//#include -extern const FONT_INFO lCD_70ptFontInfo; namespace Pinetime { + namespace System { + class SystemTask; + }; namespace Applications { class DisplayApp { public: enum class States {Idle, Running}; enum class Messages : uint8_t {GoToSleep, GoToRunning, UpdateDateTime, UpdateBleConnection, UpdateBatteryLevel, TouchEvent, SwitchScreen,ButtonPushed} ; DisplayApp(Pinetime::Drivers::St7789& lcd, - Pinetime::Components::Gfx& gfx, Pinetime::Components::LittleVgl& lvgl, Pinetime::Drivers::Cst816S&, Controllers::Battery &batteryController, Controllers::Ble &bleController, - Controllers::DateTime& dateTimeController); + Controllers::DateTime& dateTimeController, + Pinetime::System::SystemTask& systemTask); void Start(); void PushMessage(Messages msg); + enum class Apps {None, Launcher, Clock, Test}; + void StartApp(Apps app); + private: TaskHandle_t taskHandle; static void Process(void* instance); void InitHw(); Pinetime::Drivers::St7789& lcd; - Pinetime::Components::Gfx& gfx; Pinetime::Components::LittleVgl lvgl; - 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}; void Refresh(); States state = States::Running; @@ -66,6 +68,9 @@ namespace Pinetime { static constexpr uint8_t pinLcdBacklight3 = 23; bool isClock = true; + + Pinetime::System::SystemTask& systemTask; + Apps nextApp = Apps::None; }; } } diff --git a/src/DisplayApp/Screens/Clock.cpp b/src/DisplayApp/Screens/Clock.cpp index 806a1c2c..3b849150 100644 --- a/src/DisplayApp/Screens/Clock.cpp +++ b/src/DisplayApp/Screens/Clock.cpp @@ -15,7 +15,7 @@ static void event_handler(lv_obj_t * obj, lv_event_t event) { screen->OnObjectEvent(obj, event); } -Clock::Clock(DisplayApp* app, Pinetime::Components::Gfx &gfx, Controllers::DateTime& dateTimeController) : Screen(app, gfx), currentDateTime{{}}, version {{}}, dateTimeController{dateTimeController} { +Clock::Clock(DisplayApp* app, Controllers::DateTime& dateTimeController) : Screen(app), currentDateTime{{}}, version {{}}, dateTimeController{dateTimeController} { displayedChar[0] = 0; displayedChar[1] = 0; displayedChar[2] = 0; @@ -65,7 +65,7 @@ Clock::~Clock() { lv_obj_clean(lv_scr_act()); } -void Clock::Refresh(bool fullRefresh) { +bool Clock::Refresh(bool fullRefresh) { if(fullRefresh) { auto currentDateTime = dateTimeController.CurrentDateTime(); } @@ -145,6 +145,7 @@ void Clock::Refresh(bool fullRefresh) { lv_label_set_text(label_version, versionStr); } + return running; } const char *Clock::MonthToString(Pinetime::Controllers::DateTime::Months month) { @@ -185,9 +186,14 @@ char const *Clock::MonthsString[] = { void Clock::OnObjectEvent(lv_obj_t *obj, lv_event_t event) { if(obj == backgroundLabel) { if (event == LV_EVENT_CLICKED) { - nextScreen = NextScreen::Menu; + + running = false; } } } +bool Clock::OnButtonPushed() { + return Screen::OnButtonPushed(); +} + diff --git a/src/DisplayApp/Screens/Clock.h b/src/DisplayApp/Screens/Clock.h index d6e5a288..a358e41b 100644 --- a/src/DisplayApp/Screens/Clock.h +++ b/src/DisplayApp/Screens/Clock.h @@ -35,9 +35,11 @@ namespace Pinetime { class Clock : public Screen{ public: enum class BleConnectionStates{ NotConnected, Connected}; - Clock(DisplayApp* app, Components::Gfx& gfx, Controllers::DateTime& dateTimeController); + Clock(DisplayApp* app, Controllers::DateTime& dateTimeController); ~Clock() override; - void Refresh(bool fullRefresh) override; + + bool Refresh(bool fullRefresh) override; + bool OnButtonPushed() override; void SetBatteryPercentRemaining(uint8_t percent) { batteryPercentRemaining = percent; } void SetBleConnectionState(BleConnectionStates state) { bleState = state; } @@ -52,9 +54,6 @@ namespace Pinetime { char displayedChar[5]; - 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}; - uint16_t currentYear = 1970; Pinetime::Controllers::DateTime::Months currentMonth = Pinetime::Controllers::DateTime::Months::Unknown; Pinetime::Controllers::DateTime::Days currentDayOfWeek = Pinetime::Controllers::DateTime::Days::Unknown; @@ -77,6 +76,8 @@ namespace Pinetime { Controllers::DateTime& dateTimeController; + bool running = true; + }; } } diff --git a/src/DisplayApp/Screens/Screen.h b/src/DisplayApp/Screens/Screen.h index 57b8ea2a..625daada 100644 --- a/src/DisplayApp/Screens/Screen.h +++ b/src/DisplayApp/Screens/Screen.h @@ -9,16 +9,18 @@ namespace Pinetime { class Screen { public: enum class NextScreen {None, Clock, Menu, App}; - Screen(DisplayApp* app, Components::Gfx& gfx) : app{app}, gfx{gfx} {} + + Screen(DisplayApp* app) : app{app} {} virtual ~Screen() = default; - virtual void Refresh(bool fullRefresh) = 0; - NextScreen GetNextScreen() {return nextScreen;} - virtual void OnButtonPushed() {}; + + // Return false if the app can be closed, true if it must continue to run + virtual bool Refresh(bool fullRefresh) = 0; + + // Return false if the button hasn't been handled by the app, true if it has been handled + virtual bool OnButtonPushed() { return false; } protected: DisplayApp* app; - Components::Gfx& gfx; - NextScreen nextScreen = NextScreen::None; }; } } diff --git a/src/DisplayApp/Screens/Tile.cpp b/src/DisplayApp/Screens/Tile.cpp index ac930ba7..c9e33544 100644 --- a/src/DisplayApp/Screens/Tile.cpp +++ b/src/DisplayApp/Screens/Tile.cpp @@ -22,8 +22,7 @@ static void event_handler(lv_obj_t * obj, lv_event_t event) { static const char * btnm_map1[] = {"App1", "App2", "App3", "\n", "App4", "App5", "App11", ""}; -Tile::Tile(DisplayApp* app, Pinetime::Components::Gfx &gfx) : Screen(app, gfx) { - +Tile::Tile(DisplayApp* app) : Screen(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); @@ -38,11 +37,16 @@ Tile::Tile(DisplayApp* app, Pinetime::Components::Gfx &gfx) : Screen(app, gfx) { lv_btnm_set_map(btnm1, btnm_map1); lv_obj_set_size(btnm1, LV_HOR_RES, LV_VER_RES); - labelStyle = const_cast(lv_label_get_style(btnm1, LV_BTNM_STYLE_BTN_REL)); - labelStyle->text.font = &jetbrains_mono_bold_20; - labelStyle->body.grad_color = labelStyle->body.main_color; - lv_btnm_set_style(btnm1, LV_BTNM_STYLE_BTN_REL, labelStyle); - lv_btnm_set_style(btnm1, LV_BTNM_STYLE_BTN_PR, labelStyle); + labelRelStyle = const_cast(lv_label_get_style(btnm1, LV_BTNM_STYLE_BTN_REL)); + labelRelStyle->text.font = &jetbrains_mono_bold_20; + labelRelStyle->body.grad_color = labelRelStyle->body.main_color; + lv_btnm_set_style(btnm1, LV_BTNM_STYLE_BTN_REL, labelRelStyle); + + labelPrStyle = const_cast(lv_label_get_style(btnm1, LV_BTNM_STYLE_BTN_PR)); + labelPrStyle->text.font = &jetbrains_mono_bold_20; + labelPrStyle->body.grad_color = labelPrStyle->body.shadow.color; +// lv_btnm_set_style(btnm1, LV_BTNM_STYLE_BTN_PR, labelPrStyle); +//TODO better style handling lv_obj_align(btnm1, tile1, LV_ALIGN_CENTER, 0, 0); btnm1->user_data = this; @@ -100,17 +104,28 @@ Tile::~Tile() { lv_obj_clean(lv_scr_act()); } -void Tile::Refresh(bool fullRefresh) { - +bool Tile::Refresh(bool fullRefresh) { + return running; } void Tile::OnObjectEvent(lv_obj_t *obj, lv_event_t event) { + auto* tile = static_cast(obj->user_data); if(event == LV_EVENT_CLICKED) { - NRF_LOG_INFO("Clicked"); - nextScreen = Screen::NextScreen::App; + + tile->StartApp(); clickCount++; } else if(event == LV_EVENT_VALUE_CHANGED) { - NRF_LOG_INFO("Toggled"); } } + +bool Tile::OnButtonPushed() { + app->StartApp(DisplayApp::Apps::Clock); + running = false; + return true; +} + +void Tile::StartApp() { + app->StartApp(DisplayApp::Apps::Clock); + running = false; +} diff --git a/src/DisplayApp/Screens/Tile.h b/src/DisplayApp/Screens/Tile.h index c9de2c5c..03cfb6d2 100644 --- a/src/DisplayApp/Screens/Tile.h +++ b/src/DisplayApp/Screens/Tile.h @@ -15,18 +15,18 @@ namespace Pinetime { namespace Screens { class Tile : public Screen { public: - explicit Tile(DisplayApp* app, Components::Gfx& gfx); + explicit Tile(DisplayApp* app); ~Tile() override; - void Refresh(bool fullRefresh) override; - void OnObjectEvent(lv_obj_t* obj, lv_event_t event); - void OnButtonPushed() override {nextScreen = NextScreen::Clock;} + bool Refresh(bool fullRefresh) override; + bool OnButtonPushed() override; + + void OnObjectEvent(lv_obj_t* obj, lv_event_t event); 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_style_t* labelRelStyle; + lv_style_t* labelPrStyle; lv_obj_t * label1; lv_obj_t * label2; lv_obj_t * label3; @@ -50,6 +50,8 @@ namespace Pinetime { uint32_t clickCount = 0 ; uint32_t previousClickCount = 0; + void StartApp(); + bool running = true; }; } } 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 diff --git a/src/libs/lv_conf.h b/src/libs/lv_conf.h index 8d7a6f7e..34457953 100644 --- a/src/libs/lv_conf.h +++ b/src/libs/lv_conf.h @@ -123,7 +123,7 @@ typedef int16_t lv_coord_t; *==================*/ /*1: Enable the Animations */ -#define LV_USE_ANIMATION 0 +#define LV_USE_ANIMATION 1 #if LV_USE_ANIMATION /*Declare the type of the user data of animations (can be e.g. `void *`, `int`, `struct`)*/ @@ -563,7 +563,7 @@ typedef void * lv_obj_user_data_t; #define LV_USE_TILEVIEW 1 #if LV_USE_TILEVIEW /*Time of slide animation [ms] (0: no animation)*/ -# define LV_TILEVIEW_DEF_ANIM_TIME 0 +# define LV_TILEVIEW_DEF_ANIM_TIME 300 #endif /*Window (dependencies: lv_cont, lv_btn, lv_label, lv_img, lv_page)*/ diff --git a/src/main.cpp b/src/main.cpp index 2a272677..08b15f62 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -18,10 +18,10 @@ #include "../drivers/Cst816s.h" #include #include -#include #include #include +#include #if NRF_LOG_ENABLED #include "Logging/NrfLogger.h" @@ -33,8 +33,6 @@ Pinetime::Logging::DummyLogger logger; std::unique_ptr spi; std::unique_ptr lcd; -Pinetime::Drivers::St7789* ptrLcd; -std::unique_ptr gfx; std::unique_ptr lvgl; std::unique_ptr touchPanel; @@ -45,27 +43,19 @@ static constexpr uint8_t pinSpiCsn = 25; static constexpr uint8_t pinLcdDataCommand = 18; -std::unique_ptr displayApp; -TaskHandle_t systemThread; -bool isSleeping = false; TimerHandle_t debounceTimer; Pinetime::Controllers::Battery batteryController; Pinetime::Controllers::Ble bleController; Pinetime::Controllers::DateTime dateTimeController; - - void ble_manager_set_ble_connection_callback(void (*connection)()); void ble_manager_set_ble_disconnection_callback(void (*disconnection)()); -static constexpr uint8_t pinButton = 13; static constexpr uint8_t pinTouchIrq = 28; -QueueHandle_t systemTaksMsgQueue; -enum class SystemTaskMessages {GoToSleep, GoToRunning}; -void SystemTask_PushMessage(SystemTaskMessages message); +std::unique_ptr systemTask; void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action) { if(pin == pinTouchIrq) { - displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::TouchEvent); - if(!isSleeping) return; + systemTask->OnTouchEvent(); + return ; } BaseType_t xHigherPriorityTaskWoken = pdFALSE; @@ -73,7 +63,6 @@ void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action portYIELD_FROM_ISR(xHigherPriorityTaskWoken); } - extern "C" { void vApplicationIdleHook(void) { lv_tick_inc(1); @@ -82,118 +71,17 @@ extern "C" { void DebounceTimerCallback(TimerHandle_t xTimer) { xTimerStop(xTimer, 0); - /*if(isSleeping) { - SystemTask_PushMessage(SystemTaskMessages::GoToRunning); - displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToRunning); - isSleeping = false; - batteryController.Update(); - displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateBatteryLevel); - } - else { - SystemTask_PushMessage(SystemTaskMessages::GoToSleep); - displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::GoToSleep); - isSleeping = true; - }*/ - displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::ButtonPushed); -} - -void SystemTask_PushMessage(SystemTaskMessages message) { - BaseType_t xHigherPriorityTaskWoken; - xHigherPriorityTaskWoken = pdFALSE; - xQueueSendFromISR(systemTaksMsgQueue, &message, &xHigherPriorityTaskWoken); - if (xHigherPriorityTaskWoken) { - /* Actual macro used here is port specific. */ - // TODO : should I do something here? - } -} - -// TODO The whole SystemTask should go in its own class -// BUT... it has to work with pure C callback (nrfx_gpiote_evt_handler) and i've still not found -// a good design for that (the callback does not allow to pass a pointer to an instance...) -void SystemTask(void *) { - APP_GPIOTE_INIT(2); - bool erase_bonds=false; -// nrf_sdh_freertos_init(ble_manager_start_advertising, &erase_bonds); - - spi.reset(new Pinetime::Drivers::SpiMaster {Pinetime::Drivers::SpiMaster::SpiModule::SPI0, { - Pinetime::Drivers::SpiMaster::BitOrder::Msb_Lsb, - Pinetime::Drivers::SpiMaster::Modes::Mode3, - Pinetime::Drivers::SpiMaster::Frequencies::Freq8Mhz, - pinSpiSck, - pinSpiMosi, - pinSpiMiso, - pinSpiCsn - }}); - - lcd.reset(new Pinetime::Drivers::St7789(*spi, pinLcdDataCommand)); - gfx.reset(new Pinetime::Components::Gfx(*lcd)); - touchPanel.reset(new Pinetime::Drivers::Cst816S()); - - lvgl.reset(new Pinetime::Components::LittleVgl(*lcd, *touchPanel)); - ptrLcd = lcd.get(); - - spi->Init(); - lcd->Init(); - touchPanel->Init(); - batteryController.Init(); - - displayApp.reset(new Pinetime::Applications::DisplayApp(*lcd, *gfx, *lvgl, *touchPanel, batteryController, bleController, dateTimeController)); - displayApp->Start(); - - batteryController.Update(); - displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateBatteryLevel); - - debounceTimer = xTimerCreate ("debounceTimer", 200, pdFALSE, (void *) 0, DebounceTimerCallback); - - 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); - - systemTaksMsgQueue = xQueueCreate(10, 1); - bool systemTaskSleeping = false; - - while(true) { - uint8_t msg; - if (xQueueReceive(systemTaksMsgQueue, &msg, systemTaskSleeping?3600000 : 1000)) { - SystemTaskMessages message = static_cast(msg); - switch(message) { - case SystemTaskMessages::GoToRunning: systemTaskSleeping = false; break; - case SystemTaskMessages::GoToSleep: systemTaskSleeping = true; break; - default: break; - } - } - uint32_t systick_counter = nrf_rtc_counter_get(portNRF_RTC_REG); - dateTimeController.UpdateTime(systick_counter); - } + systemTask->OnButtonPushed(); } void OnBleConnection() { bleController.Connect(); - displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateBleConnection); + // TODO Notify system/Display app } void OnBleDisconnection() { bleController.Disconnect(); - displayApp->PushMessage(Pinetime::Applications::DisplayApp::Messages::UpdateBleConnection); + // TODO Notify system/Display app } void OnNewTime(current_time_char_t* currentTime) { @@ -224,12 +112,28 @@ void SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0_IRQHandler(void) { NRF_SPIM0->EVENTS_STOPPED = 0; } } + int main(void) { logger.Init(); nrf_drv_clock_init(); - if (pdPASS != xTaskCreate(SystemTask, "MAIN", 256, nullptr, 0, &systemThread)) - APP_ERROR_HANDLER(NRF_ERROR_NO_MEM); + spi.reset(new Pinetime::Drivers::SpiMaster {Pinetime::Drivers::SpiMaster::SpiModule::SPI0, { + Pinetime::Drivers::SpiMaster::BitOrder::Msb_Lsb, + Pinetime::Drivers::SpiMaster::Modes::Mode3, + Pinetime::Drivers::SpiMaster::Frequencies::Freq8Mhz, + pinSpiSck, + pinSpiMosi, + pinSpiMiso, + pinSpiCsn + }}); + lcd.reset(new Pinetime::Drivers::St7789(*spi, pinLcdDataCommand)); + touchPanel.reset(new Pinetime::Drivers::Cst816S()); + lvgl.reset(new Pinetime::Components::LittleVgl(*lcd, *touchPanel)); + debounceTimer = xTimerCreate ("debounceTimer", 200, pdFALSE, (void *) 0, DebounceTimerCallback); + + 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); diff --git a/src/main.h b/src/main.h new file mode 100644 index 00000000..b0a8a57e --- /dev/null +++ b/src/main.h @@ -0,0 +1,7 @@ +#pragma once + +#include +#include + +void nrfx_gpiote_evt_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action); +void DebounceTimerCallback(TimerHandle_t xTimer); \ 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/DisplayApp/Screens/Clock.cpp') 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 5bc0640b735573b465cfef16fb729ad5f5149eb4 Mon Sep 17 00:00:00 2001 From: JF Date: Sun, 1 Mar 2020 19:09:59 +0100 Subject: Fix typo in the name of the font "jetbrains_mono_extrabold_compressed" + use it as the default font. --- src/DisplayApp/DisplayApp.cpp | 11 +++++++++++ src/DisplayApp/Fonts/jetbrains_mono_extrabold_compressed.c | 10 +++++----- src/DisplayApp/LittleVgl.cpp | 8 ++++++-- src/DisplayApp/Screens/Clock.cpp | 4 ++-- src/DisplayApp/Screens/Gauge.cpp | 2 +- src/DisplayApp/Screens/Meter.cpp | 2 +- src/DisplayApp/Screens/Modal.cpp | 2 +- 7 files changed, 27 insertions(+), 12 deletions(-) (limited to 'src/DisplayApp/Screens/Clock.cpp') diff --git a/src/DisplayApp/DisplayApp.cpp b/src/DisplayApp/DisplayApp.cpp index 316312ed..d7d62dde 100644 --- a/src/DisplayApp/DisplayApp.cpp +++ b/src/DisplayApp/DisplayApp.cpp @@ -120,6 +120,17 @@ void DisplayApp::Refresh() { if(!currentScreen->OnButtonPushed()) { systemTask.PushMessage(System::SystemTask::Messages::GoToSleep); } +// currentScreen.reset(nullptr); +// if(toggle) { +// modal.Show(); +//// currentScreen.reset(new Screens::Tile(this)); +// toggle = false; +// } else { +// modal.Hide(); +//// currentScreen.reset(new Screens::Clock(this, dateTimeController, batteryController, bleController)); +// toggle = true; +// } + break; } } diff --git a/src/DisplayApp/Fonts/jetbrains_mono_extrabold_compressed.c b/src/DisplayApp/Fonts/jetbrains_mono_extrabold_compressed.c index c850cd91..c9917e40 100644 --- a/src/DisplayApp/Fonts/jetbrains_mono_extrabold_compressed.c +++ b/src/DisplayApp/Fonts/jetbrains_mono_extrabold_compressed.c @@ -6,11 +6,11 @@ * Opts: ******************************************************************************/ -#ifndef JETBRAINS_MONO_EXTRABOLD_COMPRESSEDEXTRABOLD_COMPRESSED -#define JETBRAINS_MONO_EXTRABOLD_COMPRESSEDEXTRABOLD_COMPRESSED 1 +#ifndef JETBRAINS_MONO_EXTRABOLD_COMPRESSED +#define JETBRAINS_MONO_EXTRABOLD_COMPRESSED 1 #endif -#if JETBRAINS_MONO_EXTRABOLD_COMPRESSEDEXTRABOLD_COMPRESSED +#if JETBRAINS_MONO_EXTRABOLD_COMPRESSED /*----------------- * BITMAPS @@ -492,7 +492,7 @@ static lv_font_fmt_txt_dsc_t font_dsc = { *----------------*/ /*Initialize a public general font descriptor*/ -lv_font_t jetbrains_mono_extrabold_compressedextrabold_compressed = { +lv_font_t jetbrains_mono_extrabold_compressed = { .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ .line_height = 60, /*The maximum line height required by the font*/ @@ -503,5 +503,5 @@ lv_font_t jetbrains_mono_extrabold_compressedextrabold_compressed = { .dsc = &font_dsc /*The custom font data. Will be accessed by `get_glyph_bitmap/dsc` */ }; -#endif /*#if JETBRAINS_MONO_EXTRABOLD_COMPRESSEDEXTRABOLD_COMPRESSED*/ +#endif /*#if JETBRAINS_MONO_EXTRABOLD_COMPRESSED*/ diff --git a/src/DisplayApp/LittleVgl.cpp b/src/DisplayApp/LittleVgl.cpp index c4fa1793..59334931 100644 --- a/src/DisplayApp/LittleVgl.cpp +++ b/src/DisplayApp/LittleVgl.cpp @@ -12,6 +12,11 @@ using namespace Pinetime::Components; +extern "C" { +LV_FONT_DECLARE(jetbrains_mono_extrabold_compressed) +LV_FONT_DECLARE(jetbrains_mono_bold_20) +} + static void disp_flush(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p) { auto* lvgl = static_cast(disp_drv->user_data); lvgl->FlushDisplay(area, color_p); @@ -135,8 +140,7 @@ void LittleVgl::InitTheme() { } void LittleVgl::InitBaseTheme() { - if(font == nullptr) font = LV_FONT_DEFAULT; - + if(font == nullptr) font = &jetbrains_mono_bold_20; lv_style_copy(&def, &lv_style_plain); /*Initialize the default style*/ def.text.font = font; diff --git a/src/DisplayApp/Screens/Clock.cpp b/src/DisplayApp/Screens/Clock.cpp index f0bd8338..1dff88c2 100644 --- a/src/DisplayApp/Screens/Clock.cpp +++ b/src/DisplayApp/Screens/Clock.cpp @@ -7,7 +7,7 @@ #include "../DisplayApp.h" using namespace Pinetime::Applications::Screens; -extern lv_font_t jetbrains_mono_extrabold_compressedextrabold_compressed; +extern lv_font_t jetbrains_mono_extrabold_compressed; extern lv_font_t jetbrains_mono_bold_20; static void event_handler(lv_obj_t * obj, lv_event_t event) { @@ -33,7 +33,7 @@ Clock::Clock(DisplayApp* app, labelStyle->text.font = &jetbrains_mono_bold_20; lv_style_copy(&labelBigStyle, labelStyle); - labelBigStyle.text.font = &jetbrains_mono_extrabold_compressedextrabold_compressed; + labelBigStyle.text.font = &jetbrains_mono_extrabold_compressed; lv_label_set_style(label_battery, LV_LABEL_STYLE_MAIN, labelStyle); diff --git a/src/DisplayApp/Screens/Gauge.cpp b/src/DisplayApp/Screens/Gauge.cpp index 33f76a74..4c4cccd9 100644 --- a/src/DisplayApp/Screens/Gauge.cpp +++ b/src/DisplayApp/Screens/Gauge.cpp @@ -3,7 +3,7 @@ #include "../DisplayApp.h" using namespace Pinetime::Applications::Screens; -extern lv_font_t jetbrains_mono_extrabold_compressedextrabold_compressed; +extern lv_font_t jetbrains_mono_extrabold_compressed; extern lv_font_t jetbrains_mono_bold_20; diff --git a/src/DisplayApp/Screens/Meter.cpp b/src/DisplayApp/Screens/Meter.cpp index 9daafad3..c74b8bdf 100644 --- a/src/DisplayApp/Screens/Meter.cpp +++ b/src/DisplayApp/Screens/Meter.cpp @@ -3,7 +3,7 @@ #include "../DisplayApp.h" using namespace Pinetime::Applications::Screens; -extern lv_font_t jetbrains_mono_extrabold_compressedextrabold_compressed; +extern lv_font_t jetbrains_mono_extrabold_compressed; extern lv_font_t jetbrains_mono_bold_20; diff --git a/src/DisplayApp/Screens/Modal.cpp b/src/DisplayApp/Screens/Modal.cpp index 13bd42fa..7a0264e3 100644 --- a/src/DisplayApp/Screens/Modal.cpp +++ b/src/DisplayApp/Screens/Modal.cpp @@ -3,7 +3,7 @@ #include "../DisplayApp.h" using namespace Pinetime::Applications::Screens; -extern lv_font_t jetbrains_mono_extrabold_compressedextrabold_compressed; +extern lv_font_t jetbrains_mono_extrabold_compressed; extern lv_font_t jetbrains_mono_bold_20; Modal::Modal(Pinetime::Applications::DisplayApp *app) : Screen(app) { -- cgit v1.2.3-70-g09d2 From 824b8a7ebd0e8b4f876dd12f564e89238a1bb1b4 Mon Sep 17 00:00:00 2001 From: JF Date: Mon, 2 Mar 2020 20:12:46 +0100 Subject: Move version display from Clock screen to the modal window (accessible from tile menu) --- src/DisplayApp/Screens/Clock.cpp | 13 +------------ src/DisplayApp/Screens/Modal.cpp | 7 +++++-- src/DisplayApp/Screens/Tile.cpp | 2 +- 3 files changed, 7 insertions(+), 15 deletions(-) (limited to 'src/DisplayApp/Screens/Clock.cpp') diff --git a/src/DisplayApp/Screens/Clock.cpp b/src/DisplayApp/Screens/Clock.cpp index 1dff88c2..7051c433 100644 --- a/src/DisplayApp/Screens/Clock.cpp +++ b/src/DisplayApp/Screens/Clock.cpp @@ -48,11 +48,7 @@ Clock::Clock(DisplayApp* app, label_date = lv_label_create(lv_scr_act(), NULL); lv_label_set_style(label_date, LV_LABEL_STYLE_MAIN, labelStyle); - lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 80); - - label_version = lv_label_create(lv_scr_act(), NULL); - lv_label_set_style(label_version, LV_LABEL_STYLE_MAIN, labelStyle); - lv_obj_align(label_version, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 100); + lv_obj_align(label_date, lv_scr_act(), LV_ALIGN_IN_LEFT_MID, 0, 60); backgroundLabel = lv_label_create(lv_scr_act(), NULL); backgroundLabel->user_data = this; @@ -140,13 +136,6 @@ bool Clock::Refresh() { } } - if(version.IsUpdated()) { - auto dummy = version.Get(); - char versionStr[20]; - sprintf(versionStr, "VERSION: %d.%d.%d", Version::Major(), Version::Minor(), Version::Patch()); - lv_label_set_text(label_version, versionStr); - } - return running; } diff --git a/src/DisplayApp/Screens/Modal.cpp b/src/DisplayApp/Screens/Modal.cpp index 7a0264e3..fc353c49 100644 --- a/src/DisplayApp/Screens/Modal.cpp +++ b/src/DisplayApp/Screens/Modal.cpp @@ -36,12 +36,15 @@ void Modal::Show() { 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", ""}; + 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); - lv_mbox_set_text(mbox, "Hello world!"); + 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); diff --git a/src/DisplayApp/Screens/Tile.cpp b/src/DisplayApp/Screens/Tile.cpp index 72fe35bc..004c8d31 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", "MsgBox", "App2", "App3", ""}; +static const char * btnm_map1[] = {"Meter", "Gauge", "Clock", "\n", "Soft\nversion", "App2", "App3", ""}; Tile::Tile(DisplayApp* app) : Screen(app) { modal.reset(new Modal(app)); -- cgit v1.2.3-70-g09d2