Firmware Runtime

App runtime src/sys/app_runtime.h
enum Screen

Enumerates shell screens. Apps use SCREEN_APP plus AppDefinition metadata.

enum Screen {
    SCREEN_HOME = 0,
    SCREEN_T9_KEYBOARD = 2,
    SCREEN_QWERTY_ZOOM_KEYBOARD = 3,
    SCREEN_MENU = 4,
    SCREEN_APP = 5,
};
enum MenuCategory

Groups launcher entries into menu pages.

enum MenuCategory {
    MENU_GAMES,
    MENU_APPS,
    MENU_NETWORK,
};
enum class AppEventResult

Normalized outcome for app hooks and runtime button handlers.

enum class AppEventResult : uint8_t {
    Unhandled,
    Handled,
    Dirty,
    QuitRequested,
    GoHome,
    GoMenu,
    Reboot,
};
enum class PeriodicWakeLevel

Initialization tier available to a periodic hook during a deep-sleep wake.

enum class PeriodicWakeLevel : uint8_t {
    Basic = 1,
    System = 2,
    Network = 3,
};
enum class PeriodicDisplayMode

E-paper initialization requested independently from a periodic wake tier.

enum class PeriodicDisplayMode : uint8_t {
    None = 0,
    Partial = 1,
    Full = 2,
};
enum class PeriodicTaskAction

Result returned by one invocation of an app's periodic hook.

enum class PeriodicTaskAction : uint8_t {
    Complete = 0,
    RequestSystem = 1,
    RequestNetwork = 2,
    WakeDevice = 3,
    WakeApp = 4,
};
struct PeriodicTaskContext

Read-only capabilities and clock state supplied to a periodic hook.

struct PeriodicTaskContext {
    int64_t localUnix = 0;
    uint16_t intervalMinutes = 0;
    PeriodicWakeLevel wakeLevel = PeriodicWakeLevel::Basic;
    PeriodicDisplayMode displayMode = PeriodicDisplayMode::None;
    bool clockSet = false;
    bool wifiPreferred = false;
    bool wifiConnected = false;
    bool lowBattery = false;
    Adafruit_GFX *display = nullptr;
};
struct PeriodicTaskSchedule

Static schedule for the single periodic hook an app may register.

struct PeriodicTaskSchedule {
    uint16_t intervalMinutes = 0;
    PeriodicWakeLevel wakeLevel = PeriodicWakeLevel::Basic;
    PeriodicDisplayMode displayMode = PeriodicDisplayMode::None;
};
class ActiveApp

Common runtime interface used to draw apps and dispatch touch input.

class ActiveApp {
    virtual ~ActiveApp() = default;
    virtual void draw(Adafruit_GFX &gfx) = 0;
    virtual bool handleTouch(const TouchPoint &point) = 0;
    virtual bool update();
    virtual AppEventResult consumePendingEvent();
    virtual bool consumeDirtyRegion(int16_t *, int16_t *, int16_t *, int16_t *);
    virtual bool hasActiveSession() const = 0;
};
class template AppScreen

Adapts an app object with touch support to the ActiveApp runtime contract.

template <typename T, bool SupportsUpdate = false> class AppScreen : public ActiveApp {
    explicit AppScreen(T &target);
    void draw(Adafruit_GFX &gfx) override;
    bool handleTouch(const TouchPoint &point) override;
    bool update() override;
    AppEventResult consumePendingEvent() override;
    bool consumeDirtyRegion(int16_t *x, int16_t *y, int16_t *w, int16_t *h) override;
    bool hasActiveSession() const override;
};
class template TouchlessAppScreen

Adapts an app object that draws itself and exposes session state, while handling input through its own app-specific path instead of ActiveApp.

template <typename T> class TouchlessAppScreen : public ActiveApp {
    explicit TouchlessAppScreen(T &target);
    void draw(Adafruit_GFX &gfx) override;
    bool handleTouch(const TouchPoint &) override;
    bool hasActiveSession() const override;
};
typedef AppCallback

Pointer to a parameterless app hook such as onEnter, onExit, launch, or reset.

typedef void (*AppCallback)();
typedef AppVisibleHandler

Reports whether an app should appear in the launcher, such as when the Files app is only available while an SD card is mounted.

typedef bool (*AppVisibleHandler)();
typedef AppEventHandler

Handles a button event such as onMenu or onPowerLong and returns an AppEventResult like GoHome or Reboot.

typedef AppEventResult (*AppEventHandler)();
typedef AppRawTouchHandler

Receives raw touch events before higher-level app dispatch.

typedef void (*AppRawTouchHandler)(const TouchEvent &event);
typedef AppSaveContextHandler

Saves app-owned state into a caller-provided buffer.

typedef size_t (*AppSaveContextHandler)(uint8_t *buffer, size_t capacity);
typedef AppRestoreContextHandler

Restores app-owned state from a previously saved buffer.

typedef void (*AppRestoreContextHandler)(const uint8_t *buffer, size_t length);
struct AppBehavior

Bundles runtime callbacks for one app, including lifecycle hooks like onEnter, onExit, and onRelease, button handlers such as onMenu and onPowerLong, raw touch handling, and state save/restore.

struct AppBehavior {
    AppCallback onEnter = nullptr;
    AppCallback onExit = nullptr;
    AppEventHandler onMenu = nullptr;
    AppEventHandler onMenuDouble = nullptr;
    AppEventHandler onMenuLong = nullptr;
    AppEventHandler onPower = nullptr;
    AppEventHandler onPowerDouble = nullptr;
    AppEventHandler onPowerLong = nullptr;
    AppRawTouchHandler onRawTouch = nullptr;
    AppSaveContextHandler onSaveContext = nullptr;
    AppRestoreContextHandler onRestoreContext = nullptr;
    AppPeriodicHandler onPeriodic = nullptr;
    PeriodicTaskSchedule periodic = {};
    AppCallback onRelease = nullptr;
};
struct AppDefinition

Declares one app entry together with launcher metadata, including optional icon-font rendering and visibility conditions, the per-launch reset/launch hooks that run before switchTo(), and the AppBehavior callback bundle used after the app becomes active.

struct AppDefinition {
    const char *id;
    const char *label;
    const char *icon;
    MenuCategory category;
    ActiveApp *runtime;
    AppVisibleHandler visible = nullptr;
    bool iconFont = false;
    AppCallback launch = nullptr;
    AppCallback reset = nullptr;
    AppBehavior behavior = {};
    uint32_t inactivityDeepSleepMs = 0;
};
struct MenuState

Stores the current launcher category and page for returning to the menu.

struct MenuState {
    MenuCategory category;
    uint8_t page;
};
Built-in apps src/sys/builtin_apps.h

Public catalog API for built-in and external launcher apps. Built-in app definitions are assembled in builtin_apps.cpp. Each entry sets its launcher metadata directly, including optional icon-font rendering and visibility conditions. The behavior builder below keeps callback composition consistent without growing one-off behavior factories.

struct AppCatalogEntry

Runtime-facing copy of one launcher entry from the built-in and external app catalogs.

struct AppCatalogEntry {
    AppDefinition definition;
    char id[24];
    char label[16];
    char icon[2];
};
function dirtyIfHandled

Converts bool-returning app handlers into AppEventResult values for catalog behavior callbacks.

inline AppEventResult dirtyIfHandled(bool handled);
function template saveAppContext

Saves app-owned context through a concrete app instance.

template <typename T, T &App> size_t saveAppContext(uint8_t *buffer, size_t capacity);
function template restoreAppContext

Restores app-owned context through a concrete app instance.

template <typename T, T &App> void restoreAppContext(const uint8_t *buffer, size_t length);
function template dirtyIfHandledMethod

Adapts a bool-returning app method to an AppEventResult callback.

template <typename T, T &App, bool (T::*Handler)()> AppEventResult dirtyIfHandledMethod();
struct BehaviorBuilder

Fluent builder for AppBehavior values used by the built-in app catalog.

struct BehaviorBuilder {
    AppBehavior behavior = {};
    BehaviorBuilder withEnter(AppCallback handler) const;
    BehaviorBuilder withExit(AppCallback handler) const;
    BehaviorBuilder withMenuBtn(AppEventHandler menu, AppEventHandler menuDouble = nullptr, AppEventHandler menuLong = nullptr) const;
    BehaviorBuilder withPowerBtn(AppEventHandler handler) const;
    BehaviorBuilder withRawTouch(AppRawTouchHandler handler) const;
    BehaviorBuilder withContext(AppSaveContextHandler save, AppRestoreContextHandler restore) const;
    BehaviorBuilder withPeriodic( AppPeriodicHandler handler, uint16_t intervalMinutes, PeriodicWakeLevel wakeLevel = PeriodicWakeLevel::Basic, PeriodicDisplayMode displayMode = PeriodicDisplayMode::None) const;
    BehaviorBuilder withRelease(AppCallback handler) const;
    AppBehavior build(const AppBehavior *behaviorOverride = nullptr) const;
};
function defaultBehavior

Starts behavior composition with the runtime defaults.

inline BehaviorBuilder defaultBehavior();
function template defaultContextBehavior

Starts behavior composition with save and restore callbacks for one app instance.

template <typename T, T &App> BehaviorBuilder defaultContextBehavior();
function appCatalogCount

Counts visible apps in one menu category after visibility filters are applied.

size_t appCatalogCount(MenuCategory category);
function tryGetVisibleAppAtIndex

Looks up the app shown in a launcher slot and writes it into out; returns false if no app exists there.

bool tryGetVisibleAppAtIndex(MenuCategory category, size_t index, AppCatalogEntry &out);
function appCatalogAllCount

Counts every installed app, including the SUN-button app hidden from the launcher.

size_t appCatalogAllCount();
function tryGetAppAtIndex

Looks up an installed app by stable catalog order without visibility filtering.

bool tryGetAppAtIndex(size_t index, AppCatalogEntry &out);
function findAppById

Looks up an app by stable id across built-in and external app catalogs, even when the app is hidden from the launcher because it is the quick-access app.

bool findAppById(const char *id, AppCatalogEntry &out);
function builtInAppDefinitionCount

Counts built-in definitions without touching the SD-backed external catalog.

size_t builtInAppDefinitionCount();
function builtInAppDefinitionAt

Returns one immutable built-in definition, or nullptr when out of range.

const AppDefinition *builtInAppDefinitionAt(size_t index);
function refreshAppCatalog

Rebuilds cached catalog state after config, storage, or external apps change.

void refreshAppCatalog();
function takePendingPinkExecLaunchPath

Takes the pending .pink executable launch path from the files app.

bool takePendingPinkExecLaunchPath(char *path, size_t pathSize);
function takePendingPocketInkJSLaunchPath

Takes the pending PocketInkJS source launch path from the files app.

bool takePendingPocketInkJSLaunchPath(char *path, size_t pathSize);
function resetApps

Resets all app-owned runtime state.

void resetApps();
Display src/sys/app_display.h
class AppDisplay

Adafruit_GFX-backed display wrapper for full and partial e-paper updates.

class AppDisplay : public Adafruit_GFX {
    AppDisplay();
    void begin();
    void beginColdPartial();
    void beginRetainedPartial();
    void drawPixel(int16_t x, int16_t y, uint16_t color) override;
    void drawBlackPixelUnchecked(int16_t x, int16_t y);
    void drawBlackBlock2x2Unchecked(int16_t x, int16_t y);
    void flush();
    void flushPartial();
    void clear();
    void seedPartialBothImages();
    void requestFullRefresh();
    void lock();
    void unlock();
    const uint8_t *framebufferData() const;
    size_t framebufferSize() const;
};
System stage service src/sys/services/system_stage_service.h
class SystemStageService

Initializes level-2 system services shared by regular and periodic boots. Audio GPIOs become available in a powered-off state; playback activates them.

class SystemStageService {
    void initialize();
};
Periodic wake service src/sys/services/periodic_wake_service.h
struct PeriodicWakeHooks

App-level actions needed when a periodic wake reaches a terminal state.

struct PeriodicWakeHooks {
    bool (*batteryCutoffReached)() = nullptr;
    void (*shutdownForLowBattery)() = nullptr;
    void (*prepareForPowerTransition)() = nullptr;
};
class PeriodicWakeService

Coordinates the staged hardware initialization and dispatch for timer wakes. Scheduling and retained-state rules remain in periodic_tasks.

class PeriodicWakeService {
    PeriodicWakeService(AppDisplay &display, SystemStageService &systemStage, const PeriodicWakeHooks &hooks);
    void registerSystemTasks(uint8_t timeSyncIntervalHours = 24);
    void enterSleepClockDeepSleep();
    bool handleTimerWake();
    bool displayInitialized() const;
};
Device controls src/sys/services/device_controls.h
struct DeviceControlSnapshot

Snapshot of user-facing hardware toggles shown by status and settings UI, used by quick settings and power dialog display.

struct DeviceControlSnapshot {
    bool bluetoothOn = false;
    uint16_t cpuMhz = 240;
    uint8_t volume = 40;
    bool muted = false;
};
function deviceControlsBegin

Initializes device-control state from persisted config and hardware defaults.

void deviceControlsBegin();
function deviceControlsApplyConfig

Applies persisted governor changes without replacing a quick-settings override.

void deviceControlsApplyConfig();
function deviceControlsNoteUserActivity

Raises balanced mode for a fresh touch or physical-button interaction.

void deviceControlsNoteUserActivity();
function deviceControlsUpdate

Lowers balanced mode after inactivity; Wi-Fi keeps a 160 MHz floor.

void deviceControlsUpdate(bool wifiOn);
function deviceControlsSelectedCpuMhz

Selected interactive maximum, including a temporary quick-settings override.

uint16_t deviceControlsSelectedCpuMhz();
function deviceControlsSnapshot

Returns the latest device-control state for display.

DeviceControlSnapshot deviceControlsSnapshot();
function deviceControlsRestoreAudio

Restores runtime audio controls from retained RTC state.

void deviceControlsRestoreAudio(uint8_t volume, bool muteState);
function toggleBluetooth

Toggles the Bluetooth preference and hardware state when supported.

void toggleBluetooth();
function cycleCpuFrequency

Advances the runtime CPU maximum without persisting the selection.

void cycleCpuFrequency();
function deviceEffectiveOutputVolumePercent

Returns source volume scaled by the current output volume and mute state.

uint8_t deviceEffectiveOutputVolumePercent(uint8_t sourceVolumePercent);
function deviceEffectiveAlarmVolumePercent

Returns current output volume, using a minimum audible gain while muted.

uint8_t deviceEffectiveAlarmVolumePercent(uint8_t sourceVolumePercent);
function volumeDown

Decreases runtime output volume by one UI step.

void volumeDown();
function volumeUp

Increases runtime output volume by one UI step.

void volumeUp();
function toggleMute

Toggles mute while preserving the configured volume level.

void toggleMute();
Power control src/sys/services/power_control.h
function releasePowerHolds

Releases transient holds before entering a low-power or shutdown path.

void releasePowerHolds();
function keepPowerLatchOn

Keeps the hardware power latch asserted while firmware is running.

void keepPowerLatchOn();
function prepareWakePowerDefaults

Restores GPIO defaults expected immediately after wake.

void prepareWakePowerDefaults();
function disableWirelessForSleep

Disables wireless peripherals before sleep or shutdown.

void disableWirelessForSleep();
function rebootDevice

Reboots the device through the platform reset path.

void rebootDevice();
function powerOffDevice

