From a379e5a6357340a696d9cbc67a8ad48a0bad0924 Mon Sep 17 00:00:00 2001 From: Jonathan Swoboda <154711427+swoboda1337@users.noreply.github.com> Date: Mon, 9 Mar 2026 17:16:29 -0400 Subject: [PATCH] [runtime_image][st7701s] Fix BMP decoder and LCD init bugs (#14663) Co-authored-by: Claude Opus 4.6 --- .../components/runtime_image/bmp_decoder.cpp | 18 +++++++++++++++--- esphome/components/st7701s/st7701s.cpp | 6 ++++-- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/esphome/components/runtime_image/bmp_decoder.cpp b/esphome/components/runtime_image/bmp_decoder.cpp index 1a56484c606..7003f4da2ff 100644 --- a/esphome/components/runtime_image/bmp_decoder.cpp +++ b/esphome/components/runtime_image/bmp_decoder.cpp @@ -63,7 +63,8 @@ int HOT BmpDecoder::decode(uint8_t *buffer, size_t size) { switch (this->bits_per_pixel_) { case 1: - this->width_bytes_ = (this->width_ % 8 == 0) ? (this->width_ / 8) : (this->width_ / 8 + 1); + this->width_bytes_ = (this->width_ + 7) / 8; + this->padding_bytes_ = (4 - (this->width_bytes_ % 4)) % 4; break; case 24: this->width_bytes_ = this->width_ * 3; @@ -92,15 +93,26 @@ int HOT BmpDecoder::decode(uint8_t *buffer, size_t size) { case 1: { while (index < size) { uint8_t current_byte = buffer[index]; + bool end_of_row = false; for (uint8_t i = 0; i < 8; i++) { - size_t x = (this->paint_index_ % static_cast(this->width_)) + i; + size_t x = this->paint_index_ % static_cast(this->width_); size_t y = static_cast(this->height_ - 1) - (this->paint_index_ / static_cast(this->width_)); Color c = (current_byte & (1 << (7 - i))) ? display::COLOR_ON : display::COLOR_OFF; this->draw(x, y, 1, 1, c); + this->paint_index_++; + // End of pixel row: skip remaining bits in this byte + if (x + 1 >= static_cast(this->width_)) { + end_of_row = true; + break; + } } - this->paint_index_ += 8; this->current_index_++; index++; + // End of pixel row: skip row padding bytes (4-byte alignment) + if (end_of_row && this->padding_bytes_ > 0) { + index += this->padding_bytes_; + this->current_index_ += this->padding_bytes_; + } } break; } diff --git a/esphome/components/st7701s/st7701s.cpp b/esphome/components/st7701s/st7701s.cpp index 221fe39b9d8..ecce4eb4b27 100644 --- a/esphome/components/st7701s/st7701s.cpp +++ b/esphome/components/st7701s/st7701s.cpp @@ -36,11 +36,13 @@ void ST7701S::setup() { config.de_gpio_num = this->de_pin_->get_pin(); config.pclk_gpio_num = this->pclk_pin_->get_pin(); esp_err_t err = esp_lcd_new_rgb_panel(&config, &this->handle_); - ESP_ERROR_CHECK(esp_lcd_panel_reset(this->handle_)); - ESP_ERROR_CHECK(esp_lcd_panel_init(this->handle_)); if (err != ESP_OK) { esph_log_e(TAG, "lcd_new_rgb_panel failed: %s", esp_err_to_name(err)); + this->mark_failed(); + return; } + ESP_ERROR_CHECK(esp_lcd_panel_reset(this->handle_)); + ESP_ERROR_CHECK(esp_lcd_panel_init(this->handle_)); } void ST7701S::loop() {