@@ -94,16 +94,31 @@ static const adc_atten_t atten = ADC_ATTENUATION;
9494#endif
9595#endif // BATTERY_PIN && ARCH_ESP32
9696
97+ #ifdef EXT_PWR_DETECT
98+ #ifndef EXT_PWR_DETECT_MODE
99+ #define EXT_PWR_DETECT_MODE INPUT
100+ // If using internal pull resistors, we can infer EXT_PWR_DETECT_VALUE
101+ #elif EXT_PWR_DETECT_MODE == INPUT_PULLUP
102+ #define EXT_PWR_DETECT_VALUE LOW
103+ #elif EXT_PWR_DETECT_MODE == INPUT_PULLDOWN
104+ #define EXT_PWR_DETECT_VALUE HIGH
105+ #endif
106+ #ifndef EXT_PWR_DETECT_VALUE
107+ #define EXT_PWR_DETECT_VALUE HIGH
108+ #endif
109+ #endif
110+
97111#ifdef EXT_CHRG_DETECT
98112#ifndef EXT_CHRG_DETECT_MODE
99- static const uint8_t ext_chrg_detect_mode = INPUT;
100- #else
101- static const uint8_t ext_chrg_detect_mode = EXT_CHRG_DETECT_MODE;
113+ #define EXT_CHRG_DETECT_MODE INPUT
114+ // If using internal pull resistors, we can infer EXT_CHRG_DETECT_VALUE
115+ #elif EXT_CHRG_DETECT_MODE == INPUT_PULLUP
116+ #define EXT_CHRG_DETECT_VALUE LOW
117+ #elif EXT_CHRG_DETECT_MODE == INPUT_PULLDOWN
118+ #define EXT_CHRG_DETECT_VALUE HIGH
102119#endif
103120#ifndef EXT_CHRG_DETECT_VALUE
104- static const uint8_t ext_chrg_detect_value = HIGH;
105- #else
106- static const uint8_t ext_chrg_detect_value = EXT_CHRG_DETECT_VALUE;
121+ #define EXT_CHRG_DETECT_VALUE HIGH
107122#endif
108123#endif
109124
@@ -469,28 +484,14 @@ class AnalogBatteryLevel : public HasBatteryLevel
469484 virtual bool isBatteryConnect () override { return getBatteryPercent () != -1 ; }
470485#endif
471486
472- // / If we see a battery voltage higher than physics allows - assume charger is
473- // / pumping in power On some boards we don't have the power management chip
474- // / (like AXPxxxx) so we use EXT_PWR_DETECT GPIO pin to detect external power
475- // / source
487+ // Detect if an external power source is connected if we don’t have a PMIC;
488+ // Firstly prefer EXT_PWR_DETECT GPIO if available,
489+ // secondly try an nRF52-specific routine on some variants,
490+ // lastly provide a fallback to indicate external power when fully charged.
476491 virtual bool isVbusIn () override
477492 {
478493#ifdef EXT_PWR_DETECT
479- #if defined(HELTEC_CAPSULE_SENSOR_V3) || defined(HELTEC_SENSOR_HUB)
480- // if external powered that pin will be pulled down
481- if (digitalRead (EXT_PWR_DETECT) == LOW) {
482- return true ;
483- }
484- // if it's not LOW - check the battery
485- #else
486- // if external powered that pin will be pulled up
487- if (digitalRead (EXT_PWR_DETECT) == HIGH) {
488- return true ;
489- }
490- // if it's not HIGH - check the battery
491- #endif
492- // If we have an EXT_PWR_DETECT pin and it indicates no external power, believe it.
493- return false ;
494+ return digitalRead (EXT_PWR_DETECT) == EXT_PWR_DETECT_VALUE;
494495
495496// technically speaking this should work for all(?) NRF52 boards
496497// but needs testing across multiple devices. NRF52 USB would not even work if
@@ -511,9 +512,9 @@ class AnalogBatteryLevel : public HasBatteryLevel
511512 }
512513#endif
513514#if defined(ELECROW_ThinkNode_M6)
514- return digitalRead (EXT_CHRG_DETECT) == ext_chrg_detect_value || isVbusIn ();
515+ return digitalRead (EXT_CHRG_DETECT) == EXT_CHRG_DETECT_VALUE || isVbusIn ();
515516#elif EXT_CHRG_DETECT
516- return digitalRead (EXT_CHRG_DETECT) == ext_chrg_detect_value ;
517+ return digitalRead (EXT_CHRG_DETECT) == EXT_CHRG_DETECT_VALUE ;
517518#elif defined(BATTERY_CHARGING_INV)
518519 return !digitalRead (BATTERY_CHARGING_INV);
519520#else
@@ -646,14 +647,10 @@ Power::Power() : OSThread("Power")
646647bool Power::analogInit ()
647648{
648649#ifdef EXT_PWR_DETECT
649- #if defined(HELTEC_CAPSULE_SENSOR_V3) || defined(HELTEC_SENSOR_HUB)
650- pinMode (EXT_PWR_DETECT, INPUT_PULLUP);
651- #else
652- pinMode (EXT_PWR_DETECT, INPUT);
653- #endif
650+ pinMode (EXT_PWR_DETECT, EXT_PWR_DETECT_MODE);
654651#endif
655652#ifdef EXT_CHRG_DETECT
656- pinMode (EXT_CHRG_DETECT, ext_chrg_detect_mode );
653+ pinMode (EXT_CHRG_DETECT, EXT_CHRG_DETECT_MODE );
657654#endif
658655
659656#ifdef BATTERY_PIN
@@ -746,37 +743,17 @@ bool Power::setup()
746743 found = true ;
747744#endif
748745 }
749- #ifdef EXT_PWR_DETECT
750- attachInterrupt (
751- EXT_PWR_DETECT,
752- []() {
753- power->setIntervalFromNow (0 );
754- runASAP = true ;
755- },
756- CHANGE);
757- #endif
758- #ifdef BATTERY_CHARGING_INV
759- attachInterrupt (
760- BATTERY_CHARGING_INV,
761- []() {
762- power->setIntervalFromNow (0 );
763- runASAP = true ;
764- },
765- CHANGE);
766- #endif
767- #ifdef EXT_CHRG_DETECT
768- attachInterrupt (
769- EXT_CHRG_DETECT,
770- []() {
771- power->setIntervalFromNow (0 );
772- runASAP = true ;
773- BaseType_t higherWake = 0 ;
774- },
775- CHANGE);
776- #endif
746+ attachPowerInterrupts ();
777747 enabled = found;
778748 low_voltage_counter = 0 ;
779749
750+ #ifdef ARCH_ESP32
751+ // Register callbacks for before and after lightsleep
752+ // Used to detach and reattach interrupts
753+ lsObserver.observe (¬ifyLightSleep);
754+ lsEndObserver.observe (¬ifyLightSleepEnd);
755+ #endif
756+
780757 return found;
781758}
782759
@@ -1023,6 +1000,17 @@ int32_t Power::runOnce()
10231000 powerFSM.trigger (EVENT_POWER_CONNECTED);
10241001 }
10251002
1003+ #ifdef T_WATCH_S3
1004+ /*
1005+ In the T-Watch S3 this code fragment reacts to the short press of the button by switching the
1006+ display on and off
1007+ */
1008+ if (PMU->isPekeyShortPressIrq ()) {
1009+ LOG_INFO (" Input: Corona Button Click" );
1010+ InputEvent event = {.inputEvent = (input_broker_event)INPUT_BROKER_CANCEL, .kbchar = 0 , .touchX = 0 , .touchY = 0 };
1011+ inputBroker->injectInputEvent (&event);
1012+ }
1013+ #endif
10261014 /*
10271015 Other things we could check if we cared...
10281016
@@ -1055,6 +1043,97 @@ int32_t Power::runOnce()
10551043 return (statusHandler && statusHandler->isInitialized ()) ? (1000 * 20 ) : RUN_SAME;
10561044}
10571045
1046+ #ifdef ARCH_ESP32
1047+
1048+ // Detach our class' interrupts before lightsleep
1049+ // Allows sleep.cpp to configure its own interrupts, which wake the device on user-button press
1050+ int Power::beforeLightSleep (void *unused)
1051+ {
1052+ LOG_WARN (" Detaching power interrupts for sleep" );
1053+ detachPowerInterrupts ();
1054+ return 0 ; // Indicates success
1055+ }
1056+
1057+ // Reconfigure our interrupts
1058+ // Our class' interrupts were disconnected during sleep, to allow the user button to wake the device from sleep
1059+ int Power::afterLightSleep (esp_sleep_wakeup_cause_t cause)
1060+ {
1061+ attachPowerInterrupts ();
1062+ return 0 ; // Indicates success
1063+ }
1064+
1065+ #endif
1066+
1067+ /*
1068+ * Attach (or re-attach) hardware interrupts for power management
1069+ * Public method. Used outside class when waking from MCU sleep
1070+ */
1071+ void Power::attachPowerInterrupts ()
1072+ {
1073+ #ifdef EXT_PWR_DETECT
1074+ attachInterrupt (
1075+ EXT_PWR_DETECT,
1076+ []() {
1077+ power->setIntervalFromNow (0 );
1078+ runASAP = true ;
1079+ },
1080+ CHANGE);
1081+ #endif
1082+ #ifdef BATTERY_CHARGING_INV
1083+ attachInterrupt (
1084+ BATTERY_CHARGING_INV,
1085+ []() {
1086+ power->setIntervalFromNow (0 );
1087+ runASAP = true ;
1088+ },
1089+ CHANGE);
1090+ #endif
1091+ #ifdef EXT_CHRG_DETECT
1092+ attachInterrupt (
1093+ EXT_CHRG_DETECT,
1094+ []() {
1095+ power->setIntervalFromNow (0 );
1096+ runASAP = true ;
1097+ BaseType_t higherWake = 0 ;
1098+ },
1099+ CHANGE);
1100+ #endif
1101+ #ifdef PMU_IRQ
1102+ if (PMU) {
1103+ attachInterrupt (
1104+ PMU_IRQ,
1105+ [] {
1106+ pmu_irq = true ;
1107+ power->setIntervalFromNow (0 );
1108+ runASAP = true ;
1109+ },
1110+ FALLING);
1111+ }
1112+ #endif
1113+ }
1114+
1115+ /*
1116+ * Detach the "normal" button interrupts.
1117+ * Public method. Used before attaching a "wake-on-button" interrupt for MCU sleep
1118+ */
1119+ void Power::detachPowerInterrupts ()
1120+ {
1121+ #ifdef EXT_PWR_DETECT
1122+ detachInterrupt (EXT_PWR_DETECT);
1123+ #endif
1124+ #ifdef BATTERY_CHARGING_INV
1125+ detachInterrupt (BATTERY_CHARGING_INV);
1126+ #endif
1127+ #ifdef EXT_CHRG_DETECT
1128+ detachInterrupt (EXT_CHRG_DETECT);
1129+ #endif
1130+ #ifdef PMU_IRQ
1131+ if (PMU) {
1132+ detachInterrupt (PMU_IRQ);
1133+ }
1134+ #endif
1135+ }
1136+
10581137/* *
10591138 * Init the power manager chip
10601139 *
@@ -1332,8 +1411,6 @@ bool Power::axpChipInit()
13321411 }
13331412
13341413 pinMode (PMU_IRQ, INPUT);
1335- attachInterrupt (
1336- PMU_IRQ, [] { pmu_irq = true ; }, FALLING);
13371414
13381415 // we do not look for AXPXXX_CHARGING_FINISHED_IRQ & AXPXXX_CHARGING_IRQ
13391416 // because it occurs repeatedly while there is no battery also it could cause
@@ -1806,7 +1883,7 @@ class SerialBatteryLevel : public HasBatteryLevel
18061883 {
18071884#if defined(EXT_CHRG_DETECT)
18081885
1809- return digitalRead (EXT_CHRG_DETECT) == ext_chrg_detect_value ;
1886+ return digitalRead (EXT_CHRG_DETECT) == EXT_CHRG_DETECT_VALUE ;
18101887
18111888#endif
18121889 return false ;
@@ -1815,7 +1892,7 @@ class SerialBatteryLevel : public HasBatteryLevel
18151892 virtual bool isCharging () override
18161893 {
18171894#ifdef EXT_CHRG_DETECT
1818- return digitalRead (EXT_CHRG_DETECT) == ext_chrg_detect_value ;
1895+ return digitalRead (EXT_CHRG_DETECT) == EXT_CHRG_DETECT_VALUE ;
18191896
18201897#endif
18211898 // by default, we check the battery voltage only
@@ -1837,10 +1914,10 @@ SerialBatteryLevel serialBatteryLevel;
18371914bool Power::serialBatteryInit ()
18381915{
18391916#ifdef EXT_PWR_DETECT
1840- pinMode (EXT_PWR_DETECT, INPUT );
1917+ pinMode (EXT_PWR_DETECT, EXT_PWR_DETECT_MODE );
18411918#endif
18421919#ifdef EXT_CHRG_DETECT
1843- pinMode (EXT_CHRG_DETECT, ext_chrg_detect_mode );
1920+ pinMode (EXT_CHRG_DETECT, EXT_CHRG_DETECT_MODE );
18441921#endif
18451922
18461923 bool result = serialBatteryLevel.runOnce ();
0 commit comments