Cleanup EInkDisplay

This commit is contained in:
Dave Allie
2025-12-16 21:31:32 +11:00
parent 4d0dcd5ff8
commit 54e6368c01
2 changed files with 27 additions and 33 deletions

View File

@@ -8,7 +8,7 @@ class EInkDisplay {
EInkDisplay(int8_t sclk, int8_t mosi, int8_t cs, int8_t dc, int8_t rst, int8_t busy); EInkDisplay(int8_t sclk, int8_t mosi, int8_t cs, int8_t dc, int8_t rst, int8_t busy);
// Destructor // Destructor
~EInkDisplay(); ~EInkDisplay() = default;
// Refresh modes (guarded to avoid redefinition in test builds) // Refresh modes (guarded to avoid redefinition in test builds)
enum RefreshMode { enum RefreshMode {
@@ -21,17 +21,17 @@ class EInkDisplay {
void begin(); void begin();
// Display dimensions // Display dimensions
static const uint16_t DISPLAY_WIDTH = 800; static constexpr uint16_t DISPLAY_WIDTH = 800;
static const uint16_t DISPLAY_HEIGHT = 480; static constexpr uint16_t DISPLAY_HEIGHT = 480;
static const uint16_t DISPLAY_WIDTH_BYTES = DISPLAY_WIDTH / 8; static constexpr uint16_t DISPLAY_WIDTH_BYTES = DISPLAY_WIDTH / 8;
static const uint32_t BUFFER_SIZE = DISPLAY_WIDTH_BYTES * DISPLAY_HEIGHT; static constexpr uint32_t BUFFER_SIZE = DISPLAY_WIDTH_BYTES * DISPLAY_HEIGHT;
// Frame buffer operations // Frame buffer operations
void clearScreen(uint8_t color = 0xFF); void clearScreen(uint8_t color = 0xFF) const;
void drawImage(const uint8_t* imageData, uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool fromProgmem = false); void drawImage(const uint8_t* imageData, uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool fromProgmem = false) const;
void swapBuffers(); void swapBuffers();
void setFramebuffer(const uint8_t* bwBuffer); void setFramebuffer(const uint8_t* bwBuffer) const;
void copyGrayscaleBuffers(const uint8_t* lsbBuffer, const uint8_t* msbBuffer); void copyGrayscaleBuffers(const uint8_t* lsbBuffer, const uint8_t* msbBuffer);
void copyGrayscaleLsbBuffers(const uint8_t* lsbBuffer); void copyGrayscaleLsbBuffers(const uint8_t* lsbBuffer);
@@ -52,7 +52,7 @@ class EInkDisplay {
void deepSleep(); void deepSleep();
// Access to frame buffer // Access to frame buffer
uint8_t* getFrameBuffer() { uint8_t* getFrameBuffer() const {
return frameBuffer; return frameBuffer;
} }

View File

@@ -121,10 +121,6 @@ EInkDisplay::EInkDisplay(int8_t sclk, int8_t mosi, int8_t cs, int8_t dc, int8_t
Serial.printf("[%lu] SCLK=%d, MOSI=%d, CS=%d, DC=%d, RST=%d, BUSY=%d\n", millis(), sclk, mosi, cs, dc, rst, busy); Serial.printf("[%lu] SCLK=%d, MOSI=%d, CS=%d, DC=%d, RST=%d, BUSY=%d\n", millis(), sclk, mosi, cs, dc, rst, busy);
} }
EInkDisplay::~EInkDisplay() {
// No dynamic memory to clean up (buffers are statically allocated)
}
void EInkDisplay::begin() { void EInkDisplay::begin() {
Serial.printf("[%lu] EInkDisplay: begin() called\n", millis()); Serial.printf("[%lu] EInkDisplay: begin() called\n", millis());
@@ -266,13 +262,11 @@ void EInkDisplay::initDisplayController() {
Serial.printf("[%lu] SSD1677 controller initialized\n", millis()); Serial.printf("[%lu] SSD1677 controller initialized\n", millis());
} }
void EInkDisplay::setRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h) { void EInkDisplay::setRamArea(const uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
const uint16_t WIDTH = 800; constexpr uint8_t DATA_ENTRY_X_INC_Y_DEC = 0x01;
const uint16_t HEIGHT = 480;
const uint8_t DATA_ENTRY_X_INC_Y_DEC = 0x01;
// Reverse Y coordinate (gates are reversed on this display) // Reverse Y coordinate (gates are reversed on this display)
y = HEIGHT - y - h; y = DISPLAY_HEIGHT - y - h;
// Set data entry mode (X increment, Y decrement for reversed gates) // Set data entry mode (X increment, Y decrement for reversed gates)
sendCommand(CMD_DATA_ENTRY_MODE); sendCommand(CMD_DATA_ENTRY_MODE);
@@ -303,28 +297,28 @@ void EInkDisplay::setRamArea(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
sendData((y + h - 1) / 256); // high byte sendData((y + h - 1) / 256); // high byte
} }
void EInkDisplay::clearScreen(uint8_t color) { void EInkDisplay::clearScreen(const uint8_t color) const {
memset(frameBuffer, color, BUFFER_SIZE); memset(frameBuffer, color, BUFFER_SIZE);
} }
void EInkDisplay::drawImage(const uint8_t* imageData, uint16_t x, uint16_t y, uint16_t w, uint16_t h, void EInkDisplay::drawImage(const uint8_t* imageData, const uint16_t x, const uint16_t y, const uint16_t w, const uint16_t h,
bool fromProgmem) { const bool fromProgmem) const {
if (!frameBuffer) { if (!frameBuffer) {
Serial.printf("[%lu] ERROR: Frame buffer not allocated!\n", millis()); Serial.printf("[%lu] ERROR: Frame buffer not allocated!\n", millis());
return; return;
} }
// Calculate bytes per line for the image // Calculate bytes per line for the image
uint16_t imageWidthBytes = w / 8; const uint16_t imageWidthBytes = w / 8;
// Copy image data to frame buffer // Copy image data to frame buffer
for (uint16_t row = 0; row < h; row++) { for (uint16_t row = 0; row < h; row++) {
uint16_t destY = y + row; const uint16_t destY = y + row;
if (destY >= DISPLAY_HEIGHT) if (destY >= DISPLAY_HEIGHT)
break; break;
uint16_t destOffset = destY * DISPLAY_WIDTH_BYTES + (x / 8); const uint16_t destOffset = destY * DISPLAY_WIDTH_BYTES + (x / 8);
uint16_t srcOffset = row * imageWidthBytes; const uint16_t srcOffset = row * imageWidthBytes;
for (uint16_t col = 0; col < imageWidthBytes; col++) { for (uint16_t col = 0; col < imageWidthBytes; col++) {
if ((x / 8 + col) >= DISPLAY_WIDTH_BYTES) if ((x / 8 + col) >= DISPLAY_WIDTH_BYTES)
@@ -343,17 +337,17 @@ void EInkDisplay::drawImage(const uint8_t* imageData, uint16_t x, uint16_t y, ui
void EInkDisplay::writeRamBuffer(uint8_t ramBuffer, const uint8_t* data, uint32_t size) { void EInkDisplay::writeRamBuffer(uint8_t ramBuffer, const uint8_t* data, uint32_t size) {
const char* bufferName = (ramBuffer == CMD_WRITE_RAM_BW) ? "BW" : "RED"; const char* bufferName = (ramBuffer == CMD_WRITE_RAM_BW) ? "BW" : "RED";
unsigned long startTime = millis(); const unsigned long startTime = millis();
Serial.printf("[%lu] Writing frame buffer to %s RAM (%lu bytes)...\n", startTime, bufferName, size); Serial.printf("[%lu] Writing frame buffer to %s RAM (%lu bytes)...\n", startTime, bufferName, size);
sendCommand(ramBuffer); sendCommand(ramBuffer);
sendData(data, size); sendData(data, size);
unsigned long duration = millis() - startTime; const unsigned long duration = millis() - startTime;
Serial.printf("[%lu] %s RAM write complete (%lu ms)\n", millis(), bufferName, duration); Serial.printf("[%lu] %s RAM write complete (%lu ms)\n", millis(), bufferName, duration);
} }
void EInkDisplay::setFramebuffer(const uint8_t* bwBuffer) { void EInkDisplay::setFramebuffer(const uint8_t* bwBuffer) const {
memcpy(frameBuffer, bwBuffer, BUFFER_SIZE); memcpy(frameBuffer, bwBuffer, BUFFER_SIZE);
} }
@@ -372,7 +366,7 @@ void EInkDisplay::grayscaleRevert() {
// Load the revert LUT // Load the revert LUT
setCustomLUT(true, lut_grayscale_revert); setCustomLUT(true, lut_grayscale_revert);
refreshDisplay(FAST_REFRESH, false); refreshDisplay(FAST_REFRESH);
setCustomLUT(false); setCustomLUT(false);
} }
@@ -421,10 +415,10 @@ void EInkDisplay::displayBuffer(RefreshMode mode) {
swapBuffers(); swapBuffers();
// Refresh the display // Refresh the display
refreshDisplay(mode, false); refreshDisplay(mode);
} }
void EInkDisplay::displayGrayBuffer(bool turnOffScreen) { void EInkDisplay::displayGrayBuffer(const bool turnOffScreen) {
drawGrayscale = false; drawGrayscale = false;
inGrayscaleMode = true; inGrayscaleMode = true;
@@ -434,7 +428,7 @@ void EInkDisplay::displayGrayBuffer(bool turnOffScreen) {
setCustomLUT(false); setCustomLUT(false);
} }
void EInkDisplay::refreshDisplay(RefreshMode mode, bool turnOffScreen) { void EInkDisplay::refreshDisplay(const RefreshMode mode, const bool turnOffScreen) {
// Configure Display Update Control 1 // Configure Display Update Control 1
sendCommand(CMD_DISPLAY_UPDATE_CTRL1); sendCommand(CMD_DISPLAY_UPDATE_CTRL1);
sendData((mode == FAST_REFRESH) ? CTRL1_NORMAL : CTRL1_BYPASS_RED); // Configure buffer comparison mode sendData((mode == FAST_REFRESH) ? CTRL1_NORMAL : CTRL1_BYPASS_RED); // Configure buffer comparison mode
@@ -490,7 +484,7 @@ void EInkDisplay::refreshDisplay(RefreshMode mode, bool turnOffScreen) {
waitWhileBusy(refreshType); waitWhileBusy(refreshType);
} }
void EInkDisplay::setCustomLUT(bool enabled, const unsigned char* lutData) { void EInkDisplay::setCustomLUT(const bool enabled, const unsigned char* lutData) {
if (enabled) { if (enabled) {
Serial.printf("[%lu] Loading custom LUT...\n", millis()); Serial.printf("[%lu] Loading custom LUT...\n", millis());