Browse Source

Merge pull request #2936 from beala/beala/MeshTowerV2_feed_watchdog_2

Feed external hardware watchdog on Heltec Tower V2 (aka MeshTower V2) Implementation 2
pull/2942/head
Liam Cottle 3 weeks ago
committed by GitHub
parent
commit
e01a2565b9
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 9
      examples/companion_radio/main.cpp
  2. 10
      examples/simple_repeater/main.cpp
  3. 7
      examples/simple_room_server/main.cpp
  4. 7
      examples/simple_secure_chat/main.cpp
  5. 7
      examples/simple_sensor/main.cpp
  6. 12
      src/helpers/ExternalWatchdogManager.h
  7. 5
      variants/heltec_mesh_solar/platformio.ini
  8. 32
      variants/heltec_mesh_solar/target.cpp
  9. 11
      variants/heltec_mesh_solar/target.h
  10. 4
      variants/heltec_mesh_solar/variant.h
  11. 33
      variants/heltec_tower_v2/target.cpp
  12. 11
      variants/heltec_tower_v2/target.h
  13. 8
      variants/heltec_tower_v2/variant.h

9
examples/companion_radio/main.cpp

@ -116,6 +116,10 @@ void setup() {
board.begin(); board.begin();
#ifdef HAS_EXTERNAL_WATCHDOG
external_watchdog.begin();
#endif
#ifdef DISPLAY_CLASS #ifdef DISPLAY_CLASS
DisplayDriver* disp = NULL; DisplayDriver* disp = NULL;
if (display.begin()) { if (display.begin()) {
@ -249,7 +253,10 @@ void loop() {
ui_task.loop(); ui_task.loop();
#endif #endif
rtc_clock.tick(); rtc_clock.tick();
#ifdef HAS_EXTERNAL_WATCHDOG
external_watchdog.loop();
#endif
if (!the_mesh.hasPendingWork()) { if (!the_mesh.hasPendingWork()) {
#if defined(NRF52_PLATFORM) #if defined(NRF52_PLATFORM)
board.sleep(0); // nrf ignores seconds param, sleeps whenever possible board.sleep(0); // nrf ignores seconds param, sleeps whenever possible

10
examples/simple_repeater/main.cpp

@ -33,6 +33,10 @@ void setup() {
board.begin(); board.begin();
#ifdef HAS_EXTERNAL_WATCHDOG
external_watchdog.begin();
#endif
#if defined(MESH_DEBUG) && defined(NRF52_PLATFORM) #if defined(MESH_DEBUG) && defined(NRF52_PLATFORM)
// give some extra time for serial to settle so // give some extra time for serial to settle so
// boot debug messages can be seen on terminal // boot debug messages can be seen on terminal
@ -152,7 +156,13 @@ void loop() {
#endif #endif
rtc_clock.tick(); rtc_clock.tick();
#ifdef HAS_EXTERNAL_WATCHDOG
external_watchdog.loop();
#endif
if (the_mesh.getNodePrefs()->powersaving_enabled && !the_mesh.hasPendingWork()) { if (the_mesh.getNodePrefs()->powersaving_enabled && !the_mesh.hasPendingWork()) {
#ifdef HAS_EXTERNAL_WATCHDOG
external_watchdog.feed();
#endif
#if defined(NRF52_PLATFORM) #if defined(NRF52_PLATFORM)
board.sleep(0); // nrf ignores seconds param, sleeps whenever possible board.sleep(0); // nrf ignores seconds param, sleeps whenever possible
#else #else

7
examples/simple_room_server/main.cpp

@ -24,6 +24,10 @@ void setup() {
board.begin(); board.begin();
#ifdef HAS_EXTERNAL_WATCHDOG
external_watchdog.begin();
#endif
#ifdef DISPLAY_CLASS #ifdef DISPLAY_CLASS
if (display.begin()) { if (display.begin()) {
display.startFrame(); display.startFrame();
@ -115,4 +119,7 @@ void loop() {
ui_task.loop(); ui_task.loop();
#endif #endif
rtc_clock.tick(); rtc_clock.tick();
#ifdef HAS_EXTERNAL_WATCHDOG
external_watchdog.loop();
#endif
} }

7
examples/simple_secure_chat/main.cpp

@ -560,6 +560,10 @@ void setup() {
board.begin(); board.begin();
#ifdef HAS_EXTERNAL_WATCHDOG
external_watchdog.begin();
#endif
if (!radio_init()) { halt(); } if (!radio_init()) { halt(); }
fast_rng.begin(radio_driver.getRngSeed()); fast_rng.begin(radio_driver.getRngSeed());
@ -591,4 +595,7 @@ void setup() {
void loop() { void loop() {
the_mesh.loop(); the_mesh.loop();
rtc_clock.tick(); rtc_clock.tick();
#ifdef HAS_EXTERNAL_WATCHDOG
external_watchdog.loop();
#endif
} }

7
examples/simple_sensor/main.cpp

@ -58,6 +58,10 @@ void setup() {
board.begin(); board.begin();
#ifdef HAS_EXTERNAL_WATCHDOG
external_watchdog.begin();
#endif
#ifdef DISPLAY_CLASS #ifdef DISPLAY_CLASS
if (display.begin()) { if (display.begin()) {
display.startFrame(); display.startFrame();
@ -147,4 +151,7 @@ void loop() {
ui_task.loop(); ui_task.loop();
#endif #endif
rtc_clock.tick(); rtc_clock.tick();
#ifdef HAS_EXTERNAL_WATCHDOG
external_watchdog.loop();
#endif
} }

12
src/helpers/ExternalWatchdogManager.h

@ -0,0 +1,12 @@
#pragma once
class ExternalWatchdogManager {
protected:
unsigned long last_feed_watchdog;
public:
ExternalWatchdogManager() { last_feed_watchdog = 0; }
virtual bool begin() { return false; }
virtual void loop() { }
virtual unsigned long getIntervalMs() const { return 0; }
virtual void feed() { }
};

5
variants/heltec_mesh_solar/platformio.ini

@ -13,6 +13,11 @@ build_flags = ${nrf52_base.build_flags}
-D LORA_TX_POWER=22 -D LORA_TX_POWER=22
-D SX126X_CURRENT_LIMIT=140 -D SX126X_CURRENT_LIMIT=140
-D SX126X_RX_BOOSTED_GAIN=1 -D SX126X_RX_BOOSTED_GAIN=1
-D HAS_EXTERNAL_WATCHDOG
-D EXTERNAL_WATCHDOG_DONE_PIN=9
-D EXTERNAL_WATCHDOG_WAKE_PIN=10
-D EXTERNAL_WATCHDOG_FEED_INTERVAL_MS=480000 ; 8 minute feed interval, safely inside the hardware watchdog timeout
build_src_filter = ${nrf52_base.build_src_filter} build_src_filter = ${nrf52_base.build_src_filter}
+<helpers/*.cpp> +<helpers/*.cpp>
+<../variants/heltec_mesh_solar> +<../variants/heltec_mesh_solar>

32
variants/heltec_mesh_solar/target.cpp

@ -13,6 +13,7 @@ VolatileRTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock); AutoDiscoverRTCClock rtc_clock(fallback_clock);
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock);
SolarSensorManager sensors = SolarSensorManager(nmea); SolarSensorManager sensors = SolarSensorManager(nmea);
SolarExternalWatchdog external_watchdog;
#ifdef DISPLAY_CLASS #ifdef DISPLAY_CLASS
DISPLAY_CLASS display; DISPLAY_CLASS display;
@ -106,3 +107,34 @@ bool SolarSensorManager::setSettingValue(const char* name, const char* value) {
} }
return false; // not supported return false; // not supported
} }
bool SolarExternalWatchdog::begin() {
last_feed_watchdog = 0;
pinMode(EXTERNAL_WATCHDOG_WAKE_PIN, INPUT);
pinMode(EXTERNAL_WATCHDOG_DONE_PIN, OUTPUT);
delay(1);
digitalWrite(EXTERNAL_WATCHDOG_DONE_PIN, LOW);
delay(1);
feed();
return true;
}
void SolarExternalWatchdog::loop() {
if (millis() - last_feed_watchdog >= EXTERNAL_WATCHDOG_FEED_INTERVAL_MS) {
feed();
}
}
unsigned long SolarExternalWatchdog::getIntervalMs() const {
unsigned long elapsed_ms = millis() - last_feed_watchdog;
if (elapsed_ms >= EXTERNAL_WATCHDOG_FEED_INTERVAL_MS) {
return 0;
}
return EXTERNAL_WATCHDOG_FEED_INTERVAL_MS - elapsed_ms;
}
void SolarExternalWatchdog::feed() {
digitalWrite(EXTERNAL_WATCHDOG_DONE_PIN, HIGH);
delay(1);
digitalWrite(EXTERNAL_WATCHDOG_DONE_PIN, LOW);
last_feed_watchdog = millis();
}

11
variants/heltec_mesh_solar/target.h

@ -8,6 +8,7 @@
#include <helpers/AutoDiscoverRTCClock.h> #include <helpers/AutoDiscoverRTCClock.h>
#include <helpers/SensorManager.h> #include <helpers/SensorManager.h>
#include <helpers/sensors/LocationProvider.h> #include <helpers/sensors/LocationProvider.h>
#include <helpers/ExternalWatchdogManager.h>
#ifdef DISPLAY_CLASS #ifdef DISPLAY_CLASS
#include <helpers/ui/ST7789Display.h> #include <helpers/ui/ST7789Display.h>
#endif #endif
@ -30,10 +31,20 @@ public:
bool setSettingValue(const char* name, const char* value) override; bool setSettingValue(const char* name, const char* value) override;
}; };
class SolarExternalWatchdog : public ExternalWatchdogManager {
public:
SolarExternalWatchdog() {}
bool begin() override;
void loop() override;
unsigned long getIntervalMs() const override;
void feed() override;
};
extern MeshSolarBoard board; extern MeshSolarBoard board;
extern WRAPPER_CLASS radio_driver; extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock; extern AutoDiscoverRTCClock rtc_clock;
extern SolarSensorManager sensors; extern SolarSensorManager sensors;
extern SolarExternalWatchdog external_watchdog;
#ifdef DISPLAY_CLASS #ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display; extern DISPLAY_CLASS display;

4
variants/heltec_mesh_solar/variant.h

@ -34,8 +34,8 @@
#define PIN_SERIAL1_RX (37) #define PIN_SERIAL1_RX (37)
#define PIN_SERIAL1_TX (39) #define PIN_SERIAL1_TX (39)
#define PIN_SERIAL2_RX (9) #define PIN_SERIAL2_RX (-1)
#define PIN_SERIAL2_TX (10) #define PIN_SERIAL2_TX (-1)
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// I2C pin definition // I2C pin definition

33
variants/heltec_tower_v2/target.cpp

@ -14,6 +14,7 @@ VolatileRTCClock fallback_clock;
AutoDiscoverRTCClock rtc_clock(fallback_clock); AutoDiscoverRTCClock rtc_clock(fallback_clock);
MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock); MicroNMEALocationProvider nmea = MicroNMEALocationProvider(Serial1, &rtc_clock);
EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea); EnvironmentSensorManager sensors = EnvironmentSensorManager(nmea);
TowerV2ExternalWatchdog external_watchdog;
#ifdef DISPLAY_CLASS #ifdef DISPLAY_CLASS
DISPLAY_CLASS display; DISPLAY_CLASS display;
@ -29,3 +30,35 @@ mesh::LocalIdentity radio_new_identity() {
RadioNoiseListener rng(radio); RadioNoiseListener rng(radio);
return mesh::LocalIdentity(&rng); return mesh::LocalIdentity(&rng);
} }
bool TowerV2ExternalWatchdog::begin() {
last_feed_watchdog = 0;
pinMode(EXTERNAL_WATCHDOG_WAKE_PIN, INPUT);
pinMode(EXTERNAL_WATCHDOG_DONE_PIN, OUTPUT);
delay(1);
digitalWrite(EXTERNAL_WATCHDOG_DONE_PIN, LOW);
delay(1);
feed();
return true;
}
void TowerV2ExternalWatchdog::loop() {
if (millis() - last_feed_watchdog >= EXTERNAL_WATCHDOG_FEED_INTERVAL_MS) {
feed();
}
}
unsigned long TowerV2ExternalWatchdog::getIntervalMs() const {
unsigned long elapsed_ms = millis() - last_feed_watchdog;
if (elapsed_ms >= EXTERNAL_WATCHDOG_FEED_INTERVAL_MS) {
return 0;
}
return EXTERNAL_WATCHDOG_FEED_INTERVAL_MS - elapsed_ms;
}
void TowerV2ExternalWatchdog::feed() {
digitalWrite(EXTERNAL_WATCHDOG_DONE_PIN, HIGH);
delay(1);
digitalWrite(EXTERNAL_WATCHDOG_DONE_PIN, LOW);
last_feed_watchdog = millis();
}

11
variants/heltec_tower_v2/target.h

@ -8,16 +8,27 @@
#include <helpers/radiolib/RadioLibWrappers.h> #include <helpers/radiolib/RadioLibWrappers.h>
#include <helpers/sensors/EnvironmentSensorManager.h> #include <helpers/sensors/EnvironmentSensorManager.h>
#include <helpers/sensors/LocationProvider.h> #include <helpers/sensors/LocationProvider.h>
#include <helpers/ExternalWatchdogManager.h>
#ifdef DISPLAY_CLASS #ifdef DISPLAY_CLASS
#include <helpers/ui/MomentaryButton.h> #include <helpers/ui/MomentaryButton.h>
#include "helpers/ui/NullDisplayDriver.h" #include "helpers/ui/NullDisplayDriver.h"
#endif #endif
class TowerV2ExternalWatchdog : public ExternalWatchdogManager {
public:
TowerV2ExternalWatchdog() {}
bool begin() override;
void loop() override;
unsigned long getIntervalMs() const override;
void feed() override;
};
extern HeltecTowerV2Board board; extern HeltecTowerV2Board board;
extern WRAPPER_CLASS radio_driver; extern WRAPPER_CLASS radio_driver;
extern AutoDiscoverRTCClock rtc_clock; extern AutoDiscoverRTCClock rtc_clock;
extern EnvironmentSensorManager sensors; extern EnvironmentSensorManager sensors;
extern TowerV2ExternalWatchdog external_watchdog;
#ifdef DISPLAY_CLASS #ifdef DISPLAY_CLASS
extern DISPLAY_CLASS display; extern DISPLAY_CLASS display;

8
variants/heltec_tower_v2/variant.h

@ -82,10 +82,10 @@
#define PIN_SERIAL2_RX (-1) #define PIN_SERIAL2_RX (-1)
#define PIN_SERIAL2_TX (-1) #define PIN_SERIAL2_TX (-1)
#define HAS_HARDWARE_WATCHDOG #define HAS_EXTERNAL_WATCHDOG
#define HARDWARE_WATCHDOG_DONE (0 + 9) #define EXTERNAL_WATCHDOG_DONE_PIN (0 + 9)
#define HARDWARE_WATCHDOG_WAKE (0 + 10) #define EXTERNAL_WATCHDOG_WAKE_PIN (0 + 10)
#define HARDWARE_WATCHDOG_TIMEOUT_MS (8 * 60 * 1000) #define EXTERNAL_WATCHDOG_FEED_INTERVAL_MS (8 * 60 * 1000)
#define SERIAL_PRINT_PORT 0 #define SERIAL_PRINT_PORT 0

Loading…
Cancel
Save