From 95da006db37990536655cc1b299295b82a7caaba Mon Sep 17 00:00:00 2001 From: liu weikai Date: Sat, 25 Jul 2026 20:06:35 +0800 Subject: [PATCH] diagnose ST7796 panel response --- boards/tlora_pager/src/tlora_pager_board.cpp | 11 ++-- .../boards/include/display/DisplayInterface.h | 2 + .../boards/src/display/DisplayInterface.cpp | 63 +++++++++++++++++++ 3 files changed, 71 insertions(+), 5 deletions(-) diff --git a/boards/tlora_pager/src/tlora_pager_board.cpp b/boards/tlora_pager/src/tlora_pager_board.cpp index bdcde144..e7007c5e 100644 --- a/boards/tlora_pager/src/tlora_pager_board.cpp +++ b/boards/tlora_pager/src/tlora_pager_board.cpp @@ -553,14 +553,15 @@ uint32_t TLoRaPagerBoard::begin(uint32_t disable_hw_init) DISP_HEIGHT, static_cast(kPagerDisplaySpiClockMhz)); - // Initialize SPI bus for LoRa/SD (shared SPI bus) - Serial.printf("[TLoRaPagerBoard::begin] shared spi bus begin sck=%d miso=%d mosi=%d\n", + // DisplayInterface::init() is the sole SPI controller initializer for + // this board. Do not call SPI.begin() again after the panel has been + // initialized: reinitializing the shared peripheral here can reset + // controller state after the ST7796 command sequence has completed. + Serial.printf("[TLoRaPagerBoard::begin] shared spi bus ready owner=display " + "sck=%d miso=%d mosi=%d\n", LORA_SCK, LORA_MISO, LORA_MOSI); - SPI.begin(LORA_SCK, LORA_MISO, LORA_MOSI); - log_d("SPI bus initialized (SCK=%d, MISO=%d, MOSI=%d)", LORA_SCK, LORA_MISO, LORA_MOSI); - Serial.printf("[TLoRaPagerBoard::begin] shared spi bus end\n"); display_hardware_initialized_ = true; Serial.printf("[TLoRaPagerBoard::begin] ===== DISPLAY HARDWARE READY =====\n"); diff --git a/platform/esp/boards/include/display/DisplayInterface.h b/platform/esp/boards/include/display/DisplayInterface.h index 5ae4183a..e37ea584 100644 --- a/platform/esp/boards/include/display/DisplayInterface.h +++ b/platform/esp/boards/include/display/DisplayInterface.h @@ -140,6 +140,8 @@ class LilyGoDispArduinoSPI void writeDataLocked(uint8_t data); void writeCommandLocked(uint8_t cmd); void setAddrWindowLocked(uint16_t xs, uint16_t ys, uint16_t xe, uint16_t ye); + bool readRegister(uint8_t cmd, uint8_t* data, size_t length); + void readRegisterLocked(uint8_t cmd, uint8_t* data, size_t length); public: uint16_t _width = 0; diff --git a/platform/esp/boards/src/display/DisplayInterface.cpp b/platform/esp/boards/src/display/DisplayInterface.cpp index c576ef1d..0d3651ed 100644 --- a/platform/esp/boards/src/display/DisplayInterface.cpp +++ b/platform/esp/boards/src/display/DisplayInterface.cpp @@ -16,6 +16,7 @@ namespace { constexpr uint32_t kDisplayFrameWaitMs = 45U; constexpr uint32_t kDisplayControlWaitMs = 50U; +constexpr uint32_t kDisplayReadFrequencyHz = 8000000U; constexpr uint32_t kDisplayLockTimeoutLogIntervalMs = 1000; constexpr uint32_t kDisplayBusResource = platform::esp::common::SharedSpiCoordinator::kSharedBusResource; constexpr uint32_t kDisplayCommandId = 0x44495350U; // "DISP" @@ -154,6 +155,31 @@ bool LilyGoDispArduinoSPI::init(int sck, return false; } + uint8_t display_id[3]{}; + uint8_t display_status[4]{}; + uint8_t display_madctl[1]{}; + uint8_t display_colmod[1]{}; + const bool id_read = readRegister(0x04, display_id, sizeof(display_id)); + const bool status_read = readRegister(0x09, display_status, sizeof(display_status)); + const bool madctl_read = readRegister(0x0B, display_madctl, sizeof(display_madctl)); + const bool colmod_read = readRegister(0x0C, display_colmod, sizeof(display_colmod)); + Serial.printf("[DISPLAY][READBACK] id_ok=%d id=%02X:%02X:%02X " + "status_ok=%d status=%02X:%02X:%02X:%02X " + "madctl_ok=%d madctl=%02X colmod_ok=%d colmod=%02X\n", + id_read ? 1 : 0, + static_cast(display_id[0]), + static_cast(display_id[1]), + static_cast(display_id[2]), + status_read ? 1 : 0, + static_cast(display_status[0]), + static_cast(display_status[1]), + static_cast(display_status[2]), + static_cast(display_status[3]), + madctl_read ? 1 : 0, + static_cast(display_madctl[0]), + colmod_read ? 1 : 0, + static_cast(display_colmod[0])); + setRotation(0); Serial.printf("[DISPLAY][INIT] rotation=0 logical=%ux%u offset=(%u,%u) " "coord_requests=%lu busy=%lu failures=%lu\n", @@ -454,3 +480,40 @@ void LilyGoDispArduinoSPI::writeParamsLocked(uint8_t cmd, uint8_t* data, size_t } } } + +bool LilyGoDispArduinoSPI::readRegister(uint8_t cmd, uint8_t* data, size_t length) +{ + if (data == nullptr || length == 0U) + { + return false; + } + + sys::runtime::ScopedBusAccessToken bus( + platform::esp::common::shared_spi_coordinator(), + make_display_request(sys::runtime::BusAccessPolicy::InteractiveWorkerBounded, + kDisplayControlWaitMs)); + if (!bus.acquired()) + { + log_display_lock_timeout("readRegister", bus.result()); + return false; + } + readRegisterLocked(cmd, data, length); + bus.release(); + return true; +} + +void LilyGoDispArduinoSPI::readRegisterLocked(uint8_t cmd, uint8_t* data, size_t length) +{ + digitalWrite(_cs, LOW); + _spi->beginTransaction(SPISettings(kDisplayReadFrequencyHz, MSBFIRST, SPI_MODE0)); + digitalWrite(_dc, LOW); + _spi->transfer(cmd); + digitalWrite(_dc, HIGH); + (void)_spi->transfer(0x00U); + for (size_t i = 0; i < length; ++i) + { + data[i] = _spi->transfer(0x00U); + } + _spi->endTransaction(); + digitalWrite(_cs, HIGH); +}