From b41b0a03c3ee4fe66acd9e03f193c0c4af0b67c8 Mon Sep 17 00:00:00 2001 From: William Emfinger Date: Tue, 12 Aug 2025 09:28:43 -0500 Subject: [PATCH] feat(ws-s3-lcd-1-47): Update backlight to be initialized by LCD instead of display --- .../ws-s3-lcd-1-47/include/ws-s3-lcd-1-47.hpp | 5 +++ .../ws-s3-lcd-1-47/src/ws-s3-lcd-1-47.cpp | 34 ++++++++++++++----- 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/components/ws-s3-lcd-1-47/include/ws-s3-lcd-1-47.hpp b/components/ws-s3-lcd-1-47/include/ws-s3-lcd-1-47.hpp index a62ef53bd..1bac1b809 100644 --- a/components/ws-s3-lcd-1-47/include/ws-s3-lcd-1-47.hpp +++ b/components/ws-s3-lcd-1-47/include/ws-s3-lcd-1-47.hpp @@ -16,6 +16,7 @@ #include "base_component.hpp" #include "interrupt.hpp" +#include "led.hpp" #include "neopixel.hpp" #include "st7789.hpp" @@ -105,10 +106,12 @@ class WsS3Lcd147 : public BaseComponent { /// Set the brightness of the backlight /// \param brightness The brightness of the backlight as a percentage (0 - 100) + /// \note This function will only work after initialize_lcd() has been called void brightness(float brightness); /// Get the brightness of the backlight /// \return The brightness of the backlight as a percentage (0 - 100) + /// \note This function will only work after initialize_lcd() has been called float brightness() const; /// Get the VRAM 0 pointer (DMA memory used by LVGL) @@ -284,6 +287,8 @@ class WsS3Lcd147 : public BaseComponent { // display std::shared_ptr> display_; + std::vector backlight_channel_configs_{}; + std::shared_ptr backlight_{}; /// SPI bus for communication with the LCD spi_bus_config_t lcd_spi_bus_config_; spi_device_interface_config_t lcd_config_; diff --git a/components/ws-s3-lcd-1-47/src/ws-s3-lcd-1-47.cpp b/components/ws-s3-lcd-1-47/src/ws-s3-lcd-1-47.cpp index 1798dabd8..23cb78a8f 100644 --- a/components/ws-s3-lcd-1-47/src/ws-s3-lcd-1-47.cpp +++ b/components/ws-s3-lcd-1-47/src/ws-s3-lcd-1-47.cpp @@ -69,13 +69,26 @@ static void IRAM_ATTR lcd_spi_post_transfer_callback(spi_transaction_t *t) { } bool WsS3Lcd147::initialize_lcd() { - if (lcd_handle_) { + if (lcd_handle_ || backlight_) { logger_.warn("LCD already initialized, not initializing again!"); return false; } logger_.info("Initializing LCD..."); + // Initialize backlight PWM (moved out of Display, like esp-box) + backlight_channel_configs_.push_back({.gpio = static_cast(backlight_io), + .channel = LEDC_CHANNEL_0, + .timer = LEDC_TIMER_0, + .output_invert = !backlight_value}); + + backlight_ = std::make_shared((Led::Config{.timer = LEDC_TIMER_0, + .frequency_hz = 5000, + .channels = backlight_channel_configs_, + .duty_resolution = LEDC_TIMER_10_BIT})); + // default 100% + brightness(100.0f); + esp_err_t ret; memset(&lcd_spi_bus_config_, 0, sizeof(lcd_spi_bus_config_)); @@ -139,8 +152,9 @@ bool WsS3Lcd147::initialize_display(size_t pixel_buffer_size) { .flush_callback = DisplayDriver::flush, .rotation_callback = DisplayDriver::rotate, .rotation = rotation}, - Display::LcdConfig{.backlight_pin = backlight_io, - .backlight_on_value = backlight_value}, + Display::OledConfig{ + .set_brightness_callback = [this](float brightness) { this->brightness(brightness); }, + .get_brightness_callback = [this]() { return this->brightness(); }}, Display::DynamicMemoryConfig{ .pixel_buffer_size = pixel_buffer_size, .double_buffered = true, @@ -304,14 +318,18 @@ uint8_t *WsS3Lcd147::frame_buffer0() const { return frame_buffer0_; } uint8_t *WsS3Lcd147::frame_buffer1() const { return frame_buffer1_; } void WsS3Lcd147::brightness(float brightness) { - brightness = std::clamp(brightness, 0.0f, 100.0f) / 100.0f; - // display expects a value between 0 and 1 - display_->set_brightness(brightness); + brightness = std::clamp(brightness, 0.0f, 100.0f); + if (backlight_) + backlight_->set_duty(backlight_channel_configs_[0].channel, brightness); } float WsS3Lcd147::brightness() const { - // display returns a value between 0 and 1 - return display_->get_brightness() * 100.0f; + if (backlight_) { + auto d = backlight_->get_duty(backlight_channel_configs_[0].channel); + if (d.has_value()) + return d.value(); + } + return 0.0f; } /////////////////////////////////////////////////////////////////////////////