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?
if (PMU->isPekeyLongPressIrq()) {
LOG_DEBUG("PEK long button press");
screen->setOn(false);
if (screen)
screen->setOn(false);
}
#endif

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -84,7 +84,8 @@ bool RemoteHardwareModule::handleReceivedProtobuf(const meshtastic_MeshPacket &r
switch (p.type) {
case meshtastic_HardwareMessage_Type_WRITE_GPIOS: {
// Print notification to LCD screen
screen->print("Write GPIOs\n");
if (screen)
screen->print("Write GPIOs\n");
pinModes(p.gpio_mask, OUTPUT, availablePins);
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
LOG_INFO("Received message from=0x%0x, id=%d, msg=%.*s", req.from, req.id, p.payload.size, p.payload.bytes);
#endif
screen->print("Send reply\n");
if (screen)
screen->print("Send reply\n");
const char *replyStr = "Message Received";
auto reply = allocDataPacket(); // Allocate a packet for sending

View File

@ -37,7 +37,8 @@ int32_t BMX160Sensor::runOnce()
if (!showingScreen) {
powerFSM.trigger(EVENT_PRESS); // keep screen alive during calibration
showingScreen = true;
screen->startAlert((FrameCallback)drawFrameCalibration);
if (screen)
screen->startAlert((FrameCallback)drawFrameCalibration);
}
if (magAccel.x > highestX)
@ -58,7 +59,8 @@ int32_t BMX160Sensor::runOnce()
doCalibration = false;
endCalibrationAt = 0;
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,
@ -103,8 +105,8 @@ int32_t BMX160Sensor::runOnce()
heading += 270;
break;
}
screen->setHeading(heading);
if (screen)
screen->setHeading(heading);
#endif
return MOTION_SENSOR_CHECK_INTERVAL_MS;
@ -118,7 +120,8 @@ void BMX160Sensor::calibrate(uint16_t forSeconds)
doCalibration = true;
uint16_t calibrateFor = forSeconds * 1000; // calibrate for seconds provided
endCalibrationAt = millis() + calibrateFor;
screen->setEndCalibration(endCalibrationAt);
if (screen)
screen->setEndCalibration(endCalibrationAt);
#endif
}

View File

@ -60,7 +60,8 @@ int32_t ICM20948Sensor::runOnce()
if (!showingScreen) {
powerFSM.trigger(EVENT_PRESS); // keep screen alive during calibration
showingScreen = true;
screen->startAlert((FrameCallback)drawFrameCalibration);
if (screen)
screen->startAlert((FrameCallback)drawFrameCalibration);
}
if (magX > highestX)
@ -81,7 +82,8 @@ int32_t ICM20948Sensor::runOnce()
doCalibration = false;
endCalibrationAt = 0;
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,
@ -124,8 +126,8 @@ int32_t ICM20948Sensor::runOnce()
heading += 270;
break;
}
screen->setHeading(heading);
if (screen)
screen->setHeading(heading);
#endif
// 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;
uint16_t calibrateFor = forSeconds * 1000; // calibrate for seconds provided
endCalibrationAt = millis() + calibrateFor;
screen->setEndCalibration(endCalibrationAt);
if (screen)
screen->setEndCalibration(endCalibrationAt);
#endif
}
// ----------------------------------------------------------------------

View File

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

View File

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

View File

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