Skip to content

MAX31865 (SPI): deadlock in SPI.beginTransaction() due to LovyanGFX holding SPI bus after DMA flush #82

Description

@knifter

Description

Selecting the MAX31865 as an input driver causes the device to hang after the boot screen.

Root Cause

The hang occurs in SPIDevice::beginTransaction() (the Arduino SPI.beginTransaction() call), which blocks forever on xSemaphoreTake().

The display on M5Stack Core uses the VSPI peripheral, driven by LovyanGFX using its own low-level ESP32 SPI driver. The Arduino SPI object also defaults to VSPI. They share the same hardware peripheral.

In the LVGL flush callback (lv_disp_cb), _lgfx.startWrite() is called followed by pushImageDMA(), which starts a DMA transfer and returns immediately — the bus is still held. endWrite() is only called from lv_flush_wait_cb, which LVGL invokes lazily at the start of the next flush cycle.

Between gui.loop() returning and pid->loop() executing in main.cpp, the LovyanGFX DMA transfer is in flight and the SPI bus is still owned. When MAX31865Driver::read() calls into SPIDevice, SPI.beginTransaction() tries to take the VSPI semaphore and blocks forever.

Affected code

  • lib-soogh/src/soogh-lgfx.cpp — lv_disp_cb / lv_flush_wait_cb
  • src/main.cpp — loop(), ordering of gui.loop() and pid->loop()
  • src/inputdrv.h — MAX31865Driver uses SPI (VSPI)

Proposed Fix

Add lgfx_check_flush() to lib-soogh: if DMA is still busy, wait and call _lgfx.endWrite() to release the bus. Call this from main.cpp::loop() after gui.loop() and before pid->loop().

// soogh-lgfx.cpp
void lgfx_check_flush() {
    if (!_lgfx.dmaBusy()) return;
    while (_lgfx.dmaBusy()) yield();
    _lgfx.endWrite();
}
// main.cpp loop()
gui.loop();
lgfx_check_flush();   // release SPI bus before PID drivers use it
for (PIDLoop* pid : pids) pid->loop();

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions