mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-10-23 20:22:26 +00:00
Keep Indicator RGB scanout alive during expander recovery
This commit is contained in:
1 parent
260b07999e
commit
6df9a9f686
3 files changed
+41
-8
No files matched your search
@@ -826,6 +826,7 @@ void halt() {
|
||||
CompanionWiFiDisplayState::NotRendered;
|
||||
static uint32_t companion_wifi_display_frames = 0;
|
||||
static bool companion_display_available = false;
|
||||
static uint8_t companion_display_begin_status = 0;
|
||||
|
||||
#if defined(COMPANION_EXCLUSIVE_WIFI_BLE)
|
||||
static CompanionTransportMode companion_transport_boot_mode =
|
||||
@@ -1174,10 +1175,11 @@ void halt() {
|
||||
const bool idf_associated =
|
||||
esp_wifi_sta_get_ap_info(&access_point) == ESP_OK;
|
||||
snprintf(reply, reply_size,
|
||||
"> state=%s, frames=%lu, display=%u, requested=%u, services=%u, "
|
||||
"> state=%s, frames=%lu, display=%u/%02X, requested=%u, services=%u, "
|
||||
"wl=%d, idf=%u, IP=%s",
|
||||
names[state], (unsigned long)companion_wifi_display_frames,
|
||||
companion_display_available ? 1U : 0U,
|
||||
(unsigned int)companion_display_begin_status,
|
||||
companion_wifi_requested ? 1U : 0U,
|
||||
companion_wifi_active ? 1U : 0U, (int)WiFi.status(),
|
||||
idf_associated ? 1U : 0U,
|
||||
@@ -1737,6 +1739,7 @@ void setup() {
|
||||
}
|
||||
#if defined(ESP32) && defined(WIFI_SSID)
|
||||
companion_display_available = disp != NULL;
|
||||
companion_display_begin_status = display.beginStatus();
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -42,10 +42,15 @@ class IndicatorDisplayProfileTest(unittest.TestCase):
|
||||
def test_panel_cs_release_cannot_discard_initialized_display(self):
|
||||
display = INDICATOR_DISPLAY.read_text()
|
||||
self.assertIn("releasePanelChipSelectWithRetry()", display)
|
||||
self.assertIn("if (!initialized) return false;", display)
|
||||
self.assertIn("if (!initialized) {", display)
|
||||
self.assertIn("begin_status = 0x82;", display)
|
||||
self.assertNotIn("if (!initialized || !released) return false;", display)
|
||||
self.assertIn("panel_chip_select_released =", display)
|
||||
self.assertIn("void startFrame(ColorVal bkg", display)
|
||||
self.assertIn("const bool controllers_prepared = prepareControllers()", display)
|
||||
self.assertIn("begin_status = controllers_prepared ? 4 : 0x84", display)
|
||||
self.assertIn("if (expander_address == 0 && prepareControllers())", display)
|
||||
self.assertIn("uint8_t beginStatus() const", display)
|
||||
|
||||
def test_preserves_original_indicator_memory_profile(self):
|
||||
profile = base_profile()
|
||||
|
||||
@@ -130,6 +130,7 @@ class SCIndicatorDisplay : public LGFXDisplay {
|
||||
uint8_t expander_address = 0;
|
||||
uint16_t expander_output = 0;
|
||||
bool panel_chip_select_released = false;
|
||||
uint8_t begin_status = 0;
|
||||
|
||||
static constexpr gpio_num_t BACKLIGHT_PIN = GPIO_NUM_45;
|
||||
static constexpr uint8_t I2C_PORT = 0;
|
||||
@@ -218,10 +219,14 @@ class SCIndicatorDisplay : public LGFXDisplay {
|
||||
}
|
||||
|
||||
bool prepareControllers() {
|
||||
if (!lgfx::i2c::init(I2C_PORT, PIN_BOARD_SDA, PIN_BOARD_SCL).has_value()) {
|
||||
return false;
|
||||
for (uint8_t attempt = 0; attempt < 10; ++attempt) {
|
||||
if (lgfx::i2c::init(I2C_PORT, PIN_BOARD_SDA, PIN_BOARD_SCL).has_value()
|
||||
&& (prepareControllersAt(0x20) || prepareControllersAt(0x39))) {
|
||||
return true;
|
||||
}
|
||||
delay(20);
|
||||
}
|
||||
return prepareControllersAt(0x20) || prepareControllersAt(0x39);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool releasePanelChipSelect() {
|
||||
@@ -258,15 +263,23 @@ public:
|
||||
#endif
|
||||
|
||||
bool begin() {
|
||||
if (!prepareControllers()) return false;
|
||||
begin_status = 1;
|
||||
const bool controllers_prepared = prepareControllers();
|
||||
begin_status = controllers_prepared ? 2 : 0x81;
|
||||
const bool initialized = LGFXDisplay::begin();
|
||||
if (!initialized) return false;
|
||||
if (!initialized) {
|
||||
begin_status = 0x82;
|
||||
return false;
|
||||
}
|
||||
begin_status = controllers_prepared ? 3 : 0x83;
|
||||
|
||||
// A failed CS release must not discard an otherwise valid 115 KiB render
|
||||
// buffer and leave the LCD showing its pre-reset scanout forever. Keep the
|
||||
// UI alive and retry from startFrame(); the common case succeeds here
|
||||
// before the external LoRa radio is initialized.
|
||||
panel_chip_select_released = releasePanelChipSelectWithRetry();
|
||||
if (controllers_prepared) {
|
||||
panel_chip_select_released = releasePanelChipSelectWithRetry();
|
||||
}
|
||||
setBacklight(true);
|
||||
size_t fontSize;
|
||||
uint8_t* fontData = IndicatorFontClient::load(fontSize);
|
||||
@@ -280,16 +293,28 @@ public:
|
||||
}
|
||||
#endif
|
||||
}
|
||||
begin_status = controllers_prepared ? 4 : 0x84;
|
||||
return true;
|
||||
}
|
||||
|
||||
void startFrame(ColorVal bkg = UIColor::window_bkg) override {
|
||||
if (expander_address == 0 && prepareControllers()) {
|
||||
// The RGB scanout can start while the shared expander is temporarily
|
||||
// unavailable. Once it recovers, re-run the panel command sequence and
|
||||
// release CS before presenting the next complete frame.
|
||||
if (disp.init()) {
|
||||
panel_chip_select_released = releasePanelChipSelectWithRetry();
|
||||
begin_status = 5;
|
||||
}
|
||||
}
|
||||
if (!panel_chip_select_released) {
|
||||
panel_chip_select_released = releasePanelChipSelectWithRetry();
|
||||
}
|
||||
LGFXDisplay::startFrame(bkg);
|
||||
}
|
||||
|
||||
uint8_t beginStatus() const { return begin_status; }
|
||||
|
||||
#ifdef INDICATOR_WIFI_FONT_RECOVERY
|
||||
void serviceFontRecovery() {
|
||||
size_t fontSize = 0;
|
||||
|
||||
Reference in new issue
Block a user