Check for null screen

This commit is contained in:
Jonathan Bennett 2025-05-17 22:03:23 -05:00
parent 212005bfe9
commit f1440a27d7
14 changed files with 85 additions and 60 deletions

View File

@ -853,7 +853,8 @@ int32_t Power::runOnce()
#ifndef T_WATCH_S3 // FIXME - why is this triggering on the T-Watch S3? #ifndef T_WATCH_S3 // FIXME - why is this triggering on the T-Watch S3?
if (PMU->isPekeyLongPressIrq()) { if (PMU->isPekeyLongPressIrq()) {
LOG_DEBUG("PEK long button press"); LOG_DEBUG("PEK long button press");
screen->setOn(false); if (screen)
screen->setOn(false);
} }
#endif #endif

View File

@ -82,7 +82,8 @@ static uint32_t secsSlept;
static void lsEnter() static void lsEnter()
{ {
LOG_INFO("lsEnter begin, ls_secs=%u", config.power.ls_secs); LOG_INFO("lsEnter begin, ls_secs=%u", config.power.ls_secs);
screen->setOn(false); if (screen)
screen->setOn(false);
secsSlept = 0; // How long have we been sleeping this time secsSlept = 0; // How long have we been sleeping this time
// LOG_INFO("lsEnter end"); // LOG_INFO("lsEnter end");
@ -160,7 +161,8 @@ static void lsExit()
static void nbEnter() static void nbEnter()
{ {
LOG_DEBUG("State: NB"); LOG_DEBUG("State: NB");
screen->setOn(false); if (screen)
screen->setOn(false);
#ifdef ARCH_ESP32 #ifdef ARCH_ESP32
// Only ESP32 should turn off bluetooth // Only ESP32 should turn off bluetooth
setBluetoothEnable(false); setBluetoothEnable(false);
@ -190,7 +192,8 @@ static void serialExit()
{ {
// Turn bluetooth back on when we leave serial stream API // Turn bluetooth back on when we leave serial stream API
setBluetoothEnable(true); setBluetoothEnable(true);
screen->print("Serial disconnected\n"); if (screen)
screen->print("Serial disconnected\n");
} }
static void powerEnter() static void powerEnter()
@ -201,7 +204,7 @@ static void powerEnter()
LOG_INFO("Loss of power in Powered"); LOG_INFO("Loss of power in Powered");
powerFSM.trigger(EVENT_POWER_DISCONNECTED); powerFSM.trigger(EVENT_POWER_DISCONNECTED);
} else { } else {
if (config.display.displaymode != meshtastic_Config_DisplayConfig_DisplayMode_COLOR ) if (screen)
screen->setOn(true); screen->setOn(true);
setBluetoothEnable(true); setBluetoothEnable(true);
// within enter() the function getState() returns the state we came from // within enter() the function getState() returns the state we came from
@ -226,7 +229,7 @@ static void powerIdle()
static void powerExit() static void powerExit()
{ {
if (screen) if (screen)
screen->setOn(true); screen->setOn(true);
setBluetoothEnable(true); setBluetoothEnable(true);
// Mothballed: print change of power-state to device screen // Mothballed: print change of power-state to device screen
@ -237,7 +240,8 @@ static void powerExit()
static void onEnter() static void onEnter()
{ {
LOG_DEBUG("State: ON"); LOG_DEBUG("State: ON");
screen->setOn(true); if (screen)
screen->setOn(true);
setBluetoothEnable(true); setBluetoothEnable(true);
} }
@ -251,7 +255,8 @@ static void onIdle()
static void screenPress() static void screenPress()
{ {
screen->onPress(); if (screen)
screen->onPress();
} }
static void bootEnter() static void bootEnter()

View File

@ -84,7 +84,8 @@ int32_t ScanAndSelectInput::runOnce()
// Dismiss the alert screen several seconds after it appears // Dismiss the alert screen several seconds after it appears
if (!Throttle::isWithinTimespanMs(alertingSinceMs, durationAlertMs)) { if (!Throttle::isWithinTimespanMs(alertingSinceMs, durationAlertMs)) {
alertingNoMessage = false; alertingNoMessage = false;
screen->endAlert(); if (screen)
screen->endAlert();
} }
} }
@ -183,13 +184,15 @@ void ScanAndSelectInput::alertNoMessage()
alertingSinceMs = millis(); alertingSinceMs = millis();
// Graphics code: the alert frame to show on screen // Graphics code: the alert frame to show on screen
screen->startAlert([](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void { if (screen) {
display->setTextAlignment(TEXT_ALIGN_CENTER_BOTH); screen->startAlert([](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
display->setFont(FONT_SMALL); display->setTextAlignment(TEXT_ALIGN_CENTER_BOTH);
int16_t textX = display->getWidth() / 2; display->setFont(FONT_SMALL);
int16_t textY = display->getHeight() / 2; int16_t textX = display->getWidth() / 2;
display->drawString(textX + x, textY + y, "No Canned Messages"); int16_t textY = display->getHeight() / 2;
}); display->drawString(textX + x, textY + y, "No Canned Messages");
});
}
} }
// Remove the canned message frame from screen // Remove the canned message frame from screen

View File

@ -1227,7 +1227,8 @@ void setup()
nodeDB->saveToDisk(SEGMENT_CONFIG); nodeDB->saveToDisk(SEGMENT_CONFIG);
if (!rIf->reconfigure()) { if (!rIf->reconfigure()) {
LOG_WARN("Reconfigure failed, rebooting"); LOG_WARN("Reconfigure failed, rebooting");
screen->startAlert("Rebooting..."); if (screen)
screen->startAlert("Rebooting...");
rebootAtMsec = millis() + 5000; rebootAtMsec = millis() + 5000;
} }
} }

View File

@ -903,6 +903,7 @@ void handleBlinkLED(HTTPRequest *req, HTTPResponse *res)
} }
} else { } else {
#if HAS_SCREEN #if HAS_SCREEN
if (screen)
screen->blink(); screen->blink();
#endif #endif
} }

