From e8b1dce67b2d31c1d8f9b2e44dc0d292d6e9d381 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Thu, 5 Mar 2026 16:28:41 -0500 Subject: [PATCH] [st7735][st7789v][st7920] Fix display buffer overflows and dead code (#14511) Co-authored-by: Claude Opus 4.6 --- esphome/components/st7735/st7735.cpp | 14 +------------ esphome/components/st7735/st7735.h | 1 - esphome/components/st7789v/st7789v.cpp | 29 +++++++++++++++++--------- esphome/components/st7920/st7920.cpp | 15 +++++++------ 4 files changed, 29 insertions(+), 30 deletions(-) diff --git a/esphome/components/st7735/st7735.cpp b/esphome/components/st7735/st7735.cpp index 58459b79bb..0fcfdd6c71 100644 --- a/esphome/components/st7735/st7735.cpp +++ b/esphome/components/st7735/st7735.cpp @@ -466,7 +466,7 @@ void HOT ST7735::write_display_data_() { } void ST7735::spi_master_write_addr_(uint16_t addr1, uint16_t addr2) { - static uint8_t byte[4]; + uint8_t byte[4]; byte[0] = (addr1 >> 8) & 0xFF; byte[1] = addr1 & 0xFF; byte[2] = (addr2 >> 8) & 0xFF; @@ -476,17 +476,5 @@ void ST7735::spi_master_write_addr_(uint16_t addr1, uint16_t addr2) { this->write_array(byte, 4); } -void ST7735::spi_master_write_color_(uint16_t color, uint16_t size) { - static uint8_t byte[1024]; - int index = 0; - for (int i = 0; i < size; i++) { - byte[index++] = (color >> 8) & 0xFF; - byte[index++] = color & 0xFF; - } - - this->dc_pin_->digital_write(true); - write_array(byte, size * 2); -} - } // namespace st7735 } // namespace esphome diff --git a/esphome/components/st7735/st7735.h b/esphome/components/st7735/st7735.h index 37fe673962..e81be520ed 100644 --- a/esphome/components/st7735/st7735.h +++ b/esphome/components/st7735/st7735.h @@ -68,7 +68,6 @@ class ST7735 : public display::DisplayBuffer, void set_addr_window_(uint16_t x, uint16_t y, uint16_t w, uint16_t h); void draw_absolute_pixel_internal(int x, int y, Color color) override; void spi_master_write_addr_(uint16_t addr1, uint16_t addr2); - void spi_master_write_color_(uint16_t color, uint16_t size); int get_width_internal() override; int get_height_internal() override; diff --git a/esphome/components/st7789v/st7789v.cpp b/esphome/components/st7789v/st7789v.cpp index cd0b6cabc3..6e4360ae74 100644 --- a/esphome/components/st7789v/st7789v.cpp +++ b/esphome/components/st7789v/st7789v.cpp @@ -1,11 +1,16 @@ #include "st7789v.h" #include "esphome/core/log.h" +#include namespace esphome { namespace st7789v { static const char *const TAG = "st7789v"; -static const size_t TEMP_BUFFER_SIZE = 128; +#ifdef USE_ESP32 +static constexpr size_t TEMP_BUFFER_SIZE = 1024; +#else +static constexpr size_t TEMP_BUFFER_SIZE = 512; +#endif void ST7789V::setup() { #ifdef USE_POWER_SUPPLY @@ -236,7 +241,7 @@ void ST7789V::write_data_(uint8_t value) { } void ST7789V::write_addr_(uint16_t addr1, uint16_t addr2) { - static uint8_t byte[4]; + uint8_t byte[4]; byte[0] = (addr1 >> 8) & 0xFF; byte[1] = addr1 & 0xFF; byte[2] = (addr2 >> 8) & 0xFF; @@ -247,15 +252,19 @@ void ST7789V::write_addr_(uint16_t addr1, uint16_t addr2) { } void ST7789V::write_color_(uint16_t color, uint16_t size) { - static uint8_t byte[1024]; - int index = 0; - for (int i = 0; i < size; i++) { - byte[index++] = (color >> 8) & 0xFF; - byte[index++] = color & 0xFF; - } - + uint8_t byte[TEMP_BUFFER_SIZE]; + uint16_t remaining = size; this->dc_pin_->digital_write(true); - write_array(byte, size * 2); + while (remaining > 0) { + uint16_t batch = std::min(remaining, static_cast(sizeof(byte) / 2)); + int index = 0; + for (int i = 0; i < batch; i++) { + byte[index++] = (color >> 8) & 0xFF; + byte[index++] = color & 0xFF; + } + this->write_array(byte, batch * 2); + remaining -= batch; + } } size_t ST7789V::get_buffer_length_() { diff --git a/esphome/components/st7920/st7920.cpp b/esphome/components/st7920/st7920.cpp index afd7cd61bd..a840f98152 100644 --- a/esphome/components/st7920/st7920.cpp +++ b/esphome/components/st7920/st7920.cpp @@ -72,16 +72,19 @@ void ST7920::goto_xy_(uint16_t x, uint16_t y) { } void HOT ST7920::write_display_data() { - uint8_t i, j, b; - for (j = 0; j < (uint8_t) (this->get_height_internal() / 2); j++) { + int i, j; + uint8_t b; + int width_bytes = this->get_width_internal() / 8; + int half_height = this->get_height_internal() / 2; + for (j = 0; j < half_height; j++) { this->goto_xy_(0, j); this->enable(); - for (i = 0; i < 16; i++) { // 16 bytes from line #0+ - b = this->buffer_[i + j * 16]; + for (i = 0; i < width_bytes; i++) { + b = this->buffer_[i + j * width_bytes]; this->send_(LCD_DATA, b); } - for (i = 0; i < 16; i++) { // 16 bytes from line #32+ - b = this->buffer_[i + (j + 32) * 16]; + for (i = 0; i < width_bytes; i++) { + b = this->buffer_[i + (j + half_height) * width_bytes]; this->send_(LCD_DATA, b); } this->disable();