Merge PowerSaving-v17 into keymindCascade

This commit is contained in:
mikecarper
2026-09-24 00:56:05 -07:00
39 changed files with 124 additions and 83 deletions
+1
View File
@@ -149,6 +149,7 @@ public:
// internally bounded operations can use this while retaining their own
// timeout. Boards without an explicit watchdog need no implementation.
virtual void serviceWatchdog() { /* no op */ }
virtual void enterDeepSleep(uint32_t secs) { (void)secs; }
// Called by example setup() functions to signal that boot is complete.
// Boards may override to stop a boot-indicator LED sequence or similar.
// Default no-op: boards that don't care need not implement anything.
+9 -5
View File
@@ -1119,11 +1119,7 @@ bool ESP32Board::otaFromManifest(const char* current_ver, bool dry_run, char rep
}
#endif // WITH_MQTT_BRIDGE
void ESP32Board::powerOff() {
enterDeepSleep(0); // Do not wakeup
}
void ESP32Board::enterDeepSleep(uint32_t secs) {
void ESP32Board::shutdownPeripherals() {
// Power off the display if any
#ifdef DISPLAY_CLASS
display.turnOff();
@@ -1155,6 +1151,14 @@ void ESP32Board::enterDeepSleep(uint32_t secs) {
Serial.flush();
#endif
delay(100);
}
void ESP32Board::powerOff() {
enterDeepSleep(0); // Do not wakeup
}
void ESP32Board::enterDeepSleep(uint32_t secs) {
shutdownPeripherals();
// Clear stale wakeup sources to avoid ghost wakeup
// This is required when Power Management and automatic lightsleep are enabled
+2 -1
View File
@@ -88,8 +88,9 @@ public:
return raw / 4;
}
virtual void shutdownPeripherals();
virtual void powerOff() override;
void enterDeepSleep(uint32_t secs);
virtual void enterDeepSleep(uint32_t secs) override;
uint32_t getIRQGpio() override {
#ifdef P_LORA_DIO_1
+23
View File
@@ -596,6 +596,29 @@ void NRF52Board::powerOff() {
}
}
void NRF52Board::enterDeepSleep(uint32_t secs) {
if (secs == 0) {
powerOff(); // Not wake up
} else {
shutdownPeripherals();
// Clear FPU interrupt flags to avoid insomnia
// see errata 87 for details
// https://docs.nordicsemi.com/bundle/errata_nRF52840_Rev3/page/ERR/nRF52840/Rev3/latest/anomaly_840_87.html
#if (__FPU_USED == 1)
__set_FPSCR(__get_FPSCR() & ~(0x0000009F));
(void)__get_FPSCR();
NVIC_ClearPendingIRQ(FPU_IRQn);
#endif
// Attemp to sleep
vTaskDelay(pdMS_TO_TICKS(secs * 1000));
// Reboot for a fresh recovery
reboot();
}
}
bool NRF52Board::getBootloaderVersion(char* out, size_t max_len) {
if (!out || max_len == 0u) return false;
out[0] = 0;
+1
View File
@@ -68,6 +68,7 @@ public:
bool rebootToUf2Bootloader() override;
virtual void shutdownPeripherals();
virtual void powerOff() override;
virtual void enterDeepSleep(uint32_t secs) override;
virtual bool getBootloaderVersion(char* version, size_t max_len) override;
virtual bool startOTAUpdate(const char *id, char reply[], bool force_ap = false) override;
virtual bool stopOTAUpdate(char reply[]) override;
@@ -43,11 +43,11 @@ public:
}
#endif
void powerOff() override {
void shutdownPeripherals() override {
NRF52Board::shutdownPeripherals();
uint32_t button_pin = PIN_BUTTON1;
nrf_gpio_cfg_input(button_pin, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_sense_set(button_pin, NRF_GPIO_PIN_SENSE_LOW);
NRF52Board::powerOff();
}
};
@@ -43,11 +43,11 @@ public:
}
#endif
void powerOff() override {
void shutdownPeripherals() override {
NRF52Board::shutdownPeripherals();
uint32_t button_pin = PIN_BUTTON1;
nrf_gpio_cfg_input(button_pin, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_sense_set(button_pin, NRF_GPIO_PIN_SENSE_LOW);
NRF52Board::powerOff();
}
};
@@ -43,11 +43,11 @@ public:
}
#endif
void powerOff() override {
void shutdownPeripherals() override {
NRF52Board::shutdownPeripherals();
uint32_t button_pin = PIN_BUTTON1;
nrf_gpio_cfg_input(button_pin, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_sense_set(button_pin, NRF_GPIO_PIN_SENSE_LOW);
NRF52Board::powerOff();
}
};
@@ -34,11 +34,11 @@ public:
}
void powerOff() override {
void shutdownPeripherals() override {
NRF52Board::shutdownPeripherals();
uint32_t button_pin = PIN_BUTTON1;
nrf_gpio_cfg_input(button_pin, NRF_GPIO_PIN_PULLUP);
nrf_gpio_cfg_sense_set(button_pin, NRF_GPIO_PIN_SENSE_LOW);
NRF52Board::powerOff();
}
};
-1
View File
@@ -22,7 +22,6 @@ public:
void onBootComplete() override;
void onBeforeTransmit() override;
void onAfterTransmit() override;
void powerOff() override;
uint16_t getBattMilliVolts() override;
bool setAdcMultiplier(float multiplier) override;
float getAdcMultiplier() const override { return adc_mult; }
+3 -2
View File
@@ -111,10 +111,11 @@ void T096Board::variant_shutdown() {
nrf_gpio_cfg_default(PIN_GPS_TX);
}
void T096Board::powerOff() {
void T096Board::shutdownPeripherals() {
NRF52Board::shutdownPeripherals();
loRaFEMControl.setSleepModeEnable();
nrf_gpio_cfg_default(PIN_GPS_EN); // 363uA down to 39uA
NRF52Board::powerOff();
}
const char* T096Board::getManufacturerName() const {
+1 -1
View File
@@ -29,7 +29,7 @@ public:
void onAfterTransmit(void) override;
uint16_t getBattMilliVolts() override;
const char* getManufacturerName() const override ;
void powerOff() override;
void shutdownPeripherals() override;
bool setLoRaFemLnaEnabled(bool enable) override;
bool canControlLoRaFemLna() const override;
bool isLoRaFemLnaEnabled() const override;
+3 -2
View File
@@ -97,9 +97,10 @@ void T1Board::variant_shutdown() {
digitalWrite(PIN_BAT_CTL, !ADC_CTRL_ENABLED);
}
void T1Board::powerOff() {
void T1Board::shutdownPeripherals() {
NRF52Board::shutdownPeripherals();
variant_shutdown();
NRF52Board::powerOff();
}
const char* T1Board::getManufacturerName() const {
+1 -1
View File
@@ -22,5 +22,5 @@ public:
void onAfterTransmit() override;
uint16_t getBattMilliVolts() override;
const char* getManufacturerName() const override;
void powerOff() override;
void shutdownPeripherals() override;
};
+3 -3
View File
@@ -46,11 +46,11 @@ public:
return "Heltec T114";
}
void powerOff() override {
void shutdownPeripherals() override {
NRF52Board::shutdownPeripherals();
#ifdef LED_PIN
digitalWrite(LED_PIN, HIGH);
#endif
NRF52Board::powerOff();
}
};
@@ -93,6 +93,12 @@ void HeltecTowerV2Board::powerOff() {
#ifdef NRF52_POWER_MANAGEMENT
initiateShutdown(SHUTDOWN_REASON_USER);
#else
sd_power_system_off();
#endif
}
void HeltecTowerV2Board::shutdownPeripherals() {
NRF52Board::shutdownPeripherals();
pinMode(PIN_GPS_EN, OUTPUT);
digitalWrite(PIN_GPS_EN, !PIN_GPS_EN_ACTIVE);
pinMode(PIN_GPS_STANDBY, OUTPUT);
@@ -103,6 +109,4 @@ void HeltecTowerV2Board::powerOff() {
pinMode(PIN_BAT_CTL, OUTPUT);
digitalWrite(PIN_BAT_CTL, LOW);
variant_shutdown();
sd_power_system_off();
#endif
}
@@ -21,4 +21,5 @@ public:
uint16_t getBattMilliVolts() override;
const char* getManufacturerName() const override;
void powerOff() override;
void shutdownPeripherals() override;
};
@@ -35,7 +35,8 @@ void HeltecTrackerV2Board::begin() {
loRaFEMControl.setRxModeEnable();
}
void HeltecTrackerV2Board::powerOff() {
void HeltecTrackerV2Board::shutdownPeripherals() {
ESP32Board::shutdownPeripherals();
// Turn off PA. Guarded because this board file is also compiled for the
// heltec_tracker_v1_1 envs, which do not define P_LORA_PA_POWER (it is set
// only in variants/heltec_tracker_v2/platformio.ini). Same guard idiom
@@ -44,8 +45,6 @@ void HeltecTrackerV2Board::begin() {
digitalWrite(P_LORA_PA_POWER, LOW);
rtc_gpio_hold_en((gpio_num_t)P_LORA_PA_POWER);
#endif
ESP32Board::powerOff();
}
uint16_t HeltecTrackerV2Board::getBattMilliVolts() {
@@ -20,7 +20,7 @@ public:
void onBeforeTransmit(void) override;
void onAfterTransmit(void) override;
void powerOff() override;
void shutdownPeripherals() override;
uint16_t getBattMilliVolts() override;
const char* getManufacturerName() const override ;
bool setLoRaFemLnaEnabled(bool enable) override;
+3 -3
View File
@@ -32,12 +32,12 @@ void HeltecV4Board::begin() {
loRaFEMControl.setRxModeEnable();
}
void HeltecV4Board::powerOff() {
void HeltecV4Board::shutdownPeripherals() {
ESP32Board::shutdownPeripherals();
// Turn off PA
digitalWrite(P_LORA_PA_POWER, LOW);
rtc_gpio_hold_en((gpio_num_t)P_LORA_PA_POWER);
ESP32Board::powerOff();
}
uint16_t HeltecV4Board::getBattMilliVolts() {
+1 -1
View File
@@ -26,7 +26,7 @@ public:
void onBeforeTransmit(void) override;
void onAfterTransmit(void) override;
void powerOff() override;
void shutdownPeripherals() override;
bool setLoRaFemLnaEnabled(bool enable) override;
bool canControlLoRaFemLna() const override;
bool isLoRaFemLnaEnabled() const override;
+5 -1
View File
@@ -46,11 +46,15 @@ void HeltecV4R8Board::onAfterTransmit(void) {
}
void HeltecV4R8Board::powerOff() {
ESP32Board::powerOff();
}
void HeltecV4R8Board::shutdownPeripherals() {
ESP32Board::shutdownPeripherals();
loRaFEMControl.setSleepModeEnable();
digitalWrite(P_LORA_PA_POWER, LOW);
rtc_gpio_hold_en((gpio_num_t)P_LORA_PA_POWER);
periph_power.release(); // Drop the permanent antenna-boost/VEXT claim from begin().
ESP32Board::powerOff();
}
uint16_t HeltecV4R8Board::getBattMilliVolts() {
+1
View File
@@ -28,6 +28,7 @@ public:
void onBeforeTransmit(void) override;
void onAfterTransmit(void) override;
void powerOff() override;
void shutdownPeripherals() override;
bool setLoRaFemLnaEnabled(bool enable) override;
bool canControlLoRaFemLna() const override;
bool isLoRaFemLnaEnabled() const override;
+6 -2
View File
@@ -130,6 +130,11 @@ const char* TBeam1WBoard::getManufacturerName() const {
}
void TBeam1WBoard::powerOff() {
ESP32Board::powerOff();
}
void TBeam1WBoard::shutdownPeripherals() {
ESP32Board::shutdownPeripherals();
portENTER_CRITICAL(&_fan_mux);
_stopped = true;
_tx_active = false;
@@ -145,8 +150,7 @@ void TBeam1WBoard::powerOff() {
radio_powered = false;
digitalWrite(LED_PIN, LOW);
ESP32Board::powerOff();
digitalWrite(FAN_CTRL_PIN, LOW);
}
void TBeam1WBoard::attachRadioDriver(CustomSX1262Wrapper* driver) {
+1
View File
@@ -76,6 +76,7 @@ public:
uint16_t getBattMilliVolts() override;
const char* getManufacturerName() const override;
void powerOff() override;
void shutdownPeripherals() override;
void powerCycleRadio();
bool supportsRadioHardReset() const override { return true; }
bool resetRadio() override {
+2 -4
View File
@@ -34,7 +34,8 @@ public:
void reboot() override { NVIC_SystemReset(); }
void powerOff() override {
void shutdownPeripherals() override {
NRF52Board::shutdownPeripherals();
#ifdef PIN_USER_BTN
while (digitalRead(PIN_USER_BTN) == LOW) {
@@ -59,8 +60,5 @@ public:
#ifdef PIN_USER_BTN
nrf_gpio_cfg_sense_input(g_ADigitalPinMap[PIN_USER_BTN], NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
#endif
NRF52Board::powerOff();
}
};
+3 -3
View File
@@ -46,7 +46,9 @@ public:
return 0;
}
void powerOff() override {
void shutdownPeripherals() override {
NRF52Board::shutdownPeripherals();
#ifdef HAS_GPS
digitalWrite(GPS_VRTC_EN, LOW);
digitalWrite(GPS_RESET, LOW);
@@ -81,7 +83,5 @@ public:
#ifdef BUTTON_PIN
nrf_gpio_cfg_sense_input(BUTTON_PIN, NRF_GPIO_PIN_PULLDOWN, NRF_GPIO_PIN_SENSE_HIGH);
#endif
sd_power_system_off();
}
};
@@ -45,7 +45,9 @@ public:
return "Minewsemi";
}
void powerOff() override {
void shutdownPeripherals() override {
NRF52Board::shutdownPeripherals();
#ifdef HAS_GPS
digitalWrite(GPS_VRTC_EN, LOW);
digitalWrite(GPS_RESET, LOW);
@@ -65,7 +67,6 @@ public:
#ifdef BUTTON_PIN
nrf_gpio_cfg_sense_input(digitalPinToInterrupt(BUTTON_PIN), NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
#endif
NRF52Board::powerOff();
}
#if defined(P_LORA_TX_LED)
+3 -3
View File
@@ -43,7 +43,9 @@ public:
const char *getManufacturerName() const override { return "Nano G2 Ultra"; }
void powerOff() override {
void shutdownPeripherals() override {
NRF52Board::shutdownPeripherals();
// put GPS chip to sleep
digitalWrite(PIN_GPS_STANDBY, LOW);
// TODO: unset buzzer to prevent notification circuit activating on hibernate
@@ -51,7 +53,5 @@ public:
nrf_gpio_cfg_sense_input(digitalPinToInterrupt(PIN_USER_BTN), NRF_GPIO_PIN_NOPULL,
NRF_GPIO_PIN_SENSE_LOW);
NRF52Board::powerOff();
}
};
@@ -40,7 +40,9 @@ public:
return "RAK WisMesh Tag";
}
void powerOff() override {
void shutdownPeripherals() override {
NRF52Board::shutdownPeripherals();
#ifdef BUZZER_EN
digitalWrite(BUZZER_EN, LOW);
#endif
@@ -68,7 +70,5 @@ public:
// configure button press to wake up when in powered off state
nrf_gpio_cfg_sense_input(digitalPinToInterrupt(BUTTON_PIN), NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
#endif
NRF52Board::powerOff();
}
};
+7 -1
View File
@@ -37,7 +37,9 @@ public:
return "Seeed SenseCap Solar";
}
void powerOff() override {
void shutdownPeripherals() override {
NRF52Board::shutdownPeripherals();
digitalWrite(LED_WHITE, LOW);
digitalWrite(LED_BLUE, LOW);
@@ -50,6 +52,10 @@ public:
// Keep pull-up enabled in system-off so the wake line doesn't float low.
nrf_gpio_cfg_sense_input(digitalPinToInterrupt(g_ADigitalPinMap[PIN_BUTTON1]), NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
#endif
}
void powerOff() override {
shutdownPeripherals();
#ifdef NRF52_POWER_MANAGEMENT
shutdownPeripherals();
+3 -3
View File
@@ -1,6 +1,8 @@
#include "StationG3Board.h"
void StationG3Board::powerOff() {
void StationG3Board::shutdownPeripherals() {
ESP32Board::shutdownPeripherals();
loRaFEMControl.setSleepModeEnable();
#ifdef P_PA1_EN
rtc_gpio_hold_en((gpio_num_t)P_PA1_EN);
@@ -9,8 +11,6 @@ void StationG3Board::powerOff() {
#ifdef P_PRIMARY_LNA_EN
rtc_gpio_hold_en((gpio_num_t)P_PRIMARY_LNA_EN);
#endif
ESP32Board::powerOff();
}
bool StationG3Board::setLoRaFemLnaEnabled(bool enable) {
+1 -1
View File
@@ -56,7 +56,7 @@ public:
bool canControlLoRaFemPaGain() const override;
bool isLoRaFemPaGainEnabled() const override;
void powerOff() override;
void shutdownPeripherals() override;
uint16_t getBattMilliVolts() override {
return 0;
+3 -3
View File
@@ -49,7 +49,9 @@ public:
return 0;
}
void powerOff() override {
void shutdownPeripherals() override {
NRF52Board::shutdownPeripherals();
#ifdef HAS_GPS
digitalWrite(GPS_VRTC_EN, LOW);
digitalWrite(GPS_RESET, LOW);
@@ -87,7 +89,5 @@ public:
#ifdef BUTTON_PIN
nrf_gpio_cfg_sense_input(BUTTON_PIN, NRF_GPIO_PIN_NOPULL, NRF_GPIO_PIN_SENSE_HIGH);
#endif
NRF52Board::powerOff();
}
};
+2 -4
View File
@@ -32,14 +32,12 @@ public:
return "Elecrow ThinkNode-M1";
}
void powerOff() override {
void shutdownPeripherals() override {
NRF52Board::shutdownPeripherals();
// turn off all leds, sd_power_system_off will not do this for us
#ifdef P_LORA_TX_LED
digitalWrite(P_LORA_TX_LED, LOW);
#endif
// power off board
NRF52Board::powerOff();
}
};
+3 -4
View File
@@ -42,13 +42,12 @@ public:
return 0;
}
void powerOff() override {
void shutdownPeripherals() override {
NRF52Board::shutdownPeripherals();
// turn off all leds, sd_power_system_off will not do this for us
digitalWrite(PIN_LED_BLUE, !LED_STATE_ON);
digitalWrite(PIN_LED_GREEN, !LED_STATE_ON);
digitalWrite(PIN_LED_RED, !LED_STATE_ON);
// power off board
NRF52Board::powerOff();
}
};
+2 -4
View File
@@ -36,14 +36,12 @@ public:
return "Elecrow ThinkNode M6";
}
void powerOff() override {
void shutdownPeripherals() override {
NRF52Board::shutdownPeripherals();
// turn off all leds, sd_power_system_off will not do this for us
#ifdef P_LORA_TX_LED
digitalWrite(P_LORA_TX_LED, LOW);
#endif
// power off board
NRF52Board::powerOff();
}
};
@@ -33,8 +33,4 @@ public:
const char* getManufacturerName() const override {
return "Seeed Wio Tracker L1";
}
void powerOff() override {
NRF52Board::powerOff();
}
};
+3 -3
View File
@@ -39,7 +39,9 @@ public:
#endif
}
void powerOff() override {
void shutdownPeripherals() override {
NRF52Board::shutdownPeripherals();
// set led on and wait for button release before poweroff
digitalWrite(PIN_LED, LOW);
#ifdef PIN_USER_BTN
@@ -53,8 +55,6 @@ public:
// configure button press to wake up when in powered off state
nrf_gpio_cfg_sense_input(digitalPinToInterrupt(g_ADigitalPinMap[PIN_USER_BTN]), NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
#endif
NRF52Board::powerOff();
}
};