diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp index 0002a62b4..a6b2aea27 100644 --- a/src/PowerFSM.cpp +++ b/src/PowerFSM.cpp @@ -102,18 +102,21 @@ static void lsIdle() powerFSM.trigger(EVENT_SERIAL_CONNECTED); break; - case ESP_SLEEP_WAKEUP_GPIO: - // GPIO wakeup is now used for all ESP32 devices during light sleep - powerFSM.trigger(EVENT_PRESS); - break; - default: - // We woke for some other reason (device interrupt?) - LOG_INFO("wakeCause2 %d\n", wakeCause2); + // We woke for some other reason (button press, device IRQ interrupt) - // Let the NB state handle the IRQ (and that state will handle stuff like IRQs etc) - // we lie and say "wake timer" because the interrupt will be handled by the regular IRQ code - powerFSM.trigger(EVENT_WAKE_TIMER); +#ifdef BUTTON_PIN + bool pressed = !digitalRead(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN); +#else + bool pressed = false; +#endif + if (pressed) { // If we woke because of press, instead generate a PRESS event. + powerFSM.trigger(EVENT_PRESS); + } else { + // Otherwise let the NB state handle the IRQ (and that state will handle stuff like IRQs etc) + // we lie and say "wake timer" because the interrupt will be handled by the regular IRQ code + powerFSM.trigger(EVENT_WAKE_TIMER); + } break; } } else { diff --git a/src/detect/LoRaRadioType.h b/src/detect/LoRaRadioType.h new file mode 100644 index 000000000..eadd92e64 --- /dev/null +++ b/src/detect/LoRaRadioType.h @@ -0,0 +1,5 @@ +#pragma once + +enum LoRaRadioType { NO_RADIO, STM32WLx_RADIO, SIM_RADIO, RF95_RADIO, SX1262_RADIO, SX1268_RADIO, LLCC68_RADIO, SX1280_RADIO }; + +extern LoRaRadioType radioType; \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 0f2ef7e67..32ac91412 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -69,6 +69,7 @@ NRF52Bluetooth *nrf52Bluetooth; #include "SX1262Interface.h" #include "SX1268Interface.h" #include "SX1280Interface.h" +#include "detect/LoRaRadioType.h" #ifdef ARCH_STM32WL #include "STM32WLE5JCInterface.h" @@ -142,6 +143,9 @@ ATECCX08A atecc; Adafruit_DRV2605 drv; #endif +// Global LoRa radio type +LoRaRadioType radioType = NO_RADIO; + bool isVibrating = false; bool eink_found = true; @@ -793,6 +797,7 @@ void setup() rIf = NULL; } else { LOG_INFO("STM32WL Radio init succeeded, using STM32WL radio\n"); + radioType = STM32WLx_RADIO; } } #endif @@ -806,6 +811,7 @@ void setup() rIf = NULL; } else { LOG_INFO("Using SIMULATED radio!\n"); + radioType = SIM_RADIO; } } #endif @@ -819,6 +825,7 @@ void setup() rIf = NULL; } else { LOG_INFO("RF95 Radio init succeeded, using RF95 radio\n"); + radioType = RF95_RADIO; } } #endif @@ -832,6 +839,7 @@ void setup() rIf = NULL; } else { LOG_INFO("SX1262 Radio init succeeded, using SX1262 radio\n"); + radioType = SX1262_RADIO; } } #endif @@ -845,6 +853,7 @@ void setup() rIf = NULL; } else { LOG_INFO("SX1268 Radio init succeeded, using SX1268 radio\n"); + radioType = SX1268_RADIO; } } #endif @@ -858,6 +867,7 @@ void setup() rIf = NULL; } else { LOG_INFO("LLCC68 Radio init succeeded, using LLCC68 radio\n"); + radioType = LLCC68_RADIO; } } #endif @@ -871,6 +881,7 @@ void setup() rIf = NULL; } else { LOG_INFO("SX1280 Radio init succeeded, using SX1280 radio\n"); + radioType = SX1280_RADIO; } } #endif diff --git a/src/sleep.cpp b/src/sleep.cpp index 7ed264183..fdfaf5e35 100644 --- a/src/sleep.cpp +++ b/src/sleep.cpp @@ -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