#pragma once #include #include class HalDisplay { public: // Constructor with pin configuration HalDisplay(); // Destructor ~HalDisplay(); // Refresh modes enum RefreshMode { FULL_REFRESH, // Full refresh with complete waveform HALF_REFRESH, // Half refresh (1720ms) - balanced quality and speed FAST_REFRESH // Fast refresh using custom LUT }; // Pass seamless=true on any path where the panel already shows the // content it should after begin() returns (silent reboot's popup, // sleep-wake with a restored buffer). Skips the wakeup-gated // requestResync() and defuses the SDK's X3 _x3InitialFullSyncsRemaining // counter; otherwise the first two paints get promoted to FULL // (~770ms each on X3). void begin(bool seamless = false); // Display dimensions static constexpr uint16_t DISPLAY_WIDTH = EInkDisplay::DISPLAY_WIDTH; static constexpr uint16_t DISPLAY_HEIGHT = EInkDisplay::DISPLAY_HEIGHT; static constexpr uint16_t DISPLAY_WIDTH_BYTES = DISPLAY_WIDTH / 8; static constexpr uint32_t BUFFER_SIZE = DISPLAY_WIDTH_BYTES * DISPLAY_HEIGHT; // Frame buffer operations 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) const; void drawImageTransparent(const uint8_t* imageData, uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool fromProgmem = false) const; void displayBuffer(RefreshMode mode = RefreshMode::FAST_REFRESH, bool turnOffScreen = false); void refreshDisplay(RefreshMode mode = RefreshMode::FAST_REFRESH, bool turnOffScreen = false); // Power management void deepSleep(); // Access to frame buffer uint8_t* getFrameBuffer() const; void copyGrayscaleBuffers(const uint8_t* lsbBuffer, const uint8_t* msbBuffer); void copyGrayscaleLsbBuffers(const uint8_t* lsbBuffer); void copyGrayscaleMsbBuffers(const uint8_t* msbBuffer); void cleanupGrayscaleBuffers(const uint8_t* bwBuffer); void displayGrayBuffer(bool turnOffScreen = false); // Tiled grayscale: stream one band of a plane (lsbPlane selects LSB/MSB RAM) // straight to the controller; supportsStripGrayscale() gates the path. See // EInkDisplay::writeGrayscalePlaneStrip. void writeGrayscalePlaneStrip(bool lsbPlane, const uint8_t* rows, uint16_t yStart, uint16_t numRows); bool supportsStripGrayscale() const; // Runtime geometry passthrough uint16_t getDisplayWidth() const; uint16_t getDisplayHeight() const; uint16_t getDisplayWidthBytes() const; uint32_t getBufferSize() const; private: EInkDisplay einkDisplay; }; extern HalDisplay display;