diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index bac3899bba..c359e4c124 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -245,6 +245,7 @@ Fsm powerFSM(&stateBOOT); void PowerFSM_setup() { bool isRouter = (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER ? 1 : 0); + bool isInfrastructureRole = isRouter || config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER; bool isTrackerOrSensor = config.device.role == meshtastic_Config_DeviceConfig_Role_TRACKER || config.device.role == meshtastic_Config_DeviceConfig_Role_TAK_TRACKER || config.device.role == meshtastic_Config_DeviceConfig_Role_SENSOR; @@ -357,10 +358,10 @@ void PowerFSM_setup() // Don't add power saving transitions if we are a power saving tracker or sensor. Sleep will be initiatiated through the // modules if ((isRouter || config.power.is_power_saving) && !isTrackerOrSensor) { - powerFSM.add_timed_transition(&stateNB, &stateLS, + powerFSM.add_timed_transition(&stateNB, isInfrastructureRole ? &stateSDS : &stateLS, getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL, "Min wake timeout"); - powerFSM.add_timed_transition(&stateDARK, &stateLS, + powerFSM.add_timed_transition(&stateDARK, isInfrastructureRole ? &stateSDS : &stateLS, getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs), NULL, "Bluetooth timeout"); } diff --git a/src/sleep.cpp b/src/sleep.cpp index 0f71ab25b3..1afba11730 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -186,7 +186,15 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false) // not using wifi yet, but once we are this is needed to shutoff the radio hw // esp_wifi_stop(); waitEnterSleep(skipPreflight); +#ifdef ARCH_ESP32 + if (shouldLoraWake(msecToWake)) { + notifySleep.notifyObservers(NULL); + } else { + notifyDeepSleep.notifyObservers(NULL); + } +#else notifyDeepSleep.notifyObservers(NULL); +#endif screen->doDeepSleep(); // datasheet says this will draw only 10ua @@ -240,6 +248,11 @@ void doDeepSleep(uint32_t msecToWake, bool skipPreflight = false) } #endif +#ifdef ARCH_ESP32 + if (shouldLoraWake(msecToWake)) { + enableLoraInterrupt(); + } +#endif cpuDeepSleep(msecToWake); } @@ -294,12 +307,7 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r gpio_wakeup_enable((gpio_num_t)BUTTON_PIN, GPIO_INTR_LOW_LEVEL); #endif #endif -#if defined(LORA_DIO1) && (LORA_DIO1 != RADIOLIB_NC) - gpio_wakeup_enable((gpio_num_t)LORA_DIO1, GPIO_INTR_HIGH_LEVEL); // SX126x/SX128x interrupt, active high -#endif -#ifdef RF95_IRQ - gpio_wakeup_enable((gpio_num_t)RF95_IRQ, GPIO_INTR_HIGH_LEVEL); // RF95 interrupt, active high -#endif + enableLoraInterrupt(); #ifdef PMU_IRQ // wake due to PMU can happen repeatedly if there is no battery installed or the battery fills if (pmu_found) @@ -359,4 +367,30 @@ void enableModemSleep() int rv = esp_pm_configure(&esp32_config); LOG_DEBUG("Sleep request result %x\n", rv); } + +bool shouldLoraWake(uint32_t msecToWake) +{ + return msecToWake < portMAX_DELAY && (config.device.role == meshtastic_Config_DeviceConfig_Role_ROUTER || + config.device.role == meshtastic_Config_DeviceConfig_Role_REPEATER); +} + +void enableLoraInterrupt() +{ +#if SOC_PM_SUPPORT_EXT_WAKEUP && defined(LORA_DIO1) && (LORA_DIO1 != RADIOLIB_NC) + rtc_gpio_pulldown_en((gpio_num_t)LORA_DIO1); +#if defined(LORA_RESET) && (LORA_RESET != RADIOLIB_NC) + rtc_gpio_pullup_en((gpio_num_t)LORA_RESET); +#endif +#if defined(LORA_CS) && (LORA_CS != RADIOLIB_NC) + rtc_gpio_pullup_en((gpio_num_t)LORA_CS); +#endif + // Setup deep sleep with wakeup by external source + esp_sleep_enable_ext0_wakeup((gpio_num_t)LORA_DIO1, RISING); +#elif defined(LORA_DIO1) && (LORA_DIO1 != RADIOLIB_NC) + gpio_wakeup_enable((gpio_num_t)LORA_DIO1, GPIO_INTR_HIGH_LEVEL); // SX126x/SX128x interrupt, active high +#endif +#ifdef RF95_IRQ + gpio_wakeup_enable((gpio_num_t)RF95_IRQ, GPIO_INTR_HIGH_LEVEL); // RF95 interrupt, active high +#endif +} #endif \ No newline at end of file diff --git a/src/sleep.h b/src/sleep.h index a592ad2c19..8d5b9a94f3 100644 --- a/src/sleep.h +++ b/src/sleep.h @@ -43,4 +43,8 @@ extern Observable notifyDeepSleep; /// Called to tell GPS thread to enter deep sleep independently of LoRa/MCU sleep, prior to full poweroff. Must return 0 extern Observable notifyGPSSleep; -void enableModemSleep(); \ No newline at end of file +void enableModemSleep(); +#ifdef ARCH_ESP32 +void enableLoraInterrupt(); +bool shouldLoraWake(uint32_t msecToWake); +#endif \ No newline at end of file