From 809552692f33691349d9afec92ad25f69467b470 Mon Sep 17 00:00:00 2001 From: Manuel <71137295+mverch67@users.noreply.github.com> Date: Sat, 30 Aug 2025 14:09:55 +0200 Subject: [PATCH] power down during LS and shutdown --- src/Power.cpp | 42 ++++++++++++++++++++---------------------- src/sleep.cpp | 36 ++++++++++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 22 deletions(-) diff --git a/src/Power.cpp b/src/Power.cpp index bf74f6e53..e0c28cce0 100644 --- a/src/Power.cpp +++ b/src/Power.cpp @@ -128,6 +128,7 @@ RAK9154Sensor rak9154Sensor; #ifdef HAS_PPM // note: XPOWERS_CHIP_XXX must be defined in variant.h #include +XPowersPPM *PPM = NULL; #endif #ifdef HAS_BQ27220 @@ -681,7 +682,7 @@ bool Power::setup() found = true; } else if (lipoChargerInit()) { found = true; - } else if (meshSolarInit()) { + } else if (meshSolarInit()) { found = true; } else if (analogInit()) { found = true; @@ -1320,7 +1321,6 @@ bool Power::lipoInit() class LipoCharger : public HasBatteryLevel { private: - XPowersPPM *ppm = nullptr; BQ27220 *bq = nullptr; public: @@ -1329,41 +1329,41 @@ class LipoCharger : public HasBatteryLevel */ bool runOnce() { - if (ppm == nullptr) { - ppm = new XPowersPPM; - bool result = ppm->init(Wire, I2C_SDA, I2C_SCL, BQ25896_ADDR); + if (PPM == nullptr) { + PPM = new XPowersPPM; + bool result = PPM->init(Wire, I2C_SDA, I2C_SCL, BQ25896_ADDR); if (result) { LOG_INFO("PPM BQ25896 init succeeded"); // Set the minimum operating voltage. Below this voltage, the PPM will protect - // ppm->setSysPowerDownVoltage(3100); + // PPM->setSysPowerDownVoltage(3100); // Set input current limit, default is 500mA - // ppm->setInputCurrentLimit(800); + // PPM->setInputCurrentLimit(800); // Disable current limit pin - // ppm->disableCurrentLimitPin(); + // PPM->disableCurrentLimitPin(); // Set the charging target voltage, Range:3840 ~ 4608mV ,step:16 mV - ppm->setChargeTargetVoltage(4288); + PPM->setChargeTargetVoltage(4288); // Set the precharge current , Range: 64mA ~ 1024mA ,step:64mA - // ppm->setPrechargeCurr(64); + // PPM->setPrechargeCurr(64); // The premise is that limit pin is disabled, or it will // only follow the maximum charging current set by limit pin. // Set the charging current , Range:0~5056mA ,step:64mA - ppm->setChargerConstantCurr(1024); + PPM->setChargerConstantCurr(1024); // To obtain voltage data, the ADC must be enabled first - ppm->enableMeasure(); + PPM->enableMeasure(); // Turn on charging function // If there is no battery connected, do not turn on the charging function - ppm->enableCharge(); + PPM->enableCharge(); } else { LOG_WARN("PPM BQ25896 init failed"); - delete ppm; - ppm = nullptr; + delete PPM; + PPM = nullptr; return false; } } @@ -1404,23 +1404,23 @@ class LipoCharger : public HasBatteryLevel /** * return true if there is a battery installed in this unit */ - virtual bool isBatteryConnect() override { return ppm->getBattVoltage() > 0; } + virtual bool isBatteryConnect() override { return PPM->getBattVoltage() > 0; } /** * return true if there is an external power source detected */ - virtual bool isVbusIn() override { return ppm->getVbusVoltage() > 0; } + virtual bool isVbusIn() override { return PPM->getVbusVoltage() > 0; } /** * return true if the battery is currently charging */ virtual bool isCharging() override { - bool isCharging = ppm->isCharging(); + bool isCharging = PPM->isCharging(); if (isCharging) { LOG_DEBUG("BQ27220 time to full charge: %d min", bq->getTimeToFull()); } else { - if (!ppm->isVbusIn()) { + if (!PPM->isVbusIn()) { LOG_DEBUG("BQ27220 time to empty: %d min (%d mAh)", bq->getTimeToEmpty(), bq->getRemainingCapacity()); } } @@ -1453,8 +1453,6 @@ bool Power::lipoChargerInit() } #endif - - #ifdef HELTEC_MESH_SOLAR #include "meshSolarApp.h" @@ -1492,7 +1490,7 @@ class meshSolarBatteryLevel : public HasBatteryLevel /** * return true if there is an external power source detected */ - virtual bool isVbusIn() override { return meshSolarIsVbusIn();} + virtual bool isVbusIn() override { return meshSolarIsVbusIn(); } /** * return true if the battery is currently charging diff --git a/src/sleep.cpp b/src/sleep.cpp index 1a5f246c5..dae9c27ac 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -32,6 +32,16 @@ esp_sleep_source_t wakeCause; // the reason we booted this time #endif #include "Throttle.h" +#ifdef USE_XL9555 +#include "ExtensionIOXL9555.hpp" +extern ExtensionIOXL9555 io; +#endif + +#ifdef HAS_PPM +#include +extern XPowersPPM *PPM; +#endif + #ifndef INCLUDE_vTaskSuspend #define INCLUDE_vTaskSuspend 0 #endif @@ -297,6 +307,14 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false, bool skipSaveN #endif #endif +#ifdef HAS_PPM + if (PPM) { + LOG_INFO("PMM shutdown"); + console->flush(); + PPM->shutdown(); + } +#endif + #ifdef HAS_PMU if (pmu_found && PMU) { // Obsolete comment: from back when we we used to receive lora packets while CPU was in deep sleep. @@ -412,6 +430,16 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r if (pmu_found) gpio_wakeup_enable((gpio_num_t)PMU_IRQ, GPIO_INTR_LOW_LEVEL); // pmu irq #endif + +#ifdef USE_XL9555 + LOG_DEBUG("power down XL9555 io"); + io.digitalWrite(EXPANDS_DRV_EN, LOW); + io.digitalWrite(EXPANDS_AMP_EN, LOW); + io.digitalWrite(EXPANDS_KB_EN, LOW); + io.digitalWrite(EXPANDS_SD_EN, LOW); + io.digitalWrite(EXPANDS_GPIO_EN, LOW); +#endif + auto res = esp_sleep_enable_gpio_wakeup(); if (res != ESP_OK) { LOG_ERROR("esp_sleep_enable_gpio_wakeup result %d", res); @@ -452,6 +480,14 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r gpio_wakeup_disable((gpio_num_t)RF95_IRQ); } #endif +#ifdef USE_XL9555 + LOG_DEBUG("power up XL9555 io"); + io.digitalWrite(EXPANDS_DRV_EN, HIGH); + io.digitalWrite(EXPANDS_AMP_EN, HIGH); + io.digitalWrite(EXPANDS_KB_EN, HIGH); + io.digitalWrite(EXPANDS_SD_EN, HIGH); + io.digitalWrite(EXPANDS_GPIO_EN, HIGH); +#endif esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause(); notifyLightSleepEnd.notifyObservers(cause); // Button interrupts are reattached here