Fix touch event stability and WFI wake filtering

This commit is contained in:
Adolfo Reyna
2026-02-18 11:51:29 -05:00
parent b01cd652a0
commit be6a217b08
4 changed files with 70 additions and 56 deletions

View File

@@ -252,6 +252,23 @@ volatile bool button_key0_pressed = false;
volatile bool button_key1_pressed = false;
#endif
/**
* @brief Returns true when an application-level wake source is pending.
*
* __wfi() can wake on unrelated interrupts (e.g. USB/background IRQs). This
* guard prevents running full input/game logic unless one of our expected
* event sources actually fired.
*/
static inline bool has_pending_wake_source() {
if (touch_interrupt_flag) return true;
if (touch_event_down) return true;
if (dim_check_flag) return true;
#ifdef BUTTON_KEY0_PIN
if (button_key0_pressed || button_key1_pressed) return true;
#endif
return false;
}
/**
* @brief Touch interrupt callback handler
*
@@ -265,18 +282,15 @@ volatile bool button_key1_pressed = false;
* @param events Event mask (GPIO_IRQ_EDGE_FALL and/or GPIO_IRQ_EDGE_RISE)
*/
void touch_interrupt_handler(uint gpio, uint32_t events) {
// Set flag to indicate touch event occurred
// Main loop will handle the actual touch reading
touch_interrupt_flag = true;
// Track which edge triggered (down vs up)
if (events & GPIO_IRQ_EDGE_FALL) {
// Track which edge triggered (down vs up).
// Keep ISR minimal: do not log/print from interrupt context.
if (events & GPIO_IRQ_EDGE_FALL) {
touch_event_down = true;
printf("INT: FALL\n");
touch_interrupt_flag = true;
}
if (events & GPIO_IRQ_EDGE_RISE) {
if (events & GPIO_IRQ_EDGE_RISE) {
touch_event_down = false;
printf("INT: RISE\n");
touch_interrupt_flag = true;
}
}
@@ -595,6 +609,8 @@ int main()
bool stay_awake = false;
if (pending_refresh) stay_awake = true;
if (serial_uploader.wants_to_launch_game()) stay_awake = true; // Don't sleep while waiting to launch
if (touch_event_down) stay_awake = true; // Keep sampling while finger is down
if (last_touch_time != 0) stay_awake = true; // Keep sampling during active touch session
if (launcher.is_game_selected()) {
Game* g = launcher.get_selected_game();
@@ -606,6 +622,12 @@ int main()
if (!stay_awake) {
// Sleep until interrupt wakes us up (very power efficient!)
__wfi(); // Wait For Interrupt - CPU sleeps until any interrupt occurs
// Ignore unrelated interrupts (USB/background/timer noise).
// Only continue loop work when one of our wake sources is pending.
if (!has_pending_wake_source()) {
continue;
}
}
InputEvent input = {INPUT_NONE, 0, 0, 0, 0, 0, false};