Powers the device down after preparing peripherals for shutdown.

void powerOffDevice();
function emergencyPowerOffDevice

Powers down through the shortest path for emergency button holds.

void emergencyPowerOffDevice();
function enterDeepSleep

Enters deep sleep, optionally keeping e-paper powered for display retention.

void enterDeepSleep(uint64_t timerWakeupUs = 0, bool keepEpdPowerOn = false);
function deepSleepWokeFromTimer

Reports whether the current boot was caused by a deep-sleep timer wake.

bool deepSleepWokeFromTimer();
function deviceResetReason

Platform reset reason used by the retained wake trace.

int16_t deviceResetReason();
function deviceWakeupCause

Platform wakeup cause used by the retained wake trace.

int16_t deviceWakeupCause();
Lockscreen guard src/sys/services/lockscreen_guard.h
function lockscreenGuardAcquire

Adds one active hold that prevents inactivity-triggered sleep.

void lockscreenGuardAcquire();
function lockscreenGuardRelease

Releases one inactivity-sleep hold.

void lockscreenGuardRelease();
function inactivitySleepKeepAwake

Resets the inactivity timer after user activity or foreground work.

void inactivitySleepKeepAwake();
function inactivitySleepBlocked

Returns true when sleep is blocked by holds or recent keep-awake activity.

bool inactivitySleepBlocked(uint32_t graceMs = 0);
class LockscreenGuard

RAII helper that keeps the lockscreen awake for the lifetime of a scope.

class LockscreenGuard {
    LockscreenGuard();
    ~LockscreenGuard();
    LockscreenGuard(const LockscreenGuard &) = delete;
    LockscreenGuard &operator=(const LockscreenGuard &) = delete;
};
PSRAM src/sys/psram_allocator.h

Small allocation policy helpers for large firmware data structures. They prefer ESP32 PSRAM, offer explicit fallback orderings for constrained paths, and map to the standard heap in host builds so the same code remains testable.

function allocate

Allocates only from PSRAM on ESP32, with no internal-memory fallback.

inline void *allocate(size_t bytes);
function allocateOrDefault

Prefers PSRAM, then permits any 8-bit-capable heap as a fallback.

inline void *allocateOrDefault(size_t bytes);
function allocateOrInternal

Prefers PSRAM, then explicitly falls back to internal 8-bit memory.

inline void *allocateOrInternal(size_t bytes);
function allocateInternalOrPsram

Prefers low-latency internal memory and uses PSRAM only when necessary.

inline void *allocateInternalOrPsram(size_t bytes);
function reallocateOrDefault

Resizes a block preferring PSRAM, then the default 8-bit heap.

inline void *reallocateOrDefault(void *memory, size_t bytes);
function reallocate

Resizes a block in PSRAM without changing the allocation policy.

inline void *reallocate(void *memory, size_t bytes);
function release

Releases memory returned by any allocator in this namespace.

inline void release(void *memory);

System State

System config src/sys/system_config.h
constant CONFIG_VALUE_MAX

Maximum stored length for a single string config value, including terminator.

static const uint16_t CONFIG_VALUE_MAX = 96;
constant CONFIG_WIFI_SAVED_MAX

Number of Wi-Fi network slots persisted for automatic reconnect.

static const uint8_t CONFIG_WIFI_SAVED_MAX = 3;
constant CONFIG_LOCKSCREEN_INACTIVITY_MAX_MINUTES

Largest supported inactivity timeout for the uint8_t setting, in minutes.

static const uint8_t CONFIG_LOCKSCREEN_INACTIVITY_MAX_MINUTES = UINT8_MAX;
constant CONFIG_PERIODIC_INTERVAL_MIN_MINUTES

Supported periodic-task interval range in whole minutes.

static const uint16_t CONFIG_PERIODIC_INTERVAL_MIN_MINUTES = 1;
constant CONFIG_PERIODIC_INTERVAL_MAX_MINUTES
static const uint16_t CONFIG_PERIODIC_INTERVAL_MAX_MINUTES = 24U * 60U;
constant PERIODIC_TASK_CPU_MHZ

Fixed hardware policy for low-power periodic wakes.

static const uint16_t PERIODIC_TASK_CPU_MHZ = 80;
constant PERIODIC_WIFI_CPU_MHZ
static const uint16_t PERIODIC_WIFI_CPU_MHZ = 160;
constant PERIODIC_LOW_BATTERY_PERCENT
static const uint8_t PERIODIC_LOW_BATTERY_PERCENT = 15;
function static_assert
static_assert(PERIODIC_LOW_BATTERY_PERCENT < 20, "Periodic low-battery threshold must stay below 20%");
enum ConfigCpuGovernor

CPU frequency policy stored in system config.

enum ConfigCpuGovernor : uint8_t {
    CONFIG_CPU_FIXED,
    CONFIG_CPU_BALANCED,
};
enum ConfigTimeFormat

User-selected clock display format.

enum ConfigTimeFormat : uint8_t {
    CONFIG_TIME_24H,
    CONFIG_TIME_12H,
};
enum ConfigDateFormat

User-selected date display format.

enum ConfigDateFormat : uint8_t {
    CONFIG_DATE_ISO,
    CONFIG_DATE_MDY,
    CONFIG_DATE_DMY,
    CONFIG_DATE_DMY_DOT,
    CONFIG_DATE_WEEKDAY,
};
enum ConfigTimeSyncProtocol

Network protocol used to set the local clock.

enum ConfigTimeSyncProtocol : uint8_t {
    CONFIG_TIME_SYNC_HTTPS,
    CONFIG_TIME_SYNC_NTP,
};
struct ConfigWifiSavedNetwork

Persisted Wi-Fi credentials for one remembered network.

struct ConfigWifiSavedNetwork {
    char ssid[33];
    char password[64];
    char bssid[18];
};
struct SystemConfig

Complete persisted system configuration loaded at boot.

struct SystemConfig {
    struct { char ssid[64]; char password[64]; char displayName[24]; bool autoConnect; uint8_t autoOffMinutes; ConfigWifiSavedNetwork saved[CONFIG_WIFI_SAVED_MAX]; } wifi;
    struct { char sunBtnApp[32]; char widgets[CONFIG_VALUE_MAX]; } home;
    char layout[16];
    struct { char topIcon[2]; bool showDate; uint8_t inactivityMinutes; } lockscreen;
    struct { uint16_t mhz; ConfigCpuGovernor governor; } cpu;
    struct { ConfigTimeFormat timeFormat; ConfigDateFormat dateFormat; ConfigTimeSyncProtocol syncProtocol; uint8_t syncIntervalHours; int32_t lastUtcOffsetSeconds; char timezone[32]; char syncServer[96]; } time;
    struct { float temperatureOffsetC; char unit[2]; } sensors;
    struct { uint16_t minIntervalMinutes; bool disableOnLowBattery; } periodic;
};
function configBegin

Initializes config storage and loads the active configuration.

void configBegin();
function configLoadDefaults

Replaces active configuration with built-in defaults.

void configLoadDefaults();
function configReload

Reloads config from persistent storage.

void configReload();
function currentSystemConfig

Returns the active read-only system configuration.

const SystemConfig &currentSystemConfig();
function configParseLockscreenInactivityMinutes

Parses a whole-minute inactivity timeout in the supported 0–255 range.

bool configParseLockscreenInactivityMinutes(const char *value, uint8_t &out);
function configParseUtcOffset

Parses UTC, auto, or a fixed UTC offset such as UTC+02:30.

bool configParseUtcOffset(const char *value, int32_t &out);
function configEffectiveUtcOffset

Returns the configured fixed offset, or the last network-provided offset when timezone is automatic.

int32_t configEffectiveUtcOffset();
function configRememberUtcOffset

Persists the latest trusted network UTC offset for automatic timezone use.

bool configRememberUtcOffset(int32_t offsetSeconds);
function configGet

Reads a raw config value by key into out.

bool configGet(const char *key, char *out, size_t outSize);
function configSet

Writes a raw config value by key.

bool configSet(const char *key, const char *value);
function configRemove

Removes a raw config value by key.

bool configRemove(const char *key);
function configGetForApp

Reads a raw string value from the config file scoped to a single app id. Does not validate the value or apply an app setting default; use appConfigGet for schema-aware reads with validation and defaults.

bool configGetForApp(const char *appId, const char *key, char *out, size_t outSize);
function configSetForApp

Writes a raw string value to the config file scoped to a single app id. Does not validate the value against an AppConfigSetting schema; use appConfigSet for schema-aware writes.

bool configSetForApp(const char *appId, const char *key, const char *value);
RTC context src/sys/rtc_context.h
constant RTC_CONTEXT_APP_CAPACITY

Maximum bytes reserved in RTC memory for app-owned suspend state.

static const size_t RTC_CONTEXT_APP_CAPACITY = 4096;
constant RTC_CONTEXT_APP_ID_SIZE

Maximum stored app id length in RTC navigation context, including terminator.

static const size_t RTC_CONTEXT_APP_ID_SIZE = 24;
struct RtcNavigationContext

Navigation state preserved across deep sleep.

struct RtcNavigationContext {
    Screen screen;
    MenuCategory menuCategory;
    uint8_t menuPage;
    bool hasActiveApp;
    char appId[RTC_CONTEXT_APP_ID_SIZE];
};
struct RtcSystemContext

System-level state preserved across deep sleep.

struct RtcSystemContext {
    bool clockSet;
    int64_t clockLocalUnix;
    int32_t clockUtcOffsetSeconds;
    bool wifiOn;
    uint8_t volume;
    bool muted;
};
struct RtcAppContext

App-owned state blob preserved across deep sleep.

struct RtcAppContext {
    uint16_t appDataLength;
    uint8_t appData[RTC_CONTEXT_APP_CAPACITY];
};
struct RtcContextSnapshot

Full RTC context payload saved before deep sleep.

struct RtcContextSnapshot {
    RtcNavigationContext navigation;
    RtcSystemContext system;
    RtcAppContext app;
};
class RtcBitWriter

Bit-packed writer used to keep RTC snapshots small and versionable.

class RtcBitWriter {
    RtcBitWriter(uint8_t *buffer, size_t capacity);
    bool writeBits(uint32_t value, uint8_t bitCount);
    bool ok() const;
    size_t bytesWritten() const;
};
class RtcBitReader

Bit-packed reader matching RtcBitWriter encoding.

class RtcBitReader {
    RtcBitReader(const uint8_t *buffer, size_t length);
    bool readBits(uint8_t bitCount, uint32_t &value);
    bool ok() const;
};
function rtcContextSave

Saves a complete RTC snapshot for restoration after deep sleep.

bool rtcContextSave(const RtcContextSnapshot &snapshot);
function rtcContextLoad

Loads a previously saved RTC snapshot.

bool rtcContextLoad(RtcContextSnapshot &snapshot);
function rtcContextClear

Clears any saved RTC snapshot.

void rtcContextClear();
Sleep clock context src/sys/sleep_clock_context.h
struct SleepClockSnapshot

Minimal clock context used by periodic sleep/wake clock updates.

struct SleepClockSnapshot {
    bool active;
    bool clockSet;
    bool timeEstimated;
    int64_t localUnix;
    int32_t utcOffsetSeconds;
    uint16_t wakeIntervalSeconds;
    bool previousFrameValid;
    ConfigTimeFormat timeFormat;
};
function sleepClockContextStart

Starts periodic sleep clock mode with the current clock state.

void sleepClockContextStart(bool clockSet, bool timeEstimated, int64_t localUnix, int32_t utcOffsetSeconds, uint16_t wakeIntervalSeconds, ConfigTimeFormat timeFormat);
function sleepClockContextLoad

Loads periodic sleep clock state after wake.

bool sleepClockContextLoad(SleepClockSnapshot &snapshot);
function sleepClockContextUpdate

Updates periodic sleep clock state before returning to sleep.

void sleepClockContextUpdate(bool clockSet, bool timeEstimated, int64_t localUnix, int32_t utcOffsetSeconds, uint16_t wakeIntervalSeconds, ConfigTimeFormat timeFormat, bool previousFrameValid = true);
function sleepClockContextClear

Clears periodic sleep clock state.

void sleepClockContextClear();
Periodic tasks src/sys/periodic_tasks.h
struct PeriodicWakePolicy

Runtime policy copied from system config and retained for level-1 wakes.

struct PeriodicWakePolicy {
    uint16_t minIntervalMinutes = 1;
    uint8_t timeSyncIntervalHours = 24;
    bool disableOnLowBattery = true;
};
struct PeriodicRetainedSnapshot

Small POD summary retained across deep sleep; no runtime pointers are kept.

struct PeriodicRetainedSnapshot {
    PeriodicWakePolicy policy;
    int64_t lastDispatchMinute = -1;
    int64_t pinkNextDueMinute = -1;
    uint32_t pendingWakeAppHash = 0;
    bool wifiPreferred = false;
    bool pinkRegistered = false;
};
struct PeriodicSystemTaskDefinition

One OS-owned task registration. The registry is rebuilt early on every boot.

struct PeriodicSystemTaskDefinition {
    const char *id = nullptr;
    PeriodicTaskSchedule schedule;
    AppPeriodicHandler onPeriodic = nullptr;
};
struct PeriodicTaskStats

Compact aggregate retained for profiling without storing task-name strings.

struct PeriodicTaskStats {
    uint16_t idHash = 0;
    uint16_t totalDuration10Ms = 0;
    uint16_t runCount = 0;
};
struct PeriodicTaskMeasurement

Start sample used to attribute elapsed time to one hook.

struct PeriodicTaskMeasurement {
    uint32_t startedAtMs = 0;
    bool shouldRun = true;
};
function periodicEffectiveIntervalMinutes

Normalizes a requested cadence against the OS policy and 1-minute/1-day limits.

uint16_t periodicEffectiveIntervalMinutes(uint16_t requestedMinutes, uint16_t policyMinimumMinutes);
function periodicTaskDueAtMinute

Uses epoch-aligned whole-minute buckets so schedules do not drift across sleep.

bool periodicTaskDueAtMinute(int64_t localMinute, uint16_t intervalMinutes);
function periodicTaskDueBetweenMinutes

Reports whether an aligned due minute falls in (previousMinute, currentMinute].

bool periodicTaskDueBetweenMinutes(int64_t previousMinute, int64_t currentMinute, uint16_t intervalMinutes);
function periodicNextDueMinute

Returns the first aligned minute strictly after currentMinute.

int64_t periodicNextDueMinute(int64_t currentMinute, uint16_t intervalMinutes);
function periodicPolicyFromConfig

Builds the low-power wake policy from the active system configuration.

PeriodicWakePolicy periodicPolicyFromConfig(const SystemConfig &config);
function periodicSystemTasksReset

Clears the boot-local OS task registry before system services repopulate it.

void periodicSystemTasksReset();
function periodicSystemTaskRegister

Registers one static-lifetime OS task; duplicate ids replace their pointer.

bool periodicSystemTaskRegister(const PeriodicSystemTaskDefinition &task);
function periodicTaskMeasurementStart

Starts/finishes compact profiling around a periodic callback.

PeriodicTaskMeasurement periodicTaskMeasurementStart(const char *taskId);
function periodicTaskMeasurementFinish
void periodicTaskMeasurementFinish(const char *taskId, const PeriodicTaskMeasurement &measurement);
function periodicTaskStatsCount

Enumerates retained profiling aggregates for diagnostics UIs/tools.

