Add Panel-Aware Local OLED Display Service

This commit is contained in:
2026-08-29 14:37:44 +02:00
parent ec9ca5e6d2
commit 4aa5ca80da
10 changed files with 900 additions and 427 deletions
+86
View File
@@ -0,0 +1,86 @@
/* SPDX-License-Identifier: GPL-3.0-only */
/* Bounded SSD1315-compatible local OLED service. */
#pragma once
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include "esp_err.h"
#ifdef __cplusplus
extern "C" {
#endif
#define LOCAL_DISPLAY_WIDTH 128U
#define LOCAL_DISPLAY_HEIGHT 64U
#define LOCAL_DISPLAY_STATUS_HEIGHT 16U
#define LOCAL_DISPLAY_CONTENT_HEIGHT 48U
/* The physical black divider lies between status row 15 and content row 16. */
typedef enum {
LOCAL_DISPLAY_PANEL_STATUS = 0,
LOCAL_DISPLAY_PANEL_CONTENT,
} local_display_panel_t;
typedef struct {
bool bus_ready;
bool initialized;
uint8_t address_7bit;
uint8_t contrast;
bool inverted;
uint8_t dirty_page_mask;
esp_err_t last_error;
} local_display_snapshot_t;
typedef void (*local_display_scan_callback_t)(uint8_t address_7bit, void *context);
/* Set up I2C0 on the board-profile pins. No display probe occurs here. */
esp_err_t local_display_init(void);
/* Probe standard OLED addresses and initialize the first responding display. */
esp_err_t local_display_start(void);
/* Select and initialize one supported 7-bit address (0x3c or 0x3d). */
esp_err_t local_display_start_at(uint8_t address_7bit);
/* Turn off the panel while preserving the I2C bus for later diagnostics/restart. */
esp_err_t local_display_stop(void);
esp_err_t local_display_get_snapshot(local_display_snapshot_t *snapshot);
esp_err_t local_display_probe_expected(uint8_t *address_7bit);
/* Bounded scan of usable 7-bit addresses 0x08 through 0x77. */
esp_err_t local_display_scan(local_display_scan_callback_t callback,
void *context,
size_t *responding_count);
esp_err_t local_display_set_contrast(uint8_t contrast);
esp_err_t local_display_set_inverted(bool inverted);
/*
* A frame holds only the display's own mutex and is owned by the task that
* begins it. Callers must never retain a service/broker mutex while beginning
* or ending a frame. Only the owning task may end or cancel it; end sends only
* modified 8-pixel pages and releases the display mutex on all outcomes.
*/
esp_err_t local_display_frame_begin(void);
esp_err_t local_display_frame_end(void);
void local_display_frame_cancel(void);
/* Drawing coordinates are panel-local and are clipped to the selected panel. */
void local_display_frame_clear(local_display_panel_t panel);
void local_display_frame_clear_all(void);
void local_display_frame_set_pixel(local_display_panel_t panel,
uint8_t x,
uint8_t y,
bool on);
void local_display_frame_draw_text(local_display_panel_t panel,
uint8_t x,
uint8_t y,
const char *text);
#ifdef __cplusplus
}
#endif