Fix CoreInk list contrast fade with a clean windowed differential partial
Navigating the vault list faded the retained content and forced whole-panel
refreshes: the list used the fast-animation partial LUT (tuned for the PIN arc),
whose short waveform does not hold retained pixels, and the standard differential
partial still drives the WHOLE panel each move so every retained pixel drifts
lighter until a full refresh cleans it. On-glass the list was unreadable.
Add a readable render mode and a true dirty-region e-paper update:
- EinkRenderMode::OneBitQuality — standard (non-fast) 1-bit partial for readable
navigable screens (the vault list, TOTP tab, settings tree, host picker); the
fast LUT stays for genuinely animated surfaces (the PIN timing arc). HomeState's
vault sub-pages now return it; the credential detail keeps GrayOnEntry.
- Quality partial now windows BOTH the RAM write and the refresh to the damage
rows, so pixels outside the window are never driven and hold full contrast. The
SSD1681 ping-pongs its B/W banks on every mode-2 update, so the touched window is
written to both banks (before and after the swap) to stay coherent.
- Crucially, settleAlternateRamBank() now runs after EVERY full refresh, not only
in fast mode: the full mode-1 refresh does not ping-pong the banks, so the
alternate bank kept an old frame (the PIN arc) that the windowed mode-2 partials
swapped back in as a ghost. Settling both banks with the displayed frame removes
it.
- Raise kFullRefreshEveryN 8 -> 40: the windowed quality partial holds contrast
without accumulating ghosting, so the periodic cleanup flash can be rare.
Verified on the M5Stack CoreInk: the list navigates dirty-region only, retained
content keeps full contrast across many moves, and the PIN-arc ghost is gone.
Claude-Session: https://claude.ai/code/session_01P6BNTpbgrvnZXSJnNuj8ZJ