size_t periodicTaskStatsCount();
function periodicTaskStatsAt
bool periodicTaskStatsAt(size_t index, PeriodicTaskStats &out);
function periodicRetainedPrepareForSleep

Saves current policy and external-task summary immediately before deep sleep.

void periodicRetainedPrepareForSleep(const PeriodicWakePolicy &policy, bool wifiPreferred, bool pinkRegistered, int64_t pinkNextDueMinute);
function periodicRetainedLoad

Loads a validated retained snapshot after a timer wake.

bool periodicRetainedLoad(PeriodicRetainedSnapshot &snapshot);
function periodicRetainedUpdate

Refreshes policy and external-task summary after level-2 config/SD init.

void periodicRetainedUpdate(const PeriodicWakePolicy &policy, bool pinkRegistered, int64_t pinkNextDueMinute);
function periodicRetainedClaimDispatchMinute

Atomically claims one minute for dispatch and rejects duplicate timer wakes.

bool periodicRetainedClaimDispatchMinute(int64_t localMinute);
function periodicRetainedRememberWakeApp

Persists a WakeApp outcome before later tasks can crash the same wake.

void periodicRetainedRememberWakeApp(const char *appId);
function periodicRetainedTakeWakeApp

Resolves and clears a retained WakeApp target after the app catalog is ready.

bool periodicRetainedTakeWakeApp(char *appId, size_t appIdSize);
class PeriodicWakeSession

One timer-wake dispatch over all statically registered built-in hooks.

class PeriodicWakeSession {
    PeriodicWakeSession(int64_t localUnix, int64_t previousDispatchMinute, bool clockSet, const PeriodicWakePolicy &policy, bool wifiPreferred, bool lowBattery);
    PeriodicWakeLevel nextWakeLevel() const;
    PeriodicDisplayMode displayModeFor(PeriodicWakeLevel level) const;
    void dispatch(PeriodicWakeLevel level, Adafruit_GFX *display, bool wifiConnected);
    PeriodicDisplayMode takeDisplayUpdate();
    bool hasPendingTasks() const;
    bool shouldWakeDevice() const;
    const char *wakeAppId() const;
    int64_t localMinute() const;
};
SD storage src/sys/services/sd_storage.h
struct SdStorageSnapshot

Last known SD-card mount and capacity state.

struct SdStorageSnapshot {
    bool mounted = false;
    uint32_t totalGb = 0;
    uint32_t freeGb = 0;
};
function sdStorageBegin

Initializes SD storage support.

void sdStorageBegin();
function sdStorageEnd

Unmounts SD storage and releases related resources.

void sdStorageEnd();
function sdStorageRequestRefresh

Marks SD storage state stale so the next update probes the card.

void sdStorageRequestRefresh();
function sdStorageUpdate

Refreshes mount and capacity state; returns true when the snapshot changed.

bool sdStorageUpdate();
function sdStorageMounted

Returns true when SD storage is currently mounted.

bool sdStorageMounted();
function currentSdStorageSnapshot

Returns the last cached SD storage snapshot.

const SdStorageSnapshot &currentSdStorageSnapshot();
App Settings src/sys/app_config.h

Declares the schema registry used by built-in apps to expose their settings in the system Settings app. Schemas stay in flash; values are validated and read from or written to app-scoped configuration files on demand.

enum class AppConfigType

Storage and editor representation for one app-owned setting.

enum class AppConfigType : uint8_t {
    Bool, Int, Float, String, OneOf,
};
struct AppConfigOption

One labelled value for an AppConfigType::OneOf setting.

struct AppConfigOption {
    const char *label;
    const char *value;
};
struct AppConfigSetting

Read-only metadata that an app registers with the Settings app. Definitions should be const so they remain in flash. Values themselves are persisted lazily in /cfg/app-<id>.cfg and are never cached here.

struct AppConfigSetting {
    const char *key;
    const char *label;
    AppConfigType type;
    const char *defaultValue;
    const AppConfigOption *options;
    uint8_t optionCount;
    uint8_t inputCapacity;
};
struct AppConfigRegistration

Settings metadata registered by one built-in app.

struct AppConfigRegistration {
    const char *appId;
    const char *label;
    const AppConfigSetting *settings;
    uint8_t settingCount;
};
function appConfigRegistryReset

Clears registrations before built-in apps register their static schemas.

void appConfigRegistryReset();
function appConfigRegister

Adds one static schema. Duplicate registrations are ignored.

bool appConfigRegister(const AppConfigRegistration &registration);
function appConfigRegistrationCount

Returns the number of registered app schemas.

uint8_t appConfigRegistrationCount();
function appConfigRegistrationAt

Returns a registered schema by index, or nullptr when out of range.

const AppConfigRegistration *appConfigRegistrationAt(uint8_t index);
function appConfigGet

Reads an app value, falling back to the registered default when absent or invalid. No per-app values are retained in RAM.

bool appConfigGet(const AppConfigRegistration &registration, const AppConfigSetting &setting, char *out, size_t outSize);
function appConfigGetBool

Reads a registered boolean as a native value, including its default.

bool appConfigGetBool(const AppConfigRegistration &registration, const AppConfigSetting &setting);
function appConfigSet

Validates and persists an app value through the existing app-scoped config.

bool appConfigSet(const AppConfigRegistration &registration, const AppConfigSetting &setting, const char *value);

Shell

Shell controller src/shell/shell_controller.h
struct ShellControllerHooks

Hooks from the sketch runtime into ShellController. These keep platform-level behaviors, such as power transitions and home data refresh, outside the controller while still allowing the shell to coordinate them from button and quick-settings flows.

struct ShellControllerHooks {
    void *context = nullptr;
    void (*refreshHome)(void *context) = nullptr;
    void (*noteUserActivity)(void *context) = nullptr;
    void (*prepareForPowerTransition)(void *context) = nullptr;
    void (*enterSleepClockDeepSleep)(void *context) = nullptr;
    void (*renderPowerOffScreen)(void *context) = nullptr;
};
class ShellController

Main coordinator for the firmware shell. The sketch owns hardware services, then calls this controller for button events, touch dispatch, active app updates, retained context, and redraws. This keeps screen routing and app lifecycle in one place.

class ShellController {
    ShellController(AppDisplay &display, TouchInput &touch, TextInputController &textInput);
    void setHooks(const ShellControllerHooks &hooks);
    Screen currentScreen() const;
    bool shouldRedrawForBatteryRefresh() const;
    unsigned long inactivityDeepSleepMs(unsigned long defaultMs) const;
    void markDirty();
    void clampMenu();
    void switchTo(Screen next, ActiveApp *nextApp = nullptr, const AppDefinition *nextDefinition = nullptr);
    void handleMenuButton();
    void handleMenuDoubleButton();
    void handleMenuLongButton();
    void handlePowerSingleButton();
    void handlePowerDoubleButton();
    void handlePowerLongButton();
    bool dispatchTouch();
    bool updateActiveApp();
    bool handlePendingFilesPinkLaunch();
    bool wakeAppById(const char *id);
    void handleCatalogChanged();
    void refreshHomeMinuteIfNeeded();
    void renderIfDirty();
    void saveRetainedContextForSleep();
    void restoreRetainedContextAfterSleep();
};
Quick settings src/shell/quick_settings.h
typedef QuickSettingsCallback

Shell-owned side effect invoked by quick settings without coupling to globals.

typedef void (*QuickSettingsCallback)(void *context);
struct QuickSettingsActions

Capability table for actions that QuickSettingsController can request. The controller owns dialog state and hit testing; the shell provides these callbacks for operations that affect power, retained context, or rendering.

struct QuickSettingsActions {
    void *context = nullptr;
    QuickSettingsCallback renderPowerOff = nullptr;
    QuickSettingsCallback prepareForPowerTransition = nullptr;
    QuickSettingsCallback saveRetainedContext = nullptr;
    QuickSettingsCallback enterSleepClock = nullptr;
    QuickSettingsCallback captureScreenshot = nullptr;
};
class QuickSettingsController

Small state machine for the power/quick-settings dialog. ShellController opens this on long power press, asks it for a render snapshot, and forwards touches here so page navigation and device actions stay together.

class QuickSettingsController {
    void open(PowerDialogPage page = PowerDialogPage::Power);
    void close();
    bool isOpen() const;
    PowerDialogSnapshot snapshot() const;
    PowerDialogAction handleTouch(const TouchPoint &point);
    void runAction(PowerDialogAction action, const QuickSettingsActions &actions) const;
};
Shell context src/shell/shell_context.h
struct ShellContextRestoreActions

Restore hooks that let retained context code resume shell state safely. The context module persists only small identifiers. ShellController supplies these callbacks so restore can relaunch apps or switch screens without owning the full controller.

struct ShellContextRestoreActions {
    void *context = nullptr;
    void (*launchApp)(void *context, const AppDefinition &app) = nullptr;
    void (*switchTo)(void *context, Screen screen) = nullptr;
    const AppDefinition *(*activeDefinition)(void *context) = nullptr;
};
function shellContextScreenForSave

Collapses transient screens into the screen value that should survive sleep.

Screen shellContextScreenForSave(Screen screen, bool textInputScreen, const AppDefinition *activeDefinition);
function shellContextSaveForSleep

Persists the current shell/app/menu position into RTC-retained state.

void shellContextSaveForSleep(Screen screen, bool textInputScreen, const AppDefinition *activeDefinition, const MenuState &menuState);
function shellContextRestoreAfterSleep

Replays retained shell state after wake; returns true when a restore happened.

bool shellContextRestoreAfterSleep(MenuState &menuState, const ShellContextRestoreActions &actions);
Shell buttons src/shell/shell_buttons.h

Bridges the two physical device buttons into shell-level click, double-click, and long-press callbacks. A background task samples the GPIO buttons; shellButtonsDispatch() safely delivers the queued events on the main loop.

typedef ShellButtonCallback

Callback signature for a recognized hardware-button gesture.

typedef void (*ShellButtonCallback)();
struct ShellButtonHandlers

Shell actions assigned to each gesture on the menu and power buttons.

struct ShellButtonHandlers {
    ShellButtonCallback onMenu = nullptr;
    ShellButtonCallback onMenuDouble = nullptr;
    ShellButtonCallback onMenuLong = nullptr;
    ShellButtonCallback onPower = nullptr;
    ShellButtonCallback onPowerDouble = nullptr;
    ShellButtonCallback onPowerLong = nullptr;
};
function shellButtonsBegin

Configures button timing, callbacks, and the background GPIO polling task.

void shellButtonsBegin(const ShellButtonHandlers &handlers);
function shellButtonsDispatch

Delivers all queued gestures on the caller's thread; returns true on activity.

bool shellButtonsDispatch();
Shell connectivity src/sys/services/connectivity_service.h

System-facing Wi-Fi service shared by the shell, runtime hosts, and network apps. WifiManager owns the lifecycle; this keeps its compile-time feature boundary and compact presentation helpers in one place.

function wifiStatusIcon

Provides the status-bar glyph for the shared Wi-Fi state.

char wifiStatusIcon();
function wifiIsOn

Reports whether the shell intends Wi-Fi to be enabled, even while connecting.

bool wifiIsOn();
function wifiIsConnected

Reports whether the shared Wi-Fi client currently has a network connection.

bool wifiIsConnected();
function wifiConnectionInProgress

Reports whether a station association attempt is still in progress.

bool wifiConnectionInProgress();
function wifiTurnOn

Enables Wi-Fi from shell UI such as quick settings.

void wifiTurnOn();
function wifiTurnOff

Disables Wi-Fi and lets shell UI reflect the power-saving state.

void wifiTurnOff();
function wifiToggle

Toggles Wi-Fi from the quick-settings device page.

void wifiToggle();
function wifiUpdate

Advances the Wi-Fi service; the shell redraws when the visible state changes.

bool wifiUpdate();
function restoreWifiOn

Reapplies retained Wi-Fi preference after boot or deep-sleep wake.

void restoreWifiOn(bool enabled);
Shell home layout src/shell/shell_home_layout.h
enum ShellLayoutMode

Home-screen density profile loaded from shell configuration.

enum ShellLayoutMode : uint8_t {
    SHELL_LAYOUT_DEFAULT,
    SHELL_LAYOUT_ULTRA_LARGE,
};
enum ShellTemperatureUnit

Display unit for temperature values shown on shell surfaces.

enum ShellTemperatureUnit : uint8_t {
    SHELL_TEMP_CELSIUS,
    SHELL_TEMP_FAHRENHEIT,
};
enum ShellWidget

Bitmask for optional home widgets so low-memory config can stay compact.

enum ShellWidget : uint16_t {
    SHELL_WIDGET_TEMP = 1U << 0,
    SHELL_WIDGET_HUM = 1U << 1,
    SHELL_WIDGET_CPU_TEMP = 1U << 2,
    SHELL_WIDGET_SD = 1U << 3,
    SHELL_WIDGET_BATTERY = 1U << 4,
    SHELL_WIDGET_NOTIFICATIONS = 1U << 5,
    SHELL_WIDGET_LOGO_TEXT = 1U << 6,
    SHELL_WIDGET_BUTTON_HELP = 1U << 7,
    SHELL_WIDGET_WALLPAPER = 1U << 8,
    SHELL_WIDGET_WEATHER = 1U << 9,
};
struct ShellLayoutConfig

User-configurable presentation state for the home screen. This separates persistent layout choices from live sensor/app data so render functions can stay deterministic and easy to test.

struct ShellLayoutConfig {
    ShellLayoutMode layout = SHELL_LAYOUT_DEFAULT;
    ShellTemperatureUnit temperatureUnit = SHELL_TEMP_CELSIUS;
    uint16_t homeWidgets = 0;
};
struct ShellData

Live data passed into shell renderers for one frame. Pointers are non-owning; callers keep sensor/storage snapshots in their service modules and pass the current view here.

struct ShellData {
    StatusBarSnapshot status;
    const BatterySnapshot *battery;
    const EnvironmentSnapshot *environment;
    const SdStorageSnapshot *sd;
};
function shellLayoutConfigReload

Reloads both home and lockscreen presentation config after settings changes.

void shellLayoutConfigReload();
function shellLayoutConfig

Shares the active presentation config with shell render paths.

const ShellLayoutConfig &shellLayoutConfig();
function shellHomeWidgetEnabled

Checks a home-widget bit against the active layout config.

bool shellHomeWidgetEnabled(uint16_t widget);
function drawHomeScreen

Renders the home surface from a live ShellData snapshot.

void drawHomeScreen(AppDisplay &display, const ShellData &data);
Shell menu layout src/shell/shell_menu_layout.h
function previousMenuCategory

Walks categories backward for button navigation.

MenuCategory previousMenuCategory(MenuCategory category);
function nextMenuCategory

Walks categories forward for button navigation.

MenuCategory nextMenuCategory(MenuCategory category);
function menuCategoryTitle

Provides the short category label used by the app menu.

const char *menuCategoryTitle(MenuCategory category);
function clampMenuState

Keeps menu state valid after app catalog or category contents change.

void clampMenuState(MenuState &state);
function moveMenuPrevious

Applies one backward menu step with category-aware wrapping.

void moveMenuPrevious(MenuState &state);
function moveMenuNext

Applies one forward menu step with category-aware wrapping.

void moveMenuNext(MenuState &state);
function drawAppMenu

Renders the category app menu and optional pressed-slot feedback.

