From 6d695eed32292fc390792139f88a0ce24e200574 Mon Sep 17 00:00:00 2001 From: William Emfinger Date: Fri, 5 Jun 2026 11:22:47 -0500 Subject: [PATCH 1/4] fix: Allow callers to request access to the underlying display controller, and add back write_lcd_lines APIs to the components --- components/byte90/include/byte90.hpp | 15 +++++++- components/byte90/src/display.cpp | 31 +++++++++++++++- components/esp-box/include/esp-box.hpp | 15 +++++++- components/esp-box/src/video.cpp | 33 ++++++++++++++++- .../m5stack-tab5/include/m5stack-tab5.hpp | 18 +++++++++- components/m5stack-tab5/src/video.cpp | 18 ++++++++-- .../include/matouch-rotary-display.hpp | 15 +++++++- .../src/matouch-rotary-display.cpp | 35 ++++++++++++++++++- .../include/seeed-studio-round-display.hpp | 15 +++++++- .../src/seeed-studio-round-display.cpp | 35 ++++++++++++++++++- .../include/smartpanlee-sc01-plus.hpp | 14 ++++++-- .../src/smartpanlee-sc01-plus.cpp | 2 +- components/t-deck/include/t-deck.hpp | 6 +++- components/t-deck/src/t-deck.cpp | 2 +- .../t-dongle-s3/include/t-dongle-s3.hpp | 20 +++++++++-- components/t-dongle-s3/src/t-dongle-s3.cpp | 33 ++++++++++++++++- components/wrover-kit/include/wrover-kit.hpp | 19 ++++++++-- components/wrover-kit/src/wrover-kit.cpp | 35 ++++++++++++++++++- components/ws-s3-geek/include/ws-s3-geek.hpp | 19 ++++++++-- components/ws-s3-geek/src/ws-s3-geek.cpp | 35 ++++++++++++++++++- .../ws-s3-lcd-1-47/include/ws-s3-lcd-1-47.hpp | 19 ++++++++-- .../ws-s3-lcd-1-47/src/ws-s3-lcd-1-47.cpp | 35 ++++++++++++++++++- .../ws-s3-touch/include/ws-s3-touch.hpp | 15 +++++++- components/ws-s3-touch/src/video.cpp | 33 ++++++++++++++++- 24 files changed, 486 insertions(+), 31 deletions(-) diff --git a/components/byte90/include/byte90.hpp b/components/byte90/include/byte90.hpp index 3587f556a..1449d534b 100644 --- a/components/byte90/include/byte90.hpp +++ b/components/byte90/include/byte90.hpp @@ -170,6 +170,10 @@ class Byte90 : public BaseComponent { /// \return A shared pointer to the display std::shared_ptr> display() const; + /// Get a shared pointer to the low-level display driver + /// \return A shared pointer to the display driver + const std::shared_ptr &display_driver() const { return display_driver_; } + /// Set the brightness of the backlight /// \param brightness The brightness of the backlight as a percentage (0 - 100) void brightness(float brightness); @@ -215,6 +219,15 @@ class Byte90 : public BaseComponent { void write_lcd_frame(const uint16_t x, const uint16_t y, const uint16_t width, const uint16_t height, uint8_t *data); + /// Write lines to the LCD + /// \param xs The x start coordinate + /// \param ys The y start coordinate + /// \param xe The x end coordinate + /// \param ye The y end coordinate + /// \param data The data to write + /// \param user_data User data to pass to the SPI transaction callback + void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); + protected: Byte90(); @@ -330,7 +343,7 @@ class Byte90 : public BaseComponent { // display std::shared_ptr> display_; - std::unique_ptr display_driver_; + std::shared_ptr display_driver_{static_cast(nullptr)}; static constexpr int spi_queue_size = 6; std::unique_ptr lcd_spi_; std::unique_ptr lcd_; diff --git a/components/byte90/src/display.cpp b/components/byte90/src/display.cpp index 54d256d12..6642be748 100644 --- a/components/byte90/src/display.cpp +++ b/components/byte90/src/display.cpp @@ -1,5 +1,7 @@ #include "byte90.hpp" +#include + using namespace espp; //////////////////////// @@ -56,7 +58,7 @@ bool Byte90::initialize_lcd() { return false; } - display_driver_ = std::make_unique( + display_driver_ = std::make_shared( espp::display_drivers::Config{.panel_io = lcd_.get(), .write_command = nullptr, .read_command = nullptr, @@ -153,6 +155,33 @@ void Byte90::write_lcd_frame(const uint16_t xs, const uint16_t ys, const uint16_ } } +void Byte90::write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, + uint32_t user_data) { + if (!lcd_) { + return; + } + size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; + if (length == 0) { + logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + lcd_->wait(); + std::array window = { + static_cast(xs & 0xff), + static_cast(xe & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::caset)); + lcd_->queue_data(window); + window = { + static_cast(ys & 0xff), + static_cast(ye & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::raset)); + lcd_->queue_data(window); + lcd_->queue_command(static_cast(DisplayDriver::Command::ramwr)); + lcd_->queue_pixels(data, length, user_data); +} + Byte90::Pixel *Byte90::vram0() const { if (!display_) { return nullptr; diff --git a/components/esp-box/include/esp-box.hpp b/components/esp-box/include/esp-box.hpp index bacdf9774..79181292d 100644 --- a/components/esp-box/include/esp-box.hpp +++ b/components/esp-box/include/esp-box.hpp @@ -187,6 +187,10 @@ class EspBox : public BaseComponent { /// \return A shared pointer to the display std::shared_ptr> display() const { return display_; } + /// Get a shared pointer to the low-level display driver + /// \return A shared pointer to the display driver + const std::shared_ptr &display_driver() const { return display_driver_; } + /// 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 @@ -234,6 +238,15 @@ class EspBox : public BaseComponent { void write_lcd_frame(const uint16_t x, const uint16_t y, const uint16_t width, const uint16_t height, uint8_t *data); + /// Write lines to the LCD + /// \param xs The x start coordinate + /// \param ys The y start coordinate + /// \param xe The x end coordinate + /// \param ye The y end coordinate + /// \param data The data to write + /// \param user_data User data to pass to the SPI transaction callback + void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); + ///////////////////////////////////////////////////////////////////////////// // Button ///////////////////////////////////////////////////////////////////////////// @@ -502,7 +515,7 @@ class EspBox : public BaseComponent { std::vector backlight_channel_configs_; std::shared_ptr backlight_; std::shared_ptr> display_; - std::unique_ptr display_driver_; + std::shared_ptr display_driver_{static_cast(nullptr)}; std::unique_ptr lcd_spi_; std::unique_ptr lcd_; uint8_t *frame_buffer0_{nullptr}; diff --git a/components/esp-box/src/video.cpp b/components/esp-box/src/video.cpp index 4a2a3ece2..d30fcc23b 100644 --- a/components/esp-box/src/video.cpp +++ b/components/esp-box/src/video.cpp @@ -65,7 +65,7 @@ bool EspBox::initialize_lcd() { lcd_spi_.reset(); return false; } - display_driver_ = std::make_unique( + display_driver_ = std::make_shared( espp::display_drivers::Config{.panel_io = lcd_.get(), .write_command = nullptr, .read_command = nullptr, @@ -167,6 +167,37 @@ void EspBox::write_lcd_frame(const uint16_t xs, const uint16_t ys, const uint16_ } } +void EspBox::write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, + uint32_t user_data) { + if (!lcd_) { + return; + } + size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; + if (length == 0) { + logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + lcd_->wait(); + std::array window = { + static_cast((xs >> 8) & 0xff), + static_cast(xs & 0xff), + static_cast((xe >> 8) & 0xff), + static_cast(xe & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::caset)); + lcd_->queue_data(window); + window = { + static_cast((ys >> 8) & 0xff), + static_cast(ys & 0xff), + static_cast((ye >> 8) & 0xff), + static_cast(ye & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::raset)); + lcd_->queue_data(window); + lcd_->queue_command(static_cast(DisplayDriver::Command::ramwr)); + lcd_->queue_pixels(data, length, user_data); +} + EspBox::Pixel *EspBox::vram0() const { if (!display_) { return nullptr; diff --git a/components/m5stack-tab5/include/m5stack-tab5.hpp b/components/m5stack-tab5/include/m5stack-tab5.hpp index 0102d3c5f..68eb1812e 100644 --- a/components/m5stack-tab5/include/m5stack-tab5.hpp +++ b/components/m5stack-tab5/include/m5stack-tab5.hpp @@ -76,6 +76,9 @@ class M5StackTab5 : public BaseComponent { /// Alias for the pixel type used by the Tab5 display using Pixel = lv_color16_t; + /// Alias for the low-level display driver interface + using DisplayDriver = espp::display_drivers::Controller; + /// Enum for display controller type enum class DisplayController { UNKNOWN, ILI9881, ST7123 }; @@ -240,6 +243,19 @@ class M5StackTab5 : public BaseComponent { /// \return The display height in pixels, according to the current orientation size_t rotated_display_height() const; + /// Get a shared pointer to the low-level display driver + /// \return A shared pointer to the display driver + const std::shared_ptr &display_driver() const { return display_driver_; } + + /// Write lines to the LCD + /// \param xs The x start coordinate + /// \param ys The y start coordinate + /// \param xe The x end coordinate + /// \param ye The y end coordinate + /// \param data The data to write + /// \param user_data User data to pass to the lower-level transport + void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); + ///////////////////////////////////////////////////////////////////////////// // Audio System ///////////////////////////////////////////////////////////////////////////// @@ -736,7 +752,7 @@ class M5StackTab5 : public BaseComponent { // Display state std::shared_ptr> display_; - std::unique_ptr display_driver_; + std::shared_ptr display_driver_{static_cast(nullptr)}; std::shared_ptr backlight_; std::vector backlight_channel_configs_; struct LcdHandles { diff --git a/components/m5stack-tab5/src/video.cpp b/components/m5stack-tab5/src/video.cpp index 47393be5b..322c3b257 100644 --- a/components/m5stack-tab5/src/video.cpp +++ b/components/m5stack-tab5/src/video.cpp @@ -221,7 +221,7 @@ bool M5StackTab5::initialize_lcd() { display_driver_.reset(); if (detected_controller == DisplayController::ILI9881) { logger_.info("Initializing as ILI9881"); - auto display_driver = std::make_unique(display_config); + auto display_driver = std::make_shared(display_config); if (display_driver->initialize()) { logger_.info("Successfully initialized ILI9881 display controller"); display_driver_ = std::move(display_driver); @@ -229,7 +229,7 @@ bool M5StackTab5::initialize_lcd() { } } else if (detected_controller == DisplayController::ST7123) { logger_.info("Initializing as ST7123"); - auto display_driver = std::make_unique(display_config); + auto display_driver = std::make_shared(display_config); if (display_driver->initialize()) { logger_.info("Successfully initialized ST7123 display controller"); display_driver_ = std::move(display_driver); @@ -333,6 +333,20 @@ size_t M5StackTab5::rotated_display_height() const { } } +void M5StackTab5::write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, + uint32_t user_data) { + (void)user_data; + if (lcd_handles_.panel == nullptr || data == nullptr) { + return; + } + if (xe < xs || ye < ys) { + logger_.error("write_lcd_lines: Bad region: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + esp_lcd_panel_draw_bitmap(lcd_handles_.panel, xs, ys, xe + 1, ye + 1, + const_cast(data)); +} + void M5StackTab5::brightness(float brightness) { brightness = std::clamp(brightness, 0.0f, 100.0f); if (backlight_) { diff --git a/components/matouch-rotary-display/include/matouch-rotary-display.hpp b/components/matouch-rotary-display/include/matouch-rotary-display.hpp index f560d2562..c4d870866 100644 --- a/components/matouch-rotary-display/include/matouch-rotary-display.hpp +++ b/components/matouch-rotary-display/include/matouch-rotary-display.hpp @@ -189,6 +189,10 @@ class MatouchRotaryDisplay : public BaseComponent { /// \return A shared pointer to the display std::shared_ptr> display() const; + /// Get a shared pointer to the low-level display driver + /// \return A shared pointer to the display driver + const std::shared_ptr &display_driver() const { return display_driver_; } + /// 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 @@ -236,6 +240,15 @@ class MatouchRotaryDisplay : public BaseComponent { void write_lcd_frame(const uint16_t x, const uint16_t y, const uint16_t width, const uint16_t height, uint8_t *data); + /// Write lines to the LCD + /// \param xs The x start coordinate + /// \param ys The y start coordinate + /// \param xe The x end coordinate + /// \param ye The y end coordinate + /// \param data The data to write + /// \param user_data User data to pass to the SPI transaction callback + void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); + protected: MatouchRotaryDisplay(); bool update_cst816(); @@ -339,7 +352,7 @@ class MatouchRotaryDisplay : public BaseComponent { std::shared_ptr> display_; std::vector backlight_channel_configs_{}; std::shared_ptr backlight_{}; - std::unique_ptr display_driver_; + std::shared_ptr display_driver_{static_cast(nullptr)}; std::unique_ptr lcd_spi_; std::unique_ptr lcd_; uint8_t *frame_buffer0_{nullptr}; diff --git a/components/matouch-rotary-display/src/matouch-rotary-display.cpp b/components/matouch-rotary-display/src/matouch-rotary-display.cpp index 648bcdcb8..f3400a1a1 100644 --- a/components/matouch-rotary-display/src/matouch-rotary-display.cpp +++ b/components/matouch-rotary-display/src/matouch-rotary-display.cpp @@ -1,5 +1,7 @@ #include "matouch-rotary-display.hpp" +#include + using namespace espp; MatouchRotaryDisplay::MatouchRotaryDisplay() @@ -247,7 +249,7 @@ bool MatouchRotaryDisplay::initialize_lcd() { lcd_spi_.reset(); return false; } - display_driver_ = std::make_unique( + display_driver_ = std::make_shared( espp::display_drivers::Config{.panel_io = lcd_.get(), .write_command = nullptr, .read_command = nullptr, @@ -363,6 +365,37 @@ void MatouchRotaryDisplay::write_lcd_frame(const uint16_t xs, const uint16_t ys, } } +void MatouchRotaryDisplay::write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, + uint32_t user_data) { + if (!lcd_) { + return; + } + size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; + if (length == 0) { + logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + lcd_->wait(); + std::array window = { + static_cast((xs >> 8) & 0xff), + static_cast(xs & 0xff), + static_cast((xe >> 8) & 0xff), + static_cast(xe & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::caset)); + lcd_->queue_data(window); + window = { + static_cast((ys >> 8) & 0xff), + static_cast(ys & 0xff), + static_cast((ye >> 8) & 0xff), + static_cast(ye & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::raset)); + lcd_->queue_data(window); + lcd_->queue_command(static_cast(DisplayDriver::Command::ramwr)); + lcd_->queue_pixels(data, length, user_data); +} + MatouchRotaryDisplay::Pixel *MatouchRotaryDisplay::vram0() const { if (!display_) { return nullptr; diff --git a/components/seeed-studio-round-display/include/seeed-studio-round-display.hpp b/components/seeed-studio-round-display/include/seeed-studio-round-display.hpp index 3f9509de4..c07220f16 100644 --- a/components/seeed-studio-round-display/include/seeed-studio-round-display.hpp +++ b/components/seeed-studio-round-display/include/seeed-studio-round-display.hpp @@ -198,6 +198,10 @@ class SsRoundDisplay : public espp::BaseComponent { /// \return A shared pointer to the display std::shared_ptr> display() const; + /// Get a shared pointer to the low-level display driver + /// \return A shared pointer to the display driver + const std::shared_ptr &display_driver() const { return display_driver_; } + /// 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 @@ -245,6 +249,15 @@ class SsRoundDisplay : public espp::BaseComponent { void write_lcd_frame(const uint16_t x, const uint16_t y, const uint16_t width, const uint16_t height, uint8_t *data); + /// Write lines to the LCD + /// \param xs The x start coordinate + /// \param ys The y start coordinate + /// \param xe The x end coordinate + /// \param ye The y end coordinate + /// \param data The data to write + /// \param user_data User data to pass to the SPI transaction callback + void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); + protected: SsRoundDisplay(); void touch_interrupt_handler(const espp::Interrupt::Event &event); @@ -303,7 +316,7 @@ class SsRoundDisplay : public espp::BaseComponent { std::shared_ptr> display_; std::vector backlight_channel_configs_{}; std::shared_ptr backlight_{}; - std::unique_ptr display_driver_; + std::shared_ptr display_driver_{static_cast(nullptr)}; std::unique_ptr lcd_spi_; std::unique_ptr lcd_; uint8_t *frame_buffer0_{nullptr}; diff --git a/components/seeed-studio-round-display/src/seeed-studio-round-display.cpp b/components/seeed-studio-round-display/src/seeed-studio-round-display.cpp index 848b1556d..0d327e64f 100644 --- a/components/seeed-studio-round-display/src/seeed-studio-round-display.cpp +++ b/components/seeed-studio-round-display/src/seeed-studio-round-display.cpp @@ -1,5 +1,7 @@ #include "seeed-studio-round-display.hpp" +#include + using namespace espp; SsRoundDisplay::PinConfig SsRoundDisplay::pin_config_; @@ -206,7 +208,7 @@ bool SsRoundDisplay::initialize_lcd() { lcd_spi_.reset(); return false; } - display_driver_ = std::make_unique( + display_driver_ = std::make_shared( espp::display_drivers::Config{.panel_io = lcd_.get(), .write_command = nullptr, .read_command = nullptr, @@ -322,6 +324,37 @@ void SsRoundDisplay::write_lcd_frame(const uint16_t xs, const uint16_t ys, const } } +void SsRoundDisplay::write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, + uint32_t user_data) { + if (!lcd_) { + return; + } + size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; + if (length == 0) { + logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + lcd_->wait(); + std::array window = { + static_cast((xs >> 8) & 0xff), + static_cast(xs & 0xff), + static_cast((xe >> 8) & 0xff), + static_cast(xe & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::caset)); + lcd_->queue_data(window); + window = { + static_cast((ys >> 8) & 0xff), + static_cast(ys & 0xff), + static_cast((ye >> 8) & 0xff), + static_cast(ye & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::raset)); + lcd_->queue_data(window); + lcd_->queue_command(static_cast(DisplayDriver::Command::ramwr)); + lcd_->queue_pixels(data, length, user_data); +} + SsRoundDisplay::Pixel *SsRoundDisplay::vram0() const { if (!display_) { return nullptr; diff --git a/components/smartpanlee-sc01-plus/include/smartpanlee-sc01-plus.hpp b/components/smartpanlee-sc01-plus/include/smartpanlee-sc01-plus.hpp index ab165edc4..7a87730b5 100755 --- a/components/smartpanlee-sc01-plus/include/smartpanlee-sc01-plus.hpp +++ b/components/smartpanlee-sc01-plus/include/smartpanlee-sc01-plus.hpp @@ -176,6 +176,9 @@ class SmartPanleeSc01Plus : public BaseComponent { /// Get the high-level LVGL display wrapper. /// \return Shared pointer to the display wrapper, or nullptr if not initialized. std::shared_ptr> display() const { return display_; } + /// Get a shared pointer to the low-level display driver. + /// \return Shared pointer to the display driver, or a typed-null handle if not initialized. + const std::shared_ptr &display_driver() const { return display_driver_; } /// Set the display backlight brightness. /// \param brightness Brightness percentage in the range [0, 100]. void brightness(float brightness); @@ -198,6 +201,14 @@ class SmartPanleeSc01Plus : public BaseComponent { /// Get the current display height after applying LVGL rotation. /// \return Rotated height in pixels. size_t rotated_display_height() const; + /// Write lines to the LCD using the legacy scanline-oriented transport signature. + /// \param xs Inclusive start X coordinate. + /// \param ys Inclusive start Y coordinate. + /// \param xe Inclusive end X coordinate. + /// \param ye Inclusive end Y coordinate. + /// \param data Pointer to pixel payload data. + /// \param user_data Opaque user data passed by the caller. + void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); /// Initialize the speaker audio path using the board's published I2S pins. /// \return True if audio playback support was initialized, false otherwise. @@ -266,7 +277,6 @@ class SmartPanleeSc01Plus : public BaseComponent { bool audio_task_callback(std::mutex &m, std::condition_variable &cv, bool &task_notified); bool update_touch(); void write_command(uint8_t command, std::span parameters, uint32_t user_data); - void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); static constexpr auto internal_i2c_port = I2C_NUM_1; static constexpr auto internal_i2c_clock_speed = 400 * 1000; @@ -346,7 +356,7 @@ class SmartPanleeSc01Plus : public BaseComponent { touch_callback_t touch_callback_{nullptr}; std::shared_ptr> display_; - std::unique_ptr display_driver_; + std::shared_ptr display_driver_{static_cast(nullptr)}; std::shared_ptr backlight_; std::vector backlight_channel_configs_; esp_lcd_i80_bus_handle_t lcd_bus_{nullptr}; diff --git a/components/smartpanlee-sc01-plus/src/smartpanlee-sc01-plus.cpp b/components/smartpanlee-sc01-plus/src/smartpanlee-sc01-plus.cpp index 2ae268e42..0837fcd99 100644 --- a/components/smartpanlee-sc01-plus/src/smartpanlee-sc01-plus.cpp +++ b/components/smartpanlee-sc01-plus/src/smartpanlee-sc01-plus.cpp @@ -221,7 +221,7 @@ bool SmartPanleeSc01Plus::initialize_lcd() { ESP_ERROR_CHECK(esp_lcd_new_panel_io_i80(lcd_bus_, &io_config, &panel_io_)); using namespace std::placeholders; - display_driver_ = std::make_unique(espp::display_drivers::Config{ + display_driver_ = std::make_shared(espp::display_drivers::Config{ .write_command = std::bind(&SmartPanleeSc01Plus::write_command, this, _1, _2, _3), .lcd_send_lines = std::bind(&SmartPanleeSc01Plus::write_lcd_lines, this, _1, _2, _3, _4, _5, _6), diff --git a/components/t-deck/include/t-deck.hpp b/components/t-deck/include/t-deck.hpp index a8dc3f6a9..e74607994 100644 --- a/components/t-deck/include/t-deck.hpp +++ b/components/t-deck/include/t-deck.hpp @@ -338,6 +338,10 @@ class TDeck : public BaseComponent { /// \return A shared pointer to the display std::shared_ptr> display() const; + /// Get a shared pointer to the low-level display driver + /// \return A shared pointer to the display driver + const std::shared_ptr &display_driver() const { return display_driver_; } + /// 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 @@ -646,7 +650,7 @@ class TDeck : public BaseComponent { // display std::shared_ptr> display_; - std::unique_ptr display_driver_; + std::shared_ptr display_driver_{static_cast(nullptr)}; std::vector backlight_channel_configs_{}; std::shared_ptr backlight_{}; static constexpr int spi_queue_size = 6; diff --git a/components/t-deck/src/t-deck.cpp b/components/t-deck/src/t-deck.cpp index 66de0c60f..a769de37f 100644 --- a/components/t-deck/src/t-deck.cpp +++ b/components/t-deck/src/t-deck.cpp @@ -316,7 +316,7 @@ bool TDeck::initialize_lcd() { return false; } - display_driver_ = std::make_unique( + display_driver_ = std::make_shared( espp::display_drivers::Config{.panel_io = lcd_.get(), .write_command = nullptr, .read_command = nullptr, diff --git a/components/t-dongle-s3/include/t-dongle-s3.hpp b/components/t-dongle-s3/include/t-dongle-s3.hpp index 3f0e59fa0..33f4357c8 100644 --- a/components/t-dongle-s3/include/t-dongle-s3.hpp +++ b/components/t-dongle-s3/include/t-dongle-s3.hpp @@ -44,6 +44,9 @@ class TDongleS3 : public BaseComponent { /// Alias for the pixel type used by the T-Dongle-S3 display using Pixel = lv_color16_t; + /// Alias for the display driver + using DisplayDriver = espp::St7789; + /// Maximum number of bytes that can be transferred in a single SPI /// transaction to the Display. 32k on the ESP32-S3. static constexpr size_t SPI_MAX_TRANSFER_BYTES = SPI_LL_DMA_MAX_BIT_LEN / 8; @@ -146,6 +149,10 @@ class TDongleS3 : public BaseComponent { /// \return A shared pointer to the display std::shared_ptr> display() const; + /// Get a shared pointer to the low-level display driver + /// \return A shared pointer to the display driver + const std::shared_ptr &display_driver() const { return display_driver_; } + /// 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 @@ -193,6 +200,15 @@ class TDongleS3 : public BaseComponent { void write_lcd_frame(const uint16_t x, const uint16_t y, const uint16_t width, const uint16_t height, uint8_t *data); + /// Write lines to the LCD + /// \param xs The x start coordinate + /// \param ys The y start coordinate + /// \param xe The x end coordinate + /// \param ye The y end coordinate + /// \param data The data to write + /// \param user_data User data to pass to the SPI transaction callback + void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); + ///////////////////////////////////////////////////////////////////////////// // uSD Card ///////////////////////////////////////////////////////////////////////////// @@ -251,8 +267,6 @@ class TDongleS3 : public BaseComponent { static constexpr bool mirror_x = false; static constexpr bool mirror_y = false; static constexpr gpio_num_t backlight_io = GPIO_NUM_38; - using DisplayDriver = espp::St7789; - // button (boot button) static constexpr gpio_num_t button_io = GPIO_NUM_0; // active low @@ -298,7 +312,7 @@ class TDongleS3 : public BaseComponent { // display std::shared_ptr> display_; - std::unique_ptr display_driver_; + std::shared_ptr display_driver_{static_cast(nullptr)}; std::vector backlight_channel_configs_{}; std::shared_ptr backlight_{}; static constexpr int spi_queue_size = 6; diff --git a/components/t-dongle-s3/src/t-dongle-s3.cpp b/components/t-dongle-s3/src/t-dongle-s3.cpp index 0920eeac8..cc9f8d188 100644 --- a/components/t-dongle-s3/src/t-dongle-s3.cpp +++ b/components/t-dongle-s3/src/t-dongle-s3.cpp @@ -172,7 +172,7 @@ bool TDongleS3::initialize_lcd() { lcd_spi_.reset(); return false; } - display_driver_ = std::make_unique( + display_driver_ = std::make_shared( espp::display_drivers::Config{.panel_io = lcd_.get(), .write_command = nullptr, .read_command = nullptr, @@ -269,6 +269,37 @@ void TDongleS3::write_lcd_frame(const uint16_t xs, const uint16_t ys, const uint } } +void IRAM_ATTR TDongleS3::write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, + uint32_t user_data) { + if (!lcd_) { + return; + } + size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; + if (length == 0) { + logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + lcd_->wait(); + std::array window = { + static_cast((xs >> 8) & 0xff), + static_cast(xs & 0xff), + static_cast((xe >> 8) & 0xff), + static_cast(xe & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::caset)); + lcd_->queue_data(window); + window = { + static_cast((ys >> 8) & 0xff), + static_cast(ys & 0xff), + static_cast((ye >> 8) & 0xff), + static_cast(ye & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::raset)); + lcd_->queue_data(window); + lcd_->queue_command(static_cast(DisplayDriver::Command::ramwr)); + lcd_->queue_pixels(data, length, user_data); +} + TDongleS3::Pixel *TDongleS3::vram0() const { if (!display_) { return nullptr; diff --git a/components/wrover-kit/include/wrover-kit.hpp b/components/wrover-kit/include/wrover-kit.hpp index 983da77e5..b43d3d4f6 100644 --- a/components/wrover-kit/include/wrover-kit.hpp +++ b/components/wrover-kit/include/wrover-kit.hpp @@ -30,6 +30,9 @@ class WroverKit : public BaseComponent { /// Alias for the pixel type used by the wrover-kit display using Pixel = lv_color16_t; + /// Alias for the display driver + using DisplayDriver = espp::Ili9341; + /// Maximum number of bytes that can be transferred in a single SPI /// transaction to the Display. 2MB on ESP32. static constexpr size_t SPI_MAX_TRANSFER_BYTES = SPI_LL_DMA_MAX_BIT_LEN / 8; @@ -97,6 +100,10 @@ class WroverKit : public BaseComponent { /// \return A shared pointer to the display std::shared_ptr> display() const; + /// Get a shared pointer to the low-level display driver + /// \return A shared pointer to the display driver + const std::shared_ptr &display_driver() const { return display_driver_; } + /// 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 @@ -144,6 +151,15 @@ class WroverKit : public BaseComponent { void write_lcd_frame(const uint16_t x, const uint16_t y, const uint16_t width, const uint16_t height, uint8_t *data); + /// Write lines to the LCD + /// \param xs The x start coordinate + /// \param ys The y start coordinate + /// \param xe The x end coordinate + /// \param ye The y end coordinate + /// \param data The data to write + /// \param user_data User data to pass to the SPI transaction callback + void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); + protected: WroverKit(); void lcd_wait_lines(); @@ -169,13 +185,12 @@ class WroverKit : public BaseComponent { static constexpr bool mirror_x = false; static constexpr bool mirror_y = false; static constexpr bool swap_xy = true; - using DisplayDriver = espp::Ili9341; // display std::shared_ptr> display_; std::vector backlight_channel_configs_{}; std::shared_ptr backlight_{}; - std::unique_ptr display_driver_; + std::shared_ptr display_driver_{static_cast(nullptr)}; std::unique_ptr lcd_spi_; std::unique_ptr lcd_; uint8_t *frame_buffer0_{nullptr}; diff --git a/components/wrover-kit/src/wrover-kit.cpp b/components/wrover-kit/src/wrover-kit.cpp index 4e76172b7..f5d6ba794 100644 --- a/components/wrover-kit/src/wrover-kit.cpp +++ b/components/wrover-kit/src/wrover-kit.cpp @@ -1,5 +1,7 @@ #include "wrover-kit.hpp" +#include + using namespace espp; WroverKit::WroverKit() @@ -68,7 +70,7 @@ bool WroverKit::initialize_lcd() { return false; } display_driver_ = - std::make_unique(espp::display_drivers::Config{.panel_io = lcd_.get(), + std::make_shared(espp::display_drivers::Config{.panel_io = lcd_.get(), .write_command = nullptr, .read_command = nullptr, .lcd_send_lines = nullptr, @@ -161,6 +163,37 @@ void WroverKit::write_lcd_frame(const uint16_t xs, const uint16_t ys, const uint } } +void WroverKit::write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, + uint32_t user_data) { + if (!lcd_) { + return; + } + size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; + if (length == 0) { + logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + lcd_->wait(); + std::array window = { + static_cast((xs >> 8) & 0xff), + static_cast(xs & 0xff), + static_cast((xe >> 8) & 0xff), + static_cast(xe & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::caset)); + lcd_->queue_data(window); + window = { + static_cast((ys >> 8) & 0xff), + static_cast(ys & 0xff), + static_cast((ye >> 8) & 0xff), + static_cast(ye & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::raset)); + lcd_->queue_data(window); + lcd_->queue_command(static_cast(DisplayDriver::Command::ramwr)); + lcd_->queue_pixels(data, length, user_data); +} + WroverKit::Pixel *WroverKit::vram0() const { if (!display_) { return nullptr; diff --git a/components/ws-s3-geek/include/ws-s3-geek.hpp b/components/ws-s3-geek/include/ws-s3-geek.hpp index 81183d074..8609f4d02 100644 --- a/components/ws-s3-geek/include/ws-s3-geek.hpp +++ b/components/ws-s3-geek/include/ws-s3-geek.hpp @@ -42,6 +42,9 @@ class WsS3Geek : public BaseComponent { /// Alias for the pixel type used by the display using Pixel = lv_color16_t; + /// Alias for the display driver + using DisplayDriver = espp::St7789; + /// Maximum number of bytes that can be transferred in a single SPI /// transaction to the Display. 32k on the ESP32-S3. static constexpr size_t SPI_MAX_TRANSFER_BYTES = SPI_LL_DMA_MAX_BIT_LEN / 8; @@ -116,6 +119,10 @@ class WsS3Geek : public BaseComponent { /// \return A shared pointer to the display std::shared_ptr> display() const; + /// Get a shared pointer to the low-level display driver + /// \return A shared pointer to the display driver + const std::shared_ptr &display_driver() const { return display_driver_; } + /// 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 @@ -149,6 +156,15 @@ class WsS3Geek : public BaseComponent { void write_lcd_frame(const uint16_t x, const uint16_t y, const uint16_t width, const uint16_t height, uint8_t *data); + /// Write lines to the LCD + /// \param xs The x start coordinate + /// \param ys The y start coordinate + /// \param xe The x end coordinate + /// \param ye The y end coordinate + /// \param data The data to write + /// \param user_data User data to pass to the SPI transaction callback + void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); + ///////////////////////////////////////////////////////////////////////////// // uSD Card ///////////////////////////////////////////////////////////////////////////// @@ -198,7 +214,6 @@ class WsS3Geek : public BaseComponent { static constexpr bool mirror_x = false; static constexpr bool mirror_y = false; static constexpr gpio_num_t backlight_io = GPIO_NUM_7; - using DisplayDriver = espp::St7789; // button (boot button) static constexpr gpio_num_t button_io = GPIO_NUM_0; // active low @@ -244,7 +259,7 @@ class WsS3Geek : public BaseComponent { // display std::shared_ptr> display_; - std::unique_ptr display_driver_; + std::shared_ptr display_driver_{static_cast(nullptr)}; std::vector backlight_channel_configs_{}; std::shared_ptr backlight_{}; static constexpr int spi_queue_size = 6; diff --git a/components/ws-s3-geek/src/ws-s3-geek.cpp b/components/ws-s3-geek/src/ws-s3-geek.cpp index 903576720..8c29362e0 100644 --- a/components/ws-s3-geek/src/ws-s3-geek.cpp +++ b/components/ws-s3-geek/src/ws-s3-geek.cpp @@ -1,5 +1,7 @@ #include "ws-s3-geek.hpp" +#include + using namespace espp; WsS3Geek::WsS3Geek() @@ -98,7 +100,7 @@ bool WsS3Geek::initialize_lcd() { lcd_spi_.reset(); return false; } - display_driver_ = std::make_unique( + display_driver_ = std::make_shared( espp::display_drivers::Config{.panel_io = lcd_.get(), .write_command = nullptr, .read_command = nullptr, @@ -190,6 +192,37 @@ void WsS3Geek::write_lcd_frame(const uint16_t xs, const uint16_t ys, const uint1 } } +void IRAM_ATTR WsS3Geek::write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, + uint32_t user_data) { + if (!lcd_) { + return; + } + size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; + if (length == 0) { + logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + lcd_->wait(); + std::array window = { + static_cast((xs >> 8) & 0xff), + static_cast(xs & 0xff), + static_cast((xe >> 8) & 0xff), + static_cast(xe & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::caset)); + lcd_->queue_data(window); + window = { + static_cast((ys >> 8) & 0xff), + static_cast(ys & 0xff), + static_cast((ye >> 8) & 0xff), + static_cast(ye & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::raset)); + lcd_->queue_data(window); + lcd_->queue_command(static_cast(DisplayDriver::Command::ramwr)); + lcd_->queue_pixels(data, length, user_data); +} + WsS3Geek::Pixel *WsS3Geek::vram0() const { if (!display_) { return nullptr; 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 924a17a0d..784546790 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 @@ -44,6 +44,9 @@ class WsS3Lcd147 : public BaseComponent { /// Alias for the pixel type used by the display using Pixel = lv_color16_t; + /// Alias for the display driver + using DisplayDriver = espp::St7789; + /// Maximum number of bytes that can be transferred in a single SPI /// transaction to the Display. 32k on the ESP32-S3. static constexpr size_t SPI_MAX_TRANSFER_BYTES = SPI_LL_DMA_MAX_BIT_LEN / 8; @@ -118,6 +121,10 @@ class WsS3Lcd147 : public BaseComponent { /// \return A shared pointer to the display std::shared_ptr> display() const; + /// Get a shared pointer to the low-level display driver + /// \return A shared pointer to the display driver + const std::shared_ptr &display_driver() const { return display_driver_; } + /// 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 @@ -165,6 +172,15 @@ class WsS3Lcd147 : public BaseComponent { void write_lcd_frame(const uint16_t x, const uint16_t y, const uint16_t width, const uint16_t height, uint8_t *data); + /// Write lines to the LCD + /// \param xs The x start coordinate + /// \param ys The y start coordinate + /// \param xe The x end coordinate + /// \param ye The y end coordinate + /// \param data The data to write + /// \param user_data User data to pass to the SPI transaction callback + void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); + ///////////////////////////////////////////////////////////////////////////// // uSD Card ///////////////////////////////////////////////////////////////////////////// @@ -236,7 +252,6 @@ class WsS3Lcd147 : public BaseComponent { static constexpr bool mirror_x = false; static constexpr bool mirror_y = false; static constexpr gpio_num_t backlight_io = GPIO_NUM_48; - using DisplayDriver = espp::St7789; // button (boot button) static constexpr gpio_num_t button_io = GPIO_NUM_0; // active low @@ -281,7 +296,7 @@ class WsS3Lcd147 : public BaseComponent { // display std::shared_ptr> display_; - std::unique_ptr display_driver_; + std::shared_ptr display_driver_{static_cast(nullptr)}; std::vector backlight_channel_configs_{}; std::shared_ptr backlight_{}; static constexpr int spi_queue_size = 6; 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 7530cd39d..6ef156725 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 @@ -1,5 +1,7 @@ #include "ws-s3-lcd-1-47.hpp" +#include + using namespace espp; WsS3Lcd147::WsS3Lcd147() @@ -97,7 +99,7 @@ bool WsS3Lcd147::initialize_lcd() { lcd_spi_.reset(); return false; } - display_driver_ = std::make_unique( + display_driver_ = std::make_shared( espp::display_drivers::Config{.panel_io = lcd_.get(), .write_command = nullptr, .read_command = nullptr, @@ -194,6 +196,37 @@ void WsS3Lcd147::write_lcd_frame(const uint16_t xs, const uint16_t ys, const uin } } +void IRAM_ATTR WsS3Lcd147::write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, + uint32_t user_data) { + if (!lcd_) { + return; + } + size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; + if (length == 0) { + logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + lcd_->wait(); + std::array window = { + static_cast((xs >> 8) & 0xff), + static_cast(xs & 0xff), + static_cast((xe >> 8) & 0xff), + static_cast(xe & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::caset)); + lcd_->queue_data(window); + window = { + static_cast((ys >> 8) & 0xff), + static_cast(ys & 0xff), + static_cast((ye >> 8) & 0xff), + static_cast(ye & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::raset)); + lcd_->queue_data(window); + lcd_->queue_command(static_cast(DisplayDriver::Command::ramwr)); + lcd_->queue_pixels(data, length, user_data); +} + WsS3Lcd147::Pixel *WsS3Lcd147::vram0() const { if (!display_) { return nullptr; diff --git a/components/ws-s3-touch/include/ws-s3-touch.hpp b/components/ws-s3-touch/include/ws-s3-touch.hpp index bf7d1ae7e..bccf38eeb 100644 --- a/components/ws-s3-touch/include/ws-s3-touch.hpp +++ b/components/ws-s3-touch/include/ws-s3-touch.hpp @@ -176,6 +176,10 @@ class WsS3Touch : public BaseComponent { /// \return A shared pointer to the display std::shared_ptr> display() const { return display_; } + /// Get a shared pointer to the low-level display driver + /// \return A shared pointer to the display driver + const std::shared_ptr &display_driver() const { return display_driver_; } + /// 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 @@ -209,6 +213,15 @@ class WsS3Touch : public BaseComponent { void write_lcd_frame(const uint16_t x, const uint16_t y, const uint16_t width, const uint16_t height, uint8_t *data); + /// Write lines to the LCD + /// \param xs The x start coordinate + /// \param ys The y start coordinate + /// \param xe The x end coordinate + /// \param ye The y end coordinate + /// \param data The data to write + /// \param user_data User data to pass to the SPI transaction callback + void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); + ///////////////////////////////////////////////////////////////////////////// // Button ///////////////////////////////////////////////////////////////////////////// @@ -403,7 +416,7 @@ class WsS3Touch : public BaseComponent { std::shared_ptr> display_; std::vector backlight_channel_configs_{}; std::shared_ptr backlight_{}; - std::unique_ptr display_driver_; + std::shared_ptr display_driver_{static_cast(nullptr)}; std::unique_ptr lcd_spi_; std::unique_ptr lcd_; diff --git a/components/ws-s3-touch/src/video.cpp b/components/ws-s3-touch/src/video.cpp index 8e3f54cf7..827791fff 100644 --- a/components/ws-s3-touch/src/video.cpp +++ b/components/ws-s3-touch/src/video.cpp @@ -56,7 +56,7 @@ bool WsS3Touch::initialize_lcd() { return false; } logger_.info("Initializing the display driver..."); - display_driver_ = std::make_unique( + display_driver_ = std::make_shared( espp::display_drivers::Config{.panel_io = lcd_.get(), .write_command = nullptr, .read_command = nullptr, @@ -171,6 +171,37 @@ void WsS3Touch::write_lcd_frame(const uint16_t xs, const uint16_t ys, const uint } } +void WsS3Touch::write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, + uint32_t user_data) { + if (!lcd_) { + return; + } + size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; + if (length == 0) { + logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + lcd_->wait(); + std::array window = { + static_cast((xs >> 8) & 0xff), + static_cast(xs & 0xff), + static_cast((xe >> 8) & 0xff), + static_cast(xe & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::caset)); + lcd_->queue_data(window); + window = { + static_cast((ys >> 8) & 0xff), + static_cast(ys & 0xff), + static_cast((ye >> 8) & 0xff), + static_cast(ye & 0xff), + }; + lcd_->queue_command(static_cast(DisplayDriver::Command::raset)); + lcd_->queue_data(window); + lcd_->queue_command(static_cast(DisplayDriver::Command::ramwr)); + lcd_->queue_pixels(data, length, user_data); +} + WsS3Touch::Pixel *WsS3Touch::vram0() const { if (!display_) { return nullptr; From 05dcb3b204667bbd391fba521858e5b40b270e75 Mon Sep 17 00:00:00 2001 From: William Emfinger Date: Sat, 6 Jun 2026 15:40:24 -0500 Subject: [PATCH 2/4] address comments and ensure write_lcd_lines has appropriate checks --- components/byte90/src/display.cpp | 12 +++++++++--- components/esp-box/src/video.cpp | 12 +++++++++--- components/m5stack-tab5/src/video.cpp | 2 +- .../src/matouch-rotary-display.cpp | 12 +++++++++--- .../src/seeed-studio-round-display.cpp | 12 +++++++++--- .../src/smartpanlee-sc01-plus.cpp | 16 ++++++++++++++-- components/t-deck/src/t-deck.cpp | 12 +++++++++--- components/t-dongle-s3/src/t-dongle-s3.cpp | 12 +++++++++--- components/wrover-kit/src/wrover-kit.cpp | 12 +++++++++--- components/ws-s3-geek/src/ws-s3-geek.cpp | 12 +++++++++--- components/ws-s3-lcd-1-47/src/ws-s3-lcd-1-47.cpp | 12 +++++++++--- components/ws-s3-touch/src/video.cpp | 12 +++++++++--- 12 files changed, 105 insertions(+), 33 deletions(-) diff --git a/components/byte90/src/display.cpp b/components/byte90/src/display.cpp index 6642be748..dda6f3b9b 100644 --- a/components/byte90/src/display.cpp +++ b/components/byte90/src/display.cpp @@ -160,11 +160,17 @@ void Byte90::write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data if (!lcd_) { return; } - size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; - if (length == 0) { - logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + if (data == nullptr) { + logger_.error("lcd_send_lines: Null data for ({},{}) to ({},{})", xs, ys, xe, ye); return; } + if (xs < 0 || ys < 0 || xe < xs || ye < ys) { + logger_.error("lcd_send_lines: Bad region: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + size_t width = static_cast(xe - xs + 1); + size_t height = static_cast(ye - ys + 1); + size_t length = width * height * lcd_bytes_per_pixel; lcd_->wait(); std::array window = { static_cast(xs & 0xff), diff --git a/components/esp-box/src/video.cpp b/components/esp-box/src/video.cpp index d30fcc23b..db02bd708 100644 --- a/components/esp-box/src/video.cpp +++ b/components/esp-box/src/video.cpp @@ -172,11 +172,17 @@ void EspBox::write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data if (!lcd_) { return; } - size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; - if (length == 0) { - logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + if (data == nullptr) { + logger_.error("lcd_send_lines: Null data for ({},{}) to ({},{})", xs, ys, xe, ye); return; } + if (xs < 0 || ys < 0 || xe < xs || ye < ys) { + logger_.error("lcd_send_lines: Bad region: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + size_t width = static_cast(xe - xs + 1); + size_t height = static_cast(ye - ys + 1); + size_t length = width * height * lcd_bytes_per_pixel; lcd_->wait(); std::array window = { static_cast((xs >> 8) & 0xff), diff --git a/components/m5stack-tab5/src/video.cpp b/components/m5stack-tab5/src/video.cpp index 322c3b257..c307ee55e 100644 --- a/components/m5stack-tab5/src/video.cpp +++ b/components/m5stack-tab5/src/video.cpp @@ -339,7 +339,7 @@ void M5StackTab5::write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t if (lcd_handles_.panel == nullptr || data == nullptr) { return; } - if (xe < xs || ye < ys) { + if (xs < 0 || ys < 0 || xe < xs || ye < ys) { logger_.error("write_lcd_lines: Bad region: ({},{}) to ({},{})", xs, ys, xe, ye); return; } diff --git a/components/matouch-rotary-display/src/matouch-rotary-display.cpp b/components/matouch-rotary-display/src/matouch-rotary-display.cpp index f3400a1a1..0dddd78b6 100644 --- a/components/matouch-rotary-display/src/matouch-rotary-display.cpp +++ b/components/matouch-rotary-display/src/matouch-rotary-display.cpp @@ -370,11 +370,17 @@ void MatouchRotaryDisplay::write_lcd_lines(int xs, int ys, int xe, int ye, const if (!lcd_) { return; } - size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; - if (length == 0) { - logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + if (data == nullptr) { + logger_.error("lcd_send_lines: Null data for ({},{}) to ({},{})", xs, ys, xe, ye); return; } + if (xs < 0 || ys < 0 || xe < xs || ye < ys) { + logger_.error("lcd_send_lines: Bad region: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + size_t width = static_cast(xe - xs + 1); + size_t height = static_cast(ye - ys + 1); + size_t length = width * height * lcd_bytes_per_pixel; lcd_->wait(); std::array window = { static_cast((xs >> 8) & 0xff), diff --git a/components/seeed-studio-round-display/src/seeed-studio-round-display.cpp b/components/seeed-studio-round-display/src/seeed-studio-round-display.cpp index 0d327e64f..2b57a5253 100644 --- a/components/seeed-studio-round-display/src/seeed-studio-round-display.cpp +++ b/components/seeed-studio-round-display/src/seeed-studio-round-display.cpp @@ -329,11 +329,17 @@ void SsRoundDisplay::write_lcd_lines(int xs, int ys, int xe, int ye, const uint8 if (!lcd_) { return; } - size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; - if (length == 0) { - logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + if (data == nullptr) { + logger_.error("lcd_send_lines: Null data for ({},{}) to ({},{})", xs, ys, xe, ye); return; } + if (xs < 0 || ys < 0 || xe < xs || ye < ys) { + logger_.error("lcd_send_lines: Bad region: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + size_t width = static_cast(xe - xs + 1); + size_t height = static_cast(ye - ys + 1); + size_t length = width * height * lcd_bytes_per_pixel; lcd_->wait(); std::array window = { static_cast((xs >> 8) & 0xff), diff --git a/components/smartpanlee-sc01-plus/src/smartpanlee-sc01-plus.cpp b/components/smartpanlee-sc01-plus/src/smartpanlee-sc01-plus.cpp index 0837fcd99..7c2638e2a 100644 --- a/components/smartpanlee-sc01-plus/src/smartpanlee-sc01-plus.cpp +++ b/components/smartpanlee-sc01-plus/src/smartpanlee-sc01-plus.cpp @@ -556,6 +556,17 @@ void SmartPanleeSc01Plus::write_command(uint8_t command, std::span window = { static_cast((xs >> 8) & 0xFF), static_cast(xs & 0xFF), @@ -574,8 +585,9 @@ void SmartPanleeSc01Plus::write_lcd_lines(int xs, int ys, int xe, int ye, const ESP_ERROR_CHECK(esp_lcd_panel_io_tx_param(panel_io_, static_cast(DisplayDriver::Command::raset), window.data(), window.size())); - size_t num_bytes = - static_cast(xe - xs + 1) * static_cast(ye - ys + 1) * sizeof(Pixel); + size_t width = static_cast(xe - xs + 1); + size_t height = static_cast(ye - ys + 1); + size_t num_bytes = width * height * sizeof(Pixel); ESP_ERROR_CHECK(esp_lcd_panel_io_tx_color( panel_io_, static_cast(DisplayDriver::Command::ramwr), data, num_bytes)); } diff --git a/components/t-deck/src/t-deck.cpp b/components/t-deck/src/t-deck.cpp index a769de37f..68f38c8df 100644 --- a/components/t-deck/src/t-deck.cpp +++ b/components/t-deck/src/t-deck.cpp @@ -422,11 +422,17 @@ void IRAM_ATTR TDeck::write_lcd_lines(int xs, int ys, int xe, int ye, const uint if (!lcd_) { return; } - size_t length = (xe - xs + 1) * (ye - ys + 1) * 2; - if (length == 0) { - logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + if (data == nullptr) { + logger_.error("lcd_send_lines: Null data for ({},{}) to ({},{})", xs, ys, xe, ye); return; } + if (xs < 0 || ys < 0 || xe < xs || ye < ys) { + logger_.error("lcd_send_lines: Bad region: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + size_t width = static_cast(xe - xs + 1); + size_t height = static_cast(ye - ys + 1); + size_t length = width * height * 2; lcd_->wait(); std::array window = { static_cast((xs >> 8) & 0xff), diff --git a/components/t-dongle-s3/src/t-dongle-s3.cpp b/components/t-dongle-s3/src/t-dongle-s3.cpp index cc9f8d188..3f8fe3088 100644 --- a/components/t-dongle-s3/src/t-dongle-s3.cpp +++ b/components/t-dongle-s3/src/t-dongle-s3.cpp @@ -274,11 +274,17 @@ void IRAM_ATTR TDongleS3::write_lcd_lines(int xs, int ys, int xe, int ye, const if (!lcd_) { return; } - size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; - if (length == 0) { - logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + if (data == nullptr) { + logger_.error("lcd_send_lines: Null data for ({},{}) to ({},{})", xs, ys, xe, ye); return; } + if (xs < 0 || ys < 0 || xe < xs || ye < ys) { + logger_.error("lcd_send_lines: Bad region: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + size_t width = static_cast(xe - xs + 1); + size_t height = static_cast(ye - ys + 1); + size_t length = width * height * lcd_bytes_per_pixel; lcd_->wait(); std::array window = { static_cast((xs >> 8) & 0xff), diff --git a/components/wrover-kit/src/wrover-kit.cpp b/components/wrover-kit/src/wrover-kit.cpp index f5d6ba794..9b0843495 100644 --- a/components/wrover-kit/src/wrover-kit.cpp +++ b/components/wrover-kit/src/wrover-kit.cpp @@ -168,11 +168,17 @@ void WroverKit::write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *d if (!lcd_) { return; } - size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; - if (length == 0) { - logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + if (data == nullptr) { + logger_.error("lcd_send_lines: Null data for ({},{}) to ({},{})", xs, ys, xe, ye); return; } + if (xs < 0 || ys < 0 || xe < xs || ye < ys) { + logger_.error("lcd_send_lines: Bad region: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + size_t width = static_cast(xe - xs + 1); + size_t height = static_cast(ye - ys + 1); + size_t length = width * height * lcd_bytes_per_pixel; lcd_->wait(); std::array window = { static_cast((xs >> 8) & 0xff), diff --git a/components/ws-s3-geek/src/ws-s3-geek.cpp b/components/ws-s3-geek/src/ws-s3-geek.cpp index 8c29362e0..57625d273 100644 --- a/components/ws-s3-geek/src/ws-s3-geek.cpp +++ b/components/ws-s3-geek/src/ws-s3-geek.cpp @@ -197,11 +197,17 @@ void IRAM_ATTR WsS3Geek::write_lcd_lines(int xs, int ys, int xe, int ye, const u if (!lcd_) { return; } - size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; - if (length == 0) { - logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + if (data == nullptr) { + logger_.error("lcd_send_lines: Null data for ({},{}) to ({},{})", xs, ys, xe, ye); return; } + if (xs < 0 || ys < 0 || xe < xs || ye < ys) { + logger_.error("lcd_send_lines: Bad region: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + size_t width = static_cast(xe - xs + 1); + size_t height = static_cast(ye - ys + 1); + size_t length = width * height * lcd_bytes_per_pixel; lcd_->wait(); std::array window = { static_cast((xs >> 8) & 0xff), 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 6ef156725..022b151ef 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 @@ -201,11 +201,17 @@ void IRAM_ATTR WsS3Lcd147::write_lcd_lines(int xs, int ys, int xe, int ye, const if (!lcd_) { return; } - size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; - if (length == 0) { - logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + if (data == nullptr) { + logger_.error("lcd_send_lines: Null data for ({},{}) to ({},{})", xs, ys, xe, ye); return; } + if (xs < 0 || ys < 0 || xe < xs || ye < ys) { + logger_.error("lcd_send_lines: Bad region: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + size_t width = static_cast(xe - xs + 1); + size_t height = static_cast(ye - ys + 1); + size_t length = width * height * lcd_bytes_per_pixel; lcd_->wait(); std::array window = { static_cast((xs >> 8) & 0xff), diff --git a/components/ws-s3-touch/src/video.cpp b/components/ws-s3-touch/src/video.cpp index 827791fff..6864b4725 100644 --- a/components/ws-s3-touch/src/video.cpp +++ b/components/ws-s3-touch/src/video.cpp @@ -176,11 +176,17 @@ void WsS3Touch::write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *d if (!lcd_) { return; } - size_t length = (xe - xs + 1) * (ye - ys + 1) * lcd_bytes_per_pixel; - if (length == 0) { - logger_.error("lcd_send_lines: Bad length: ({},{}) to ({},{})", xs, ys, xe, ye); + if (data == nullptr) { + logger_.error("lcd_send_lines: Null data for ({},{}) to ({},{})", xs, ys, xe, ye); return; } + if (xs < 0 || ys < 0 || xe < xs || ye < ys) { + logger_.error("lcd_send_lines: Bad region: ({},{}) to ({},{})", xs, ys, xe, ye); + return; + } + size_t width = static_cast(xe - xs + 1); + size_t height = static_cast(ye - ys + 1); + size_t length = width * height * lcd_bytes_per_pixel; lcd_->wait(); std::array window = { static_cast((xs >> 8) & 0xff), From 3fb9990086f4d8aa40add8428a44ce91d38529aa Mon Sep 17 00:00:00 2001 From: William Emfinger Date: Sat, 6 Jun 2026 15:57:35 -0500 Subject: [PATCH 3/4] address comments --- components/byte90/include/byte90.hpp | 2 ++ components/esp-box/include/esp-box.hpp | 2 ++ components/m5stack-tab5/include/m5stack-tab5.hpp | 2 ++ components/m5stack-tab5/src/video.cpp | 3 +-- .../matouch-rotary-display/include/matouch-rotary-display.hpp | 2 ++ .../include/seeed-studio-round-display.hpp | 2 ++ .../smartpanlee-sc01-plus/include/smartpanlee-sc01-plus.hpp | 2 ++ components/t-deck/include/t-deck.hpp | 4 ++-- components/t-dongle-s3/include/t-dongle-s3.hpp | 2 ++ components/wrover-kit/include/wrover-kit.hpp | 2 ++ components/ws-s3-geek/include/ws-s3-geek.hpp | 2 ++ components/ws-s3-lcd-1-47/include/ws-s3-lcd-1-47.hpp | 2 ++ components/ws-s3-touch/include/ws-s3-touch.hpp | 2 ++ 13 files changed, 25 insertions(+), 4 deletions(-) diff --git a/components/byte90/include/byte90.hpp b/components/byte90/include/byte90.hpp index 1449d534b..7fb881c7c 100644 --- a/components/byte90/include/byte90.hpp +++ b/components/byte90/include/byte90.hpp @@ -226,6 +226,8 @@ class Byte90 : public BaseComponent { /// \param ye The y end coordinate /// \param data The data to write /// \param user_data User data to pass to the SPI transaction callback + /// \note This method queues the panel transfer asynchronously and may return + /// before the write has completed. void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); protected: diff --git a/components/esp-box/include/esp-box.hpp b/components/esp-box/include/esp-box.hpp index 79181292d..2a8ac26d4 100644 --- a/components/esp-box/include/esp-box.hpp +++ b/components/esp-box/include/esp-box.hpp @@ -245,6 +245,8 @@ class EspBox : public BaseComponent { /// \param ye The y end coordinate /// \param data The data to write /// \param user_data User data to pass to the SPI transaction callback + /// \note This method queues the panel transfer asynchronously and may return + /// before the write has completed. void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); ///////////////////////////////////////////////////////////////////////////// diff --git a/components/m5stack-tab5/include/m5stack-tab5.hpp b/components/m5stack-tab5/include/m5stack-tab5.hpp index 68eb1812e..6705e8bc3 100644 --- a/components/m5stack-tab5/include/m5stack-tab5.hpp +++ b/components/m5stack-tab5/include/m5stack-tab5.hpp @@ -254,6 +254,8 @@ class M5StackTab5 : public BaseComponent { /// \param ye The y end coordinate /// \param data The data to write /// \param user_data User data to pass to the lower-level transport + /// \note This method queues the panel transfer asynchronously and may return + /// before the write has completed. void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); ///////////////////////////////////////////////////////////////////////////// diff --git a/components/m5stack-tab5/src/video.cpp b/components/m5stack-tab5/src/video.cpp index c307ee55e..258a59f1a 100644 --- a/components/m5stack-tab5/src/video.cpp +++ b/components/m5stack-tab5/src/video.cpp @@ -343,8 +343,7 @@ void M5StackTab5::write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t logger_.error("write_lcd_lines: Bad region: ({},{}) to ({},{})", xs, ys, xe, ye); return; } - esp_lcd_panel_draw_bitmap(lcd_handles_.panel, xs, ys, xe + 1, ye + 1, - const_cast(data)); + esp_lcd_panel_draw_bitmap(lcd_handles_.panel, xs, ys, xe + 1, ye + 1, data); } void M5StackTab5::brightness(float brightness) { diff --git a/components/matouch-rotary-display/include/matouch-rotary-display.hpp b/components/matouch-rotary-display/include/matouch-rotary-display.hpp index c4d870866..f661bc4a8 100644 --- a/components/matouch-rotary-display/include/matouch-rotary-display.hpp +++ b/components/matouch-rotary-display/include/matouch-rotary-display.hpp @@ -247,6 +247,8 @@ class MatouchRotaryDisplay : public BaseComponent { /// \param ye The y end coordinate /// \param data The data to write /// \param user_data User data to pass to the SPI transaction callback + /// \note This method queues the panel transfer asynchronously and may return + /// before the write has completed. void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); protected: diff --git a/components/seeed-studio-round-display/include/seeed-studio-round-display.hpp b/components/seeed-studio-round-display/include/seeed-studio-round-display.hpp index c07220f16..d1acc7120 100644 --- a/components/seeed-studio-round-display/include/seeed-studio-round-display.hpp +++ b/components/seeed-studio-round-display/include/seeed-studio-round-display.hpp @@ -256,6 +256,8 @@ class SsRoundDisplay : public espp::BaseComponent { /// \param ye The y end coordinate /// \param data The data to write /// \param user_data User data to pass to the SPI transaction callback + /// \note This method queues the panel transfer asynchronously and may return + /// before the write has completed. void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); protected: diff --git a/components/smartpanlee-sc01-plus/include/smartpanlee-sc01-plus.hpp b/components/smartpanlee-sc01-plus/include/smartpanlee-sc01-plus.hpp index 7a87730b5..8f3d772b9 100755 --- a/components/smartpanlee-sc01-plus/include/smartpanlee-sc01-plus.hpp +++ b/components/smartpanlee-sc01-plus/include/smartpanlee-sc01-plus.hpp @@ -208,6 +208,8 @@ class SmartPanleeSc01Plus : public BaseComponent { /// \param ye Inclusive end Y coordinate. /// \param data Pointer to pixel payload data. /// \param user_data Opaque user data passed by the caller. + /// \note This method queues the panel transfer asynchronously and may return + /// before the write has completed. void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); /// Initialize the speaker audio path using the board's published I2S pins. diff --git a/components/t-deck/include/t-deck.hpp b/components/t-deck/include/t-deck.hpp index e74607994..b27c76d5d 100644 --- a/components/t-deck/include/t-deck.hpp +++ b/components/t-deck/include/t-deck.hpp @@ -405,8 +405,8 @@ class TDeck : public BaseComponent { /// \param ye The y end coordinate /// \param data The data to write /// \param user_data User data to pass to the spi transaction callback - /// \note This method queues the data to be written to the LCD, only blocking - /// if there is an ongoing SPI transaction + /// \note This method queues the panel transfer asynchronously and may return + /// before the write has completed. void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); ///////////////////////////////////////////////////////////////////////////// diff --git a/components/t-dongle-s3/include/t-dongle-s3.hpp b/components/t-dongle-s3/include/t-dongle-s3.hpp index 33f4357c8..aa63ff41e 100644 --- a/components/t-dongle-s3/include/t-dongle-s3.hpp +++ b/components/t-dongle-s3/include/t-dongle-s3.hpp @@ -207,6 +207,8 @@ class TDongleS3 : public BaseComponent { /// \param ye The y end coordinate /// \param data The data to write /// \param user_data User data to pass to the SPI transaction callback + /// \note This method queues the panel transfer asynchronously and may return + /// before the write has completed. void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); ///////////////////////////////////////////////////////////////////////////// diff --git a/components/wrover-kit/include/wrover-kit.hpp b/components/wrover-kit/include/wrover-kit.hpp index b43d3d4f6..f7917fd1e 100644 --- a/components/wrover-kit/include/wrover-kit.hpp +++ b/components/wrover-kit/include/wrover-kit.hpp @@ -158,6 +158,8 @@ class WroverKit : public BaseComponent { /// \param ye The y end coordinate /// \param data The data to write /// \param user_data User data to pass to the SPI transaction callback + /// \note This method queues the panel transfer asynchronously and may return + /// before the write has completed. void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); protected: diff --git a/components/ws-s3-geek/include/ws-s3-geek.hpp b/components/ws-s3-geek/include/ws-s3-geek.hpp index 8609f4d02..9b2a14cb1 100644 --- a/components/ws-s3-geek/include/ws-s3-geek.hpp +++ b/components/ws-s3-geek/include/ws-s3-geek.hpp @@ -163,6 +163,8 @@ class WsS3Geek : public BaseComponent { /// \param ye The y end coordinate /// \param data The data to write /// \param user_data User data to pass to the SPI transaction callback + /// \note This method queues the panel transfer asynchronously and may return + /// before the write has completed. void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); ///////////////////////////////////////////////////////////////////////////// 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 784546790..ecc10fad1 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 @@ -179,6 +179,8 @@ class WsS3Lcd147 : public BaseComponent { /// \param ye The y end coordinate /// \param data The data to write /// \param user_data User data to pass to the SPI transaction callback + /// \note This method queues the panel transfer asynchronously and may return + /// before the write has completed. void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); ///////////////////////////////////////////////////////////////////////////// diff --git a/components/ws-s3-touch/include/ws-s3-touch.hpp b/components/ws-s3-touch/include/ws-s3-touch.hpp index bccf38eeb..ba0bf3bd0 100644 --- a/components/ws-s3-touch/include/ws-s3-touch.hpp +++ b/components/ws-s3-touch/include/ws-s3-touch.hpp @@ -220,6 +220,8 @@ class WsS3Touch : public BaseComponent { /// \param ye The y end coordinate /// \param data The data to write /// \param user_data User data to pass to the SPI transaction callback + /// \note This method queues the panel transfer asynchronously and may return + /// before the write has completed. void write_lcd_lines(int xs, int ys, int xe, int ye, const uint8_t *data, uint32_t user_data); ///////////////////////////////////////////////////////////////////////////// From 118f0c55940bab697d9a15ccbd6629e73cd8c760 Mon Sep 17 00:00:00 2001 From: William Emfinger Date: Sat, 6 Jun 2026 16:07:49 -0500 Subject: [PATCH 4/4] address comments --- components/esp-box/src/video.cpp | 2 ++ components/t-deck/src/t-deck.cpp | 2 ++ components/t-dongle-s3/src/t-dongle-s3.cpp | 2 ++ components/ws-s3-touch/src/video.cpp | 2 ++ 4 files changed, 8 insertions(+) diff --git a/components/esp-box/src/video.cpp b/components/esp-box/src/video.cpp index db02bd708..9574b4f96 100644 --- a/components/esp-box/src/video.cpp +++ b/components/esp-box/src/video.cpp @@ -1,5 +1,7 @@ #include "esp-box.hpp" +#include + using namespace espp; //////////////////////// diff --git a/components/t-deck/src/t-deck.cpp b/components/t-deck/src/t-deck.cpp index 68f38c8df..cf80dc9fb 100644 --- a/components/t-deck/src/t-deck.cpp +++ b/components/t-deck/src/t-deck.cpp @@ -1,5 +1,7 @@ #include "t-deck.hpp" +#include + using namespace espp; TDeck::TDeck() diff --git a/components/t-dongle-s3/src/t-dongle-s3.cpp b/components/t-dongle-s3/src/t-dongle-s3.cpp index 3f8fe3088..8a26d9263 100644 --- a/components/t-dongle-s3/src/t-dongle-s3.cpp +++ b/components/t-dongle-s3/src/t-dongle-s3.cpp @@ -1,5 +1,7 @@ #include "t-dongle-s3.hpp" +#include + using namespace espp; TDongleS3::TDongleS3() diff --git a/components/ws-s3-touch/src/video.cpp b/components/ws-s3-touch/src/video.cpp index 6864b4725..517c923eb 100644 --- a/components/ws-s3-touch/src/video.cpp +++ b/components/ws-s3-touch/src/video.cpp @@ -1,5 +1,7 @@ #include "ws-s3-touch.hpp" +#include + using namespace espp; ////////////////////////