Improved sleep() and added enterDeepSleep()
This commit is contained in:
1 parent
3301a022d7
commit
552599fb34
5 files changed
+62
-9
No files matched your search
@@ -37,6 +37,15 @@
|
||||
#define BRIDGE_DEBUG_PRINTLN(...) {}
|
||||
#endif
|
||||
|
||||
#if POWERSAVING_DEBUG && ARDUINO
|
||||
#include <Arduino.h>
|
||||
#define POWERSAVING_DEBUG_PRINT(F, ...) Serial.printf("POWERSAVING: " F, ##__VA_ARGS__)
|
||||
#define POWERSAVING_DEBUG_PRINTLN(F, ...) Serial.printf("POWERSAVING: " F "\n", ##__VA_ARGS__)
|
||||
#else
|
||||
#define POWERSAVING_DEBUG_PRINT(...) {}
|
||||
#define POWERSAVING_DEBUG_PRINTLN(...) {}
|
||||
#endif
|
||||
|
||||
namespace mesh {
|
||||
|
||||
#define BD_STARTUP_NORMAL 0 // getStartupReason() codes
|
||||
@@ -53,6 +62,7 @@ public:
|
||||
virtual void onAfterTransmit() { }
|
||||
virtual void reboot() = 0;
|
||||
virtual void powerOff() { /* no op */ }
|
||||
virtual void enterDeepSleep(uint32_t secs) { /* no op */ }
|
||||
// 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.
|
||||
@@ -90,6 +100,7 @@ public:
|
||||
// Called from the example main loops. Lets a board feed its watchdog and
|
||||
// run periodic housekeeping. Default no-op.
|
||||
virtual void loop() { /* no op */ }
|
||||
inline static uint32_t n_cad_busy = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
@@ -45,11 +45,7 @@ bool ESP32Board::startOTAUpdate(const char* id, char reply[]) {
|
||||
}
|
||||
#endif
|
||||
|
||||
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();
|
||||
@@ -74,6 +70,14 @@ void ESP32Board::enterDeepSleep(uint32_t secs) {
|
||||
// Flush serial buffers
|
||||
Serial.flush();
|
||||
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
|
||||
|
||||
@@ -21,6 +21,7 @@ class ESP32Board : public mesh::MainBoard {
|
||||
protected:
|
||||
uint8_t startup_reason;
|
||||
bool inhibit_sleep = false;
|
||||
uint32_t inhibit_sleep_until = 0;
|
||||
static inline portMUX_TYPE sleepMux = portMUX_INITIALIZER_UNLOCKED;
|
||||
|
||||
public:
|
||||
@@ -66,8 +67,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 {
|
||||
return P_LORA_DIO_1; // default for SX1262
|
||||
@@ -75,13 +77,13 @@ public:
|
||||
|
||||
void sleep(uint32_t secs) override {
|
||||
// Skip if not allow to sleep
|
||||
if (inhibit_sleep) {
|
||||
if (inhibit_sleep || (int32_t)(inhibit_sleep_until - millis()) > 0) {
|
||||
delay(1); // Give MCU to OTA to run
|
||||
return;
|
||||
}
|
||||
|
||||
// Set GPIO wakeup
|
||||
gpio_num_t wakeupPin = (gpio_num_t)getIRQGpio();
|
||||
gpio_num_t wakeupPin = (gpio_num_t)getIRQGpio();
|
||||
|
||||
// Configure timer wakeup
|
||||
if (secs > 0) {
|
||||
@@ -100,7 +102,10 @@ public:
|
||||
|
||||
// Configure GPIO wakeup
|
||||
esp_sleep_enable_gpio_wakeup();
|
||||
gpio_wakeup_enable((gpio_num_t)wakeupPin, GPIO_INTR_HIGH_LEVEL); // Wake up when receiving a LoRa packet
|
||||
gpio_wakeup_enable(wakeupPin, GPIO_INTR_HIGH_LEVEL); // Wake up when receiving a LoRa packet
|
||||
#if defined(PIN_USER_BTN) && (PIN_USER_BTN >= 0)
|
||||
gpio_wakeup_enable((gpio_num_t)PIN_USER_BTN, GPIO_INTR_LOW_LEVEL); // Wakeup when pressing button
|
||||
#endif
|
||||
|
||||
// MCU enters light sleep
|
||||
esp_light_sleep_start();
|
||||
@@ -108,6 +113,15 @@ public:
|
||||
// Avoid ISR flood during wakeup due to HIGH LEVEL interrupt
|
||||
gpio_wakeup_disable(wakeupPin);
|
||||
gpio_set_intr_type(wakeupPin, GPIO_INTR_POSEDGE);
|
||||
#if defined(PIN_USER_BTN) && (PIN_USER_BTN >= 0)
|
||||
gpio_wakeup_disable((gpio_num_t)PIN_USER_BTN);
|
||||
gpio_set_intr_type((gpio_num_t)PIN_USER_BTN, GPIO_INTR_POSEDGE);
|
||||
|
||||
// Check if waken up by PIN_USER_BTN
|
||||
if (gpio_get_level((gpio_num_t)PIN_USER_BTN) == LOW) {
|
||||
inhibit_sleep_until = millis() + 30000; // Do not sleep in the next 30s. Should be longer than OLED timeout
|
||||
}
|
||||
#endif
|
||||
|
||||
// Enable CPU interrupt servicing
|
||||
portEXIT_CRITICAL(&sleepMux);
|
||||
|
||||
@@ -390,6 +390,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) {
|
||||
static const char BOOTLOADER_MARKER[] = "UF2 Bootloader ";
|
||||
const uint8_t* flash = (const uint8_t*)0x000FB000; // earliest known info.txt location is 0xFB90B, latest is 0xFCC4B
|
||||
|
||||
@@ -54,6 +54,7 @@ public:
|
||||
virtual void reboot() override { NVIC_SystemReset(); }
|
||||
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[]) override;
|
||||
virtual void sleep(uint32_t secs) override;
|
||||
|
||||
Reference in new issue
Block a user