mirror of
https://github.com/MarekZegare4/MeshCore-Solo.git
synced 2026-10-08 18:56:40 +00:00
fix(radio): keep the radio serviced while an e-ink refresh blocks the loop
GxEPD2 polls the panel's BUSY pin for the whole refresh (up to ~1-2s), stalling the main loop. A TX finishing in that window left the SX126x in standby -- deaf -- until the refresh ended; packets received meanwhile could be lost (only the latest is readable, and a later CRC failure rejects a good one still pending). Hook GxEPD2's busy callback to finish TX / drain RX into a small staging queue and re-arm right away, without touching dispatch/UI. Wired only where the display driver supports it (GxEPD2: the two e-ink Solo boards); OLED and sim builds are unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -30,6 +30,14 @@ protected:
|
||||
unsigned long _marquee_next_at = 0;
|
||||
DisplayDriver(int w, int h) { _w = w; _h = h; }
|
||||
void setDimensions(int w, int h) { _w = w; _h = h; }
|
||||
|
||||
// Registered via setBusyPumpFn() below; drivers whose underlying vendor
|
||||
// library exposes a hook for its blocking hardware wait (e.g. GxEPD2's
|
||||
// setBusyCallback()) call this from it. Default no-op, so any driver/board
|
||||
// that never wires one up behaves exactly as before.
|
||||
void (*_busy_pump_fn)(void*) = nullptr;
|
||||
void* _busy_pump_ctx = nullptr;
|
||||
void callBusyPump() { if (_busy_pump_fn) _busy_pump_fn(_busy_pump_ctx); }
|
||||
public:
|
||||
enum Color { DARK=0, LIGHT, RED, GREEN, BLUE, YELLOW, ORANGE }; // on b/w screen, colors will be !=0 synonym of light
|
||||
|
||||
@@ -499,6 +507,14 @@ public:
|
||||
virtual void setFullRefreshInterval(uint8_t n) { } // e-ink: do full refresh every n partial refreshes (0=never)
|
||||
virtual void endFrame() = 0;
|
||||
|
||||
// Called from board setup to run safe background work during a blocking
|
||||
// hardware wait (currently: an e-ink panel's BUSY-pin poll, which can run
|
||||
// for over a second on a full refresh and would otherwise stall the whole
|
||||
// main loop -- see RadioLibWrapper::pumpRecvDuringBlockingWait(), the
|
||||
// motivating use). fn must not touch this display or any UI state: it can
|
||||
// run reentrantly, nested inside the very call it's servicing.
|
||||
void setBusyPumpFn(void (*fn)(void*), void* ctx) { _busy_pump_fn = fn; _busy_pump_ctx = ctx; }
|
||||
|
||||
#ifdef ENABLE_SCREENSHOT
|
||||
// Screenshot support — return raw framebuffer and its size in bytes.
|
||||
// 0=OLED (page-based, column-major), 1=e-ink (row-major, MSB-first, 1=white/0=black).
|
||||
|
||||
Reference in New Issue
Block a user