refactor: use EPD-exact bgr888 palette with bulk pushImage

Replace the PALETTE_565 + writePixel loop with a bgr888_t palette whose
values exactly match Panel_ED2208's internal epd_palette, pushed via a
single pushImage() call.

Benefits:
- Eliminates ~240K individual writePixel calls per frame
- Zero-distance palette values guarantee correct color mapping
- Removes lossy RGB565 intermediate encoding
- Remove unused paletteToColor565() helper

Also adds informational comment to triggerRefresh() noting that
Panel_ED2208::_exec_transfer always sends the full 400x600 frame.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-03 19:54:59 -04:00
parent 065d80ca89
commit 7805c5359e
2 changed files with 16 additions and 22 deletions

View File

@@ -2,14 +2,16 @@
#include "power_manager.h"
#include <M5Unified.h>
// Map 6-color palette indices to RGB565 for M5GFX
static const uint16_t PALETTE_565[6] = {
0x0000, // Black
0xFFFF, // White
0xF800, // Red (approximate)
0x07E0, // Green (approximate)
0x001F, // Blue (approximate)
0xFFE0 // Yellow (approximate)
// EPD-exact palette: values produce distance=0 in Panel_ED2208's
// _rgb_to_epd_color nearest-color lookup, guaranteeing correct mapping.
// Order matches our pipeline's palette indices (0=black..5=yellow).
static const lgfx::bgr888_t EPD_PALETTE[6] = {
{0, 0, 0}, // Black (EPD_BLACK)
{255, 255, 255}, // White (EPD_WHITE)
{191, 0, 0}, // Red (EPD_RED)
{67, 138, 28}, // Green (EPD_GREEN)
{100, 64, 255}, // Blue (EPD_BLUE)
{255, 243, 56} // Yellow (EPD_YELLOW)
};
void DisplayManager::begin(PowerManager& power) {
@@ -92,14 +94,10 @@ void DisplayManager::showImage(const ProcessedImage& img) {
Serial.println("[display] Writing framebuffer to e-ink...");
// Write pixel by pixel using palette-mapped colors
// Bulk-write framebuffer using palette lookup (handles rotation internally)
_display->startWrite();
for (uint16_t y = 0; y < img.height; y++) {
for (uint16_t x = 0; x < img.width; x++) {
uint8_t colorIdx = img.framebuffer[y * img.width + x];
_display->writePixel(x, y, PALETTE_565[colorIdx]);
}
}
_display->pushImage(0, 0, img.width, img.height,
img.framebuffer, lgfx::color_depth_t::palette_8bit, EPD_PALETTE);
_display->endWrite();
// Do NOT refresh here — caller should add metadata overlay then call refresh()
}
@@ -361,12 +359,9 @@ void DisplayManager::refresh() {
}
void DisplayManager::triggerRefresh() {
// M5GFX handles e-ink refresh internally when using the EPD panel driver
// The display() call triggers the actual e-ink refresh cycle (10-20s)
// Panel_ED2208::_exec_transfer always sends the full 400x600 frame
// regardless of dirty region — the dirty rect only gates whether
// a transfer happens at all. ~30ms at 4MHz SPI, fine for photo frame.
_display->display();
}
uint16_t DisplayManager::paletteToColor565(uint8_t index) {
if (index >= DISPLAY_COLORS) return 0;
return PALETTE_565[index];
}

View File

@@ -31,5 +31,4 @@ private:
void drawBadge(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
void triggerRefresh();
uint16_t paletteToColor565(uint8_t index);
};