diff --git a/src/lgfx/v1/panel/Panel_AMOLED.cpp b/src/lgfx/v1/panel/Panel_AMOLED.cpp index 7aed8b9..3d402b1 100644 --- a/src/lgfx/v1/panel/Panel_AMOLED.cpp +++ b/src/lgfx/v1/panel/Panel_AMOLED.cpp @@ -685,6 +685,31 @@ namespace lgfx buf[0] = bus->getDMABuffer(wb); buf[1] = bus->getDMABuffer(wb); + // getDMABuffer() returns nullptr when the DMA-capable internal heap + // cannot satisfy the per-line buffer (transient starvation under + // memory pressure). Skip this flush rather than memcpy into a null + // pointer; _range_mod stays dirty so the next display() retries once + // memory frees. Without this a null buffer faults (StoreProhibited). + // Log only the OOM edge and the recovery edge, not every frame. + if (!buf[0] || !buf[1]) + { + if (!_dma_oom) + { + _dma_oom = true; +#if defined ( ESP_LOGW ) + ESP_LOGW("Panel_AMOLED", "DMA buffer alloc failed (%u bytes/line); deferring flush", (unsigned)wb); +#endif + } + return; + } + if (_dma_oom) + { + _dma_oom = false; +#if defined ( ESP_LOGI ) + ESP_LOGI("Panel_AMOLED", "DMA buffer available; resuming flush"); +#endif + } + _panel->start_qspi(); int fbpos = ys * stride + (xs * bpp); diff --git a/src/lgfx/v1/panel/Panel_AMOLED.hpp b/src/lgfx/v1/panel/Panel_AMOLED.hpp index 807fe08..8ebe56b 100644 --- a/src/lgfx/v1/panel/Panel_AMOLED.hpp +++ b/src/lgfx/v1/panel/Panel_AMOLED.hpp @@ -55,6 +55,7 @@ namespace lgfx protected: uint8_t* _frame_buffer = nullptr; Panel_AMOLED* _panel = nullptr; + bool _dma_oom = false; // edge state: DMA line-buffer alloc failing };