View File

@ -154,7 +154,8 @@ void createSSLCert()
esp_task_wdt_reset(); esp_task_wdt_reset();
#if HAS_SCREEN #if HAS_SCREEN
if (millis() / 1000 >= 3) { if (millis() / 1000 >= 3) {
screen->setSSLFrames(); if (screen)
screen->setSSLFrames();
} }
#endif #endif
} }

View File

@ -200,14 +200,16 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta
#if defined(ARCH_ESP32) #if defined(ARCH_ESP32)
#if !MESHTASTIC_EXCLUDE_BLUETOOTH #if !MESHTASTIC_EXCLUDE_BLUETOOTH
if (!BleOta::getOtaAppVersion().isEmpty()) { if (!BleOta::getOtaAppVersion().isEmpty()) {
screen->startFirmwareUpdateScreen(); if (screen)
screen->startFirmwareUpdateScreen();
BleOta::switchToOtaApp(); BleOta::switchToOtaApp();
LOG_INFO("Rebooting to BLE OTA"); LOG_INFO("Rebooting to BLE OTA");
} }
#endif #endif
#if !MESHTASTIC_EXCLUDE_WIFI #if !MESHTASTIC_EXCLUDE_WIFI
if (WiFiOTA::trySwitchToOTA()) { if (WiFiOTA::trySwitchToOTA()) {
screen->startFirmwareUpdateScreen(); if (screen)
screen->startFirmwareUpdateScreen();
WiFiOTA::saveConfig(&config.network); WiFiOTA::saveConfig(&config.network);
LOG_INFO("Rebooting to WiFi OTA"); LOG_INFO("Rebooting to WiFi OTA");
} }
@ -1111,7 +1113,8 @@ void AdminModule::handleGetDeviceUIConfig(const meshtastic_MeshPacket &req)
void AdminModule::reboot(int32_t seconds) void AdminModule::reboot(int32_t seconds)
{ {
LOG_INFO("Reboot in %d seconds", seconds); LOG_INFO("Reboot in %d seconds", seconds);
screen->startAlert("Rebooting..."); if (screen)
screen->startAlert("Rebooting...");
rebootAtMsec = (seconds < 0) ? 0 : (millis() + seconds * 1000); rebootAtMsec = (seconds < 0) ? 0 : (millis() + seconds * 1000);
} }

View File

