init commit
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
#pragma once
|
||||
|
||||
/**
|
||||
* @file DisplayManager.h
|
||||
* @brief E-Ink display driver abstraction using GxEPD2_BW.
|
||||
*
|
||||
* Responsibilities:
|
||||
* - Manage the 400×300 Waveshare 4.2" GxEPD2 display via SPI.
|
||||
* - Render a 2×2 tile grid; each tile shows one data field.
|
||||
* - Perform partial refresh for numeric value updates (fast, no flicker).
|
||||
* - Perform full refresh on page change or periodically to prevent ghosting.
|
||||
* - Show a splash/boot screen, BLE status overlay and AP-mode notice.
|
||||
*
|
||||
* Partial refresh strategy:
|
||||
* Each tile's "value area" (excluding the fixed label and border) is
|
||||
* re-drawn with partial update. The borders and labels are only redrawn
|
||||
* during a full refresh, saving ~250 ms per cycle.
|
||||
*/
|
||||
|
||||
#include "Config.h"
|
||||
#include <GxEPD2_BW.h>
|
||||
#include <Fonts/FreeMonoBold24pt7b.h>
|
||||
#include <Fonts/FreeMonoBold12pt7b.h>
|
||||
#include <Fonts/FreeMono9pt7b.h>
|
||||
|
||||
// ── Display model — Waveshare 4.2" mono GDEY042T81 (400×300) ─────────────────
|
||||
// Adjust the model constant if your display differs.
|
||||
using DisplayType = GxEPD2_BW<GxEPD2_420_GDEY042T81,
|
||||
GxEPD2_420_GDEY042T81::HEIGHT>;
|
||||
|
||||
class DisplayManager {
|
||||
public:
|
||||
/**
|
||||
* @brief Initialise the SPI bus and display. Shows the splash screen.
|
||||
* Must be called from setup() before any render methods.
|
||||
*/
|
||||
void begin();
|
||||
|
||||
/**
|
||||
* @brief Main render call — invoke from loop().
|
||||
* Decides between partial and full refresh based on:
|
||||
* - Whether data has changed since the last render.
|
||||
* - Whether FULL_REFRESH_INTERVAL_MS has elapsed.
|
||||
* - An explicit forceFullRefresh() request.
|
||||
* @param state Current boat data snapshot.
|
||||
* @param cfg Current page configuration.
|
||||
*/
|
||||
void render(const BoatState& state, const PageConfig& cfg);
|
||||
|
||||
/** @brief Request a full (slow) refresh on the next render() call. */
|
||||
void forceFullRefresh() { _needFullRefresh = true; }
|
||||
|
||||
/** @brief Show a BLE scanning / connecting notice. */
|
||||
void showBleStatus(AppState::BleStatus status);
|
||||
|
||||
/** @brief Show the AP mode access screen with SSID and IP. */
|
||||
void showApScreen(const char* ssid, const char* ip);
|
||||
|
||||
/** @brief Show the OTA progress screen. */
|
||||
void showOtaScreen(uint8_t percent);
|
||||
|
||||
/** @brief Show the passkey entry prompt. */
|
||||
void showPasskeyPrompt(uint32_t pin);
|
||||
|
||||
/** @brief Hibernate the display to save power (full blank). */
|
||||
void hibernate();
|
||||
|
||||
// Internal access for GxEPD2
|
||||
DisplayType& epd() { return _display; }
|
||||
|
||||
private:
|
||||
DisplayType _display {
|
||||
GxEPD2_420_GDEY042T81(Pins::EPD_CS,
|
||||
Pins::EPD_DC,
|
||||
Pins::EPD_RST,
|
||||
Pins::EPD_BUSY)
|
||||
};
|
||||
|
||||
bool _initialised = false;
|
||||
bool _needFullRefresh = true;
|
||||
uint32_t _lastFullRefresh = 0;
|
||||
uint32_t _lastRender = 0;
|
||||
|
||||
// Cached value strings per tile to detect changes
|
||||
char _prevValue[Display::TILE_COUNT][16];
|
||||
|
||||
// ── Drawing helpers ───────────────────────────────────────────────────────
|
||||
|
||||
void _drawSplash();
|
||||
void _drawGrid();
|
||||
void _drawTile(uint8_t idx, const TileConfig& tile, const BoatState& state, bool partial);
|
||||
void _drawTileLabel(uint8_t idx, const TileConfig& tile);
|
||||
void _drawTileValue(uint8_t idx, const char* value, bool partial);
|
||||
|
||||
// Compute the pixel rect for a tile
|
||||
struct Rect { uint16_t x, y, w, h; };
|
||||
Rect _tileRect(uint8_t idx) const;
|
||||
Rect _valuRect(uint8_t idx) const; ///< Sub-rect for the value only
|
||||
|
||||
// Extract a display string from the boat state for a given field
|
||||
void _fieldToString(DataField field, const BoatState& state,
|
||||
char* out, size_t outLen) const;
|
||||
|
||||
// Centre text in a rect
|
||||
void _drawCentred(const char* text, uint16_t x, uint16_t y,
|
||||
uint16_t w, uint16_t h);
|
||||
};
|
||||
|
||||
// Singleton accessor
|
||||
extern DisplayManager displayManager;
|
||||
Reference in New Issue
Block a user