From a02d538b5836ba0a63e5e7423a08ba9b516f1908 Mon Sep 17 00:00:00 2001 From: Manuel <71137295+mverch67@users.noreply.github.com> Date: Mon, 17 Feb 2025 17:35:11 +0100 Subject: [PATCH] MUI: move UI initialization out of main.cpp and adding lightsleep observer + mutex (#6078) * added device-ui to lightSleep observers for handling graceful sleep; refactoring main.cpp * bump lib version --- lib/device-ui | 2 +- src/graphics/tftSetup.cpp | 126 ++++++++++++++++++++++++++++++++++++++ src/main.cpp | 117 ++--------------------------------- 3 files changed, 133 insertions(+), 112 deletions(-) create mode 100644 src/graphics/tftSetup.cpp diff --git a/lib/device-ui b/lib/device-ui index 6adfb70ee..a5c496f41 160000 --- a/lib/device-ui +++ b/lib/device-ui @@ -1 +1 @@ -Subproject commit 6adfb70ee9d9db524a821b26dd5ef2982113df18 +Subproject commit a5c496f41e31fd5512834b5bfdf9cbbfe652203e diff --git a/src/graphics/tftSetup.cpp b/src/graphics/tftSetup.cpp new file mode 100644 index 000000000..c31659c62 --- /dev/null +++ b/src/graphics/tftSetup.cpp @@ -0,0 +1,126 @@ +#if HAS_TFT + +#include "SPILock.h" +#include "sleep.h" + +#include "api/PacketAPI.h" +#include "comms/PacketClient.h" +#include "comms/PacketServer.h" +#include "graphics/DeviceScreen.h" +#include "graphics/driver/DisplayDriverConfig.h" + +#ifdef ARCH_PORTDUINO +#include "PortduinoGlue.h" +#endif + +DeviceScreen *deviceScreen = nullptr; + +#ifdef ARCH_ESP32 +// Get notified when the system is entering light sleep +CallbackObserver tftSleepObserver = + CallbackObserver(deviceScreen, &DeviceScreen::prepareSleep); +CallbackObserver endSleepObserver = + CallbackObserver(deviceScreen, &DeviceScreen::wakeUp); +#endif + +void tft_task_handler(void *param = nullptr) +{ + while (true) { + if (deviceScreen) { + spiLock->lock(); + deviceScreen->task_handler(); + spiLock->unlock(); + deviceScreen->sleep(); + } + } +} + +void tftSetup(void) +{ +#ifndef ARCH_PORTDUINO + deviceScreen = &DeviceScreen::create(); + PacketAPI::create(PacketServer::init()); + deviceScreen->init(new PacketClient); +#else + if (settingsMap[displayPanel] != no_screen) { + DisplayDriverConfig displayConfig; + static char *panels[] = {"NOSCREEN", "X11", "ST7789", "ST7735", "ST7735S", "ST7796", + "ILI9341", "ILI9342", "ILI9486", "ILI9488", "HX8357D"}; + static char *touch[] = {"NOTOUCH", "XPT2046", "STMPE610", "GT911", "FT5x06"}; +#ifdef USE_X11 + if (settingsMap[displayPanel] == x11) { + if (settingsMap[displayWidth] && settingsMap[displayHeight]) + displayConfig = DisplayDriverConfig(DisplayDriverConfig::device_t::X11, (uint16_t)settingsMap[displayWidth], + (uint16_t)settingsMap[displayHeight]); + else + displayConfig.device(DisplayDriverConfig::device_t::X11); + } else +#endif + { + displayConfig.device(DisplayDriverConfig::device_t::CUSTOM_TFT) + .panel(DisplayDriverConfig::panel_config_t{.type = panels[settingsMap[displayPanel]], + .panel_width = (uint16_t)settingsMap[displayWidth], + .panel_height = (uint16_t)settingsMap[displayHeight], + .rotation = (bool)settingsMap[displayRotate], + .pin_cs = (int16_t)settingsMap[displayCS], + .pin_rst = (int16_t)settingsMap[displayReset], + .offset_x = (uint16_t)settingsMap[displayOffsetX], + .offset_y = (uint16_t)settingsMap[displayOffsetY], + .offset_rotation = (uint8_t)settingsMap[displayOffsetRotate], + .invert = settingsMap[displayInvert] ? true : false, + .rgb_order = (bool)settingsMap[displayRGBOrder], + .dlen_16bit = settingsMap[displayPanel] == ili9486 || + settingsMap[displayPanel] == ili9488}) + .bus(DisplayDriverConfig::bus_config_t{.freq_write = (uint32_t)settingsMap[displayBusFrequency], + .freq_read = 16000000, + .spi{.pin_dc = (int8_t)settingsMap[displayDC], + .use_lock = true, + .spi_host = (uint16_t)settingsMap[displayspidev]}}) + .input(DisplayDriverConfig::input_config_t{.keyboardDevice = settingsStrings[keyboardDevice], + .pointerDevice = settingsStrings[pointerDevice]}) + .light(DisplayDriverConfig::light_config_t{.pin_bl = (int16_t)settingsMap[displayBacklight], + .pwm_channel = (int8_t)settingsMap[displayBacklightPWMChannel], + .invert = (bool)settingsMap[displayBacklightInvert]}); + if (settingsMap[touchscreenI2CAddr] == -1) { + displayConfig.touch( + DisplayDriverConfig::touch_config_t{.type = touch[settingsMap[touchscreenModule]], + .freq = (uint32_t)settingsMap[touchscreenBusFrequency], + .pin_int = (int16_t)settingsMap[touchscreenIRQ], + .offset_rotation = (uint8_t)settingsMap[touchscreenRotate], + .spi{ + .spi_host = (int8_t)settingsMap[touchscreenspidev], + }, + .pin_cs = (int16_t)settingsMap[touchscreenCS]}); + } else { + displayConfig.touch(DisplayDriverConfig::touch_config_t{ + .type = touch[settingsMap[touchscreenModule]], + .freq = (uint32_t)settingsMap[touchscreenBusFrequency], + .x_min = 0, + .x_max = + (int16_t)((settingsMap[touchscreenRotate] & 1 ? settingsMap[displayWidth] : settingsMap[displayHeight]) - + 1), + .y_min = 0, + .y_max = + (int16_t)((settingsMap[touchscreenRotate] & 1 ? settingsMap[displayHeight] : settingsMap[displayWidth]) - + 1), + .pin_int = (int16_t)settingsMap[touchscreenIRQ], + .offset_rotation = (uint8_t)settingsMap[touchscreenRotate], + .i2c{.i2c_addr = (uint8_t)settingsMap[touchscreenI2CAddr]}}); + } + } + deviceScreen = &DeviceScreen::create(&displayConfig); + PacketAPI::create(PacketServer::init()); + deviceScreen->init(new PacketClient); + } else { + LOG_INFO("Running without TFT display!"); + } +#endif + +#ifdef ARCH_ESP32 + tftSleepObserver.observe(¬ifyLightSleep); + endSleepObserver.observe(¬ifyLightSleepEnd); + xTaskCreatePinnedToCore(tft_task_handler, "tft", 8192, NULL, 1, NULL, 0); +#endif +} + +#endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index ebd984573..f467d89c6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -116,15 +116,7 @@ AudioThread *audioThread = nullptr; #endif #if HAS_TFT -#include "api/PacketAPI.h" -#include "comms/PacketClient.h" -#include "comms/PacketServer.h" -#include "graphics/DeviceScreen.h" -#include "graphics/driver/DisplayDriverConfig.h" - -void tft_task_handler(void *); - -DeviceScreen *deviceScreen = nullptr; +extern void tftSetup(void); #endif #ifdef HAS_UDP_MULTICAST @@ -464,6 +456,10 @@ void setup() digitalWrite(AQ_SET_PIN, HIGH); #endif +#if HAS_TFT + tftSetup(); +#endif + // Currently only the tbeam has a PMU // PMU initialization needs to be placed before i2c scanning power = new Power(); @@ -766,86 +762,6 @@ void setup() SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS); LOG_DEBUG("SPI.begin(SCK=%d, MISO=%d, MOSI=%d, NSS=%d)", LORA_SCK, LORA_MISO, LORA_MOSI, LORA_CS); SPI.setFrequency(4000000); -#endif -#if HAS_TFT -#ifdef PORTDUINO - if (settingsMap[displayPanel] != no_screen) { - DisplayDriverConfig displayConfig; - static char *panels[] = {"NOSCREEN", "X11", "ST7789", "ST7735", "ST7735S", "ST7796", - "ILI9341", "ILI9342", "ILI9486", "ILI9488", "HX8357D"}; - static char *touch[] = {"NOTOUCH", "XPT2046", "STMPE610", "GT911", "FT5x06"}; -#ifdef USE_X11 - if (settingsMap[displayPanel] == x11) { - if (settingsMap[displayWidth] && settingsMap[displayHeight]) - displayConfig = DisplayDriverConfig(DisplayDriverConfig::device_t::X11, (uint16_t)settingsMap[displayWidth], - (uint16_t)settingsMap[displayHeight]); - else - displayConfig.device(DisplayDriverConfig::device_t::X11); - } else -#endif - { - displayConfig.device(DisplayDriverConfig::device_t::CUSTOM_TFT) - .panel(DisplayDriverConfig::panel_config_t{.type = panels[settingsMap[displayPanel]], - .panel_width = (uint16_t)settingsMap[displayWidth], - .panel_height = (uint16_t)settingsMap[displayHeight], - .rotation = (bool)settingsMap[displayRotate], - .pin_cs = (int16_t)settingsMap[displayCS], - .pin_rst = (int16_t)settingsMap[displayReset], - .offset_x = (uint16_t)settingsMap[displayOffsetX], - .offset_y = (uint16_t)settingsMap[displayOffsetY], - .offset_rotation = (uint8_t)settingsMap[displayOffsetRotate], - .invert = settingsMap[displayInvert] ? true : false, - .rgb_order = (bool)settingsMap[displayRGBOrder], - .dlen_16bit = settingsMap[displayPanel] == ili9486 || - settingsMap[displayPanel] == ili9488}) - .bus(DisplayDriverConfig::bus_config_t{.freq_write = (uint32_t)settingsMap[displayBusFrequency], - .freq_read = 16000000, - .spi{.pin_dc = (int8_t)settingsMap[displayDC], - .use_lock = true, - .spi_host = (uint16_t)settingsMap[displayspidev]}}) - .input(DisplayDriverConfig::input_config_t{.keyboardDevice = settingsStrings[keyboardDevice], - .pointerDevice = settingsStrings[pointerDevice]}) - .light(DisplayDriverConfig::light_config_t{.pin_bl = (int16_t)settingsMap[displayBacklight], - .pwm_channel = (int8_t)settingsMap[displayBacklightPWMChannel], - .invert = (bool)settingsMap[displayBacklightInvert]}); - if (settingsMap[touchscreenI2CAddr] == -1) { - displayConfig.touch( - DisplayDriverConfig::touch_config_t{.type = touch[settingsMap[touchscreenModule]], - .freq = (uint32_t)settingsMap[touchscreenBusFrequency], - .pin_int = (int16_t)settingsMap[touchscreenIRQ], - .offset_rotation = (uint8_t)settingsMap[touchscreenRotate], - .spi{ - .spi_host = (int8_t)settingsMap[touchscreenspidev], - }, - .pin_cs = (int16_t)settingsMap[touchscreenCS]}); - } else { - displayConfig.touch(DisplayDriverConfig::touch_config_t{ - .type = touch[settingsMap[touchscreenModule]], - .freq = (uint32_t)settingsMap[touchscreenBusFrequency], - .x_min = 0, - .x_max = - (int16_t)((settingsMap[touchscreenRotate] & 1 ? settingsMap[displayWidth] : settingsMap[displayHeight]) - - 1), - .y_min = 0, - .y_max = - (int16_t)((settingsMap[touchscreenRotate] & 1 ? settingsMap[displayHeight] : settingsMap[displayWidth]) - - 1), - .pin_int = (int16_t)settingsMap[touchscreenIRQ], - .offset_rotation = (uint8_t)settingsMap[touchscreenRotate], - .i2c{.i2c_addr = (uint8_t)settingsMap[touchscreenI2CAddr]}}); - } - } - deviceScreen = &DeviceScreen::create(&displayConfig); - PacketAPI::create(PacketServer::init()); - deviceScreen->init(new PacketClient); - } else { - LOG_INFO("Running without TFT display!"); - } -#else - deviceScreen = &DeviceScreen::create(); - PacketAPI::create(PacketServer::init()); - deviceScreen->init(new PacketClient); -#endif #endif // Initialize the screen first so we can show the logo while we start up everything else. @@ -1252,11 +1168,7 @@ void setup() PowerFSM_setup(); // we will transition to ON in a couple of seconds, FIXME, only do this for cold boots, not waking from SDS powerFSMthread = new PowerFSMThread(); -#if HAS_TFT -#ifdef HAS_FREE_RTOS - xTaskCreatePinnedToCore(tft_task_handler, "tft", 8192, NULL, 1, NULL, 0); -#endif -#else +#if !HAS_TFT setCPUFast(false); // 80MHz is fine for our slow peripherals #endif @@ -1361,21 +1273,4 @@ void loop() } } -#if HAS_TFT -void tft_task_handler(void *param = nullptr) -{ - while (true) { - if (deviceScreen) { - spiLock->lock(); - deviceScreen->task_handler(); - spiLock->unlock(); - } -#ifdef HAS_FREE_RTOS - vTaskDelay(5 / portTICK_PERIOD_MS); -#else - delay(5); -#endif - } -} -#endif #endif \ No newline at end of file