@ -84,7 +84,8 @@ bool RemoteHardwareModule::handleReceivedProtobuf(const meshtastic_MeshPacket &r
switch (p.type) { switch (p.type) {
case meshtastic_HardwareMessage_Type_WRITE_GPIOS: { case meshtastic_HardwareMessage_Type_WRITE_GPIOS: {
// Print notification to LCD screen // Print notification to LCD screen
screen->print("Write GPIOs\n"); if (screen)
screen->print("Write GPIOs\n");
pinModes(p.gpio_mask, OUTPUT, availablePins); pinModes(p.gpio_mask, OUTPUT, availablePins);
for (uint8_t i = 0; i < NUM_GPIOS; i++) { for (uint8_t i = 0; i < NUM_GPIOS; i++) {

View File

@ -14,8 +14,8 @@ meshtastic_MeshPacket *ReplyModule::allocReply()
// The incoming message is in p.payload // The incoming message is in p.payload
LOG_INFO("Received message from=0x%0x, id=%d, msg=%.*s", req.from, req.id, p.payload.size, p.payload.bytes); LOG_INFO("Received message from=0x%0x, id=%d, msg=%.*s", req.from, req.id, p.payload.size, p.payload.bytes);
#endif #endif
if (screen)
screen->print("Send reply\n"); screen->print("Send reply\n");
const char *replyStr = "Message Received"; const char *replyStr = "Message Received";
auto reply = allocDataPacket(); // Allocate a packet for sending auto reply = allocDataPacket(); // Allocate a packet for sending

View File

@ -37,7 +37,8 @@ int32_t BMX160Sensor::runOnce()
if (!showingScreen) { if (!showingScreen) {
powerFSM.trigger(EVENT_PRESS); // keep screen alive during calibration powerFSM.trigger(EVENT_PRESS); // keep screen alive during calibration
showingScreen = true; showingScreen = true;
screen->startAlert((FrameCallback)drawFrameCalibration); if (screen)
screen->startAlert((FrameCallback)drawFrameCalibration);
} }
if (magAccel.x > highestX) if (magAccel.x > highestX)
@ -58,7 +59,8 @@ int32_t BMX160Sensor::runOnce()
doCalibration = false; doCalibration = false;
endCalibrationAt = 0; endCalibrationAt = 0;
showingScreen = false; showingScreen = false;
screen->endAlert(); if (screen)
screen->endAlert();
} }
// LOG_DEBUG("BMX160 min_x: %.4f, max_X: %.4f, min_Y: %.4f, max_Y: %.4f, min_Z: %.4f, max_Z: %.4f", lowestX, highestX, // LOG_DEBUG("BMX160 min_x: %.4f, max_X: %.4f, min_Y: %.4f, max_Y: %.4f, min_Z: %.4f, max_Z: %.4f", lowestX, highestX,
@ -103,8 +105,8 @@ int32_t BMX160Sensor::runOnce()
heading += 270; heading += 270;
break; break;
} }
if (screen)
screen->setHeading(heading); screen->setHeading(heading);
#endif #endif
return MOTION_SENSOR_CHECK_INTERVAL_MS; return MOTION_SENSOR_CHECK_INTERVAL_MS;
@ -118,7 +120,8 @@ void BMX160Sensor::calibrate(uint16_t forSeconds)
doCalibration = true; doCalibration = true;
uint16_t calibrateFor = forSeconds * 1000; // calibrate for seconds provided uint16_t calibrateFor = forSeconds * 1000; // calibrate for seconds provided
endCalibrationAt = millis() + calibrateFor; endCalibrationAt = millis() + calibrateFor;
screen->setEndCalibration(endCalibrationAt); if (screen)
screen->setEndCalibration(endCalibrationAt);
#endif #endif
} }

View File

@ -60,7 +60,8 @@ int32_t ICM20948Sensor::runOnce()
if (!showingScreen) { if (!showingScreen) {
powerFSM.trigger(EVENT_PRESS); // keep screen alive during calibration powerFSM.trigger(EVENT_PRESS); // keep screen alive during calibration
showingScreen = true; showingScreen = true;
screen->startAlert((FrameCallback)drawFrameCalibration); if (screen)
screen->startAlert((FrameCallback)drawFrameCalibration);
} }
if (magX > highestX) if (magX > highestX)
@ -81,7 +82,8 @@ int32_t ICM20948Sensor::runOnce()
doCalibration = false; doCalibration = false;
endCalibrationAt = 0; endCalibrationAt = 0;
showingScreen = false; showingScreen = false;
screen->endAlert(); if (screen)
screen->endAlert();
} }
// LOG_DEBUG("ICM20948 min_x: %.4f, max_X: %.4f, min_Y: %.4f, max_Y: %.4f, min_Z: %.4f, max_Z: %.4f", lowestX, highestX, // LOG_DEBUG("ICM20948 min_x: %.4f, max_X: %.4f, min_Y: %.4f, max_Y: %.4f, min_Z: %.4f, max_Z: %.4f", lowestX, highestX,
@ -124,8 +126,8 @@ int32_t ICM20948Sensor::runOnce()
heading += 270; heading += 270;
break; break;
} }
if (screen)
screen->setHeading(heading); screen->setHeading(heading);
#endif #endif
// Wake on motion using polling - this is not as efficient as using hardware interrupt pin (see above) // Wake on motion using polling - this is not as efficient as using hardware interrupt pin (see above)
@ -159,7 +161,8 @@ void ICM20948Sensor::calibrate(uint16_t forSeconds)
doCalibration = true; doCalibration = true;
uint16_t calibrateFor = forSeconds * 1000; // calibrate for seconds provided uint16_t calibrateFor = forSeconds * 1000; // calibrate for seconds provided
endCalibrationAt = millis() + calibrateFor; endCalibrationAt = millis() + calibrateFor;
screen->setEndCalibration(endCalibrationAt); if (screen)
screen->setEndCalibration(endCalibrationAt);
#endif #endif
} }
// ---------------------------------------------------------------------- // ----------------------------------------------------------------------

