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

@@ -143,11 +143,6 @@ bool ft6336u_init(const ft6336u_config_t *config) {
printf("[FT6336U] WARNING: Failed to set CTRL mode\n");
}
// Enable polling mode - INT pin stays LOW while touched, goes HIGH when released
printf("[FT6336U] Enabling polling mode...\n");
if (!ft6336u_write_reg(FT6336U_REG_G_MODE, FT6336U_G_MODE_POLLING)) {
printf("[FT6336U] WARNING: Failed to set G_MODE\n");
}
// Configure gesture parameters for better detection
printf("[FT6336U] Configuring gesture detection parameters...\n");

View File

@@ -42,77 +42,73 @@ bool InputManager::has_buttons() const {
InputEvent InputManager::process_touch_input(uint32_t* last_time) {
InputEvent event = {INPUT_NONE, 0, 0, 0, 0, 0, false};
// Check if touch interrupt flag is set
if (!touch_interrupt_flag) {
// Process immediately on IRQ, and continue sampling while a touch is active.
// Some controllers only IRQ on edge transitions, so move events require polling.
if (!touch_interrupt_flag && *last_time == 0) {
return event; // No touch event
}
printf("Processing touch: flag=%d, event_down=%d\n", touch_interrupt_flag, touch_event_down);
// Don't clear the flag yet - we may still be processing continuous touch
// Check if touch is active
if (!touch_event_down) {
// Touch released - reset timing for next touch
touch_interrupt_flag = false;
*last_time = 0; // Reset so next touch is treated as new touch-down
event.type = INPUT_TOUCH_UP;
event.valid = true;
printf("Touch UP\n");
return event;
}
// Touch is down - check debounce timing
uint32_t now = to_ms_since_boot(get_absolute_time());
if (now - *last_time < config->touch_debounce_ms) {
return event; // Too soon, skip
}
// Read touch data
// Always validate via controller state instead of relying on edge flag alone.
// Edge chatter can flip touch_event_down without a real touch transition.
TouchData touch_data;
if (!touch || !touch->read_touch(&touch_data)) {
// Clear flag even if read failed to prevent getting stuck
touch_interrupt_flag = false;
printf("Touch read FAILED\n");
return event; // Read failed
return event;
}
// Clear the interrupt flag after successfully reading touch data
// This allows the next touch interrupt to be detected
touch_interrupt_flag = false;
printf("Touch DOWN at (%d,%d)\n", touch_data.points[0].x, touch_data.points[0].y);
// Populate event structure
uint32_t now = to_ms_since_boot(get_absolute_time());
// No active touch points: require consecutive empty reads before release to
// avoid false TOUCH_UP events from transient controller jitter.
if (touch_data.touch_count == 0) {
if (*last_time != 0) {
no_touch_samples++;
if (no_touch_samples >= 2) {
*last_time = 0;
no_touch_samples = 0;
event.type = INPUT_TOUCH_UP;
event.valid = true;
}
}
return event;
}
no_touch_samples = 0;
// Debounce touch-down/move updates.
if (*last_time != 0 && (now - *last_time) < config->touch_debounce_ms) {
return event;
}
// Populate event from first touch point.
event.x = touch_data.points[0].x;
event.y = touch_data.points[0].y;
event.pressure = touch_data.points[0].pressure;
event.gesture_code = touch_data.gesture;
event.valid = true;
// Determine event type
if (*last_time == 0) {
event.type = INPUT_TOUCH_DOWN;
// Check for virtual buttons
InputType virtual_type;
if (check_virtual_buttons(event.x, event.y, virtual_type)) {
event.type = virtual_type;
event.button_id = (virtual_type == INPUT_BUTTON_0) ? 0 : 1;
printf("Virtual button %d pressed via touch\n", event.button_id);
if (config->debug_verbose) {
printf("Virtual button %d pressed via touch\n", event.button_id);
}
}
} else {
event.type = INPUT_TOUCH_MOVE;
}
// Handle gesture events
if (config->enable_gestures && touch_data.gesture != 0) {
event.type = INPUT_GESTURE;
if (config->debug_verbose) {
printf("Gesture: 0x%02X (%s)\n", event.gesture_code, get_gesture_name(event.gesture_code));
}
}
*last_time = now;
return event;
}

View File

@@ -97,6 +97,7 @@ public:
private:
LowLevelTouch* touch;
const GameConfig* config;
uint8_t no_touch_samples = 0;
// Virtual button regions
int v_button_a[4] = {0, 0, 0, 0}; // [x, y, w, h]