13#include "driver/ledc.h"
16#include "freertos/FreeRTOS.h"
17#include "freertos/task.h"
18#include "freertos/semphr.h"
19#include <goodisplay/gdey029T94.h>
20#include <Fonts/FreeMonoBold12pt7b.h>
21#include <Fonts/FreeMonoBold9pt7b.h>
25static const char*
TAG =
"EpaperDisplay";
35static constexpr ledc_mode_t
LEDC_MODE = LEDC_LOW_SPEED_MODE;
45static constexpr uint16_t
WIDTH = 296;
46static constexpr uint16_t
HEIGHT = 128;
133 if (nvs_open(
NVS_NAMESPACE, NVS_READWRITE, &nvs) == ESP_OK) {
137 LOG_D(
TAG,
"Backlight saved to NVS: %u", level);
147 ulTaskNotifyTake(pdTRUE, portMAX_DELAY);
175 bool init()
override;
176 bool start()
override;
177 void stop()
override;
179 const char*
getName()
const override {
return "display"; }
181 void clear()
override;
194 void showSplash(
const char* subtitle =
nullptr)
override;
197 void drawPixel(int16_t x, int16_t y, uint16_t color)
override;
198 void drawLine(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color)
override;
199 void drawRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
override;
200 void fillRect(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color)
override;
201 void setCursor(int16_t x, int16_t y)
override;
204 void setFont(
const void* font)
override;
205 void print(
const char* text)
override;
206 void printf(
const char* fmt, ...)
override;
221 LOG_I(
TAG,
"Initializing E-Paper display...");
227 ledc_timer_config_t ledcTimer = {
232 .clk_cfg = LEDC_USE_XTAL_CLK,
235 ledc_timer_config(&ledcTimer);
237 ledc_channel_config_t ledcChannel = {
241 .intr_type = LEDC_INTR_DISABLE,
245 .sleep_mode = LEDC_SLEEP_MODE_KEEP_ALIVE,
246 .flags = {.output_invert = 0}
248 ledc_channel_config(&ledcChannel);
267 LOG_I(
TAG,
"Display hardware initialized");
273 LOG_E(
TAG,
"Failed to create render mutex");
280 LOG_E(
TAG,
"Failed to create render task");
413 LOG_I(
TAG,
"Showing splash screen");
441 snprintf(build_str,
sizeof(build_str),
"%.3s%2.2s %.5s", __DATE__, __DATE__ + 4, __TIME__);
446 const char* status_text =
"Open Hardware Security";
447 int status_x =
s_epd_display->width() - (strlen(status_text) * 6) - 2;
453 LOG_I(
TAG,
"Splash screen displayed");
554 vsnprintf(buf,
sizeof(buf), fmt, args);
574 if (count == 0) count = 1;
575 if (count > 10) count = 10;
576 if (period_ms < 50) period_ms = 50;
577 if (period_ms > 1000) period_ms = 1000;
580 if (!display)
return;
582 const bool was_on = display->isBacklightOn();
583 const TickType_t ticks = pdMS_TO_TICKS(period_ms);
584 for (uint8_t i = 0; i < count; ++i) {
585 display->backlightOff();
587 display->backlightOn();
590 if (!was_on) display->backlightOff();
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,...)
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.
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 uint32_t LEDC_FREQUENCY
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 constexpr uint16_t kMaxPartialsBeforeFull
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 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 uint16_t s_partialsSinceFull
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 constexpr const char * NVS_KEY_BACKLIGHT
static void loadBacklight()
Loads persisted backlight level from NVS.
static SemaphoreHandle_t s_panelMutex
static constexpr ledc_timer_bit_t LEDC_DUTY_RES
static bool resolveFullRefresh(RefreshMode mode)