void drawAppMenu(AppDisplay &display, const MenuState &state, int8_t pressedSlot = -1);
function hitTestAppMenu

Converts a touch into menu movement or an app selection.

bool hitTestAppMenu(const TouchPoint &point, MenuState &state, AppCatalogEntry &selected, bool &stateChanged, int8_t *hitSlot = nullptr);
Shell dialog layout src/shell/shell_dialog_layout.h
function drawQuitDialog

Overlays the app quit confirmation dialog.

void drawQuitDialog(AppDisplay &display, const StatusBarSnapshot &status);
function quitDialogHitYes

Hit-tests the quit confirmation action.

bool quitDialogHitYes(const TouchPoint &point);
function quitDialogHitNo

Hit-tests the quit cancel action.

bool quitDialogHitNo(const TouchPoint &point);
enum class PowerDialogAction

Semantic actions emitted by the power/quick-settings dialog.

enum class PowerDialogAction : uint8_t {
    None,
    PreviousPage,
    NextPage,
    Reboot,
    PowerOff,
    DeepSleep,
    WifiToggle,
    BluetoothToggle,
    CpuCycle,
    VolumeDown,
    VolumeMute,
    VolumeUp,
    Screenshot,
};
enum class PowerDialogPage

Paged groups in the power/quick-settings dialog.

enum class PowerDialogPage : uint8_t {
    Power,
    Device,
    Volume,
    Screen,
};
struct PowerDialogSnapshot

Live device state displayed by the power/quick-settings dialog.

struct PowerDialogSnapshot {
    PowerDialogPage page = PowerDialogPage::Power;
    bool wifiOn = false;
    bool wifiConnected = false;
    bool bluetoothOn = false;
    uint16_t cpuMhz = 240;
    uint8_t volume = 60;
    bool muted = false;
};
function drawPowerDialog

Renders the power/quick-settings dialog from the supplied snapshot.

void drawPowerDialog(AppDisplay &display, const StatusBarSnapshot &status, const PowerDialogSnapshot &snapshot, PowerDialogAction pressed = PowerDialogAction::None);
function powerDialogHitAction

Converts a dialog touch into a semantic quick-settings action.

PowerDialogAction powerDialogHitAction(const TouchPoint &point, PowerDialogPage page);
function drawPowerOffScreen

Draws the final user-visible frame before powering off.

void drawPowerOffScreen(AppDisplay &display);
function drawLowBatteryScreen

Draws the battery-protection screen used before forced sleep/shutdown.

void drawLowBatteryScreen(AppDisplay &display);
Lockscreen layout src/shell/shell_lockscreen_layout.h

Owns the presentation of the screen shown while the device is entering or remaining in low-power lockscreen mode. It keeps drawing separate from the sleep-clock state machine and exposes the small user-configurable layout.

struct LockscreenLayoutConfig

User-configurable presentation state for the lockscreen/sleep clock.

struct LockscreenLayoutConfig {
    char topIcon = 'S';
    bool showDate = true;
};
function lockscreenLayoutConfigReload

Reloads lockscreen presentation config after settings changes.

void lockscreenLayoutConfigReload();
function lockscreenLayoutConfig

Returns the active lockscreen configuration.

const LockscreenLayoutConfig &lockscreenLayoutConfig();
function drawLockscreenSleepScreen

Draws the simple deep-sleep transition frame.

void drawLockscreenSleepScreen(AppDisplay &display);
function drawLockscreenClockScreen

Draws the low-power lockscreen clock frame.

void drawLockscreenClockScreen(AppDisplay &display, const char *timeText, const char *dateText, bool timeEstimated = false);
Framebuffer capture src/shell/screenshot.h

Exports the e-paper display's live one-bit framebuffer as a timestamped BMP on the SD card. This is the firmware screenshot boundary used by shell UI, including stable result codes suitable for short on-device messages.

enum class ScreenshotResult

Result of exporting the current display buffer to the SD card.

enum class ScreenshotResult : uint8_t {
    Saved,
    NoSdCard,
    NoFramebuffer,
    WriteFailed,
};
function saveFramebufferScreenshot

Writes the current one-bit framebuffer as a BMP under /screenshots. The caller must keep the display framebuffer stable for the duration.

ScreenshotResult saveFramebufferScreenshot(const AppDisplay &display);
function screenshotResultMessage

Provides a short UI-safe message for an unsuccessful screenshot export.

const char *screenshotResultMessage(ScreenshotResult result);

UI

Status bar src/ui/status_bar.h
struct StatusBarSnapshot

Data needed to render the top status bar for shell and app screens. The status bar does not query services directly; callers provide one compact snapshot so app rendering remains predictable and cheap.

struct StatusBarSnapshot {
    const char *dateText;
    const char *timeText;
    const BatterySnapshot *battery;
    char wifiIcon;
    bool usbConnected;
};
function drawStatusBar

Draws date/time, battery, and connectivity indicators into the display.

void drawStatusBar(AppDisplay &display, const StatusBarSnapshot &status);
Text input controller src/ui/text_input_controller.h
class TextInputController

Shared controller for the firmware text-entry modes. Apps switch to these screens instead of owning keyboard widgets directly. The controller keeps the current draft text and routes draw/touch behavior to the selected keyboard implementation.

class TextInputController {
    bool isScreen(Screen screen) const;
    bool toggleCaps(Screen screen);
    Screen nextMode(Screen screen) const;
    void draw(AppDisplay &display, Screen screen);
    bool handleTouch(Screen screen, const TouchPoint &point);
};
UI helpers src/ui/ui_helpers.h
constant UI_PRESS_FEEDBACK_MS
static const unsigned long UI_PRESS_FEEDBACK_MS = 180;
constant UI_TOUCH_ASSIST_PX
static const uint8_t UI_TOUCH_ASSIST_PX = 2;
struct UiPressFeedback

Small helper for pressed feedback in screens without a full component. Screens store an integer control id, call press() from hit testing, and call update() from their loop to know when to redraw the released state.

struct UiPressFeedback {
    int8_t id = -1;
    unsigned long until = 0;
    void clear();
    void press(int8_t nextId, unsigned long durationMs = UI_PRESS_FEEDBACK_MS);
    bool isPressed(int8_t queryId) const;
    bool update();
};
function uiContains

Hit-tests a standard rectangular control using TouchButton semantics.

inline bool uiContains(const UiRect &rect, const TouchPoint &point);
function uiTouchContains

Hit-tests a small visual control with extra invisible touch padding.

inline bool uiTouchContains(const UiRect &rect, const TouchPoint &point, uint8_t touchPadding = UI_TOUCH_ASSIST_PX);
function uiDrawButton

Draws the common compact monochrome text button used across shell screens.

inline void uiDrawButton(Adafruit_GFX &gfx, const UiRect &rect, const char *label, bool pressed = false, uint8_t textSize = 1);
function uiDrawBorderlessIconButton

Draws an icon-only control without a border, retaining pressed feedback.

inline void uiDrawBorderlessIconButton(Adafruit_GFX &gfx, const UiRect &rect, char icon, bool pressed = false);
Touch button src/ui/components/touch_button.h
struct UiRect

Integer rectangle used by touchable UI controls.

struct UiRect {
    int16_t x;
    int16_t y;
    int16_t w;
    int16_t h;
};
enum class TouchButtonShapeType

Built-in shape kinds for touch button rendering and hit testing.

enum class TouchButtonShapeType : uint8_t {
    Rectangle,
    RoundedRectangle,
    Circle,
    Custom,
};
typedef TouchButtonHitTest

Custom touch-button hit-test callback.

typedef bool (*TouchButtonHitTest)(const UiRect &bounds, const TouchPoint &point, void *context);
typedef TouchButtonPainter

Custom touch-button painter callback.

typedef void (*TouchButtonPainter)(Adafruit_GFX &gfx, const UiRect &bounds, bool pressed, void *context);
struct TouchButtonShape

Shape configuration for a touch button.

struct TouchButtonShape {
    TouchButtonShapeType type = TouchButtonShapeType::Rectangle;
    uint8_t radius = 0;
    TouchButtonHitTest hitTest = nullptr;
    TouchButtonPainter painter = nullptr;
    void *context = nullptr;
    static TouchButtonShape rectangle();
    static TouchButtonShape rounded(uint8_t radius);
    static TouchButtonShape circle();
    static TouchButtonShape custom(TouchButtonHitTest hitTest, TouchButtonPainter painter = nullptr, void *context = nullptr);
};
enum class TouchButtonIconPlacement

Icon placement relative to text.

enum class TouchButtonIconPlacement : uint8_t {
    None,
    Only,
    AboveText,
    Left,
    Right,
};
enum class TouchButtonAlign

Alignment value used for button text positioning.

enum class TouchButtonAlign : uint8_t {
    Start,
    Center,
    End,
};
struct TouchButtonContent

Text and icon content for a touch button.

struct TouchButtonContent {
    const char *text = nullptr;
    const char *icon = nullptr;
    TouchButtonIconPlacement iconPlacement = TouchButtonIconPlacement::None;
    bool iconUsesIconFont = true;
    uint8_t iconTextSize = 1;
    TouchButtonAlign textX = TouchButtonAlign::Center;
    TouchButtonAlign textY = TouchButtonAlign::Center;
    uint8_t textSize = 1;
    int8_t textOffsetX = 0;
    int8_t textOffsetY = 0;
    int8_t iconOffsetX = 0;
    int8_t iconOffsetY = 0;
};
struct TouchButtonStyle

Drawing and hit-test style for a touch button.

struct TouchButtonStyle {
    uint8_t color = 1;
    uint8_t backgroundColor = 0;
    uint8_t pressedColor = 0;
    uint8_t pressedBackgroundColor = 1;
    uint8_t padding = 4;
    uint8_t touchPadding = 0;
    bool drawOutline = true;
    bool fillPressed = true;
};
class TouchButton

Reusable touchable button primitive for e-paper UI controls.

class TouchButton {
    TouchButton(const UiRect &bounds, TouchButtonShape shape = TouchButtonShape::rectangle());
    TouchButton(const UiRect &bounds, const TouchButtonContent &content, TouchButtonShape shape = TouchButtonShape::rectangle(), const TouchButtonStyle &style = TouchButtonStyle());
    bool contains(const TouchPoint &point) const;
    void draw(Adafruit_GFX &gfx, bool pressed = false) const;
    const UiRect &bounds() const;
};
Keyboard src/ui/components/keyboard_component.h
enum KeyboardAction

Actions emitted by keyboard hit testing.

enum KeyboardAction {
    KEY_NONE,
    KEY_CHAR,
    KEY_BACKSPACE,
    KEY_SPACE,
    KEY_SHIFT,
    KEY_NAV,
    KEY_OK,
};
struct KeyboardEvent

Keyboard hit-test result.

struct KeyboardEvent {
    KeyboardAction action;
    char value;
};
class KeyboardComponent

Shared contract for keyboard components backed by external text state.

class KeyboardComponent {
    virtual ~KeyboardComponent() = default;
    virtual void draw(Adafruit_GFX &gfx, const String &text) = 0;
    virtual void draw(Adafruit_GFX &gfx, const String &text, int maxLength) = 0;
    virtual KeyboardEvent hitTest(const TouchPoint &point) = 0;
    virtual KeyboardEvent hitTest(const TouchPoint &point, int currentLength, int maxLength) = 0;
    virtual void toggleCaps() = 0;
};
T9 keyboard src/ui/components/t9_keyboard_component.h
class T9KeyboardComponent

Draws and hit-tests a phone-style T9 keyboard.

class T9KeyboardComponent {
    enum class Layout : uint8_t { Text, Numbers, Numeric };
    void draw(Adafruit_GFX &gfx, const String &text);
    void draw(Adafruit_GFX &gfx, const String &text, int maxLength);
    void draw(Adafruit_GFX &gfx, const char *text, int maxLength);
    KeyboardEvent hitTest(const TouchPoint &point, String &text);
    KeyboardEvent hitTest(const TouchPoint &point, String &text, int maxLength);
    KeyboardEvent hitTest(const TouchPoint &point, char *text, int capacity);
    void setLayout(Layout nextLayout);
    bool update();
    void toggleCaps();
};
QWERTY zoom keyboard src/ui/qwerty_zoom/qwerty_zoom_keyboard_component.h
class QwertyZoomKeyboardComponent

Draws and hit-tests a paged zoomed QWERTY keyboard.

class QwertyZoomKeyboardComponent : public KeyboardComponent {
    void draw(Adafruit_GFX &gfx, const String &text) override;
    void draw(Adafruit_GFX &gfx, const String &text, int maxLength) override;
    KeyboardEvent hitTest(const TouchPoint &point) override;
    KeyboardEvent hitTest(const TouchPoint &point, int currentLength, int maxLength) override;
    void toggleCaps() override;
};
List helpers src/ui/components/list_component.h
enum class UiListNavMode

Touch navigation behavior for compact list controls.

enum class UiListNavMode : uint8_t {
    Scroll,
    Select,
    Split,
};
enum class UiListTouchAction

Result action from list hit testing.

enum class UiListTouchAction : uint8_t {
    None,
    Scroll,
    Select,
};
struct UiListTouchResult

List hit-test result.

struct UiListTouchResult {
    UiListTouchAction action = UiListTouchAction::None;
    uint16_t index = 0;
};
function uiListMaxOffset

Returns the largest valid scroll offset for a list.

inline uint16_t uiListMaxOffset(uint16_t itemCount, uint8_t visibleCount);
function uiListClampOffset

Clamps a list scroll offset in place.

inline void uiListClampOffset(uint16_t &offset, uint16_t itemCount, uint8_t visibleCount);
function uiListScrollBy

Scrolls a list offset by a signed row delta.

inline bool uiListScrollBy(uint16_t &offset, uint16_t itemCount, uint8_t visibleCount, int8_t delta);
function uiListHandleTouch

Maps a touch point to scroll or select behavior for a simple list.

inline UiListTouchResult uiListHandleTouch(const TouchPoint &point, uint16_t itemCount, uint8_t visibleCount, int16_t listY, int16_t rowHeight, int16_t listHeight, int16_t splitX, UiListNavMode mode, uint16_t &offset);
Date/time picker src/ui/components/date_time_picker_component.h
struct DatePickerDate

Calendar date selected by the date picker.

struct DatePickerDate {
    int year = 1970;
    int month = 1;
    int day = 1;
};
struct TimePickerTime

Clock time selected by the time picker.

struct TimePickerTime {
    uint8_t hour = 0;
    uint8_t minute = 0;
};
class DateTimePickerComponent

Draws and edits a small date picker with optional time selection.

class DateTimePickerComponent {
    void reset(const DatePickerDate &date);
    void setToday(const DatePickerDate &date, bool available);
    void setTime(const TimePickerTime &time);
    void setTimePickerEnabled(bool enabled);
    void setMondayFirst(bool enabled);
    void draw(Adafruit_GFX &gfx);
    bool handleTouch(const TouchPoint &point);
    bool dateAtPoint(const TouchPoint &point, DatePickerDate &out) const;
    bool update();
    DatePickerDate selectedDate() const;
    TimePickerTime selectedTime() const;
    bool timePickerEnabled() const;
    static int daysInMonth(int year, int month);
    static int weekdayForDate(int year, int month, int day);
    static DatePickerDate dateFromUnixDays(int days);
    static const char *monthName(int month);
    static const char *weekdayName(int weekday);
};
Audio player src/ui/components/audio_player_component.h
enum class AudioPlayerAction

