Refactor haltdelay to let it hang or reboot

This commit is contained in:
brentru 2025-02-13 09:45:16 -05:00
parent 340e3f880b
commit 71aa594eaf
4 changed files with 62 additions and 48 deletions

View file

@ -876,22 +876,36 @@ void Wippersnapper_V2::runNetFSMV2() {
The desired error to print to serial.
@param ledStatusColor
The desired color to blink.
@param reboot
If true, the device will reboot after the WDT bites.
If false, the device will not allow the WDT to bite and
instead hang indefinitely, holding the WIPPER drive open
*/
/**************************************************************************/
void Wippersnapper_V2::haltErrorV2(String error,
ws_led_status_t ledStatusColor) {
void Wippersnapper_V2::haltErrorV2(String error, ws_led_status_t ledStatusColor,
bool reboot) {
WS_DEBUG_PRINT("ERROR ");
if (reboot) {
WS_DEBUG_PRINT("[RESET]: ");
} else {
WS_DEBUG_PRINT("[HANG]: ");
}
WS_DEBUG_PRINTLN(error);
statusLEDSolid(ledStatusColor);
for (;;) {
WS_DEBUG_PRINT("ERROR [WDT RESET]: ");
WS_DEBUG_PRINTLN(error);
// let the WDT fail out and reset!
statusLEDSolid(ledStatusColor);
if (!reboot) {
WsV2.feedWDTV2(); // Feed the WDT indefinitely to hold the WIPPER drive
// open
} else {
// Let the WDT fail out and reset!
#ifndef ARDUINO_ARCH_ESP8266
delay(1000);
delay(1000);
#else
// Calls to delay() and yield() feed the ESP8266's
// hardware and software watchdog timers, delayMicroseconds does not.
delayMicroseconds(1000000);
// Calls to delay() and yield() feed the ESP8266's
// hardware and software watchdog timers, delayMicroseconds does not.
delayMicroseconds(1000000);
#endif
}
}
}

View file

@ -214,8 +214,7 @@ public:
// Error handling helpers
void
haltErrorV2(String error,
ws_led_status_t ledStatusColor = WS_LED_STATUS_ERROR_RUNTIME);
haltErrorV2(String error, ws_led_status_t ledStatusColor = WS_LED_STATUS_ERROR_RUNTIME, bool reboot = true);
void errorWriteHangV2(String error);
bool _is_offline_mode; ///< Global flag for if the device is in offline mode

View file

@ -518,15 +518,13 @@ bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) {
// Before we do anything on the bus - was the bus initialized correctly?
if (!IsBusStatusOK(use_alt_bus)) {
WS_DEBUG_PRINTLN("[i2c] ERROR: I2C bus is not operational or stuck, please "
"restart device!");
WsV2.haltErrorV2("[i2c] I2C bus is stuck or not operational, reset the board!", WS_LED_STATUS_ERROR_RUNTIME, false);
if (!PublishI2cDeviceAddedorReplaced(device_descriptor, device_status))
return false;
return true;
}
// Mux case #1 - We are creating a mux via I2cDeviceAddorReplace message
// TODO: Refactor
if ((strcmp(device_name, "pca9546") == 0) ||
(strcmp(device_name, "pca9548") == 0)) {
WS_DEBUG_PRINTLN("[i2c] Creating a new MUX driver obj");
@ -536,7 +534,7 @@ bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) {
_i2c_bus_alt->AddMuxToBus(device_descriptor.i2c_mux_address,
device_name);
} else {
WS_DEBUG_PRINTLN("[i2c] ERROR: Mux specified but not created");
WsV2.haltErrorV2("[i2c] Unable to initialize I2C MUX!", WS_LED_STATUS_ERROR_RUNTIME, false);
}
} else {
if (!_i2c_bus_default->HasMux()) {
@ -544,7 +542,7 @@ bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) {
_i2c_bus_default->AddMuxToBus(device_descriptor.i2c_mux_address,
device_name);
} else {
WS_DEBUG_PRINTLN("[i2c] ERROR: Mux specified but not created");
WsV2.haltErrorV2("[i2c] Unable to initialize I2C MUX!", WS_LED_STATUS_ERROR_RUNTIME, false);
}
}
// TODO: Publish back out to IO instead of blindly returning true
@ -562,11 +560,10 @@ bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) {
WS_DEBUG_PRINTLN(mux_channel);
did_set_mux_ch = true;
} else {
WS_DEBUG_PRINTLN("[i2c] ERROR: Device requests a MUX but MUX has not "
"been initialized first");
device_status =
wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_FAIL_INIT;
PublishI2cDeviceAddedorReplaced(device_descriptor, device_status);
WsV2.haltErrorV2("[i2c] Device requires a MUX but MUX not present within config.json!", WS_LED_STATUS_ERROR_RUNTIME, false);
// TODO: Online mode needs the below implemented
// device_status = wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_FAIL_INIT;
// PublishI2cDeviceAddedorReplaced(device_descriptor, device_status);
return false;
}
} else {
@ -576,11 +573,10 @@ bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) {
WS_DEBUG_PRINTLN(mux_channel);
did_set_mux_ch = true;
} else {
WS_DEBUG_PRINTLN("[i2c] ERROR: Device requests a MUX but MUX has not "
"been initialized first");
device_status =
wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_FAIL_INIT;
PublishI2cDeviceAddedorReplaced(device_descriptor, device_status);
WsV2.haltErrorV2("[i2c] Device requires a MUX but MUX not present within config.json!", WS_LED_STATUS_ERROR_RUNTIME, false);
// TODO: Online mode needs the below implemented
// device_status = wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_FAIL_INIT;
// PublishI2cDeviceAddedorReplaced(device_descriptor, device_status);
return false;
}
}
@ -636,15 +632,11 @@ bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) {
wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_FAIL_INIT;
if (WsV2._sdCardV2->isModeOffline()) {
WS_DEBUG_PRINTLN("[i2c] Driver failed to initialize!\n\tDid you set "
WsV2.haltErrorV2("[i2c] Driver failed to initialize!\n\tDid you set "
"the correct value for i2cDeviceName?\n\tDid you set "
"the correct value for"
"i2cDeviceAddress?");
while (
1) { // Keep the WIPPER drive open to allow user to edit config.json
WsV2.feedWDTV2();
delay(500);
}
"i2cDeviceAddress?",
WS_LED_STATUS_ERROR_RUNTIME, false);
}
if (!PublishI2cDeviceAddedorReplaced(device_descriptor, device_status))
return false;
@ -656,15 +648,11 @@ bool I2cController::Handle_I2cDeviceAddOrReplace(pb_istream_t *stream) {
wippersnapper_i2c_I2cDeviceStatus_I2C_DEVICE_STATUS_FAIL_UNSUPPORTED_SENSOR;
if (WsV2._sdCardV2->isModeOffline()) {
WS_DEBUG_PRINTLN("[i2c] Driver failed to initialize!\n\tDid you set "
WsV2.haltErrorV2("[i2c] Driver failed to initialize!\n\tDid you set "
"the correct value for i2cDeviceName?\n\tDid you set "
"the correct value for"
"i2cDeviceAddress?");
while (
1) { // Keep the WIPPER drive open to allow user to edit config.json
WsV2.feedWDTV2();
delay(500);
}
"i2cDeviceAddress?",
WS_LED_STATUS_ERROR_RUNTIME, false);
}
if (!PublishI2cDeviceAddedorReplaced(device_descriptor, device_status))

View file

@ -16,6 +16,7 @@
#ifndef DRV_PM25_H
#define DRV_PM25_H
#include "Wippersnapper_V2.h"
#include "drvBase.h"
#include <Adafruit_PM25AQI.h>
#include <Wire.h>
@ -41,7 +42,8 @@ public:
The name of the driver.
*/
/*******************************************************************************/
drvPm25(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel, const char* driver_name)
drvPm25(TwoWire *i2c, uint16_t sensorAddress, uint32_t mux_channel,
const char *driver_name)
: drvBase(i2c, sensorAddress, mux_channel, driver_name) {
_i2c = i2c;
_address = sensorAddress;
@ -58,8 +60,8 @@ public:
/*******************************************************************************/
bool begin() override {
_pm25 = new Adafruit_PM25AQI();
// Wait one second for sensor to boot up!
delay(1000);
// Wait three seconds for the sensor to boot up!
delay(3000);
return _pm25->begin_I2C(_i2c);
}
@ -74,10 +76,14 @@ public:
/*******************************************************************************/
bool getEventPM10_STD(sensors_event_t *pm10StdEvent) {
PM25_AQI_Data data;
if (!_pm25->read(&data))
if (!_pm25->read(&data)) {
WS_DEBUG_PRINTLN("Failed to read PM10STD data");
return false; // couldn't read data
}
pm10StdEvent->pm10_std = (float)data.pm10_standard;
WS_DEBUG_PRINT("PM10STD: ");
WS_DEBUG_PRINTLN(pm10StdEvent->pm10_std);
return true;
}
@ -92,10 +98,13 @@ public:
/*******************************************************************************/
bool getEventPM25_STD(sensors_event_t *pm25StdEvent) {
PM25_AQI_Data data;
if (!_pm25->read(&data))
if (!_pm25->read(&data)) {
WS_DEBUG_PRINTLN("Failed to read PM25STD data");
return false; // couldn't read data
}
pm25StdEvent->pm25_std = (float)data.pm25_standard;
WS_DEBUG_PRINT("PM25STD: ");
WS_DEBUG_PRINTLN(pm25StdEvent->pm25_std);
return true;
}
@ -110,10 +119,14 @@ public:
/*******************************************************************************/
bool getEventPM100_STD(sensors_event_t *pm100StdEvent) {
PM25_AQI_Data data;
if (!_pm25->read(&data))
if (!_pm25->read(&data)) {
WS_DEBUG_PRINTLN("Failed to read PM100STD data");
return false; // couldn't read data
}
pm100StdEvent->pm100_std = (float)data.pm100_standard;
WS_DEBUG_PRINT("PM100STD: ");
WS_DEBUG_PRINTLN(pm100StdEvent->pm100_std);
return true;
}