15#include "driver/ledc.h"
18#include "freertos/FreeRTOS.h"
19#include "freertos/task.h"
20#include "freertos/semphr.h"
21#include <goodisplay/gdey029T94.h>
22#include <Fonts/FreeMonoBold12pt7b.h>
23#include <Fonts/FreeMonoBold9pt7b.h>
27static const char*
TAG =
"EpaperDisplay";
37static constexpr ledc_mode_t
LEDC_MODE = LEDC_LOW_SPEED_MODE;
47static constexpr uint16_t
WIDTH = 296;
48static constexpr uint16_t
HEIGHT = 128;
111#if FEATURE_EPD_FAST_REFRESH
185 if (nvs_open(
NVS_NAMESPACE, NVS_READWRITE, &nvs) == ESP_OK) {
189 LOG_D(
TAG,
"Backlight saved to NVS: %u", level);
199 ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
234 bool init()
override;
235 bool start()
override;
236 void stop()
override;
238 const char*
getName()
const override {
return "display"; }
240 void clear()
override;
253 void showSplash(
const char* subtitle =
nullptr)
override;
256 void drawPixel(int16_t x, int16_t y, uint16_t color)
override;
257 void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color)
override;
258 void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
override;
259 void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
override;
260 void setCursor(int16_t x, int16_t y)
override;
263 void setFont(
const void* font)
override;
264 void print(
const char* text)
override;
265 void printf(
const char* fmt, ...)
override;
280 LOG_I(
TAG,
"Initializing E-Paper display...");
286 ledc_timer_config_t ledcTimer = {
291 .clk_cfg = LEDC_USE_XTAL_CLK,
294 ledc_timer_config(&ledcTimer);
296 ledc_channel_config_t ledcChannel = {
300 .intr_type = LEDC_INTR_DISABLE,
304 .sleep_mode = LEDC_SLEEP_MODE_KEEP_ALIVE,
305 .flags = {.output_invert = 0}
307 ledc_channel_config(&ledcChannel);
326 LOG_I(
TAG,
"Display hardware initialized");
333 LOG_E(
TAG,
"Failed to create render mutex");
340 LOG_E(
TAG,
"Failed to create render task");
470 LOG_I(
TAG,
"Showing splash screen");
498 snprintf(build_str,
sizeof(build_str),
"%.3s%2.2s %.5s", __DATE__, __DATE__ + 4, __TIME__);
503 const char* status_text =
"Open Hardware Security";
504 int status_x =
s_epd_display->width() - (strlen(status_text) * 6) - 2;
510 LOG_I(
TAG,
"Splash screen displayed");
611 vsnprintf(buf,
sizeof(buf), fmt, args);
631 if (count == 0) count = 1;
632 if (count > 10) count = 10;
633 if (period_ms < 50) period_ms = 50;
634 if (period_ms > 1000) period_ms = 1000;
637 if (!display)
return;
641 const TickType_t ticks = pdMS_TO_TICKS(period_ms);
642 for (uint8_t i = 0; i < count; ++i) {
static constexpr const char * SPLASH_VERSION
static constexpr const char * SPLASH_TITLE
Splash-screen text defaults.
Shared RAII wrappers for firmware resources.
CDC Log: logging over TinyUSB CDC and UART.
#define LOG_D(tag, fmt,...)
#define LOG_I(tag, fmt,...)
#define LOG_E(tag, fmt,...)
static EventBus & instance()
Returns singleton event-bus instance.
bool publish(const Event &event, bool fromISR=false)
Publishes an event to the queue.
RAII wrapper for a FreeRTOS semaphore / mutex.
const char * getName() const override
void stop() override
Stops display service and disables backlight.
void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color) override
Draws a line on framebuffer.
uint16_t getWidth() const override
void backlightOn() override
Enables backlight using current configured level.
core::ServiceState getState() const override
bool isBacklightOn() const override
void setTextSize(uint8_t size) override
Sets active text scale.
void saveBacklight() override
Persists current backlight level.
uint16_t getHeight() const override
void showSplash(const char *subtitle=nullptr) override
Renders and displays boot splash screen.
void setFont(const void *font) override
Sets active font pointer.
void clear() override
Clears framebuffer to white.
void drawPixel(int16_t x, int16_t y, uint16_t color) override
Adafruit-GFX method implementations.
void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) override
Draws filled rectangle on framebuffer.
void print(const char *text) override
Prints text at current cursor position.
void flushSync(RefreshMode mode) override
Performs synchronous display refresh.
uint16_t getBacklight() const override
void setBacklight(uint16_t level) override
Sets current backlight level and applies immediately.
void backlightOff() override
Disables backlight output.
bool start() override
Starts display service and enables backlight.
void * getNativeHandle() override
void setCursor(int16_t x, int16_t y) override
Sets text cursor position.
bool isBusy() const override
void flush(RefreshMode mode) override
Requests asynchronous display refresh.
void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color) override
Draws rectangle outline on framebuffer.
void setTextColor(uint16_t color) override
Sets active text color.
void printf(const char *fmt,...) override
Formatted print helper for display text output.
bool init() override
Initializes display hardware, backlight, and render task.
#define FEATURE_EPD_MAX_FASTS_BEFORE_FULL
#define FEATURE_EPD_MAX_PARTIALS_BEFORE_FAST
static bool s_backlightOn
static volatile RefreshMode s_renderMode
static int refreshStrength(RefreshMode mode)
static constexpr ledc_mode_t LEDC_MODE
IDisplay * getDisplayInstance()
Returns lazily created singleton display instance.
static constexpr uint16_t kMaxPartialsBeforeFast
static constexpr uint32_t LEDC_FREQUENCY
static uint16_t s_partialsSinceFast
static constexpr ledc_timer_t LEDC_TIMER
LEDC backlight PWM configuration constants.
static constexpr uint16_t WIDTH
Display timing and geometry constants.
static constexpr uint16_t HEIGHT
static EpaperDisplay * s_display
Lazily created singleton display instance.
static void driveRefresh(RefreshMode resolved)
static constexpr uint16_t BACKLIGHT_MAX
static void renderTask(void *arg)
Render worker task processing async flush requests.
static constexpr uint16_t BACKLIGHT_DEFAULT
static SemaphoreHandle_t s_renderMutex
Render-task runtime state.
static constexpr uint16_t kMaxFastsBeforeFull
static bool s_initialized
Mutable display state cache.
static void applyBacklight(uint16_t level)
Applies backlight PWM duty level.
void winkBacklight(uint8_t count=2, uint16_t period_ms=150)
Blink the backlight as a visual "look at me" signal.
static constexpr const char * NVS_NAMESPACE
NVS namespace and keys for display settings.
static EpdSpi * s_epd_spi
Lazily initialized display objects to avoid global constructors.
static volatile bool s_renderPending
static constexpr ledc_channel_t LEDC_CHANNEL
static uint16_t s_backlightLevel
static Gdey029T94 * s_epd_display
static void persistBacklight(uint16_t level)
Persists backlight level to NVS.
static TaskHandle_t s_renderTask
static RefreshMode resolveRefresh(RefreshMode mode)
static constexpr const char * NVS_KEY_BACKLIGHT
static void loadBacklight()
Loads persisted backlight level from NVS.
static SemaphoreHandle_t s_panelMutex
static SemaphoreHandle_t s_backlightMutex
static constexpr ledc_timer_bit_t LEDC_DUTY_RES
static uint16_t s_fastsSinceFull