fix: device sleep (part 1) (#3590)

* fix sleep part 1

* always show wakeup reason in debug log

* fix screen turn on issue

* avoid unnecessary reboot when entering light sleep

* set DIO1 based on radio type

---------

Co-authored-by: Ben Meadors <benmmeadors@gmail.com>
This commit is contained in:
Manuel
2024-04-12 17:01:24 +02:00
committed by GitHub
parent 8fd32f3452
commit 4c9646f7d9
4 changed files with 76 additions and 24 deletions

View File

@@ -8,6 +8,7 @@
#include "MeshRadio.h"
#include "MeshService.h"
#include "NodeDB.h"
#include "detect/LoRaRadioType.h"
#include "error.h"
#include "main.h"
#include "sleep.h"
@@ -153,7 +154,7 @@ void initDeepSleep()
// If waking from sleep, release any and all RTC GPIOs
if (wakeCause != ESP_SLEEP_WAKEUP_UNDEFINED) {
LOG_DEBUG("Disabling any holds on RTC IO pads\n");
for (uint8_t i = 0; i <= 45; i++) {
for (uint8_t i = 0; i <= GPIO_NUM_MAX; i++) {
if (rtc_gpio_is_valid_gpio((gpio_num_t)i))
rtc_gpio_hold_dis((gpio_num_t)i);
}
@@ -360,19 +361,23 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
#endif
auto res = esp_sleep_enable_gpio_wakeup();
if (res != ESP_OK) {
LOG_DEBUG("esp_sleep_enable_gpio_wakeup result %d\n", res);
LOG_ERROR("esp_sleep_enable_gpio_wakeup result %d\n", res);
}
assert(res == ESP_OK);
res = esp_sleep_enable_timer_wakeup(sleepUsec);
if (res != ESP_OK) {
LOG_DEBUG("esp_sleep_enable_timer_wakeup result %d\n", res);
LOG_ERROR("esp_sleep_enable_timer_wakeup result %d\n", res);
}
assert(res == ESP_OK);
console->flush();
res = esp_light_sleep_start();
if (res != ESP_OK) {
LOG_DEBUG("esp_light_sleep_start result %d\n", res);
LOG_ERROR("esp_light_sleep_start result %d\n", res);
}
assert(res == ESP_OK);
// commented out because it's not that crucial;
// if it sporadically happens the node will go into light sleep during the next round
// assert(res == ESP_OK);
#ifdef BUTTON_PIN
// Disable wake-on-button interrupt. Re-attach normal button-interrupts
@@ -380,13 +385,27 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
buttonThread->attachButtonInterrupts();
#endif
#if !defined(SOC_PM_SUPPORT_EXT_WAKEUP) && defined(LORA_DIO1) && (LORA_DIO1 != RADIOLIB_NC)
if (radioType != RF95_RADIO) {
gpio_wakeup_disable((gpio_num_t)LORA_DIO1);
}
#endif
#if defined(RF95_IRQ) && (RF95_IRQ != RADIOLIB_NC)
if (radioType == RF95_RADIO) {
gpio_wakeup_disable((gpio_num_t)RF95_IRQ);
}
#endif
esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
#ifdef BUTTON_PIN
if (cause == ESP_SLEEP_WAKEUP_GPIO) {
LOG_INFO("Exit light sleep gpio: btn=%d\n",
!digitalRead(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN));
}
} else
#endif
{
LOG_INFO("Exit light sleep cause: %d\n", cause);
}
return cause;
}
@@ -428,20 +447,34 @@ bool shouldLoraWake(uint32_t msecToWake)
void enableLoraInterrupt()
{
#if SOC_PM_SUPPORT_EXT_WAKEUP && defined(LORA_DIO1) && (LORA_DIO1 != RADIOLIB_NC)
rtc_gpio_pulldown_en((gpio_num_t)LORA_DIO1);
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);
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);
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);
if (rtc_gpio_is_valid_gpio((gpio_num_t)LORA_DIO1)) {
// Setup light/deep sleep with wakeup by external source
LOG_INFO("setup LORA_DIO1 (GPIO%02d) with wakeup by external source\n", LORA_DIO1);
esp_sleep_enable_ext0_wakeup((gpio_num_t)LORA_DIO1, HIGH);
} else {
LOG_INFO("setup LORA_DIO1 (GPIO%02d) with wakeup by gpio interrupt\n", LORA_DIO1);
gpio_wakeup_enable((gpio_num_t)LORA_DIO1, GPIO_INTR_HIGH_LEVEL);
}
#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
if (radioType != RF95_RADIO) {
LOG_INFO("setup LORA_DIO1 (GPIO%02d) with wakeup by gpio interrupt\n", LORA_DIO1);
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
#if defined(RF95_IRQ) && (RF95_IRQ != RADIOLIB_NC)
if (radioType == RF95_RADIO) {
LOG_INFO("setup RF95_IRQ (GPIO%02d) with wakeup by gpio interrupt\n", RF95_IRQ);
gpio_wakeup_enable((gpio_num_t)RF95_IRQ, GPIO_INTR_HIGH_LEVEL); // RF95 interrupt, active high
}
#endif
}
#endif