@@ -717,37 +717,17 @@ bool Power::setup()
717717 found = true ;
718718#endif
719719 }
720- #ifdef EXT_PWR_DETECT
721- attachInterrupt (
722- EXT_PWR_DETECT,
723- []() {
724- power->setIntervalFromNow (0 );
725- runASAP = true ;
726- },
727- CHANGE);
728- #endif
729- #ifdef BATTERY_CHARGING_INV
730- attachInterrupt (
731- BATTERY_CHARGING_INV,
732- []() {
733- power->setIntervalFromNow (0 );
734- runASAP = true ;
735- },
736- CHANGE);
737- #endif
738- #ifdef EXT_CHRG_DETECT
739- attachInterrupt (
740- EXT_CHRG_DETECT,
741- []() {
742- power->setIntervalFromNow (0 );
743- runASAP = true ;
744- BaseType_t higherWake = 0 ;
745- },
746- CHANGE);
747- #endif
720+ attachPowerInterrupts ();
748721 enabled = found;
749722 low_voltage_counter = 0 ;
750723
724+ #ifdef ARCH_ESP32
725+ // Register callbacks for before and after lightsleep
726+ // Used to detach and reattach interrupts
727+ lsObserver.observe (¬ifyLightSleep);
728+ lsEndObserver.observe (¬ifyLightSleepEnd);
729+ #endif
730+
751731 return found;
752732}
753733
@@ -1026,6 +1006,97 @@ int32_t Power::runOnce()
10261006 return (statusHandler && statusHandler->isInitialized ()) ? (1000 * 20 ) : RUN_SAME;
10271007}
10281008
1009+ #ifdef ARCH_ESP32
1010+
1011+ // Detach our class' interrupts before lightsleep
1012+ // Allows sleep.cpp to configure its own interrupts, which wake the device on user-button press
1013+ int Power::beforeLightSleep (void *unused)
1014+ {
1015+ LOG_WARN (" Detaching power interrupts for sleep" );
1016+ detachPowerInterrupts ();
1017+ return 0 ; // Indicates success
1018+ }
1019+
1020+ // Reconfigure our interrupts
1021+ // Our class' interrupts were disconnected during sleep, to allow the user button to wake the device from sleep
1022+ int Power::afterLightSleep (esp_sleep_wakeup_cause_t cause)
1023+ {
1024+ attachPowerInterrupts ();
1025+ return 0 ; // Indicates success
1026+ }
1027+
1028+ #endif
1029+
1030+ /*
1031+ * Attach (or re-attach) hardware interrupts for power management
1032+ * Public method. Used outside class when waking from MCU sleep
1033+ */
1034+ void Power::attachPowerInterrupts ()
1035+ {
1036+ #ifdef EXT_PWR_DETECT
1037+ attachInterrupt (
1038+ EXT_PWR_DETECT,
1039+ []() {
1040+ power->setIntervalFromNow (0 );
1041+ runASAP = true ;
1042+ },
1043+ CHANGE);
1044+ #endif
1045+ #ifdef BATTERY_CHARGING_INV
1046+ attachInterrupt (
1047+ BATTERY_CHARGING_INV,
1048+ []() {
1049+ power->setIntervalFromNow (0 );
1050+ runASAP = true ;
1051+ },
1052+ CHANGE);
1053+ #endif
1054+ #ifdef EXT_CHRG_DETECT
1055+ attachInterrupt (
1056+ EXT_CHRG_DETECT,
1057+ []() {
1058+ power->setIntervalFromNow (0 );
1059+ runASAP = true ;
1060+ BaseType_t higherWake = 0 ;
1061+ },
1062+ CHANGE);
1063+ #endif
1064+ #ifdef PMU_IRQ
1065+ if (PMU) {
1066+ attachInterrupt (
1067+ PMU_IRQ,
1068+ [] {
1069+ pmu_irq = true ;
1070+ power->setIntervalFromNow (0 );
1071+ runASAP = true ;
1072+ },
1073+ FALLING);
1074+ }
1075+ #endif
1076+ }
1077+
1078+ /*
1079+ * Detach the "normal" button interrupts.
1080+ * Public method. Used before attaching a "wake-on-button" interrupt for MCU sleep
1081+ */
1082+ void Power::detachPowerInterrupts ()
1083+ {
1084+ #ifdef EXT_PWR_DETECT
1085+ detachInterrupt (EXT_PWR_DETECT);
1086+ #endif
1087+ #ifdef BATTERY_CHARGING_INV
1088+ detachInterrupt (BATTERY_CHARGING_INV);
1089+ #endif
1090+ #ifdef EXT_CHRG_DETECT
1091+ detachInterrupt (EXT_CHRG_DETECT);
1092+ #endif
1093+ #ifdef PMU_IRQ
1094+ if (PMU) {
1095+ detachInterrupt (PMU_IRQ);
1096+ }
1097+ #endif
1098+ }
1099+
10291100/* *
10301101 * Init the power manager chip
10311102 *
@@ -1303,8 +1374,6 @@ bool Power::axpChipInit()
13031374 }
13041375
13051376 pinMode (PMU_IRQ, INPUT);
1306- attachInterrupt (
1307- PMU_IRQ, [] { pmu_irq = true ; }, FALLING);
13081377
13091378 // we do not look for AXPXXX_CHARGING_FINISHED_IRQ & AXPXXX_CHARGING_IRQ
13101379 // because it occurs repeatedly while there is no battery also it could cause
0 commit comments