From d2fd001e7011d86e4b4ac8c04e8ba3ce1dd236b1 Mon Sep 17 00:00:00 2001 From: Adolfo Reyna Date: Fri, 30 Jan 2026 23:02:53 -0500 Subject: [PATCH] Add display color inversion flag and logic for Feather TFT --- board_configs/board_feather_tft.h | 3 +++ display/low_level_display_factory.cpp | 7 ++++++- display/low_level_display_st7796.cpp | 15 ++++++++------- display/low_level_display_st7796.h | 17 +++++++++++------ 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/board_configs/board_feather_tft.h b/board_configs/board_feather_tft.h index 61524b3..d4253d5 100644 --- a/board_configs/board_feather_tft.h +++ b/board_configs/board_feather_tft.h @@ -20,6 +20,9 @@ #define TOUCH_INVERT_X true #define TOUCH_INVERT_Y false +// Invert display color (black <-> white) +#define DISPLAY_INVERT_COLOR true + // SPI pins for display - Feather RP2350 with 4.0" TFT #define DISPLAY_SPI_PORT spi1 #define DISPLAY_SCK_PIN 10 // D10 (SCK) diff --git a/display/low_level_display_factory.cpp b/display/low_level_display_factory.cpp index c547c83..403432a 100644 --- a/display/low_level_display_factory.cpp +++ b/display/low_level_display_factory.cpp @@ -22,7 +22,12 @@ LowLevelDisplay* LowLevelDisplay::create(DisplayType type, int width, int height .gpio_bl = DISPLAY_BL_PIN, }; printf("Creating ST7796 display (%dx%d)\n", width, height); - return new LowLevelDisplayST7796(&lcd_config, width, height); + // Use board config flag for color inversion +#ifdef DISPLAY_INVERT_COLOR + return new LowLevelDisplayST7796(&lcd_config, width, height, DISPLAY_INVERT_COLOR); +#else + return new LowLevelDisplayST7796(&lcd_config, width, height, false); +#endif } case DISPLAY_TYPE_ST7789: { diff --git a/display/low_level_display_st7796.cpp b/display/low_level_display_st7796.cpp index 35076e1..f318e14 100644 --- a/display/low_level_display_st7796.cpp +++ b/display/low_level_display_st7796.cpp @@ -6,8 +6,8 @@ #define COLOR_BLACK 0x0000 #define COLOR_WHITE 0xFFFF -LowLevelDisplayST7796::LowLevelDisplayST7796(const st7796_config* cfg, int w, int h) - : config(cfg), width(w), height(h), initialized(false), rgb_buffer(nullptr) { +LowLevelDisplayST7796::LowLevelDisplayST7796(const st7796_config* cfg, int w, int h, bool invert) + : config(cfg), width(w), height(h), initialized(false), rgb_buffer(nullptr), invert_color(invert) { } LowLevelDisplayST7796::~LowLevelDisplayST7796() { @@ -38,26 +38,27 @@ bool LowLevelDisplayST7796::init() { } void LowLevelDisplayST7796::clear(bool white) { - st7796_fill(white ? COLOR_WHITE : COLOR_BLACK); + bool out_white = invert_color ? !white : white; + st7796_fill(out_white ? COLOR_WHITE : COLOR_BLACK); } void LowLevelDisplayST7796::draw_pixel(int x, int y, bool white) { - st7796_draw_pixel(x, y, white ? COLOR_WHITE : COLOR_BLACK); + bool out_white = invert_color ? !white : white; + st7796_draw_pixel(x, y, out_white ? COLOR_WHITE : COLOR_BLACK); } void LowLevelDisplayST7796::draw_buffer(const uint8_t* bit_buffer) { if (!bit_buffer || !rgb_buffer) return; - // Convert 1-bit buffer to RGB565 using persistent buffer for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { int byte_index = (y * width + x) / 8; int bit_index = 7 - (x % 8); bool pixel_white = (bit_buffer[byte_index] >> bit_index) & 0x01; - rgb_buffer[y * width + x] = pixel_white ? COLOR_WHITE : COLOR_BLACK; + bool out_white = invert_color ? !pixel_white : pixel_white; + rgb_buffer[y * width + x] = out_white ? COLOR_WHITE : COLOR_BLACK; } } - // Draw entire buffer at once st7796_set_cursor(0, 0); st7796_write(rgb_buffer, width * height); diff --git a/display/low_level_display_st7796.h b/display/low_level_display_st7796.h index 2c6b330..cd8c394 100644 --- a/display/low_level_display_st7796.h +++ b/display/low_level_display_st7796.h @@ -11,29 +11,34 @@ private: int height; bool initialized; uint16_t* rgb_buffer; // Persistent buffer for 1-bit to RGB565 conversion - + bool invert_color; // If true, swap black/white + public: - LowLevelDisplayST7796(const st7796_config* cfg, int w, int h); + LowLevelDisplayST7796(const st7796_config* cfg, int w, int h, bool invert = false); ~LowLevelDisplayST7796() override; - + // Core display operations - converts 1-bit to RGB565 internally bool init() override; void clear(bool white = true) override; void draw_pixel(int x, int y, bool white) override; void draw_buffer(const uint8_t* bit_buffer) override; void refresh() override; - + // Display properties int get_width() const override { return width; } int get_height() const override { return height; } DisplayType get_type() const override { return DISPLAY_TYPE_ST7796; } bool is_color() const override { return true; } - + // Backlight control void set_backlight(bool on) override; - + // Orientation control void set_rotation(uint8_t rotation) override; + + // Color inversion control + void set_invert_color(bool inv) { invert_color = inv; } + bool get_invert_color() const { return invert_color; } }; #endif // LOW_LEVEL_DISPLAY_ST7796_H