Merge remote-tracking branch 'IoTThinks/PowerSaving-v16' into keymindCascade
# Conflicts: # build-iotthinks.sh # build.sh # examples/simple_repeater/MyMesh.h # src/helpers/CommonCLI.cpp # variants/heltec_ct62/platformio.ini # variants/heltec_t096/T096Board.cpp # variants/heltec_t096/platformio.ini # variants/heltec_tracker/platformio.ini # variants/heltec_tracker_v2/platformio.ini # variants/heltec_v2/platformio.ini # variants/heltec_v3/HeltecV3Board.h # variants/heltec_v3/platformio.ini # variants/heltec_v4/HeltecV4Board.cpp # variants/heltec_v4/platformio.ini # variants/heltec_wireless_paper/platformio.ini # variants/lilygo_tbeam_1w/platformio.ini # variants/lilygo_tbeam_SX1262/platformio.ini # variants/lilygo_tbeam_SX1276/platformio.ini # variants/lilygo_tbeam_supreme_SX1262/platformio.ini # variants/lilygo_tlora_v2_1/platformio.ini # variants/xiao_c3/platformio.ini # variants/xiao_s3_wio/platformio.ini
This commit is contained in:
commit
d9cefed1b1
96 files changed
+757
-878
No files matched your search
@@ -0,0 +1,6 @@
|
||||
#include <stdint.h>
|
||||
|
||||
extern "C" {
|
||||
__attribute__((section(".persistent_magic"))) uint32_t persistent_magic;
|
||||
__attribute__((section(".persistent_data"))) uint32_t persistent_time;
|
||||
}
|
||||
@@ -3,19 +3,57 @@
|
||||
#include <Mesh.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
#ifdef NRF52_PLATFORM
|
||||
#define CLOCK_MAGIC_NUM 0xAA55CC33
|
||||
#define RTC_TIME_MIN 1772323200 // 1 Mar 2026
|
||||
|
||||
extern uint32_t persistent_magic;
|
||||
extern uint32_t persistent_time;
|
||||
#endif
|
||||
|
||||
class VolatileRTCClock : public mesh::RTCClock {
|
||||
uint32_t base_time;
|
||||
uint64_t accumulator;
|
||||
unsigned long prev_millis;
|
||||
|
||||
public:
|
||||
VolatileRTCClock() { base_time = 1715770351; accumulator = 0; prev_millis = millis(); } // 15 May 2024, 8:50pm
|
||||
VolatileRTCClock() {
|
||||
#ifdef NRF52_PLATFORM
|
||||
if (persistent_magic == CLOCK_MAGIC_NUM && persistent_time >= RTC_TIME_MIN) {
|
||||
base_time = persistent_time;
|
||||
} else {
|
||||
base_time = RTC_TIME_MIN;
|
||||
}
|
||||
#else
|
||||
base_time = 1715770351;
|
||||
#endif
|
||||
|
||||
accumulator = 0;
|
||||
prev_millis = millis();
|
||||
}
|
||||
|
||||
uint32_t getCurrentTime() override { return base_time + accumulator/1000; }
|
||||
void setCurrentTime(uint32_t time) override { base_time = time; accumulator = 0; prev_millis = millis(); }
|
||||
|
||||
void setCurrentTime(uint32_t time) override {
|
||||
base_time = time;
|
||||
accumulator = 0;
|
||||
prev_millis = millis();
|
||||
|
||||
#ifdef NRF52_PLATFORM
|
||||
persistent_magic = CLOCK_MAGIC_NUM;
|
||||
persistent_time = time;
|
||||
#endif
|
||||
}
|
||||
|
||||
void tick() override {
|
||||
unsigned long now = millis();
|
||||
accumulator += (now - prev_millis);
|
||||
prev_millis = now;
|
||||
|
||||
#ifdef NRF52_PLATFORM
|
||||
persistent_magic = CLOCK_MAGIC_NUM;
|
||||
persistent_time = getCurrentTime();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include "AdvertDataHelpers.h"
|
||||
#include "TxtDataHelpers.h"
|
||||
#include <RTClib.h>
|
||||
#define STR_HELPER(x) #x
|
||||
#define STR(x) STR_HELPER(x)
|
||||
|
||||
#ifndef BRIDGE_MAX_BAUD
|
||||
#define BRIDGE_MAX_BAUD 115200
|
||||
@@ -81,7 +83,8 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
||||
file.read((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 135
|
||||
file.read((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 136
|
||||
file.read((uint8_t *)&_prefs->powersaving_enabled, sizeof(_prefs->powersaving_enabled)); // 152
|
||||
file.read(pad, 3); // 153
|
||||
file.read((uint8_t *)&_prefs->reboot_interval, sizeof(_prefs->reboot_interval)); // 153
|
||||
file.read(pad, 2); // 154
|
||||
file.read((uint8_t *)&_prefs->gps_enabled, sizeof(_prefs->gps_enabled)); // 156
|
||||
file.read((uint8_t *)&_prefs->gps_interval, sizeof(_prefs->gps_interval)); // 157
|
||||
file.read((uint8_t *)&_prefs->advert_loc_policy, sizeof (_prefs->advert_loc_policy)); // 161
|
||||
@@ -117,6 +120,7 @@ void CommonCLI::loadPrefsInt(FILESYSTEM* fs, const char* filename) {
|
||||
_prefs->bridge_channel = constrain(_prefs->bridge_channel, 0, 14);
|
||||
|
||||
_prefs->powersaving_enabled = constrain(_prefs->powersaving_enabled, 0, 1);
|
||||
_prefs->reboot_interval = constrain(_prefs->reboot_interval, 0, 255);
|
||||
|
||||
_prefs->gps_enabled = constrain(_prefs->gps_enabled, 0, 1);
|
||||
_prefs->advert_loc_policy = constrain(_prefs->advert_loc_policy, 0, 2);
|
||||
@@ -178,7 +182,8 @@ void CommonCLI::savePrefs(FILESYSTEM* fs) {
|
||||
file.write((uint8_t *)&_prefs->bridge_channel, sizeof(_prefs->bridge_channel)); // 135
|
||||
file.write((uint8_t *)&_prefs->bridge_secret, sizeof(_prefs->bridge_secret)); // 136
|
||||
file.write((uint8_t *)&_prefs->powersaving_enabled, sizeof(_prefs->powersaving_enabled)); // 152
|
||||
file.write(pad, 3); // 153
|
||||
file.write((uint8_t *)&_prefs->reboot_interval, sizeof(_prefs->reboot_interval)); // 153
|
||||
file.write(pad, 2); // 154
|
||||
file.write((uint8_t *)&_prefs->gps_enabled, sizeof(_prefs->gps_enabled)); // 156
|
||||
file.write((uint8_t *)&_prefs->gps_interval, sizeof(_prefs->gps_interval)); // 157
|
||||
file.write((uint8_t *)&_prefs->advert_loc_policy, sizeof(_prefs->advert_loc_policy)); // 161
|
||||
@@ -461,6 +466,36 @@ void CommonCLI::handleCommand(uint32_t sender_timestamp, char* command, char* re
|
||||
} else {
|
||||
strcpy(reply, "off");
|
||||
}
|
||||
} else if (memcmp(command, "sensor", 6) == 0) {
|
||||
// I2C
|
||||
#if defined(ENV_PIN_SDA) && defined(ENV_PIN_SCL)
|
||||
sprintf(reply, "I2C Wire1: SDA=%s,SCL=%s\r\n", STR(ENV_PIN_SDA), STR(ENV_PIN_SCL));
|
||||
#elif defined(PIN_BOARD_SDA) && defined(PIN_BOARD_SCL)
|
||||
sprintf(reply, "I2C Wire: SDA=%s, SCL=%s\r\n", STR(PIN_BOARD_SDA), STR(PIN_BOARD_SCL));
|
||||
#elif defined(PIN_WIRE_SDA) && defined(PIN_WIRE_SCL)
|
||||
sprintf(reply, "I2C Wire: SDA=%s, SCL=%s\r\n", STR(PIN_WIRE_SDA), STR(PIN_WIRE_SCL));
|
||||
#else
|
||||
sprintf(reply, "I2C GPIOs not defined\r\n");
|
||||
#endif
|
||||
|
||||
// GPS
|
||||
#if defined(PIN_GPS_RX) && defined(PIN_GPS_TX)
|
||||
sprintf(reply + strlen(reply), "GPS Serial: RX=%s, TX=%s", STR(PIN_GPS_RX), STR(PIN_GPS_TX));
|
||||
#ifdef ENV_INCLUDE_GPS> 0
|
||||
sprintf(reply + strlen(reply), ". Configured");
|
||||
#else
|
||||
sprintf(reply + strlen(reply), ". Not configured");
|
||||
#endif
|
||||
#else
|
||||
sprintf(reply + strlen(reply), "GPS Serial not defined");
|
||||
#endif
|
||||
} else if (memcmp(command, "powerlog", 8) == 0) {
|
||||
sprintf(reply, "Last reset reason: %s", _board->getResetReasonString(_board->getResetReason()));
|
||||
#if defined(NRF52_PLATFORM)
|
||||
sprintf(reply + strlen(reply), "\r\nLast shutdown reason: %s",
|
||||
_board->getShutdownReasonString(_board->getShutdownReason()));
|
||||
sprintf(reply + strlen(reply), "\r\nLast boot voltage: %u mV", _board->getBootVoltage());
|
||||
#endif
|
||||
} else if (memcmp(command, "log start", 9) == 0) {
|
||||
_callbacks->setLoggingOn(true);
|
||||
strcpy(reply, " logging on");
|
||||
@@ -791,6 +826,19 @@ void CommonCLI::handleSetCmd(uint32_t sender_timestamp, char* command, char* rep
|
||||
_prefs->adc_multiplier = 0.0f;
|
||||
strcpy(reply, "Error: unsupported");
|
||||
};
|
||||
} else if (memcmp(config, "reboot.interval ", 16) == 0) {
|
||||
int hours = _atoi(&config[16]);
|
||||
if (hours == 0) {
|
||||
_prefs->reboot_interval = 0;
|
||||
savePrefs();
|
||||
strcpy(reply, "reboot.interval disabled");
|
||||
} else if (hours < 1 || 255 < hours) {
|
||||
strcpy(reply, "Error: interval range is 1-255 hours");
|
||||
} else {
|
||||
_prefs->reboot_interval = hours;
|
||||
savePrefs();
|
||||
sprintf(reply, "OK - reboot.interval set to %d", _prefs->reboot_interval);
|
||||
}
|
||||
} else {
|
||||
strcpy(reply, "unknown config: ");
|
||||
StrHelper::strncpy(&reply[16], config, 160-17);
|
||||
@@ -966,6 +1014,12 @@ void CommonCLI::handleGetCmd(uint32_t sender_timestamp, char* command, char* rep
|
||||
#else
|
||||
strcpy(reply, "ERROR: Power management not supported");
|
||||
#endif
|
||||
} else if (memcmp(config, "reboot.interval", 15) == 0) {
|
||||
if (_prefs->reboot_interval == 0) {
|
||||
strcpy(reply, "disabled");
|
||||
} else {
|
||||
sprintf(reply, "> %d", (uint8_t)_prefs->reboot_interval);
|
||||
}
|
||||
} else {
|
||||
sprintf(reply, "??: %s", config);
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ struct NodePrefs { // persisted to file
|
||||
char bridge_secret[16]; // for XOR encryption of bridge packets (ESP-NOW only)
|
||||
// Power setting
|
||||
uint8_t powersaving_enabled; // boolean
|
||||
uint8_t reboot_interval; // hours, 0-255 (default 0=disable)
|
||||
// Gps settings
|
||||
uint8_t gps_enabled;
|
||||
uint32_t gps_interval; // in seconds
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#ifdef ESP_PLATFORM
|
||||
|
||||
#include "ESP32Board.h"
|
||||
#include <target.h>
|
||||
|
||||
#if defined(ADMIN_PASSWORD) && !defined(DISABLE_WIFI_OTA) // Repeater or Room Server only
|
||||
#include <WiFi.h>
|
||||
@@ -44,4 +45,45 @@ bool ESP32Board::startOTAUpdate(const char* id, char reply[]) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void ESP32Board::powerOff() {
|
||||
enterDeepSleep(0); // Do not wakeup
|
||||
}
|
||||
|
||||
void ESP32Board::enterDeepSleep(uint32_t secs) {
|
||||
// Power off the display if any
|
||||
#ifdef DISPLAY_CLASS
|
||||
display.turnOff();
|
||||
#endif
|
||||
|
||||
// Power off LoRa
|
||||
radio_driver.powerOff();
|
||||
|
||||
// Keep LoRa inactive during deepsleep
|
||||
digitalWrite(P_LORA_NSS, HIGH);
|
||||
#if CONFIG_IDF_TARGET_ESP32C3
|
||||
gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
||||
#else
|
||||
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
||||
#endif
|
||||
|
||||
// Power off GPS if any
|
||||
if (sensors.getLocationProvider() != NULL) {
|
||||
sensors.getLocationProvider()->stop();
|
||||
}
|
||||
|
||||
// Flush serial buffers
|
||||
Serial.flush();
|
||||
delay(100);
|
||||
|
||||
// Clear stale wakeup sources to avoid ghost wakeup
|
||||
// This is required when Power Management and automatic lightsleep are enabled
|
||||
esp_sleep_disable_wakeup_source(ESP_SLEEP_WAKEUP_ALL);
|
||||
|
||||
if (secs > 0) {
|
||||
esp_sleep_enable_timer_wakeup(secs * 1000000ULL);
|
||||
}
|
||||
|
||||
// Finally set ESP32 into deepsleep
|
||||
esp_deep_sleep_start(); // CPU halts here and never returns!
|
||||
}
|
||||
#endif
|
||||
@@ -14,6 +14,7 @@
|
||||
#include <Wire.h>
|
||||
#include "soc/rtc.h"
|
||||
#include "esp_system.h"
|
||||
#include <driver/rtc_io.h>
|
||||
|
||||
class ESP32Board : public mesh::MainBoard {
|
||||
protected:
|
||||
@@ -62,6 +63,9 @@ public:
|
||||
return raw / 4;
|
||||
}
|
||||
|
||||
virtual void powerOff() override;
|
||||
void enterDeepSleep(uint32_t secs);
|
||||
|
||||
uint32_t getIRQGpio() override {
|
||||
return P_LORA_DIO_1; // default for SX1262
|
||||
}
|
||||
@@ -155,21 +159,68 @@ public:
|
||||
void setInhibitSleep(bool inhibit) {
|
||||
inhibit_sleep = inhibit;
|
||||
}
|
||||
|
||||
uint32_t getResetReason() const override {
|
||||
return esp_reset_reason();
|
||||
}
|
||||
|
||||
// https://docs.espressif.com/projects/esp-idf/en/v4.4.7/esp32/api-reference/system/system.html
|
||||
const char *getResetReasonString(uint32_t reason) {
|
||||
switch (reason) {
|
||||
case ESP_RST_UNKNOWN:
|
||||
return "Unknown or first boot";
|
||||
case ESP_RST_POWERON:
|
||||
return "Power-on reset";
|
||||
case ESP_RST_EXT:
|
||||
return "External reset";
|
||||
case ESP_RST_SW:
|
||||
return "Software reset";
|
||||
case ESP_RST_PANIC:
|
||||
return "Panic / exception reset";
|
||||
case ESP_RST_INT_WDT:
|
||||
return "Interrupt watchdog reset";
|
||||
case ESP_RST_TASK_WDT:
|
||||
return "Task watchdog reset";
|
||||
case ESP_RST_WDT:
|
||||
return "Other watchdog reset";
|
||||
case ESP_RST_DEEPSLEEP:
|
||||
return "Wake from deep sleep";
|
||||
case ESP_RST_BROWNOUT:
|
||||
return "Brownout (low voltage)";
|
||||
case ESP_RST_SDIO:
|
||||
return "SDIO reset";
|
||||
default:
|
||||
static char buf[40];
|
||||
snprintf(buf, sizeof(buf), "Unknown reset reason (%d)", reason);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
static RTC_NOINIT_ATTR uint32_t _rtc_backup_time;
|
||||
static RTC_NOINIT_ATTR uint32_t _rtc_backup_magic;
|
||||
#define RTC_BACKUP_MAGIC 0xAA55CC33
|
||||
#define RTC_TIME_MIN 1772323200 // 1 Mar 2026
|
||||
|
||||
class ESP32RTCClock : public mesh::RTCClock {
|
||||
public:
|
||||
ESP32RTCClock() { }
|
||||
void begin() {
|
||||
esp_reset_reason_t reason = esp_reset_reason();
|
||||
if (reason == ESP_RST_POWERON) {
|
||||
// start with some date/time in the recent past
|
||||
struct timeval tv;
|
||||
tv.tv_sec = 1715770351; // 15 May 2024, 8:50pm
|
||||
if (reason == ESP_RST_DEEPSLEEP) {
|
||||
return; // ESP-IDF preserves system time across deep sleep
|
||||
}
|
||||
// All other resets (power-on, crash, WDT, brownout) lose system time.
|
||||
// Restore from RTC backup if valid, otherwise use hardcoded seed.
|
||||
struct timeval tv;
|
||||
if (_rtc_backup_magic == RTC_BACKUP_MAGIC && _rtc_backup_time > RTC_TIME_MIN) {
|
||||
tv.tv_sec = _rtc_backup_time;
|
||||
} else {
|
||||
tv.tv_sec = RTC_TIME_MIN;
|
||||
}
|
||||
tv.tv_usec = 0;
|
||||
settimeofday(&tv, NULL);
|
||||
}
|
||||
}
|
||||
uint32_t getCurrentTime() override {
|
||||
time_t _now;
|
||||
time(&_now);
|
||||
@@ -180,6 +231,16 @@ public:
|
||||
tv.tv_sec = time;
|
||||
tv.tv_usec = 0;
|
||||
settimeofday(&tv, NULL);
|
||||
_rtc_backup_time = time;
|
||||
_rtc_backup_magic = RTC_BACKUP_MAGIC;
|
||||
}
|
||||
void tick() override {
|
||||
time_t now;
|
||||
time(&now);
|
||||
if (now > RTC_TIME_MIN && (uint32_t)now != _rtc_backup_time) {
|
||||
_rtc_backup_time = (uint32_t)now;
|
||||
_rtc_backup_magic = RTC_BACKUP_MAGIC;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -15,8 +15,6 @@
|
||||
|
||||
#include "ESP32Board.h"
|
||||
|
||||
#include <driver/rtc_io.h>
|
||||
|
||||
class MeshadventurerBoard : public ESP32Board {
|
||||
|
||||
public:
|
||||
@@ -35,34 +33,6 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1) {
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||
|
||||
// Make sure the DIO1 and NSS GPIOs are held on required levels during deep sleep
|
||||
rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY);
|
||||
rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1);
|
||||
|
||||
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
||||
|
||||
if (pin_wake_btn < 0) {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet
|
||||
} else {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn
|
||||
}
|
||||
|
||||
if (secs > 0) {
|
||||
esp_sleep_enable_timer_wakeup(secs * 1000000);
|
||||
}
|
||||
|
||||
// Finally set ESP32 into sleep
|
||||
esp_deep_sleep_start(); // CPU halts here and never returns!
|
||||
}
|
||||
|
||||
void powerOff() override {
|
||||
// TODO: re-enable this when there is a definite wake-up source pin:
|
||||
// enterDeepSleep(0);
|
||||
}
|
||||
|
||||
uint16_t getBattMilliVolts() override {
|
||||
analogReadResolution(12);
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#if defined(NRF52_PLATFORM)
|
||||
#include "NRF52Board.h"
|
||||
#include <target.h>
|
||||
|
||||
#include <bluefruit.h>
|
||||
#include <nrf_soc.h>
|
||||
@@ -297,6 +298,37 @@ float NRF52Board::getMCUTemperature() {
|
||||
return temp * 0.25f; // Convert to *C
|
||||
}
|
||||
|
||||
void NRF52Board::powerOff() {
|
||||
// Power off the display if any
|
||||
#ifdef DISPLAY_CLASS
|
||||
display.turnOff();
|
||||
#endif
|
||||
|
||||
// Power off LoRa
|
||||
radio_driver.powerOff();
|
||||
|
||||
// Keep LoRa inactive during deepsleep
|
||||
digitalWrite(P_LORA_NSS, HIGH);
|
||||
|
||||
// Power off GPS if any
|
||||
if(sensors.getLocationProvider() != NULL) {
|
||||
sensors.getLocationProvider()->stop();
|
||||
}
|
||||
|
||||
// Flush serial buffers
|
||||
Serial.flush();
|
||||
delay(100);
|
||||
|
||||
// Enter SYSTEMOFF
|
||||
uint8_t sd_enabled = 0;
|
||||
sd_softdevice_is_enabled(&sd_enabled);
|
||||
if (sd_enabled) { // SoftDevice is enabled
|
||||
sd_power_system_off();
|
||||
} else { // SoftDevice is not enable
|
||||
NRF_POWER->SYSTEMOFF = POWER_SYSTEMOFF_SYSTEMOFF_Enter;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
@@ -50,6 +50,7 @@ public:
|
||||
virtual uint8_t getStartupReason() const override { return startup_reason; }
|
||||
virtual float getMCUTemperature() override;
|
||||
virtual void reboot() override { NVIC_SystemReset(); }
|
||||
virtual void powerOff() 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;
|
||||
|
||||
@@ -86,7 +86,6 @@
|
||||
#include <Arduino.h>
|
||||
#include "XPowersLib.h"
|
||||
#include "helpers/ESP32Board.h"
|
||||
#include <driver/rtc_io.h>
|
||||
|
||||
class TBeamBoard : public ESP32Board {
|
||||
XPowersLibInterface *PMU = NULL;
|
||||
@@ -131,29 +130,6 @@ public:
|
||||
}
|
||||
#endif
|
||||
|
||||
void enterDeepSleep(uint32_t secs, int pin_wake_btn) {
|
||||
esp_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_ON);
|
||||
|
||||
// Make sure the DIO1 and NSS GPIOs are hold on required levels during deep sleep
|
||||
rtc_gpio_set_direction((gpio_num_t)P_LORA_DIO_1, RTC_GPIO_MODE_INPUT_ONLY);
|
||||
rtc_gpio_pulldown_en((gpio_num_t)P_LORA_DIO_1);
|
||||
|
||||
rtc_gpio_hold_en((gpio_num_t)P_LORA_NSS);
|
||||
|
||||
if (pin_wake_btn < 0) {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet
|
||||
} else {
|
||||
esp_sleep_enable_ext1_wakeup( (1L << P_LORA_DIO_1) | (1L << pin_wake_btn), ESP_EXT1_WAKEUP_ANY_HIGH); // wake up on: recv LoRa packet OR wake btn
|
||||
}
|
||||
|
||||
if (secs > 0) {
|
||||
esp_sleep_enable_timer_wakeup(secs * 1000000);
|
||||
}
|
||||
|
||||
// Finally set ESP32 into sleep
|
||||
esp_deep_sleep_start(); // CPU halts here and never returns!
|
||||
}
|
||||
|
||||
uint16_t getBattMilliVolts(){
|
||||
return PMU->getBattVoltage();
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#if ENV_INCLUDE_BME680_BSEC
|
||||
#ifndef TELEM_BME680_ADDRESS
|
||||
#define TELEM_BME680_ADDRESS 0x76
|
||||
#define TELEM_BME680_ADDRESS_2 0x77
|
||||
#endif
|
||||
#define TELEM_BME680_SEALEVELPRESSURE_HPA (1013.25)
|
||||
#include <bsec.h>
|
||||
@@ -40,6 +41,7 @@ static uint32_t bsec_last_save_ms = 0;
|
||||
#ifdef ENV_INCLUDE_BME680
|
||||
#ifndef TELEM_BME680_ADDRESS
|
||||
#define TELEM_BME680_ADDRESS 0x76
|
||||
#define TELEM_BME680_ADDRESS_2 0x77
|
||||
#endif
|
||||
#define TELEM_BME680_SEALEVELPRESSURE_HPA (1013.25)
|
||||
#include <Adafruit_BME680.h>
|
||||
@@ -63,6 +65,7 @@ static Adafruit_AHTX0 AHTX0;
|
||||
#if ENV_INCLUDE_BME280
|
||||
#ifndef TELEM_BME280_ADDRESS
|
||||
#define TELEM_BME280_ADDRESS 0x76 // BME280 environmental sensor I2C address
|
||||
#define TELEM_BME280_ADDRESS_2 0x77
|
||||
#endif
|
||||
#define TELEM_BME280_SEALEVELPRESSURE_HPA (1013.25) // Atmospheric pressure at sea level
|
||||
#include <Adafruit_BME280.h>
|
||||
@@ -72,6 +75,7 @@ static Adafruit_BME280 BME280;
|
||||
#if ENV_INCLUDE_BMP280
|
||||
#ifndef TELEM_BMP280_ADDRESS
|
||||
#define TELEM_BMP280_ADDRESS 0x76 // BMP280 environmental sensor I2C address
|
||||
#define TELEM_BMP280_ADDRESS_2 0x77
|
||||
#endif
|
||||
#define TELEM_BMP280_SEALEVELPRESSURE_HPA (1013.25) // Atmospheric pressure at sea level
|
||||
#include <Adafruit_BMP280.h>
|
||||
@@ -557,15 +561,27 @@ static const SensorDef SENSOR_TABLE[] = {
|
||||
#endif
|
||||
#ifdef ENV_INCLUDE_BME680
|
||||
{ TELEM_BME680_ADDRESS, "BME680", init_bme680, query_bme680 },
|
||||
#ifdef TELEM_BME680_ADDRESS_2
|
||||
{ TELEM_BME680_ADDRESS_2, "BME680", init_bme680, query_bme680 },
|
||||
#endif
|
||||
#endif
|
||||
#if ENV_INCLUDE_BME680_BSEC
|
||||
{ TELEM_BME680_ADDRESS, "BME680+BSEC", init_bme680_bsec, query_bme680_bsec },
|
||||
#ifdef TELEM_BME680_ADDRESS_2
|
||||
{ TELEM_BME680_ADDRESS_2, "BME680+BSEC", init_bme680_bsec, query_bme680_bsec },
|
||||
#endif
|
||||
#endif
|
||||
#if ENV_INCLUDE_BME280
|
||||
{ TELEM_BME280_ADDRESS, "BME280", init_bme280, query_bme280 },
|
||||
#ifdef TELEM_BME280_ADDRESS_2
|
||||
{ TELEM_BME280_ADDRESS_2, "BME280", init_bme280, query_bme280 },
|
||||
#endif
|
||||
#endif
|
||||
#if ENV_INCLUDE_BMP280
|
||||
{ TELEM_BMP280_ADDRESS, "BMP280", init_bmp280, query_bmp280 },
|
||||
#ifdef TELEM_BMP280_ADDRESS_2
|
||||
{ TELEM_BMP280_ADDRESS_2, "BMP280", init_bmp280, query_bmp280 },
|
||||
#endif
|
||||
#endif
|
||||
#if ENV_INCLUDE_SHTC3
|
||||
{ 0x70, "SHTC3", init_shtc3, query_shtc3 },
|
||||
|
||||
@@ -63,6 +63,15 @@ void ST7735Display::turnOff() {
|
||||
#else
|
||||
digitalWrite(PIN_TFT_LEDA_CTL, LOW);
|
||||
#endif
|
||||
|
||||
// Prevent back-powering to save 2.8 mA
|
||||
pinMode(PIN_TFT_CS, INPUT);
|
||||
pinMode(PIN_TFT_DC, INPUT);
|
||||
pinMode(PIN_TFT_SDA, INPUT);
|
||||
pinMode(PIN_TFT_SCL, INPUT);
|
||||
pinMode(PIN_TFT_RST, INPUT);
|
||||
pinMode(PIN_TFT_LEDA_CTL, INPUT);
|
||||
|
||||
_isOn = false;
|
||||
|
||||
if (_peripher_power) _peripher_power->release();
|
||||
|
||||
Reference in new issue
Block a user