diff --git a/radio/src/gui/colorlcd/LvglWrapper.cpp b/radio/src/gui/colorlcd/LvglWrapper.cpp index 2eb38a6a8..93491bb5b 100644 --- a/radio/src/gui/colorlcd/LvglWrapper.cpp +++ b/radio/src/gui/colorlcd/LvglWrapper.cpp @@ -203,7 +203,7 @@ extern BitmapBuffer * lcd; static lv_disp_drv_t disp_drv; -static lv_disp_drv_t* init_disp_drv() +void init_disp_drv() { lv_disp_draw_buf_init(&disp_buf, lcdFront->getData(), lcd->getData(), LCD_W*LCD_H); lv_disp_drv_init(&disp_drv); /*Basic initialization*/ @@ -219,7 +219,8 @@ static lv_disp_drv_t* init_disp_drv() // disp_drv.rotated = LV_DISP_ROT_90; disp_drv.sw_rotate = 1; - return &disp_drv; + // Register the driver and save the created display objects + disp = lv_disp_drv_register(&disp_drv); } static void init_lvgl_drivers() @@ -229,7 +230,7 @@ static void init_lvgl_drivers() lv_group_set_default(inputGroup); // Register the driver and save the created display objects - disp = lv_disp_drv_register(init_disp_drv()); + init_disp_drv(); // Register the driver in LVGL and save the created input device object lv_indev_drv_init(&touchDriver); /*Basic initialization*/ @@ -346,7 +347,7 @@ LvglWrapper::LvglWrapper() // Create main window and load that screen auto window = MainWindow::instance(); - lv_scr_load(window->getLvObj()); + window->setActiveScreen(); } void LvglWrapper::run() diff --git a/radio/src/gui/colorlcd/splash.cpp b/radio/src/gui/colorlcd/splash.cpp index 27b0382cd..7a78e24b3 100644 --- a/radio/src/gui/colorlcd/splash.cpp +++ b/radio/src/gui/colorlcd/splash.cpp @@ -31,13 +31,38 @@ const uint8_t __bmp_splash_chr[] { #include "splash_chr.lbm" }; +void draw_splash_cb(lv_event_t * e) +{ + auto draw_ctx = lv_event_get_draw_ctx(e); + auto splashImg = (BitmapBuffer*)lv_event_get_user_data(e); + + // lcd->clear(splash_background_color); + + if (splashImg) { + lv_draw_img_dsc_t img_dsc; + lv_draw_img_dsc_init(&img_dsc); + + // TODO: center image + lv_area_t coords; + coords.x1 = 0; + coords.y1 = 0; + coords.x2 = splashImg->width()-1; + coords.y2 = splashImg->height()-1; + + lv_draw_img_decoded(draw_ctx, &img_dsc, &coords, + (const uint8_t *)splashImg->getData(), + LV_IMG_CF_TRUE_COLOR); + } +} + void drawSplash() { constexpr LcdFlags splash_background_color = COLOR2FLAGS(((0xC >> 3) << 11) | ((0x3F >> 2) << 5) | (0x66 >> 3)); static bool loadSplashImg = true; - static BitmapBuffer * splashImg = nullptr; + static BitmapBuffer* splashImg = nullptr; + static lv_obj_t* splashScreen = nullptr; // try splash from SD card first if (loadSplashImg && splashImg == nullptr) { @@ -47,30 +72,32 @@ void drawSplash() // otherwise load from FLASH struct gtm t; - gettime(&t); - // Please do not spoil the suprise by discussing following lines in public - // mon == 11 == December, starts from 0! - if (t.tm_mon == 11 && t.tm_mday >= 24 && t.tm_mday <= 26) - { - if (splashImg == nullptr) { - splashImg = BitmapBuffer::loadRamBitmap(__bmp_splash_chr, sizeof(__bmp_splash_chr)); - } - } else - { - if (splashImg == nullptr) { - splashImg = BitmapBuffer::loadRamBitmap(__bmp_splash, sizeof(__bmp_splash)); - } - } + gettime(&t); + // Please do not spoil the suprise by discussing following lines in public + // mon == 11 == December, starts from 0! + if (t.tm_mon == 11 && t.tm_mday >= 24 && t.tm_mday <= 26) { + if (splashImg == nullptr) { + splashImg = BitmapBuffer::loadRamBitmap(__bmp_splash_chr, + sizeof(__bmp_splash_chr)); + } + } else { + if (splashImg == nullptr) { + splashImg = + BitmapBuffer::loadRamBitmap(__bmp_splash, sizeof(__bmp_splash)); + } + } + + splashScreen = lv_obj_create(nullptr); + if (splashScreen) { + lv_obj_add_event_cb(splashScreen, draw_splash_cb, LV_EVENT_DRAW_MAIN, splashImg); + } } - lcd->clear(splash_background_color); - - if (splashImg) { - lcd->drawBitmap((LCD_W - splashImg->width())/2, - (LCD_H - splashImg->height())/2, - splashImg); + if (splashScreen) { + lv_scr_load(splashScreen); + lv_refr_now(nullptr); } - lcdRefresh(); + MainWindow::instance()->setActiveScreen(); } #endif diff --git a/radio/src/opentx.cpp b/radio/src/opentx.cpp index c7dc7fe4d..a1e8dd803 100644 --- a/radio/src/opentx.cpp +++ b/radio/src/opentx.cpp @@ -637,6 +637,9 @@ void doSplash() checkBacklight(); } +#if defined(LIBOPENUI) + MainWindow::instance()->setActiveScreen(); +#endif } } #else @@ -1770,7 +1773,6 @@ void opentxInit() TRACE("opentxInit"); #if defined(LIBOPENUI) // create ViewMain - LvglWrapper::instance(); ViewMain::instance(); #elif defined(GUI) // TODO add a function for this (duplicated) diff --git a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt index d2a119164..b2700d5ad 100644 --- a/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt +++ b/radio/src/targets/common/arm/stm32/bootloader/CMakeLists.txt @@ -114,6 +114,7 @@ if(PCB STREQUAL X10 OR PCB STREQUAL X12S OR PCB STREQUAL NV14) ${BOOTLOADER_SRC} ../../../../../gui/colorlcd/fonts.cpp ../../../../../gui/colorlcd/colors.cpp + ../../../../../fonts/lvgl/lv_font_roboto_16.c ../../../../../thirdparty/libopenui/src/bitmapbuffer.cpp ../../../../../targets/${TARGET_DIR}/sdram_driver.c ../../../../../targets/common/arm/stm32/sdio_sd.c @@ -122,6 +123,11 @@ if(PCB STREQUAL X10 OR PCB STREQUAL X12S OR PCB STREQUAL NV14) ../../../../../syscalls.c ) + # Add LVGL sources + foreach(LVGL_FILE ${LVGL_SRC_FILES}) + set(BOOTLOADER_SRC ${BOOTLOADER_SRC} ../../../../../${LVGL_FILE}) + endforeach() + if(USB_CHARGER) set(BOOTLOADER_SRC ${BOOTLOADER_SRC} diff --git a/radio/src/targets/horus/lcd_driver.cpp b/radio/src/targets/horus/lcd_driver.cpp index e60b7447c..decf33364 100644 --- a/radio/src/targets/horus/lcd_driver.cpp +++ b/radio/src/targets/horus/lcd_driver.cpp @@ -47,7 +47,6 @@ uint8_t LCD_FIRST_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(pixel_t)] __SDRAM; uint8_t LCD_SECOND_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(pixel_t)] __SDRAM; uint8_t LCD_BACKUP_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(pixel_t)] __SDRAM; -uint8_t LCD_SCRATCH_FRAME_BUFFER[DISPLAY_BUFFER_SIZE * sizeof(pixel_t)] __SDRAM; uint8_t currentLayer = LCD_FIRST_LAYER; BitmapBuffer lcdBuffer1(BMP_RGB565, LCD_W, LCD_H, (uint16_t *)LCD_FIRST_FRAME_BUFFER); @@ -628,10 +627,6 @@ uint16_t* lcdGetBackupBuffer() return (uint16_t*)LCD_BACKUP_FRAME_BUFFER; } -uint16_t* lcdGetScratchBuffer() -{ - return (uint16_t*)LCD_SCRATCH_FRAME_BUFFER; -} static volatile uint8_t _frameBufferAddressReloaded = 0; @@ -673,6 +668,7 @@ void newLcdRefresh(uint16_t * buffer) while(_frameBufferAddressReloaded == 0); #endif } + void lcdRefresh() { //lcdSwitchLayers(); diff --git a/radio/src/targets/simu/simulcd.cpp b/radio/src/targets/simu/simulcd.cpp index 5b353c66a..a40495ca9 100644 --- a/radio/src/targets/simu/simulcd.cpp +++ b/radio/src/targets/simu/simulcd.cpp @@ -59,19 +59,16 @@ void lcdRefresh() pixel_t displayBuf1[DISPLAY_BUFFER_SIZE]; pixel_t displayBuf2[DISPLAY_BUFFER_SIZE]; -pixel_t scratchBuf[DISPLAY_BUFFER_SIZE]; pixel_t LCD_BACKUP_FRAME_BUFFER[DISPLAY_BUFFER_SIZE]; BitmapBuffer lcdBackup(BMP_RGB565, LCD_W, LCD_H, LCD_BACKUP_FRAME_BUFFER); -BitmapBuffer scratch(BMP_RGB565, LCD_W, LCD_H, scratchBuf); BitmapBuffer _lcd1(BMP_RGB565, LCD_W, LCD_H, displayBuf1); BitmapBuffer _lcd2(BMP_RGB565, LCD_W, LCD_H, displayBuf2); BitmapBuffer * lcd = &_lcd1; BitmapBuffer * lcdFront = &_lcd2; -uint16_t *lcdGetScratchBuffer() { return static_cast(scratchBuf); } void lcdStoreBackupBuffer() { @@ -115,10 +112,10 @@ void newLcdRefresh(uint16_t *buffer, const rect_t& copy_area) // Mark screen dirty for async refresh simuLcdRefresh = true; - // .. and wait for refresh - auto start = RTOS_GET_MS(); - while(simuLcdRefresh || - (RTOS_GET_MS() - start > 100)); + // // .. and wait for refresh + // auto start = RTOS_GET_MS(); + // while(simuLcdRefresh || + // (RTOS_GET_MS() - start <= 100)); } void lcdRefresh() { @@ -145,8 +142,8 @@ void lcdRefresh() void lcdInit() { - _lcd1.clear(); - _lcd2.clear(); + memset(displayBuf1, 0, sizeof(displayBuf1)); + memset(displayBuf2, 0, sizeof(displayBuf2)); } void DMAFillRect(uint16_t *dest, uint16_t destw, uint16_t desth, uint16_t x, diff --git a/radio/src/tasks.cpp b/radio/src/tasks.cpp index 495a11718..a7c74a8dd 100644 --- a/radio/src/tasks.cpp +++ b/radio/src/tasks.cpp @@ -183,6 +183,10 @@ bool perMainEnabled = true; TASK_FUNCTION(menusTask) { +#if defined(LIBOPENUI) + LvglWrapper::instance(); +#endif + #if defined(SPLASH) && !defined(STARTUP_ANIMATION) if (!UNEXPECTED_SHUTDOWN()) { drawSplash(); diff --git a/radio/src/tests/frsky.cpp b/radio/src/tests/frsky.cpp index 978e47455..2d7f3e35f 100644 --- a/radio/src/tests/frsky.cpp +++ b/radio/src/tests/frsky.cpp @@ -299,9 +299,6 @@ TEST(FrSkySPORT, frskySetCellVoltage) EXPECT_EQ(telemetryItems[0].value, 2068); EXPECT_EQ(telemetryItems[0].valueMin, 1756); EXPECT_EQ(telemetryItems[0].valueMax, 2071); - - //display test - lcdClear(); } TEST(FrSkySPORT, StrangeCellsBug) @@ -379,9 +376,6 @@ TEST(FrSkySPORT, frskySetCellVoltageTwoSensors) EXPECT_EQ(telemetryItems[2].value, 283); EXPECT_EQ(telemetryItems[2].valueMin, 283); EXPECT_EQ(telemetryItems[2].valueMax, 287); - - //display test - lcdClear(); } void generateSportFasVoltagePacket(uint8_t * packet, uint32_t voltage) diff --git a/radio/src/tests/gtests.cpp b/radio/src/tests/gtests.cpp index d6bbf6abd..eb9666d41 100644 --- a/radio/src/tests/gtests.cpp +++ b/radio/src/tests/gtests.cpp @@ -155,6 +155,9 @@ const char * nchar2string(const char * string, int size) return _stringResult; } +#if defined(LIBOPENUI) +void init_disp_drv(); +#endif int main(int argc, char **argv) { @@ -180,5 +183,10 @@ int main(int argc, char **argv) listeners.Append(new TersePrinter(defaultPrinter)); } +#if defined(LIBOPENUI) + lv_init(); + init_disp_drv(); +#endif + return RUN_ALL_TESTS(); } diff --git a/radio/src/tests/lcd_480x272.cpp b/radio/src/tests/lcd_480x272.cpp index 38a40fb50..c47477bc8 100644 --- a/radio/src/tests/lcd_480x272.cpp +++ b/radio/src/tests/lcd_480x272.cpp @@ -28,7 +28,6 @@ #if defined(COLORLCD) -#include "gui/colorlcd/fonts.h" #define STB_IMAGE_WRITE_IMPLEMENTATION #include "stb_image_write.h" @@ -126,6 +125,8 @@ static void init_fake_disp(BitmapBuffer* dc) TEST(Lcd_colorlcd, lines) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); + init_fake_disp(&dc); + dc.clear(COLOR_THEME_SECONDARY3); dc.setClippingRect(50, 400, 50, 230); @@ -144,6 +145,8 @@ TEST(Lcd_colorlcd, lines) TEST(Lcd_colorlcd, vline) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); + init_fake_disp(&dc); + dc.clear(COLOR_THEME_SECONDARY3); for (int x=0; x<100; x+=2) { @@ -155,7 +158,6 @@ TEST(Lcd_colorlcd, vline) TEST(Lcd_colorlcd, primitives) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); - init_fake_disp(&dc); dc.clear(COLOR_THEME_SECONDARY3); @@ -186,7 +188,6 @@ TEST(Lcd_colorlcd, primitives) TEST(Lcd_colorlcd, transparency) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); - init_fake_disp(&dc); dc.clear(COLOR_THEME_SECONDARY3); @@ -256,6 +257,8 @@ TEST(Lcd_colorlcd, fonts) TEST(Lcd_colorlcd, clipping) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); + init_fake_disp(&dc); + dc.clear(COLOR_THEME_SECONDARY3); dc.drawSolidVerticalLine(100, 0, LCD_H, COLOR_THEME_SECONDARY1); @@ -282,6 +285,8 @@ TEST(Lcd_colorlcd, clipping) TEST(Lcd_colorlcd, bitmap) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); + init_fake_disp(&dc); + dc.clear(COLOR_THEME_SECONDARY3); dc.setClippingRect(100, 400, 50, 200); @@ -297,6 +302,8 @@ TEST(Lcd_colorlcd, bitmap) TEST(Lcd_colorlcd, masks) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); + init_fake_disp(&dc); + dc.clear(COLOR_THEME_SECONDARY3); BitmapBuffer* mask = BitmapBuffer::loadMask(TESTS_PATH "/mask_menu_radio.png"); @@ -320,14 +327,16 @@ const uint8_t LBM_USB_PLUGGED[] = { TEST(Lcd_colorlcd, darkmode) { BitmapBuffer dc(BMP_RGB565, LCD_W, LCD_H); + init_fake_disp(&dc); + dc.clear(COLOR2FLAGS(BLACK)); dc.drawText(20, 28, "The quick brown fox jumps over the lazy dog", COLOR2FLAGS(WHITE)); - dc.drawSolidFilledRect(28, 56, 422, 2, COLOR2FLAGS(RED)); + dc.drawSolidFilledRect(28, 56, 422, 2, COLOR2FLAGS(RGB(0xFF, 0, 0))); dc.drawBitmapPattern(LCD_W/2 - LBM_USB_PLUGGED_W/2, LCD_H/2 - LBM_USB_PLUGGED_H/2, LBM_USB_PLUGGED, - COLOR2FLAGS(BLUE)); + COLOR2FLAGS(RGB(0, 0, 0xFF))); EXPECT_TRUE(checkScreenshot_colorlcd(&dc, "darkmode_" TRANSLATIONS)); } diff --git a/radio/src/thirdparty/libopenui b/radio/src/thirdparty/libopenui index 7e03db94c..3da9b3393 160000 --- a/radio/src/thirdparty/libopenui +++ b/radio/src/thirdparty/libopenui @@ -1 +1 @@ -Subproject commit 7e03db94cdc1f684e028fad2b211dca0d94c675d +Subproject commit 3da9b3393fc83fed9e8393ad8b26c0a60396cb4b