Touch actions emitted by the audio player component.

enum class AudioPlayerAction : uint8_t {
    None,
    TogglePlayPause,
    VolumeDown,
    VolumeUp,
    Seek,
};
struct AudioPlayerEvent

Result of hit-testing the audio player component.

struct AudioPlayerEvent {
    AudioPlayerAction action = AudioPlayerAction::None;
    uint16_t seekPermille = 0;
};
struct AudioPlayerState

Render state for the audio player component.

struct AudioPlayerState {
    const char *title = nullptr;
    const char *subtitle = nullptr;
    const char *detail = nullptr;
    bool playing = false;
    AudioPlayerAction pressedAction = AudioPlayerAction::None;
    uint8_t volumePercent = 80;
    bool muted = false;
    uint32_t positionMs = 0;
    uint32_t durationMs = 0;
};
class AudioPlayerComponent

Draws and hit-tests the compact/fullscreen audio playback controls.

class AudioPlayerComponent {
    void draw(Adafruit_GFX &gfx, const AudioPlayerState &state, bool fullscreen) const;
    AudioPlayerEvent hitTest(const TouchPoint &point, bool fullscreen, uint32_t durationMs) const;
};
System fonts src/sys/system_fonts.h

Registry of fonts deliberately linked into every firmware build. It lets runtime-driven UI discover and select known GFX fonts by stable names without pulling unrelated generated font assets into the binary.

struct SystemFontInfo

Describes a font already compiled into the firmware.

struct SystemFontInfo {
    const char *name = nullptr;
    uint8_t nominalSize = 0;
};
function systemFontCount

Returns the number of fonts in the firmware-wide registry.

size_t systemFontCount();
function systemFontInfo

Copies metadata for one registry entry; returns false out of range.

bool systemFontInfo(size_t index, SystemFontInfo &out);
function systemFontIndex

Looks up a stable font name, returning -1 when it is unknown.

int systemFontIndex(const char *name);
function systemFontApply

Applies a registry font by index to a GFX drawing surface.

bool systemFontApply(Adafruit_GFX &gfx, size_t index);
function systemFontApply

Applies a registry font by name to a GFX drawing surface.

bool systemFontApply(Adafruit_GFX &gfx, const char *name);

Drivers

Low-level interfaces that initialize or communicate directly with device hardware. Services build lifecycle, caching, and policy on top of these device-specific operations.

Shared I2C bus src/sys/drivers/shared_i2c_bus.h
function sharedI2cBegin

Initializes the board I2C bus shared by touch, RTC, and sensors.

bool sharedI2cBegin();
function sharedI2cBusHandle

Returns the initialized shared bus, or nullptr before successful setup.

i2c_master_bus_handle_t sharedI2cBusHandle();
Touch controller src/sys/drivers/touch_controller.h
struct TouchControllerSample

Raw sample reported by the FT6336 touch controller.

struct TouchControllerSample {
    uint8_t count = 0;
    uint16_t x = 0;
    uint16_t y = 0;
};
class TouchController

Low-level FT6336 access on the board's shared I2C bus.

class TouchController {
    bool begin();
    bool read(TouchControllerSample &sample);
};
Environment sensors src/sys/drivers/environment_sensors.h
struct EnvironmentSensorReadings

Raw readings produced by the board's ambient and chip sensors.

struct EnvironmentSensorReadings {
    bool ambientTemperatureValid = false;
    bool ambientHumidityValid = false;
    bool chipTemperatureValid = false;
    float ambientTemperatureC = 0.0f;
    float ambientHumidityPct = 0.0f;
    float chipTemperatureC = 0.0f;
};
class EnvironmentSensors

Low-level access to the SHTC3 and ESP32 internal temperature sensor.

class EnvironmentSensors {
    void begin();
    void read(EnvironmentSensorReadings &readings);
};
Power hardware src/sys/drivers/power_hardware.h
function powerHardwareReleaseHolds

Releases GPIO and RTC holds left by a sleep transition.

void powerHardwareReleaseHolds();
function powerHardwarePrepareWakeDefaults

Applies safe board GPIO levels immediately after wake.

void powerHardwarePrepareWakeDefaults();
function powerHardwareKeepLatchOn

Keeps the board power latch asserted.

void powerHardwareKeepLatchOn();
function powerHardwareReboot

Restarts through the platform reset mechanism.

void powerHardwareReboot();
function powerHardwareOff

Drops power rails and waits for a power-button wake.

void powerHardwareOff();
function powerHardwareEnterDeepSleep

Enters deep sleep with the configured wake timer and panel power state.

void powerHardwareEnterDeepSleep(uint64_t timerWakeupUs, bool keepEpdPowerOn);
function powerHardwareWokeFromTimer

Reports whether deep sleep ended because of the timer.

bool powerHardwareWokeFromTimer();
function powerHardwareResetReason

Returns the platform reset reason as a stable diagnostic integer.

int16_t powerHardwareResetReason();
function powerHardwareWakeupCause

Returns the platform wakeup cause as a stable diagnostic integer.

int16_t powerHardwareWakeupCause();
SD card src/sys/drivers/sd_card.h
struct SdCardCapacity

Raw SD-card capacity reported by the board storage driver.

struct SdCardCapacity {
    uint64_t totalBytes = 0;
    uint64_t usedBytes = 0;
};
function sdCardMount

Mounts the board SD card in one-bit SD_MMC mode.

bool sdCardMount();
function sdCardUnmount

Unmounts the board SD card.

void sdCardUnmount();
function sdCardPresent

Reports whether hardware still exposes a mounted card.

bool sdCardPresent();
function sdCardCapacity

Reads raw card capacity counters.

SdCardCapacity sdCardCapacity();
Hardware button src/sys/drivers/hw_button.h
class HwButton

Debounces one hardware button and emits single-click, double-click, long-press, and activity callbacks.

class HwButton {
    HwButton(uint8_t pin, bool activeLow = true);
    void begin();
    void update();
    void attachSingleClick(std::function<void()> callback);
    void attachDoubleClick(std::function<void()> callback);
    void attachLongPressStart(std::function<void()> callback);
    void attachHold(std::function<void()> callback, uint16_t ms);
    void attachActivity(std::function<void()> callback);
    void setLongPressMs(uint16_t ms);
    void setDoubleClickMs(uint16_t ms);
};
E-paper board driver src/sys/drivers/epaper_driver_bsp.h

Low-level board driver for the 200x200 monochrome e-paper panel. It owns the SPI device and framebuffer and implements full and partial refresh sequences; higher-level drawing normally reaches it through AppDisplay.

class epaper_driver_display

Owns one e-paper controller, its SPI attachment, and its framebuffer.

class epaper_driver_display {
    epaper_driver_display(int width, int height, custom_lcd_spi_t _lcd_spi_data);
    ~epaper_driver_display();
    void EPD_Init();
    void EPD_InitColdPartial();
    void EPD_ReattachPartial();
    void EPD_Clear();
    void EPD_Display();
    [[deprecated("EPD_DisplayRegion is not hardware-safe; use EPD_DisplayPart/full-buffer partial refresh")]] void EPD_DisplayRegion(int16_t x, int16_t y, int16_t w, int16_t h);
    void EPD_LoadPartBaseImage();
    void EPD_LoadPartBothImages();
    void EPD_DisplayPartBaseImage();
    void EPD_Init_Partial();
    void EPD_DisplayPart();
    void EPD_DrawColorPixel(uint16_t x, uint16_t y, uint8_t color);
    void EPD_DrawBlackPixelUnchecked(uint16_t x, uint16_t y);
    void EPD_DrawBlackBlock2x2Unchecked(uint16_t x, uint16_t y);
    const uint8_t *framebufferData() const;
    int framebufferSize() const;
};
Real-time clock src/sys/drivers/pcf85063_clock.h

Driver for the PCF85063 battery-backed real-time clock on the shared I2C bus. The chip stores local date and time fields, not a Unix timestamp.

class Pcf85063Clock

Minimal access for reading and writing the battery-backed PCF85063.

class Pcf85063Clock {
    void begin();
    bool readLocalUnix(int64_t &localUnix);
    bool writeFromUnix(int64_t unixTime, int32_t utcOffsetSeconds);
};
USB status src/sys/drivers/usb_status.h
function usbConnected

Returns true when the device sees a USB host connection.

bool usbConnected();

Hardware Services

Battery monitor src/sys/services/battery_monitor.h
constant BATTERY_EMPTY_VOLTAGE

Voltage treated as 0 percent when estimating battery state of charge.

constexpr float BATTERY_EMPTY_VOLTAGE = 2.80f;
constant BATTERY_FULL_VOLTAGE

Voltage treated as 100 percent when estimating battery state of charge.

constexpr float BATTERY_FULL_VOLTAGE = 3.95f;
struct BatterySocPoint

One voltage-to-percentage point in the battery state-of-charge curve.

struct BatterySocPoint {
    float voltage;
    int percentage;
};
struct BatteryMonitorConfig

Hardware and calibration settings used by BatteryMonitor.

struct BatteryMonitorConfig {
    int adcPin;
    int controlPin;
    int sampleCount;
    int adcMaxReading;
    float adcReferenceVoltage;
    float dividerScale;
    const BatterySocPoint *socCurve;
    size_t socCurveLength;
};
struct BatterySnapshot

Cached battery reading exposed to UI and power policy.

struct BatterySnapshot {
    bool valid;
    float voltage;
    int percentage;
};
class BatteryMonitor

Samples battery voltage and exposes a cached percentage estimate.

class BatteryMonitor {
    void begin();
    void refresh();
    void configure(const BatteryMonitorConfig &config);
    const BatterySnapshot &snapshot() const;
};
Environment monitor src/sys/services/environment_monitor.h
struct EnvironmentSnapshot

Cached temperature and humidity readings from onboard sensors.

struct EnvironmentSnapshot {
    bool ambientTemperatureValid;
    bool ambientHumidityValid;
    bool chipTemperatureValid;
    float ambientTemperatureC;
    float ambientHumidityPct;
    float chipTemperatureC;
};
class EnvironmentMonitor

Polls environmental sensors and caches values for UI display.

class EnvironmentMonitor {
    void begin();
    void refresh();
    const EnvironmentSnapshot &snapshot() const;
};
Touch input src/sys/services/touch_input.h
struct TouchPoint

One sampled touch coordinate in display space.

struct TouchPoint {
    uint16_t x;
    uint16_t y;
};
enum TouchEventType

Type of touch transitions reported by the controller.

enum TouchEventType {
    TOUCH_EVENT_DOWN,
    TOUCH_EVENT_MOVE,
    TOUCH_EVENT_UP,
};
struct TouchEvent

Packs one touch event with its type and coordinates.

struct TouchEvent {
    TouchEventType type;
    TouchPoint point;
};
class TouchInput

Reads debounced touch points and higher-level touch events from the panel.

class TouchInput {
    void begin();
    bool read(TouchPoint &point);
    bool readEvent(TouchEvent &event);
};
Device clock src/sys/services/device_clock.h
class DeviceClock

Monotonic-millis backed local clock used after network or RTC time sync.

class DeviceClock {
    void set(int64_t unixTime, int32_t utcOffsetSeconds);
    bool isSet() const;
    bool isEstimated() const;
    bool snapshotLocalUnix(int64_t &localUnix) const;
    bool snapshotLocalUnixMillis(int64_t &localUnix, uint16_t &millisIntoSecond) const;
    bool snapshotUnixMillis(int64_t &unixTime, uint16_t &millisIntoSecond) const;
    void restoreLocalUnix(int64_t localUnix, int32_t utcOffsetSeconds, bool estimated = false);
    int32_t utcOffsetSeconds() const;
    int64_t localMinuteIndex() const;
    void formatTime(char *out, size_t outSize) const;
    void formatTime(char *out, size_t outSize, ConfigTimeFormat format) const;
    void formatDate(char *out, size_t outSize) const;
};
Board definition src/sys/global.h

Central board definition for device hardware: GPIO assignments, panel dimensions, SPI selection, and touch orientation. Drivers use these constants so board wiring is not duplicated throughout the firmware.

Connectivity

Wi-Fi manager src/sys/services/wifi_manager.h
enum WifiDisplayState

Coarse Wi-Fi state used by compact status indicators.

enum WifiDisplayState {
    WIFI_DISPLAY_OFF,
    WIFI_DISPLAY_ON,
    WIFI_DISPLAY_CONNECTED,
};
class WifiManager

Owns station-mode Wi-Fi lifecycle, remembered networks, and time sync updates.

class WifiManager {
    enum ConnectionState : uint8_t { STATE_IDLE, STATE_CONNECTING, STATE_CONNECTED, STATE_FAILED };
    void reset();
    bool update();
    bool startSta();
    void connect();
    void connectTo(const char *ssid, const char *password);
    void disconnect();
    void toggle();
    void restoreOn(bool enabled);
    bool isOn() const;
    bool isConnected() const;
    bool isConnecting() const;
    bool hasActiveSession() const;
    WifiDisplayState displayState() const;
    ConnectionState connectionState() const;
    bool preferredMatches(const char *ssid) const;
    void saveNetworkSlot(uint8_t slot, const char *ssid, const char *password, const char *bssid);
    void savePreferred(const char *ssid, const char *password);
    void clearPreferredIfMatches(const char *ssid);
    const char *statusText() const;
    const char *datetimeText() const;
    void setStatus(const char *status);
};
Time sync src/sys/services/time_sync.h
class TimeSyncService

Network time synchronizer that updates DeviceClock and exposes UI status text.

class TimeSyncService {
    void reset();
    bool update(bool wifiConnected);
    bool hasActiveSession() const;
    const char *statusText() const;
    const char *datetimeText() const;
    void setStatus(const char *value);
};

Audio

Playback renderer src/sys/audio/audio_playback_renderer.h
struct AudioPlaybackStream

Pull-based PCM source consumed by AudioPlaybackRenderer.

struct AudioPlaybackStream {
    void *user = nullptr;
    size_t (*fillPcm16)(void *user, int16_t *stereoFrames, size_t frameCount) = nullptr;
};
struct AudioPlaybackConfig

Runtime audio playback settings.

struct AudioPlaybackConfig {
    uint32_t sampleRate = 16000;
    size_t chunkFrames = 512;
    uint8_t volumePercent = 80;
    bool playWhenMutedAtMinimumVolume = false;
};
class AudioPlaybackRenderer

Streams signed 16-bit stereo PCM to the codec and I2S output path.

class AudioPlaybackRenderer {
    static void stopActive();
    bool begin(const AudioPlaybackStream &stream, const AudioPlaybackConfig &config, char *error, int errorSize);
    bool pump(char *error, int errorSize);
    void stop();
    void setVolumePercent(uint8_t percent);
    uint8_t volumePercent() const;
    bool active() const;
    bool finished() const;
    uint32_t sampleRate() const;
    uint16_t lastPeak() const;
    uint32_t chunksWritten() const;
};
Audio Capture src/sys/audio/audio_capture.h
struct AudioCaptureResult

Owned PCM recording buffer returned by AudioCapture.

struct AudioCaptureResult {
    uint8_t *data = nullptr;
    size_t length = 0;
    uint32_t sampleRate = 16000;
    bool wav = false;
};
class AudioCapture

Captures microphone audio as signed 16-bit PCM.

