diff --git a/src/lgfx/v1/panel/Panel_IT8951.cpp b/src/lgfx/v1/panel/Panel_IT8951.cpp index 223b4a0f..d3beaef4 100644 --- a/src/lgfx/v1/panel/Panel_IT8951.cpp +++ b/src/lgfx/v1/panel/Panel_IT8951.cpp @@ -241,10 +241,14 @@ IT8951 Registers defines _bus->endTransaction(); } - bool Panel_IT8951::_wait_busy(uint32_t timeout) + // Bounded poll of the BUSY pin, without touching chip-select. + // Returns false after `timeout` ms if BUSY never deasserts (e.g. the + // panel's boost converter browned out and left BUSY stuck), instead of + // spinning forever. Shared by _wait_busy() below and by _write_args(), + // which must keep CS asserted continuously across a multi-word burst + // and therefore can't use _wait_busy() directly. + bool Panel_IT8951::_wait_busy_pin(uint32_t timeout) { - _bus->wait(); - cs_control(true); if (_cfg.pin_busy >= 0 && !lgfx::gpio_in(_cfg.pin_busy)) { auto start_ms = millis(); @@ -264,6 +268,17 @@ IT8951 Registers defines } } while (!lgfx::gpio_in(_cfg.pin_busy)); } + return true; + } + + bool Panel_IT8951::_wait_busy(uint32_t timeout) + { + _bus->wait(); + cs_control(true); + if (!_wait_busy_pin(timeout)) + { + return false; + } cs_control(false); return true; } @@ -339,7 +354,13 @@ IT8951 Registers defines { uint32_t buf = getSwap16(args[i]); _bus->wait(); - while (!lgfx::gpio_in(_cfg.pin_busy)); + // CS must stay asserted for the whole multi-word burst, so this + // can't go through _wait_busy() (it toggles CS). A stuck BUSY + // line must still fail out here rather than hang forever. + if (!_wait_busy_pin()) + { + return false; + } _bus->writeData(buf, 16); } while ( ++i < length ); return true; diff --git a/src/lgfx/v1/panel/Panel_IT8951.hpp b/src/lgfx/v1/panel/Panel_IT8951.hpp index 0a44a700..89033e56 100644 --- a/src/lgfx/v1/panel/Panel_IT8951.hpp +++ b/src/lgfx/v1/panel/Panel_IT8951.hpp @@ -88,6 +88,7 @@ namespace lgfx uint16_t _vcom = 0; bool _wait_busy( uint32_t timeout = 4096); + bool _wait_busy_pin( uint32_t timeout = 4096); bool _write_command( uint16_t cmd); bool _write_word( uint16_t data); bool _write_args( uint16_t cmd, uint16_t *args, int32_t length);