diff --git a/src/PowerFSM.cpp b/src/PowerFSM.cpp
index b6e267e28..0002a62b4 100644
--- a/src/PowerFSM.cpp
+++ b/src/PowerFSM.cpp
@@ -102,23 +102,18 @@ 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 (button press, device interrupt)
-                // uint64_t status = esp_sleep_get_ext1_wakeup_status();
+                // We woke for some other reason (device interrupt?)
                 LOG_INFO("wakeCause2 %d\n", wakeCause2);
 
-#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);
-                }
+                // 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 {
@@ -348,9 +343,6 @@ void PowerFSM_setup()
     powerFSM.add_timed_transition(&statePOWER, &stateDARK,
                                   Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
                                   "Screen-on timeout");
-    powerFSM.add_timed_transition(&stateDARK, &stateDARK,
-                                  Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
-                                  "Screen-on timeout");
 
 // We never enter light-sleep or NB states on NRF52 (because the CPU uses so little power normally)
 #ifdef ARCH_ESP32
@@ -361,11 +353,24 @@ void PowerFSM_setup()
         powerFSM.add_timed_transition(&stateNB, &stateLS,
                                       Default::getConfiguredOrDefaultMs(config.power.min_wake_secs, default_min_wake_secs), NULL,
                                       "Min wake timeout");
+
+        // If ESP32 and using power-saving, timer mover from DARK to light-sleep
+        // Also serves purpose of the old DARK to DARK transition(?) See https://github.com/meshtastic/firmware/issues/3517
         powerFSM.add_timed_transition(
             &stateDARK, &stateLS,
             Default::getConfiguredOrDefaultMs(config.power.wait_bluetooth_secs, default_wait_bluetooth_secs), NULL,
             "Bluetooth timeout");
+    } else {
+        // If ESP32, but not using power-saving, check periodically if config has drifted out of stateDark
+        powerFSM.add_timed_transition(&stateDARK, &stateDARK,
+                                      Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs),
+                                      NULL, "Screen-on timeout");
     }
+#else
+    // If not ESP32, light-sleep not used. Check periodically if config has drifted out of stateDark
+    powerFSM.add_timed_transition(&stateDARK, &stateDARK,
+                                  Default::getConfiguredOrDefaultMs(config.display.screen_on_secs, default_screen_on_secs), NULL,
+                                  "Screen-on timeout");
 #endif
 
     powerFSM.run_machine(); // run one iteration of the state machine, so we run our on enter tasks for the initial DARK state
diff --git a/src/sleep.cpp b/src/sleep.cpp
index 2f4bd09e1..e91bda782 100644
--- a/src/sleep.cpp
+++ b/src/sleep.cpp
@@ -312,13 +312,11 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
     // assert(esp_sleep_enable_uart_wakeup(0) == ESP_OK);
 #endif
 #ifdef BUTTON_PIN
-#if SOC_PM_SUPPORT_EXT_WAKEUP
-    esp_sleep_enable_ext0_wakeup((gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN),
-                                 LOW); // when user presses, this button goes low
-#else
+    // The enableLoraInterrupt() method is using ext0_wakeup, so we are forced to use GPIO wakeup
+    gpio_num_t pin = (gpio_num_t)(config.device.button_gpio ? config.device.button_gpio : BUTTON_PIN);
+    gpio_intr_disable(pin);
+    gpio_wakeup_enable(pin, GPIO_INTR_LOW_LEVEL);
     esp_sleep_enable_gpio_wakeup();
-    gpio_wakeup_enable((gpio_num_t)BUTTON_PIN, GPIO_INTR_LOW_LEVEL);
-#endif
 #endif
     enableLoraInterrupt();
 #ifdef PMU_IRQ
@@ -342,6 +340,12 @@ esp_sleep_wakeup_cause_t doLightSleep(uint64_t sleepMsec) // FIXME, use a more r
     }
     assert(res == ESP_OK);
 
+#ifdef BUTTON_PIN
+    gpio_wakeup_disable(pin);
+    // Would have thought that need gpio_intr_enable() here, but nope..
+    // Works fine without it; crashes with it.
+#endif
+
     esp_sleep_wakeup_cause_t cause = esp_sleep_get_wakeup_cause();
 #ifdef BUTTON_PIN
     if (cause == ESP_SLEEP_WAKEUP_GPIO) {
@@ -406,4 +410,4 @@ void enableLoraInterrupt()
     gpio_wakeup_enable((gpio_num_t)RF95_IRQ, GPIO_INTR_HIGH_LEVEL); // RF95 interrupt, active high
 #endif
 }
-#endif
\ No newline at end of file
+#endif