class AudioCapture {
    bool beginPcm16(AudioCaptureResult &out, uint32_t maxDurationMs, char *error, int errorSize);
    bool beginWav(AudioCaptureResult &out, uint32_t maxDurationMs, char *error, int errorSize);
    bool pumpPcm16(AudioCaptureResult &out, char *error, int errorSize);
    void finishPcm16(AudioCaptureResult &out);
    bool recordPcm16(AudioCaptureResult &out, uint32_t durationMs, char *error, int errorSize);
    bool recordWav(AudioCaptureResult &out, uint32_t durationMs, char *error, int errorSize);
    void release(AudioCaptureResult &result);
};
Audio power src/sys/audio/audio_power.h
function audioPowerBegin

Initializes GPIOs that control codec and speaker power.

void audioPowerBegin();
function audioPowerOn

Enables shared audio power rails.

void audioPowerOn();
function audioPowerOff

Disables shared audio power rails.

void audioPowerOff();
function audioSpeakerAmpOn

Enables the speaker amplifier.

void audioSpeakerAmpOn();
function audioSpeakerAmpOff

Disables the speaker amplifier.

void audioSpeakerAmpOff();
function audioPowerIsOn

Returns true when audio power rails are enabled.

bool audioPowerIsOn();
Headless audio src/sys/audio/audio.h

@file UI-independent audio source used by headless and external-app playback. Sources can be preloaded independently, while playback is serialized through the device's single physical audio output. Some codecs are edition-specific.

enum class AudioCodec

Formats accepted by Audio's memory-backed constructor. WAV, MP3, and AAC/M4A decoding are extended-edition codecs. MIDI uses the existing headless parser/synth shared with the MIDI file viewer.

enum class AudioCodec : uint8_t {
    Auto,
    Wav,
    Mp3,
    Aac,
    Midi,
    Pcm16Mono16k,
};
class Audio

UI-independent, independently preloadable audio source. Multiple Audio objects may remain preloaded at once. The device has one physical codec output, so play() hands output ownership to the newest caller while preserving every other object's decoded/preloaded state.

class Audio {
    struct State;
    explicit Audio(const char *path, const char *providerId = "sd");
    Audio(const uint8_t *bytes, size_t length, AudioCodec codec);
    ~Audio();
    Audio(const Audio &) = delete;
    Audio &operator=(const Audio &) = delete;
    static bool codecAvailable(AudioCodec codec);
    bool preload();
    bool play();
    bool update();
    void stop();
    void release();
    bool loaded() const;
    bool playing() const;
    bool finished() const;
    uint32_t positionMs() const;
    uint32_t durationMs() const;
    uint32_t sampleRate() const;
    uint8_t channels() const;
    const char *error() const;
};
WAV encoder src/sys/audio/wav_encoder.h

Writes the canonical RIFF/WAVE header used to package captured interleaved integer PCM samples. The encoder only creates metadata; callers own the sample buffer and append its bytes after the header.

constant kPcmHeaderSize

Size of a canonical PCM RIFF/WAVE header.

constexpr size_t kPcmHeaderSize = 44;
function writePcmHeader

Writes a mono/stereo PCM header in front of already captured sample bytes. The destination must have room for kPcmHeaderSize bytes.

bool writePcmHeader(uint8_t *header, size_t headerSize, uint32_t sampleRate, uint16_t channels, uint16_t bitsPerSample, size_t pcmByteCount);
E-app audio

See E-app audio capture and E-app audio playback in the External Apps section.

External Apps

External app ABI examples/pink/include/pink_app_api.h
constant PINK_EXECUTABLE_MAGIC

Magic value that marks a binary as a .pink executable.

static const uint32_t PINK_EXECUTABLE_MAGIC = 0x4b4e4950UL;
constant PINK_EXECUTABLE_ABI_VERSION

ABI version emitted by the current .pink build tooling.

static const uint16_t PINK_EXECUTABLE_ABI_VERSION = 12;
constant PINK_EXECUTABLE_MIN_ABI_VERSION

Oldest .pink ABI version the current firmware still accepts.

static const uint16_t PINK_EXECUTABLE_MIN_ABI_VERSION = 7;
constant PINK_EXECUTABLE_HEADER_SIZE
static const uint16_t PINK_EXECUTABLE_HEADER_SIZE = 28;
constant PINK_EXECUTABLE_MAX_IMAGE_BYTES
static const size_t PINK_EXECUTABLE_MAX_IMAGE_BYTES = 64U * 1024U;
enum PinkEventType

Events that the firmware can deliver to an external .pink app.

enum PinkEventType : uint8_t {
    PINK_EVENT_START = 1,
    PINK_EVENT_STOP = 2,
    PINK_EVENT_DRAW = 3,
    PINK_EVENT_TOUCH = 4,
    PINK_EVENT_UPDATE = 5,
    PINK_EVENT_TOUCH_DOWN = 6,
    PINK_EVENT_TOUCH_MOVE = 7,
    PINK_EVENT_TOUCH_UP = 8,
    PINK_EVENT_MENU_BUTTON = 9,
    PINK_EVENT_MENU_DOUBLE = 10,
    PINK_EVENT_MENU_LONG = 11,
    PINK_EVENT_POWER_BUTTON = 12,
    PINK_EVENT_POWER_DOUBLE = 13,
    PINK_EVENT_POWER_LONG = 14,
    PINK_EVENT_SAVE_STATE = 15,
    PINK_EVENT_RESTORE_STATE = 16,
    PINK_EVENT_PERIODIC = 17,
};
enum PinkFont

Fonts exposed by the firmware drawing host.

enum PinkFont : uint8_t {
    PINK_FONT_DEFAULT = 0,
    PINK_FONT_ICON_8 = 1,
    PINK_FONT_ICON_12 = 2,
};
enum PinkApiStatus
enum PinkApiStatus : int8_t {
    PINK_API_ERROR = -1,
    PINK_API_DENIED = -2,
    PINK_API_UNSUPPORTED = -3,
    PINK_API_PENDING = 0,
    PINK_API_OK = 1,
    PINK_API_END = 2,
};
enum PinkFeature
enum PinkFeature : uint32_t {
    PINK_FEATURE_READ_FILES = 1U << 0U,
    PINK_FEATURE_WRITE_FILES = 1U << 1U,
    PINK_FEATURE_DELETE_FILES = 1U << 2U,
    PINK_FEATURE_AUDIO_CAPTURE = 1U << 3U,
    PINK_FEATURE_GPIO = 1U << 4U,
    PINK_FEATURE_SENSORS = 1U << 5U,
    PINK_FEATURE_WIFI_SCAN = 1U << 6U,
};
enum PinkPeriodicWakeLevel
enum PinkPeriodicWakeLevel : uint8_t {
    PINK_PERIODIC_SYSTEM = 2,
    PINK_PERIODIC_NETWORK = 3,
};
enum PinkPeriodicDisplayMode
enum PinkPeriodicDisplayMode : uint8_t {
    PINK_PERIODIC_DISPLAY_NONE = 0,
    PINK_PERIODIC_DISPLAY_PARTIAL = 1,
    PINK_PERIODIC_DISPLAY_FULL = 2,
};
enum PinkPeriodicAction
enum PinkPeriodicAction : uint8_t {
    PINK_PERIODIC_COMPLETE = 0,
    PINK_PERIODIC_WAKE_DEVICE = 3,
    PINK_PERIODIC_WAKE_APP = 4,
};
struct PinkImageTransform
struct PinkImageTransform {
    float a = 1.0f;
    float b = 0.0f;
    float c = 0.0f;
    float d = 1.0f;
    float tx = 0.0f;
    float ty = 0.0f;
};
struct PinkSensorSnapshot
struct PinkSensorSnapshot {
    uint8_t temperatureValid = 0;
    uint8_t humidityValid = 0;
    uint8_t cpuTemperatureValid = 0;
    uint8_t reserved = 0;
    float temperatureC = 0.0f;
    float humidityPct = 0.0f;
    float cpuTemperatureC = 0.0f;
};
struct PinkWifiNetwork
struct PinkWifiNetwork {
    char ssid[33] = {};
    int32_t rssi = -127;
};
struct PinkEvent

Shared event payload exchanged between the firmware and a .pink app.

struct PinkEvent {
    uint8_t type = 0;
    uint8_t handled = 0;
    uint8_t dirty = 0;
    uint8_t reserved = 0;
    uint16_t x = 0;
    uint16_t y = 0;
    uint8_t *data = nullptr;
    size_t dataLength = 0;
    size_t dataCapacity = 0;
    size_t eventSize = 0;
    uint32_t featureFlags = 0;
    int64_t periodicLocalUnix = 0;
    uint16_t periodicIntervalMinutes = 0;
    uint8_t periodicWakeLevel = 0;
    uint8_t periodicDisplayMode = 0;
    uint8_t periodicAction = 0;
    uint8_t periodicReserved[3] = {};
};
struct PinkHost

Function table and runtime context passed to a .pink app instance.

