Detach power interrupts for sleep (#10230)
* Detach power interrupts for sleep * Gate PMU IRQ behind a found PMU
This commit is contained in:
co-authored by
GitHub
parent
fcb9ec0c2d
commit
28e705de5c
+99
-30
@@ -746,37 +746,17 @@ bool Power::setup()
|
|||||||
found = true;
|
found = true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef EXT_PWR_DETECT
|
attachPowerInterrupts();
|
||||||
attachInterrupt(
|
|
||||||
EXT_PWR_DETECT,
|
|
||||||
[]() {
|
|
||||||
power->setIntervalFromNow(0);
|
|
||||||
runASAP = true;
|
|
||||||
},
|
|
||||||
CHANGE);
|
|
||||||
#endif
|
|
||||||
#ifdef BATTERY_CHARGING_INV
|
|
||||||
attachInterrupt(
|
|
||||||
BATTERY_CHARGING_INV,
|
|
||||||
[]() {
|
|
||||||
power->setIntervalFromNow(0);
|
|
||||||
runASAP = true;
|
|
||||||
},
|
|
||||||
CHANGE);
|
|
||||||
#endif
|
|
||||||
#ifdef EXT_CHRG_DETECT
|
|
||||||
attachInterrupt(
|
|
||||||
EXT_CHRG_DETECT,
|
|
||||||
[]() {
|
|
||||||
power->setIntervalFromNow(0);
|
|
||||||
runASAP = true;
|
|
||||||
BaseType_t higherWake = 0;
|
|
||||||
},
|
|
||||||
CHANGE);
|
|
||||||
#endif
|
|
||||||
enabled = found;
|
enabled = found;
|
||||||
low_voltage_counter = 0;
|
low_voltage_counter = 0;
|
||||||
|
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
// Register callbacks for before and after lightsleep
|
||||||
|
// Used to detach and reattach interrupts
|
||||||
|
lsObserver.observe(¬ifyLightSleep);
|
||||||
|
lsEndObserver.observe(¬ifyLightSleepEnd);
|
||||||
|
#endif
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1055,6 +1035,97 @@ int32_t Power::runOnce()
|
|||||||
return (statusHandler && statusHandler->isInitialized()) ? (1000 * 20) : RUN_SAME;
|
return (statusHandler && statusHandler->isInitialized()) ? (1000 * 20) : RUN_SAME;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
|
||||||
|
// Detach our class' interrupts before lightsleep
|
||||||
|
// Allows sleep.cpp to configure its own interrupts, which wake the device on user-button press
|
||||||
|
int Power::beforeLightSleep(void *unused)
|
||||||
|
{
|
||||||
|
LOG_WARN("Detaching power interrupts for sleep");
|
||||||
|
detachPowerInterrupts();
|
||||||
|
return 0; // Indicates success
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reconfigure our interrupts
|
||||||
|
// Our class' interrupts were disconnected during sleep, to allow the user button to wake the device from sleep
|
||||||
|
int Power::afterLightSleep(esp_sleep_wakeup_cause_t cause)
|
||||||
|
{
|
||||||
|
attachPowerInterrupts();
|
||||||
|
return 0; // Indicates success
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Attach (or re-attach) hardware interrupts for power management
|
||||||
|
* Public method. Used outside class when waking from MCU sleep
|
||||||
|
*/
|
||||||
|
void Power::attachPowerInterrupts()
|
||||||
|
{
|
||||||
|
#ifdef EXT_PWR_DETECT
|
||||||
|
attachInterrupt(
|
||||||
|
EXT_PWR_DETECT,
|
||||||
|
[]() {
|
||||||
|
power->setIntervalFromNow(0);
|
||||||
|
runASAP = true;
|
||||||
|
},
|
||||||
|
CHANGE);
|
||||||
|
#endif
|
||||||
|
#ifdef BATTERY_CHARGING_INV
|
||||||
|
attachInterrupt(
|
||||||
|
BATTERY_CHARGING_INV,
|
||||||
|
[]() {
|
||||||
|
power->setIntervalFromNow(0);
|
||||||
|
runASAP = true;
|
||||||
|
},
|
||||||
|
CHANGE);
|
||||||
|
#endif
|
||||||
|
#ifdef EXT_CHRG_DETECT
|
||||||
|
attachInterrupt(
|
||||||
|
EXT_CHRG_DETECT,
|
||||||
|
[]() {
|
||||||
|
power->setIntervalFromNow(0);
|
||||||
|
runASAP = true;
|
||||||
|
BaseType_t higherWake = 0;
|
||||||
|
},
|
||||||
|
CHANGE);
|
||||||
|
#endif
|
||||||
|
#ifdef PMU_IRQ
|
||||||
|
if (PMU) {
|
||||||
|
attachInterrupt(
|
||||||
|
PMU_IRQ,
|
||||||
|
[] {
|
||||||
|
pmu_irq = true;
|
||||||
|
power->setIntervalFromNow(0);
|
||||||
|
runASAP = true;
|
||||||
|
},
|
||||||
|
FALLING);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Detach the "normal" button interrupts.
|
||||||
|
* Public method. Used before attaching a "wake-on-button" interrupt for MCU sleep
|
||||||
|
*/
|
||||||
|
void Power::detachPowerInterrupts()
|
||||||
|
{
|
||||||
|
#ifdef EXT_PWR_DETECT
|
||||||
|
detachInterrupt(EXT_PWR_DETECT);
|
||||||
|
#endif
|
||||||
|
#ifdef BATTERY_CHARGING_INV
|
||||||
|
detachInterrupt(BATTERY_CHARGING_INV);
|
||||||
|
#endif
|
||||||
|
#ifdef EXT_CHRG_DETECT
|
||||||
|
detachInterrupt(EXT_CHRG_DETECT);
|
||||||
|
#endif
|
||||||
|
#ifdef PMU_IRQ
|
||||||
|
if (PMU) {
|
||||||
|
detachInterrupt(PMU_IRQ);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Init the power manager chip
|
* Init the power manager chip
|
||||||
*
|
*
|
||||||
@@ -1332,8 +1403,6 @@ bool Power::axpChipInit()
|
|||||||
}
|
}
|
||||||
|
|
||||||
pinMode(PMU_IRQ, INPUT);
|
pinMode(PMU_IRQ, INPUT);
|
||||||
attachInterrupt(
|
|
||||||
PMU_IRQ, [] { pmu_irq = true; }, FALLING);
|
|
||||||
|
|
||||||
// we do not look for AXPXXX_CHARGING_FINISHED_IRQ & AXPXXX_CHARGING_IRQ
|
// we do not look for AXPXXX_CHARGING_FINISHED_IRQ & AXPXXX_CHARGING_IRQ
|
||||||
// because it occurs repeatedly while there is no battery also it could cause
|
// because it occurs repeatedly while there is no battery also it could cause
|
||||||
|
|||||||
+17
-1
@@ -86,7 +86,7 @@ extern RAK9154Sensor rak9154Sensor;
|
|||||||
extern XPowersLibInterface *PMU;
|
extern XPowersLibInterface *PMU;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class Power : private concurrency::OSThread
|
class Power : public concurrency::OSThread
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
@@ -101,6 +101,14 @@ class Power : private concurrency::OSThread
|
|||||||
void setStatusHandler(meshtastic::PowerStatus *handler) { statusHandler = handler; }
|
void setStatusHandler(meshtastic::PowerStatus *handler) { statusHandler = handler; }
|
||||||
const uint16_t OCV[11] = {OCV_ARRAY};
|
const uint16_t OCV[11] = {OCV_ARRAY};
|
||||||
|
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
int beforeLightSleep(void *unused);
|
||||||
|
int afterLightSleep(esp_sleep_wakeup_cause_t cause);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void attachPowerInterrupts();
|
||||||
|
void detachPowerInterrupts();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
meshtastic::PowerStatus *statusHandler;
|
meshtastic::PowerStatus *statusHandler;
|
||||||
|
|
||||||
@@ -125,6 +133,14 @@ class Power : private concurrency::OSThread
|
|||||||
// open circuit voltage lookup table
|
// open circuit voltage lookup table
|
||||||
uint8_t low_voltage_counter;
|
uint8_t low_voltage_counter;
|
||||||
uint32_t lastLogTime = 0;
|
uint32_t lastLogTime = 0;
|
||||||
|
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
// Get notified when lightsleep begins and ends
|
||||||
|
CallbackObserver<Power, void *> lsObserver = CallbackObserver<Power, void *>(this, &Power::beforeLightSleep);
|
||||||
|
CallbackObserver<Power, esp_sleep_wakeup_cause_t> lsEndObserver =
|
||||||
|
CallbackObserver<Power, esp_sleep_wakeup_cause_t>(this, &Power::afterLightSleep);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef DEBUG_HEAP
|
#ifdef DEBUG_HEAP
|
||||||
uint32_t lastheap;
|
uint32_t lastheap;
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+5
-6
@@ -497,13 +497,12 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
|
|||||||
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
|
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
|
||||||
notifyLightSleepEnd.notifyObservers(cause); // Button interrupts are reattached here
|
notifyLightSleepEnd.notifyObservers(cause); // Button interrupts are reattached here
|
||||||
|
|
||||||
#ifdef BUTTON_PIN
|
|
||||||
if (cause == ESP_SLEEP_WAKEUP_GPIO) {
|
if (cause == ESP_SLEEP_WAKEUP_GPIO) {
|
||||||
LOG_INFO("Exit light sleep gpio: btn=%d",
|
LOG_INFO("Exit light sleep gpio");
|
||||||
!digitalRead(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN));
|
// If we woke because of a GPIO, it's possible power needs to run to handle.
|
||||||
} else
|
power->setIntervalFromNow(0);
|
||||||
#endif
|
runASAP = true;
|
||||||
{
|
} else {
|
||||||
LOG_INFO("Exit light sleep cause: %d", cause);
|
LOG_INFO("Exit light sleep cause: %d", cause);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user