View File

@ -94,31 +94,33 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
bluetoothStatus->updateStatus(new meshtastic::BluetoothStatus(std::to_string(passkey))); bluetoothStatus->updateStatus(new meshtastic::BluetoothStatus(std::to_string(passkey)));
#if HAS_SCREEN // Todo: migrate this display code back into Screen class, and observe bluetoothStatus #if HAS_SCREEN // Todo: migrate this display code back into Screen class, and observe bluetoothStatus
screen->startAlert([passkey](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void { if (screen) {
char btPIN[16] = "888888"; screen->startAlert([passkey](OLEDDisplay *display, OLEDDisplayUiState *state, int16_t x, int16_t y) -> void {
snprintf(btPIN, sizeof(btPIN), "%06u", passkey); char btPIN[16] = "888888";
int x_offset = display->width() / 2; snprintf(btPIN, sizeof(btPIN), "%06u", passkey);
int y_offset = display->height() <= 80 ? 0 : 32; int x_offset = display->width() / 2;
display->setTextAlignment(TEXT_ALIGN_CENTER); int y_offset = display->height() <= 80 ? 0 : 32;
display->setFont(FONT_MEDIUM); display->setTextAlignment(TEXT_ALIGN_CENTER);
display->drawString(x_offset + x, y_offset + y, "Bluetooth"); display->setFont(FONT_MEDIUM);
display->drawString(x_offset + x, y_offset + y, "Bluetooth");
display->setFont(FONT_SMALL); display->setFont(FONT_SMALL);
y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_MEDIUM - 4 : y_offset + FONT_HEIGHT_MEDIUM + 5; y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_MEDIUM - 4 : y_offset + FONT_HEIGHT_MEDIUM + 5;
display->drawString(x_offset + x, y_offset + y, "Enter this code"); display->drawString(x_offset + x, y_offset + y, "Enter this code");
display->setFont(FONT_LARGE); display->setFont(FONT_LARGE);
String displayPin(btPIN); String displayPin(btPIN);
String pin = displayPin.substring(0, 3) + " " + displayPin.substring(3, 6); String pin = displayPin.substring(0, 3) + " " + displayPin.substring(3, 6);
y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_SMALL - 5 : y_offset + FONT_HEIGHT_SMALL + 5; y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_SMALL - 5 : y_offset + FONT_HEIGHT_SMALL + 5;
display->drawString(x_offset + x, y_offset + y, pin); display->drawString(x_offset + x, y_offset + y, pin);
display->setFont(FONT_SMALL); display->setFont(FONT_SMALL);
String deviceName = "Name: "; String deviceName = "Name: ";
deviceName.concat(getDeviceName()); deviceName.concat(getDeviceName());
y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_LARGE - 6 : y_offset + FONT_HEIGHT_LARGE + 5; y_offset = display->height() == 64 ? y_offset + FONT_HEIGHT_LARGE - 6 : y_offset + FONT_HEIGHT_LARGE + 5;
display->drawString(x_offset + x, y_offset + y, deviceName); display->drawString(x_offset + x, y_offset + y, deviceName);
}); });
}
#endif #endif
passkeyShowing = true; passkeyShowing = true;
@ -134,7 +136,8 @@ class NimbleBluetoothServerCallback : public NimBLEServerCallbacks
// Todo: migrate this display code back into Screen class, and observe bluetoothStatus // Todo: migrate this display code back into Screen class, and observe bluetoothStatus
if (passkeyShowing) { if (passkeyShowing) {
passkeyShowing = false; passkeyShowing = false;
screen->endAlert(); if (screen)
screen->endAlert();
} }
} }

View File

@ -41,7 +41,7 @@ void powerCommandsCheck()
} }
#if defined(ARCH_ESP32) || defined(ARCH_NRF52) #if defined(ARCH_ESP32) || defined(ARCH_NRF52)
if (shutdownAtMsec) { if (shutdownAtMsec && screen) {
screen->startAlert("Shutting down..."); screen->startAlert("Shutting down...");
} }
#endif #endif

View File

@ -221,8 +221,8 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false, bool skipSaveN
#endif #endif
powerMon->setState(meshtastic_PowerMon_State_CPU_DeepSleep); powerMon->setState(meshtastic_PowerMon_State_CPU_DeepSleep);
if (screen)
screen->doDeepSleep(); // datasheet says this will draw only 10ua screen->doDeepSleep(); // datasheet says this will draw only 10ua
if (!skipSaveNodeDb) { if (!skipSaveNodeDb) {
nodeDB->saveToDisk(); nodeDB->saveToDisk();