struct PinkHost {
    uint16_t abiVersion;
    uint16_t screenWidth;
    uint16_t screenHeight;
    uint16_t reserved;
    const char *appId;
    const char *appPath;
    uint8_t *memory;
    size_t memorySize;
    uint32_t (*millis)();
    void (*delayMs)(uint32_t ms);
    void (*log)(const char *message);
    bool (*networkConnected)();
    void (*keepAwake)();
    void (*deepSleepPreventAcquire)();
    void (*deepSleepPreventRelease)();
    void (*setFont)(uint8_t font);
    void (*setTextSize)(uint8_t size);
    void (*setTextColor)(uint16_t color);
    void (*setCursor)(int16_t x, int16_t y);
    void (*print)(const char *text);
    void (*drawPixel)(int16_t x, int16_t y, uint16_t color);
    void (*drawLine)(int16_t x0, int16_t y0, int16_t x1, int16_t y1, uint16_t color);
    void (*drawRect)(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
    void (*fillRect)(int16_t x, int16_t y, int16_t w, int16_t h, uint16_t color);
    void (*fillScreen)(uint16_t color);
    void *(*psramAlloc)(size_t bytes);
    void (*psramFree)(void *ptr);
    bool (*configGet)(const char *key, char *out, size_t outSize);
    bool (*configSet)(const char *key, const char *value);
    size_t hostSize;
    uint32_t featureFlags;
    uint32_t reserved2;
    int8_t (*drawImagePath)(const char *path, int16_t x, int16_t y, int16_t w, int16_t h, uint8_t dither, bool scaleToFit, const PinkImageTransform *transform);
    int8_t (*drawImageBuffer)(const uint8_t *data, size_t size, const char *format, int16_t x, int16_t y, int16_t w, int16_t h, uint8_t dither, bool scaleToFit, const PinkImageTransform *transform);
    int8_t (*fileRead)(const char *path, size_t offset, uint8_t *out, size_t capacity, size_t *outRead, size_t *outFileSize);
    int8_t (*fileWrite)(const char *path, const uint8_t *data, size_t size, bool append);
    int8_t (*filePicker)(const char *initialPath, const char *extensionFilter, char *outPath, size_t outSize);
    bool (*openApp)(const char *appId);
    int8_t (*gpioConfigure)(uint8_t pin, uint8_t mode);
    int8_t (*gpioRead)(uint8_t pin, int *value);
    int8_t (*gpioWrite)(uint8_t pin, bool high);
    bool (*sensorSnapshot)(PinkSensorSnapshot *out, bool refresh);
    int8_t (*wifiScan)();
    size_t (*wifiNetworkCount)();
    bool (*wifiNetworkAt)(size_t index, PinkWifiNetwork *out);
    size_t (*fontCount)();
    bool (*fontInfo)(size_t index, char *name, size_t nameSize, uint8_t *nominalSize);
    bool (*setFontByName)(const char *name);
    void *reservedAbi9Capture[5];
    int32_t (*audioLoadPath)(const char *path);
    bool (*audioFormatSupported)(const char *format);
    int32_t (*audioLoadBuffer)(const uint8_t *data, size_t size, const char *format);
    int8_t (*audioPlay)(uint32_t handle);
    int8_t (*audioStop)(uint32_t handle);
    int8_t (*audioUpdate)(uint32_t handle);
    void (*audioRelease)(uint32_t handle);
    void *reservedAbi9DatePicker[4];
    bool (*drawQr)(const char *text, int16_t x, int16_t y, int16_t size, uint16_t color);
    void *reservedAbi9Keyboard[6];
    int8_t (*fileDelete)(const char *path);
    int8_t (*audioCaptureWav)(uint32_t maxDurationMs, const uint8_t **data, size_t *size);
    int8_t (*getDateInput)(int initialYear, int initialMonth, int initialDay, int *year, int *month, int *day);
    int8_t (*getKeyboardInput)(const char *initialText, uint8_t layout, size_t maxLength, char *out, size_t outSize);
    int8_t (*audioCapturePcm16)(uint32_t maxDurationMs, const uint8_t **data, size_t *size);
    int8_t (*drawVectorPath)(const char *path, int16_t x, int16_t y, int16_t w, int16_t h, const PinkImageTransform *transform);
    int8_t (*drawVectorString)(const char *svg, size_t size, int16_t x, int16_t y, int16_t w, int16_t h, const PinkImageTransform *transform);
};
Executable loader src/sys/pink_executable.h
function pinkExecutableRuntime

Returns the runtime adapter used when a .pink app is active.

ActiveApp *pinkExecutableRuntime();
function pinkExecutableRefreshApps

Re-scans storage for available .pink apps.

void pinkExecutableRefreshApps();
function pinkExecutableCount

Counts visible .pink apps in one launcher category.

size_t pinkExecutableCount(MenuCategory category);
function pinkExecutableDefinitionAt

Copies one visible .pink app definition into caller-provided buffers.

bool pinkExecutableDefinitionAt(MenuCategory category, size_t index, AppDefinition *out, char *id, size_t idSize, char *label, size_t labelSize, char *icon, size_t iconSize);
function pinkExecutableLaunchById

Launches a discovered .pink app by stable id.

bool pinkExecutableLaunchById(const char *id);
function pinkExecutableLaunchPath

Launches a .pink executable at an explicit filesystem path.

bool pinkExecutableLaunchPath(const char *path, AppDefinition *out, char *id, size_t idSize, char *label, size_t labelSize, char *icon, size_t iconSize);
function pinkExecutableStop

Stops the active .pink app and releases its loaded image.

void pinkExecutableStop();
E-app periodic tasks src/sys/pink_periodic_tasks.h
struct PinkPeriodicPlan

Summary of installed .pink hooks due in one wake window.

struct PinkPeriodicPlan {
    bool anyRegistered = false;
    bool dueAtSystem = false;
    bool dueAtNetwork = false;
    int64_t nextDueMinute = -1;
    PeriodicDisplayMode systemDisplayMode = PeriodicDisplayMode::None;
    PeriodicDisplayMode networkDisplayMode = PeriodicDisplayMode::None;
};
struct PinkPeriodicRunResult

Combined outcome of the due .pink hooks invoked at one wake tier.

struct PinkPeriodicRunResult {
    bool wakeDevice = false;
    bool displayUpdated = false;
    char wakeAppId[24] = {};
};
function pinkPeriodicPlan

Re-scans installed artifacts and plans their valid static schedules.

PinkPeriodicPlan pinkPeriodicPlan(int64_t localMinute, int64_t previousMinute, uint16_t minIntervalMinutes);
function pinkRunDuePeriodic

Invokes the due hooks at one initialized tier using the last plan's scan.

PinkPeriodicRunResult pinkRunDuePeriodic( int64_t localUnix, int64_t previousMinute, uint16_t minIntervalMinutes, PeriodicWakeLevel wakeLevel, Adafruit_GFX *display);
E-app service API src/sys/ext_app_api/app_api.h

Public firmware gateway for sandboxed external apps. It turns app requests for files, modal UI, GPIO, sensors, Wi-Fi, recording, and playback into session-scoped operations that the shell can permission and safely service.

enum class AppApiStatus

Shared result contract used by PinkApp's C ABI and PocketInkJS's adapters.

enum class AppApiStatus : int8_t {
    Error = -1,
    Denied = -2,
    Unsupported = -3,
    Pending = 0,
    Ok = 1,
};
enum class AppApiGpioMode

Portable GPIO modes exposed to external apps rather than Arduino constants.

enum class AppApiGpioMode : uint8_t {
    Input = 0,
    InputPullup = 1,
    Output = 2,
};
struct AppApiWifiNetwork

Bounded Wi-Fi scan entry copied out of the platform network stack.

struct AppApiWifiNetwork {
    char ssid[33] = {};
    int32_t rssi = -127;
};
function bool

Callback used to consume transient directory entries during enumeration.

using AppApiDirectoryEntryHandler = bool (*)(const char *name, bool directory, uint32_t size, void *context);
function appApiBeginSession

Starts or resumes capability state for the active external app. Permissions live only for this session and are discarded by appApiEndSession().

bool appApiBeginSession(const char *appId);
function appApiEndSession

Releases permissions, modal state, media, capture, and configured GPIO.

void appApiEndSession();
function appApiSessionMatches

Checks whether the active capability session belongs to an app id.

bool appApiSessionMatches(const char *appId);
function appApiUpdateOnMainCore

Performs deferred hardware work from the shell/main core.

bool appApiUpdateOnMainCore();
function appApiOverlayActive

Shell-owned overlay hooks for permission prompts and the file picker.

bool appApiOverlayActive();
function appApiDrawOverlay
void appApiDrawOverlay(Adafruit_GFX &gfx);
function appApiHandleOverlayTouch
bool appApiHandleOverlayTouch(const TouchPoint &point);
function appApiHandleOverlayMenuButton
bool appApiHandleOverlayMenuButton();
function appApiHandleOverlayPowerButton
bool appApiHandleOverlayPowerButton();
function appApiReadFile

Reads an arbitrary chunk. outRead may be zero with End when offset is at or beyond EOF. Passing a null output is allowed only when capacity is zero and can be used to query the file size.

AppApiStatus appApiReadFile(const char *path, size_t offset, uint8_t *out, size_t capacity, size_t *outRead, size_t *outFileSize);
function appApiListDirectory

Enumerates one directory synchronously. The callback may return false to stop early; names are valid only for the duration of the callback.

AppApiStatus appApiListDirectory(const char *path, AppApiDirectoryEntryHandler handler, void *context);
function appApiWriteFile

Writes or appends one chunk after a once-per-session, once-per-path prompt.

AppApiStatus appApiWriteFile(const char *path, const uint8_t *data, size_t size, bool append);
function appApiDeleteFile

Deletes one file after a once-per-session, once-per-path prompt.

AppApiStatus appApiDeleteFile(const char *path);
function appApiRequestFilePicker

Opens the full-screen file picker. Repeating the request polls its state; appApiTakePickedFile consumes a completed selection.

AppApiStatus appApiRequestFilePicker(const char *initialPath, const char *extensionFilter);
function appApiTakePickedFile
AppApiStatus appApiTakePickedFile(char *out, size_t outSize);
function appApiGetKeyboardInput

One-call modal input APIs. The first call opens system UI; subsequent calls return Pending until the user accepts or cancels. Sandbox code never draws or hit-tests the system widgets.

AppApiStatus appApiGetKeyboardInput(const char *initialText, uint8_t layout, size_t maxLength, char *out, size_t outSize);
function appApiGetDateInput
AppApiStatus appApiGetDateInput(const DatePickerDate &initial, DatePickerDate &out);
function appApiRequestOpenApp

Queues a stable catalog id for the shell to launch after the current app callback returns.

bool appApiRequestOpenApp(const char *appId);
function appApiTakeOpenAppRequest
bool appApiTakeOpenAppRequest(char *out, size_t outSize);
function appApiGpioConfigure

Configures an allow-listed expansion GPIO after session permission.

AppApiStatus appApiGpioConfigure(uint8_t pin, AppApiGpioMode mode);
function appApiGpioRead

Reads an allow-listed GPIO previously configured by this session.

AppApiStatus appApiGpioRead(uint8_t pin, int *value);
function appApiGpioWrite

Writes an allow-listed output GPIO previously configured by this session.

AppApiStatus appApiGpioWrite(uint8_t pin, bool high);
function appApiSensorSnapshot

Returns the cached environment snapshot and optionally requests a refresh.

EnvironmentSnapshot appApiSensorSnapshot(bool refresh);
function appApiWifiScan

Starts a confirmed scan and exposes a bounded snapshot after completion.

AppApiStatus appApiWifiScan();
function appApiWifiNetworkCount

Returns the number of entries in the completed bounded scan snapshot.

size_t appApiWifiNetworkCount();
function appApiWifiNetworkAt

Copies one completed scan entry; returns false when out of range.

bool appApiWifiNetworkAt(size_t index, AppApiWifiNetwork &out);
function appApiCaptureWav

Simplified capture operation. The system pumps recording while Pending and returns a session-owned WAV buffer at End.

AppApiStatus appApiCaptureWav(uint32_t maxDurationMs, const uint8_t **data, size_t *size);
function appApiCapturePcm16
AppApiStatus appApiCapturePcm16(uint32_t maxDurationMs, const uint8_t **data, size_t *size);
function appApiAudioFormatSupported

Preloads independently replayable audio. MIDI is always available; other codecs follow the firmware edition's headless Audio implementation.

bool appApiAudioFormatSupported(const char *format);
function appApiAudioLoadPath

Preloads an audio path and returns a session handle, or a negative error.

int32_t appApiAudioLoadPath(const char *path);
function appApiAudioLoadBuffer

Preloads copied audio bytes and returns a session handle, or a negative error.

int32_t appApiAudioLoadBuffer(const uint8_t *data, size_t size, const char *format);
function appApiAudioPlay

Starts the selected preloaded source from its beginning.

AppApiStatus appApiAudioPlay(uint32_t handle);
function appApiAudioStop

Stops the selected source while retaining its preload state.

AppApiStatus appApiAudioStop(uint32_t handle);
function appApiAudioUpdate

Polls playback and reports End after a source finishes naturally.

AppApiStatus appApiAudioUpdate(uint32_t handle);
function appApiAudioRelease

Releases one session audio handle and its owned resources.

void appApiAudioRelease(uint32_t handle);
E-app audio capture src/sys/ext_app_api/audio_capture_service.h

Cross-core recording service for external apps. App code submits a bounded PCM or WAV request, the main core drives the microphone capture, and an atomic mailbox publishes the session-owned result back without touching hardware.

class AudioCaptureService

Asynchronous mailbox between an app task and main-core microphone hardware.

class AudioCaptureService {
    enum class Format : uint8_t { Pcm16, Wav };
    ServiceResult request(Format format, uint32_t maxDurationMs, const uint8_t **data, size_t *size);
    void updateOnMainCore();
    void release();
};
E-app audio playback src/sys/ext_app_api/audio_service.h

Session-owned audio handle table for external apps. It normalizes MIDI and edition-specific codecs behind load/play/update/release operations while bounding the number of simultaneously preloaded sources.

struct AudioHandleResult

Result of loading a source into the bounded session handle table.

struct AudioHandleResult {
    ServiceResult result;
    int32_t handle = -1;
};
class AudioService

Owns the bounded set of audio sources preloaded by one external app session.

class AudioService {
    explicit AudioService(FileService &files);
    bool formatSupported(const char *format) const;
    AudioHandleResult loadPath(const char *path);
    AudioHandleResult loadBuffer(const uint8_t *data, size_t size, const char *format);
    ServiceResult play(uint32_t handle);
    ServiceResult stop(uint32_t handle);
    ServiceResult update(uint32_t handle);
    void release(uint32_t handle);
    void releaseAll();
};
E-app file service src/sys/ext_app_api/file_service.h

File-provider facade for an external-app session. Reads and listings are exposed through one provider, while mutations are routed through the shared permission service before reaching storage.

class FileService

Validates and permissions external-app operations on the active file provider.

class FileService {
    explicit FileService(PermissionService &permissions);
    ServiceResult read(const char *path, size_t offset, uint8_t *out, size_t capacity, size_t *outRead, size_t *outFileSize);
    ServiceResult list(const char *path, AppApiDirectoryEntryHandler handler, void *context);
    ServiceResult write(const char *path, const uint8_t *data, size_t size, bool append);
    ServiceResult remove(const char *path);
    ServiceResult openRead(const char *path, File &out);
    const char *providerId() const;
};
E-app modal service src/sys/ext_app_api/modal_service.h

Coordinates shell-owned modal UI requested by sandboxed apps. It serializes permission prompts, file picking, keyboard input, and date input so external runtimes poll results without drawing or handling system widgets themselves.

class ModalService

State machine for all system UI that may temporarily cover an external app.

class ModalService {
    ModalService(PermissionService &permissions, const char *appId);
    bool update();
    bool active();
    void draw(Adafruit_GFX &gfx);
    bool handleTouch(const TouchPoint &point);
    bool handleMenuButton();
    bool handlePowerButton();
    ServiceResult requestFilePicker(const char *initialPath, const char *extensionFilter);
    ServiceResult takePickedFile(char *out, size_t outSize);
    ServiceResult keyboardInput(const char *initialText, uint8_t layout, size_t maxLength, char *out, size_t outSize);
    ServiceResult dateInput(const DatePickerDate &initial, DatePickerDate &out);
    void release();
};
E-app permissions src/sys/ext_app_api/permission_service.h

Holds per-session capability decisions for potentially destructive or privacy-sensitive external-app operations. Unknown requests become a shell prompt; grants and denials are remembered only until the app session ends.

enum class PermissionKind

Capability classes that require explicit user consent.

enum class PermissionKind : uint8_t {
    FileWrite, FileDelete, Gpio, WifiScan,
};
enum class PermissionDecision

Stored or pending answer to one capability request.

enum class PermissionDecision : int8_t {
    Denied = -1, Pending = 0, Granted = 1,
};
class PermissionService

Session-local permission records plus the currently unresolved user prompt.

class PermissionService {
    ServiceResult request(PermissionKind kind, const char *resource);
    bool promptActive() const;
    void drawPrompt(Adafruit_GFX &gfx, const char *appId) const;
    bool handlePromptTouch(const TouchPoint &point);
    void release();
};
E-app service results src/sys/ext_app_api/service_result.h

Internal result vocabulary shared by external-app services. It separates asynchronous progress from completion and carries structured failure causes before the public adapter reduces them to the stable app ABI status values.

enum class ServiceState

Lifecycle outcome of an internal app service operation.

enum class ServiceState : uint8_t {
    Ok, Pending, End, Failed,
};
enum class ServiceError

Structured failure reason retained before conversion to the public ABI.

enum class ServiceError : uint8_t {
    None,
    InvalidArgument,
    Denied,
    Unsupported,
    Busy,
    OutOfMemory,
    NotFound,
    Io,
    Hardware,
};
struct ServiceResult

State, error category, and optional static detail for one service call.

struct ServiceResult {
    ServiceState state = ServiceState::Ok;
    ServiceError error = ServiceError::None;
    const char *detail = nullptr;
    static ServiceResult ok();
    static ServiceResult pending();
    static ServiceResult end();
    static ServiceResult fail(ServiceError error, const char *detail);
};
E-app service utilities src/sys/ext_app_api/service_utils.h

Shared size limits and defensive text/path validation for external-app services. Keeping these rules here makes every service apply the same ABI buffer and storage-sandbox assumptions.

constant kAppIdCapacity

Maximum app identifier size, including the terminating null byte.

constexpr size_t kAppIdCapacity = 24;
constant kPathCapacity

Maximum service path size, including the terminating null byte.

constexpr size_t kPathCapacity = 288;
function copyText

Copies null-terminated text without truncation or unterminated output.

bool copyText(char *out, size_t outSize, const char *text);
function safePath

Accepts only absolute, normalized paths that cannot escape app storage rules.

bool safePath(const char *path);
PocketInkJS app adapter src/sys/pocketinkjs_app.h

Adapts a JavaScript file on SD storage to the firmware's ActiveApp lifecycle. Launch creates a fresh PocketInkJS VM and metadata; stop tears down all VM and source memory so relaunching a file provides a clean hot-reload boundary.

function PocketInkJSAppRuntime

Returns the ActiveApp adapter used for a JavaScript file launched by Files.

ActiveApp *PocketInkJSAppRuntime();
function PocketInkJSAppLaunchPath

Loads and evaluates the current contents of a .js file from SD storage. Re-launching the path is the hot-reload boundary: no old VM state survives.

bool PocketInkJSAppLaunchPath(const char *path, AppDefinition *out, char *id, size_t idSize, char *label, size_t labelSize, char *icon, size_t iconSize);
function PocketInkJSAppStop

Stops callbacks and releases all source/runtime PSRAM owned by PocketInkJS.

void PocketInkJSAppStop();
PocketInkJS runtime src/sys/runtime/pocketinkjs/pocketinkjs.h
struct Value

Compact NaN-boxed JavaScript value; only Runtime should interpret its bits.

struct Value {
    uint64_t bits = 0;
};
enum class ValueType

Public type categories returned by Runtime::typeOf().

enum class ValueType : uint8_t {
    Undefined,
    Null,
    Boolean,
    Number,
    String,
    Object,
    Array,
    Set,
    Promise,
    Function,
};
struct StringView

Non-owning UTF-8 byte span into runtime-managed string storage.

struct StringView {
    const char *data = nullptr;
    size_t size = 0;
};
enum class ErrorCode

Stable numeric script error code used where retaining messages is too costly.

enum class ErrorCode : uint8_t {

};
enum class PromiseState

Observable lifecycle of a JavaScript promise.

enum class PromiseState : uint8_t {
    Pending, Fulfilled, Rejected,
};
struct Options

Fixed capacity limits and optional platform hooks for one Runtime instance.

struct Options {
    uint16_t maxBindings = 160;
    uint16_t maxNatives = 48;
    uint16_t maxTemporaryRoots = 48;
    uint16_t maxHostRoots = 32;
    uint16_t maxGcWork = 256;
    uint8_t maxCallDepth = 12;
    uint8_t maxCallArguments = 16;
    uint8_t maxParseDepth = 32;
    uint32_t maxSteps = 120000;
    int64_t (*nowMilliseconds)(void *userData) = nullptr;
    void *nowUserData = nullptr;
    JsonParseFunction jsonParse = nullptr;
    void *jsonUserData = nullptr;
    AwaitPendingFunction awaitPending = nullptr;
    void *awaitUserData = nullptr;
};
struct Error

Last script failure with location and a bounded source excerpt.

struct Error {
    char message[96] = {};
    char sourceLine[160] = {};
    uint32_t line = 0;
    uint32_t column = 0;
    uint16_t sourceColumn = 0;
};
struct RunResult

Outcome and resulting value from evaluation or a function call.

struct RunResult {
    bool ok = false;
    Value value = {};
};
struct MemoryStats

Current and peak use of the caller-owned runtime workspace.

struct MemoryStats {
    size_t workspaceBytes = 0;
    size_t metadataBytes = 0;
    size_t heapBytes = 0;
    size_t heapUsedBytes = 0;
    size_t heapFreeBytes = 0;
    size_t peakHeapUsedBytes = 0;
    size_t bindingCount = 0;
};
struct ScratchAllocator

C callback facade for temporary memory borrowed from a runtime workspace.

struct ScratchAllocator {
    void *context = nullptr;
    void *(*allocate)(void *context, size_t bytes, size_t alignment) = nullptr;
    void (*release)(void *context, void *memory) = nullptr;
    size_t (*available)(void *context) = nullptr;
};
class Runtime

Allocation-bounded JavaScript VM operating entirely in caller-owned memory.

class Runtime {
    class ScratchLease { public: ScratchLease() = default; ScratchLease(const ScratchLease &) = delete; ScratchLease &operator=(const ScratchLease &) = delete; ScratchLease(ScratchLease &&) = delete; ScratchLease &operator=(ScratchLease &&) = delete; ~ScratchLease(); void *allocate(size_t bytes, size_t alignment = alignof(std::max_align_t)); void release(void *memory); size_t available() const; ScratchAllocator allocator(); explicit operator bool() const { return runtime_ != nullptr; } private: friend class Runtime; explicit ScratchLease(Runtime *runtime) : runtime_(runtime) {} static void *allocateCallback(void *context, size_t bytes, size_t alignment); static void releaseCallback(void *context, void *memory); static size_t availableCallback(void *context); Runtime *runtime_ = nullptr; uint32_t firstBlock_ = 0; };
    Runtime(void *workspace, size_t workspaceBytes, const Options &options = Options;
    Runtime(const Runtime &) = delete;
    Runtime &operator=(const Runtime &) = delete;
    bool ready() const;
    const Error &error() const;
    Value undefined() const;
    Value null() const;
    Value boolean(bool value) const;
    Value number(double value) const;
    ValueType typeOf(Value value) const;
    bool isCallable(Value value) const;
    bool isTruthy(Value value) const;
    bool isUndefined(Value value) const;
    bool isString(Value value) const;
    bool isNumber(Value value) const;
    double toNumber(Value value) const;
    bool toBoolean(Value value) const;
    StringView stringView(Value value) const;
    size_t format(Value value, char *out, size_t outSize) const;
    Value makeString(const char *text, size_t length);
    Value makeString(const char *text);
    Value makeStringBuffer(size_t length, char **data);
    Value makeObject();
    Value makeArray(size_t reserve = 0);
    Value makeSet();
    Value makePromise();
    Value rejectCurrentError();
    bool arrayPush(Value array, Value value);
    size_t arrayLength(Value array) const;
    Value arrayAt(Value array, size_t index) const;
    bool arraySet(Value array, size_t index, Value value);
    bool objectSet(Value object, const char *key, Value value);
    bool objectSet(Value object, const char *key, size_t keyLength, Value value);
    Value objectGet(Value object, const char *key) const;
    Value objectGet(Value object, const char *key, size_t keyLength) const;
    size_t objectPropertyCount(Value object) const;
    bool objectPropertyAt(Value object, size_t index, Value *key, Value *value) const;
    bool bind(const char *path, NativeFunction function, void *userData = nullptr);
    bool bindMethod(const char *path, NativeMethodFunction function, void *userData = nullptr);
    bool set(const char *path, Value value, bool constant = true);
    Value get(const char *name) const;
    RunResult eval(const char *source, size_t length);
    RunResult eval(const char *source);
    RunResult call(const char *name, const Value *args = nullptr, size_t argc = 0);
    RunResult call(Value function, const Value *args = nullptr, size_t argc = 0);
    RunResult callIfFunction(const char *name, const Value *args, size_t argc, bool *called);
    void collectGarbage();
    RootHandle retain(Value value);
    void release(RootHandle handle);
    Value retained(RootHandle handle) const;
    PromiseState promiseState(Value promise) const;
    Value promiseResult(Value promise) const;
    bool settlePromise(Value promise, Value result, bool rejected = false);
    Value parseJsonPromise(Value text);
    RunResult drainJobs(size_t maximum = 8);
    MemoryStats memoryStats() const;
    ScratchLease leaseScratch();
    Value fail(const char *message);
    Value fail(ErrorCode code);
};
PocketInkJS API

app

KindJavaScript APIDescription
Function app.configGet( key: string ): string | undefined Reads a per-app configuration value by key. Returns the value string or undefined.
Function app.configSet( key: string, value: string ): boolean Writes a per-app configuration value by key.
Runtime value (string) app.id Current PocketInkJS app identifier string.
Function app.open( appId: string ): boolean Launches another app by its app ID.
Runtime value (string) app.path File system path of the currently running script.
Function app.setWakeLock( active: boolean ): void Prevents the device from entering sleep while the app is active.

audio

KindJavaScript APIDescription
Async Function audio.capturePcm16( durationMs: number ): Promise Captures audio as raw PCM16 data. Returns a Promise that resolves with the audio data.
Async Function audio.captureWav( durationMs: number ): Promise Captures audio as a WAV file. Returns a Promise that resolves with the audio data.
Function audio.load( path: string ): number Loads an audio file from a path. Returns a numeric handle.
Function audio.loadBuffer( data: string, format: string ): number Loads audio from a binary data buffer with the given format. Returns a numeric handle.
Function audio.play( handle: number ): stream.OK | stream.ERROR Starts playback of a previously loaded audio handle.
Function audio.release( handle: number ): void Releases resources for a previously loaded audio handle.
Function audio.stop( handle: number ): stream.OK | stream.ERROR Stops playback of a previously loaded audio handle.
Function audio.supports( format: string ): boolean Checks whether a given audio format string is supported.
Function audio.update( handle: number ): stream.END | stream.OK Updates audio playback state for a given handle.

console

KindJavaScript APIDescription
Function console.log( ...values: any ): void Prints values to the PocketInkJS debug log.

files

KindJavaScript APIDescription
Function files.delete( path: string ): Permissions Deletes a file by path.
Async Function files.pick( initialPath?: string, filter?: string ): Promise Opens the system file picker UI. Returns a Promise that resolves with the selected path.
Function files.readBinary( path: string, offset?: number, maxBytes?: number ): object Reads a file and returns binary data with metadata (same as readText).
Returns
{ data: string, bytes: number, size: number, offset: number, eof: boolean }
Function files.readText( path: string, offset?: number, maxBytes?: number ): object Reads a file and returns an object with data, bytes, size, offset, and eof properties.
Returns
{ data: string, bytes: number, size: number, offset: number, eof: boolean }
Function files.write( path: string, data: string, append?: boolean ): Permissions Writes string data to a file. Optionally appends instead of overwriting.

fs

KindJavaScript APIDescription
Async Function fs.appendFile( path: string, data: string, encoding?: string ): Promise Appends data to a file. Returns a Promise.
Function fs.appendFileSync( path: string, data: string, encoding?: string ): Permissions Appends data to a file. Synchronous.
Function fs.existsSync( path: string ): boolean Checks whether a file exists at the given path.
Async Function fs.readdir( path: string, encoding?: string ): Promise Lists the entries in a directory. Returns a Promise that resolves with an array of names.
Function fs.readdirSync( path: string, encoding?: string ): string[] Lists the entries in a directory. Synchronous. Returns an array of names.
Async Function fs.readFile( path: string, encoding?: string ): Promise Reads an entire file as a string. Returns a Promise.
Function fs.readFileSync( path: string, encoding?: string ): string Reads an entire file as a string. Synchronous.
Async Function fs.stat( path: string ): Promise Gets file stats (size, isFile, isDirectory). Returns a Promise.
Function fs.statSync( path: string ): object Gets file stats (size, isFile, isDirectory). Synchronous.
Returns
{ size: number, isFile: boolean, isDirectory: boolean }
Async Function fs.unlink( path: string ): Promise Deletes a file. Returns a Promise.
Function fs.unlinkSync( path: string ): Permissions Deletes a file. Synchronous.
Async Function fs.writeFile( path: string, data: string, encoding?: string ): Promise Writes data to a file. Returns a Promise.
Function fs.writeFileSync( path: string, data: string, encoding?: string ): Permissions Writes data to a file. Synchronous.

fs.promises

KindJavaScript APIDescription
Promise alias fs.promises.appendFile Async file append (Promise).
Promise alias fs.promises.readdir Async directory listing (Promise).
Promise alias fs.promises.readFile Async file read (Promise).
Promise alias fs.promises.stat Async file stat (Promise).
Promise alias fs.promises.unlink Async file delete (Promise).
Promise alias fs.promises.writeFile Async file write (Promise).

Global

KindJavaScript APIDescription
Function clearInterval( id: number ): void Cancels a timeout or interval previously created with setTimeout or setInterval.
Function clearTimeout( id: number ): void Cancels a timeout or interval previously created with setTimeout or setInterval.
Async Function fetch( url: string, options?: object ): Promise Queues an async HTTP request. Returns a Promise that resolves with a Response object.
Function setInterval( callback: function, intervalMs: number ): number Schedules a function to run repeatedly at an interval in milliseconds.
Function setTimeout( callback: function, delayMs: number ): number Schedules a function to run once after a delay in milliseconds.

gpio

KindJavaScript APIDescription
Constant gpio.INPUT GPIO digital input mode.
Constant gpio.INPUT_PULLUP GPIO input with internal pull-up.
Function gpio.mode( pin: number, mode: number ): Permissions Configures a GPIO pin as input, input pull-up, or output.
Constant gpio.OUTPUT GPIO digital output mode.
Function gpio.read( pin: number ): object Reads the current value of a GPIO pin. Returns an object with status and value.
Returns
{ status: number, value: number }
Function gpio.write( pin: number, value: boolean ): Permissions Sets the output value of a GPIO pin.

http

KindJavaScript APIDescription
Function http.get( url: string, maxBytes?: number ): string Performs a synchronous HTTP GET request and returns the response body.

network

KindJavaScript APIDescription
Function network.connected( ): boolean Checks whether Wi-Fi is connected.
Function network.networks( ): object[] Returns the list of networks found by the last scan.
Returns
{ ssid: string, rssi: number }
Function network.scan( ): Permissions Starts an asynchronous scan for nearby Wi-Fi networks.

permissions

KindJavaScript APIDescription
Constant permissions.DENIED Permission denied.
Constant permissions.ERROR Operation failed.
Constant permissions.OK Operation succeeded.
Constant permissions.PENDING Operation pending.
Constant permissions.UNSUPPORTED Feature not supported.

PocketInkJS

KindJavaScript APIDescription
Function PocketInkJS.heapFree( ): number Returns the number of heap bytes currently free in the JS runtime.
Function PocketInkJS.heapPeak( ): number Returns the peak heap usage since the JS runtime was created.
Function PocketInkJS.heapUsed( ): number Returns the number of heap bytes currently used by the JS runtime.

screen

KindJavaScript APIDescription
Runtime value (number) screen.height Screen height in pixels.
Runtime value (number) screen.width Screen width in pixels.

sensors

KindJavaScript APIDescription
Function sensors.read( refresh?: boolean ): object Reads environment sensor values (temperature, humidity). Optionally forces a refresh.
Returns
{ temperatureValid: boolean, humidityValid: boolean, cpuTemperatureValid: boolean, temperatureC: number, humidityPct: number, cpuTemperatureC: number }

stream

KindJavaScript APIDescription
Constant stream.END End of data reached.
Constant stream.ERROR Stream operation failed.
Constant stream.OK Stream operation succeeded.

time

KindJavaScript APIDescription
Function time.millis( ): number Returns the number of milliseconds since boot.

ui

KindJavaScript APIDescription
Constant ui.BLACK Black color value.
Function ui.button( x: number, y: number, w: number, h: number, label: string, pressed?: boolean, textSize?: number ): void Draws a touch button at the given bounds with a text label.
Function ui.buttonContains( x: number, y: number, bx: number, by: number, bw: number, bh: number, padding?: number ): boolean Tests whether a touch point hits a button drawn at the given bounds.
Function ui.drawLine( x0: number, y0: number, x1: number, y1: number, color: number ): void Draws a line from (x0, y0) to (x1, y1) with the given color.
Function ui.drawPixel( x: number, y: number, color: number ): void Draws a single pixel at (x, y) with the given color.
Function ui.drawRect( x: number, y: number, w: number, h: number, color: number ): void Draws a rectangle outline at (x, y) with the given width, height, and color.
Function ui.fillRect( x: number, y: number, w: number, h: number, color: number ): void Draws a filled rectangle at (x, y) with the given width, height, and color.
Function ui.fillScreen( color: number ): void Fills the entire screen with the given color.
Constant ui.FONT_DEFAULT Default system font.
Constant ui.FONT_ICON_12 12-pixel icon font.
Constant ui.FONT_ICON_8 8-pixel icon font.
Function ui.fonts( ): object[] Returns an array of objects describing available system fonts.
Returns
{ name: string, size: number }
Async Function ui.getDateInput( year: number, month: number, day: number ): Promise Opens the system date picker. Returns a Promise that resolves with the selected date string.
Async Function ui.getKeyboardInput( initialText: string, layout?: number, maxLength?: number ): Promise Opens the system on-screen keyboard. Returns a Promise that resolves with the entered text.
Function ui.imageBuffer( data: string, format: string, options?: object ): void Draws an image from a binary string buffer with the given format and optional options.
Function ui.imagePath( path: string, options?: object ): void Draws an image loaded from a file path with optional position and transform options.
Constant ui.KEYBOARD_NUMBERS Numeric keypad layout.
Constant ui.KEYBOARD_NUMERIC Numeric input layout.
Constant ui.KEYBOARD_TEXT Full text keyboard layout.
Constant ui.LIST_SCROLL Scroll list navigation mode.
Constant ui.LIST_SELECT Select list navigation mode.
Constant ui.LIST_SPLIT Split list navigation mode.
Function ui.listTouch( tx: number, ty: number, itemH: number, visible: number, x: number, y: number, w: number, h: number, mode: number, offset: number ): object Handles touch interaction for a scrollable list. Returns an object with action, index, and offset.
Returns
{ action: string, index: number, offset: number }
Function ui.print( text: any ): void Prints text at the current cursor position.
Function ui.qr( text: string, x: number, y: number, size: number, color?: number ): void Draws a QR code from the given text at the specified position and size.
Function ui.selectDraw( options: array, selected: number, textSize?: number ): void Draws a set of selectable option buttons from an array of option objects.
Function ui.selectHit( x: number, y: number, options: array, padding?: number ): any | undefined Hits tests a set of selectable option buttons. Returns the value of the hit option or undefined.
Function ui.setCursor( x: number, y: number ): void Moves the text cursor to the given x, y position.
Function ui.setFont( font: string|number ): void Sets the current font by name string or numeric font ID.
Function ui.setTextColor( color: number ): void Sets the text color (0 = white, 1 = black).
Function ui.setTextSize( size: number ): void Sets the text size multiplier.
Function ui.vectorPath( path: string, options?: object ): void Draws a vector graphic (SVG) loaded from a file with optional position and transform.
Function ui.vectorString( svg: string, options?: object ): void Draws a vector graphic (SVG) from an inline string with optional position and transform.
Constant ui.WHITE White color value.