From 2df72a04b350d9af22b6f1be87f185de7ac90dd8 Mon Sep 17 00:00:00 2001 From: Steven Dan Date: Mon, 1 Jun 2026 15:13:14 +0800 Subject: [PATCH] suppress single-key events for all combo keys Unify combo_key_suppress for GAME+MIC, FPS+MIC, VOL+/VOL-, and FPS+GAME factory reset. Arm on combo detect or factory-reset start; poll until all involved keys release so staggered release does not fire short presses. Co-authored-by: Cursor --- .../src/extensions/audiohw.xc | 240 +++++++++++++++--- 1 file changed, 211 insertions(+), 29 deletions(-) diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/audiohw.xc b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/audiohw.xc index 7d612d6..428829d 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/audiohw.xc +++ b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/audiohw.xc @@ -205,6 +205,20 @@ typedef enum { FEATURE_MODE_MIC_LEVEL = 4 } tx1_feature_mode_t; +/* 改动原因:组合键参与键在组合前/后松键时吞掉单键边沿,每位对应一个物理键 */ +#define TX1_KEY_SUPPRESS_FPS 0x01u +#define TX1_KEY_SUPPRESS_GAME 0x02u +#define TX1_KEY_SUPPRESS_MIC 0x04u +#define TX1_KEY_SUPPRESS_VOL_PLUS 0x08u +#define TX1_KEY_SUPPRESS_VOL_MINUS 0x10u + +typedef enum { + COMBO_NONE = 0, + COMBO_GAME_MIC, + COMBO_VOL_UP_DOWN, + COMBO_FPS_MIC +} tx1_combo_t; + timer tm; #define SE_DELAY (2000000000) //20s delay #define MUTE_ENABLE_DELAY (100000000) //1s delay @@ -983,12 +997,14 @@ static unsigned tx1_vol_plus_step(tx1_feature_mode_t mode, unsigned &feature_vol return 0; } feature_volume++; + debug_printf("tx1_vol_plus_step gunshot_thr=%d\n", gunshot_thr); return tx1_apply_gunshot_bar(feature_volume, cc_mic_level, gunshot_thr); case FEATURE_MODE_FOOTSTEPS_LEVEL: if (feature_volume >= TX1_VOL_BAR_MAX) { return 0; } feature_volume++; + debug_printf("tx1_vol_plus_step footstep_gain=%u\n", footstep_gain); return tx1_apply_footstep_bar(feature_volume, cc_mic_level, footstep_gain); case FEATURE_MODE_MIC_LEVEL: if (feature_volume < TX1_VOL_BAR_MAX) { @@ -1028,12 +1044,14 @@ static unsigned tx1_vol_minus_step(tx1_feature_mode_t mode, unsigned &feature_vo return 0; } feature_volume--; + debug_printf("tx1_vol_minus_step gunshot_thr=%d\n", gunshot_thr); return tx1_apply_gunshot_bar(feature_volume, cc_mic_level, gunshot_thr); case FEATURE_MODE_FOOTSTEPS_LEVEL: if (feature_volume == 0) { return 0; } feature_volume--; + debug_printf("tx1_vol_minus_step footstep_gain=%u\n", footstep_gain); return tx1_apply_footstep_bar(feature_volume, cc_mic_level, footstep_gain); case FEATURE_MODE_MIC_LEVEL: if (feature_volume > 0) { @@ -1073,6 +1091,158 @@ static void tx1_feature_mode_fps_short_press(tx1_feature_mode_t &feature_mode, } } +/** + * 改动原因:组合键按下/释放时参与键往往不同时动作;置位 mask 并同步 prev,避免松键误触发单键。 + */ +static void tx1_combo_suppress_arm_mask(unsigned mask, + unsigned &combo_key_suppress, + unsigned fps, unsigned &prev_fps, unsigned &fps_long_fired, + unsigned game, unsigned &prev_game, unsigned &game_long_fired, + unsigned mic, unsigned &prev_mic, unsigned &mic_long_fired, + unsigned vol_plus, unsigned &prev_vol_plus, + unsigned &vol_plus_long_fired, + unsigned vol_minus, unsigned &prev_vol_minus, + unsigned &vol_minus_long_fired) +{ + combo_key_suppress |= mask; + if (mask & TX1_KEY_SUPPRESS_FPS) { + prev_fps = fps; + fps_long_fired = 1; + } + if (mask & TX1_KEY_SUPPRESS_GAME) { + prev_game = game; + game_long_fired = 1; + } + if (mask & TX1_KEY_SUPPRESS_MIC) { + prev_mic = mic; + mic_long_fired = 1; + } + if (mask & TX1_KEY_SUPPRESS_VOL_PLUS) { + prev_vol_plus = vol_plus; + vol_plus_long_fired = 1; + } + if (mask & TX1_KEY_SUPPRESS_VOL_MINUS) { + prev_vol_minus = vol_minus; + vol_minus_long_fired = 1; + } +} + +static void tx1_combo_suppress_arm_for_combo(tx1_combo_t combo, + unsigned &combo_key_suppress, + unsigned fps, unsigned &prev_fps, unsigned &fps_long_fired, + unsigned game, unsigned &prev_game, unsigned &game_long_fired, + unsigned mic, unsigned &prev_mic, unsigned &mic_long_fired, + unsigned vol_plus, unsigned &prev_vol_plus, + unsigned &vol_plus_long_fired, + unsigned vol_minus, unsigned &prev_vol_minus, + unsigned &vol_minus_long_fired) +{ + switch (combo) { + case COMBO_GAME_MIC: + tx1_combo_suppress_arm_mask(TX1_KEY_SUPPRESS_GAME | TX1_KEY_SUPPRESS_MIC, + combo_key_suppress, + fps, prev_fps, fps_long_fired, + game, prev_game, game_long_fired, + mic, prev_mic, mic_long_fired, + vol_plus, prev_vol_plus, vol_plus_long_fired, + vol_minus, prev_vol_minus, vol_minus_long_fired); + break; + case COMBO_FPS_MIC: + tx1_combo_suppress_arm_mask(TX1_KEY_SUPPRESS_FPS | TX1_KEY_SUPPRESS_MIC, + combo_key_suppress, + fps, prev_fps, fps_long_fired, + game, prev_game, game_long_fired, + mic, prev_mic, mic_long_fired, + vol_plus, prev_vol_plus, vol_plus_long_fired, + vol_minus, prev_vol_minus, vol_minus_long_fired); + break; + case COMBO_VOL_UP_DOWN: + tx1_combo_suppress_arm_mask(TX1_KEY_SUPPRESS_VOL_PLUS | TX1_KEY_SUPPRESS_VOL_MINUS, + combo_key_suppress, + fps, prev_fps, fps_long_fired, + game, prev_game, game_long_fired, + mic, prev_mic, mic_long_fired, + vol_plus, prev_vol_plus, vol_plus_long_fired, + vol_minus, prev_vol_minus, vol_minus_long_fired); + break; + default: + break; + } +} + +/** + * 改动原因:组合键释放后持续同步 prev,直至参与键全部弹起再清除抑制。 + */ +static void tx1_combo_suppress_poll(unsigned &combo_key_suppress, + unsigned fps, unsigned &prev_fps, unsigned &fps_long_fired, + unsigned game, unsigned &prev_game, unsigned &game_long_fired, + unsigned mic, unsigned &prev_mic, unsigned &mic_long_fired, + unsigned vol_plus, unsigned &prev_vol_plus, + unsigned &vol_plus_long_fired, + unsigned vol_minus, unsigned &prev_vol_minus, + unsigned &vol_minus_long_fired) +{ + unsigned was; + unsigned ready = 1; + + if (combo_key_suppress == 0) { + return; + } + + if (combo_key_suppress & TX1_KEY_SUPPRESS_FPS) { + prev_fps = fps; + if (fps == 0) { + ready = 0; + } + } + if (combo_key_suppress & TX1_KEY_SUPPRESS_GAME) { + prev_game = game; + if (game == 0) { + ready = 0; + } + } + if (combo_key_suppress & TX1_KEY_SUPPRESS_MIC) { + prev_mic = mic; + if (mic == 0) { + ready = 0; + } + } + if (combo_key_suppress & TX1_KEY_SUPPRESS_VOL_PLUS) { + prev_vol_plus = vol_plus; + if (vol_plus == 0) { + ready = 0; + } + } + if (combo_key_suppress & TX1_KEY_SUPPRESS_VOL_MINUS) { + prev_vol_minus = vol_minus; + if (vol_minus == 0) { + ready = 0; + } + } + + if (!ready) { + return; + } + + was = combo_key_suppress; + combo_key_suppress = 0; + if (was & TX1_KEY_SUPPRESS_FPS) { + fps_long_fired = 0; + } + if (was & TX1_KEY_SUPPRESS_GAME) { + game_long_fired = 0; + } + if (was & TX1_KEY_SUPPRESS_MIC) { + mic_long_fired = 0; + } + if (was & TX1_KEY_SUPPRESS_VOL_PLUS) { + vol_plus_long_fired = 0; + } + if (was & TX1_KEY_SUPPRESS_VOL_MINUS) { + vol_minus_long_fired = 0; + } +} + static void tx1_apply_mic_mute_hw(unsigned mic_muted, unsigned &old_adc_vol, client interface i2c_master_if i2c) { @@ -1215,14 +1385,12 @@ void AudioHwRemote2(streaming chanend c, chanend cc_mic_level, client interface unsigned vol_plus_long_fired = 0, vol_minus_long_fired = 0; // TX1 combo key state - /* 改动原因:增加 FPS+MIC 组合键切换 EX3D 算法开关 */ - typedef enum { COMBO_NONE = 0, COMBO_GAME_MIC, COMBO_VOL_UP_DOWN, COMBO_FPS_MIC } tx1_combo_t; tx1_combo_t current_combo = COMBO_NONE; unsigned combo_triggered = 0; unsigned combo_release_time = 0; unsigned combo_just_released = 0; - /* 改动原因:FPS+MIC 组合键触发后,两键往往不同时松开;须吞掉松键边沿,避免误触发 feature/MIC 短按 */ - unsigned fps_mic_combo_suppress = 0; + /* 改动原因:所有组合键参与键在组合前/后松键时抑制单键事件(见 tx1_combo_suppress_*) */ + unsigned combo_key_suppress = 0; // TX1 factory reset state unsigned factory_reset_counting = 0; @@ -1964,6 +2132,16 @@ void AudioHwRemote2(streaming chanend c, chanend cc_mic_level, client interface combo_release_time = now; combo_just_released = 1; } + if (new_combo != COMBO_NONE) { + tx1_combo_suppress_arm_for_combo(new_combo, combo_key_suppress, + fps, prev_fps, fps_long_fired, + game, prev_game, game_long_fired, + mic, prev_mic, mic_long_fired, + vol_plus, prev_vol_plus, + vol_plus_long_fired, + vol_minus, prev_vol_minus, + vol_minus_long_fired); + } current_combo = new_combo; combo_triggered = 0; } @@ -1991,11 +2169,6 @@ void AudioHwRemote2(streaming chanend c, chanend cc_mic_level, client interface ex3d_enable = !ex3d_enable; tx1_send_ex3d_onoff_to_tile1(cc_mic_level, ex3d_enable); gpio_leds_dirty = 1; - fps_mic_combo_suppress = 1; - prev_fps = fps; - prev_mic = mic; - fps_long_fired = 1; - mic_long_fired = 1; debug_printf("TX1: FPS+MIC combo - ex3d_enable=%d\n", ex3d_enable); } } @@ -2015,6 +2188,15 @@ void AudioHwRemote2(streaming chanend c, chanend cc_mic_level, client interface factory_reset_6s_fired = 0; factory_reset_10s_fired = 0; factory_reset_done = 0; + tx1_combo_suppress_arm_mask(TX1_KEY_SUPPRESS_FPS | TX1_KEY_SUPPRESS_GAME, + combo_key_suppress, + fps, prev_fps, fps_long_fired, + game, prev_game, game_long_fired, + mic, prev_mic, mic_long_fired, + vol_plus, prev_vol_plus, + vol_plus_long_fired, + vol_minus, prev_vol_minus, + vol_minus_long_fired); tx1_factory_reset_countdown_start(); debug_printf("TX1: Factory reset countdown started\n"); } else if (!factory_reset_done) { @@ -2048,19 +2230,15 @@ void AudioHwRemote2(streaming chanend c, chanend cc_mic_level, client interface // Individual button processing (only when no combo active and outside silence window) if (current_combo == COMBO_NONE && !combo_just_released) { - /* 改动原因:FPS+MIC 组合松键阶段只同步 prev,不进入 FPS/MIC 单键逻辑 */ - if (fps_mic_combo_suppress) { - if (fps == 1 && mic == 1) { - fps_mic_combo_suppress = 0; - fps_long_fired = 0; - mic_long_fired = 0; - } - prev_fps = fps; - prev_mic = mic; - } + tx1_combo_suppress_poll(combo_key_suppress, + fps, prev_fps, fps_long_fired, + game, prev_game, game_long_fired, + mic, prev_mic, mic_long_fired, + vol_plus, prev_vol_plus, vol_plus_long_fired, + vol_minus, prev_vol_minus, vol_minus_long_fired); // FPS button - cycle feature modes - if (!fps_mic_combo_suppress && fps != prev_fps) { + if (!(combo_key_suppress & TX1_KEY_SUPPRESS_FPS) && fps != prev_fps) { if (fps == 0) { // Pressed fps_press_time = now; fps_long_fired = 0; @@ -2080,7 +2258,7 @@ void AudioHwRemote2(streaming chanend c, chanend cc_mic_level, client interface } // GAME button - cycle game modes - if (game != prev_game) { + if (!(combo_key_suppress & TX1_KEY_SUPPRESS_GAME) && game != prev_game) { if (game == 0) { game_press_time = now; game_long_fired = 0; @@ -2097,7 +2275,7 @@ void AudioHwRemote2(streaming chanend c, chanend cc_mic_level, client interface } // MIC button - toggle mute - if (!fps_mic_combo_suppress && mic != prev_mic) { + if (!(combo_key_suppress & TX1_KEY_SUPPRESS_MIC) && mic != prev_mic) { if (mic == 0) { mic_press_time = now; mic_long_fired = 0; @@ -2116,7 +2294,7 @@ void AudioHwRemote2(streaming chanend c, chanend cc_mic_level, client interface } // MIC long press - toggle DNR - if (!fps_mic_combo_suppress && mic == 0 && !mic_long_fired + if (!(combo_key_suppress & TX1_KEY_SUPPRESS_MIC) && mic == 0 && !mic_long_fired && (now - mic_press_time) >= 1000000000ull) { mic_long_fired = 1; dnr_enabled = !dnr_enabled; @@ -2125,7 +2303,7 @@ void AudioHwRemote2(streaming chanend c, chanend cc_mic_level, client interface } /* 改动原因:VOL+ 对齐 jok buttons.xc——松开且<1s为短按;≥1s后每100ms连发(同 on_vol_plus_long_press) */ - if (vol_plus != prev_vol_plus) { + if (!(combo_key_suppress & TX1_KEY_SUPPRESS_VOL_PLUS) && vol_plus != prev_vol_plus) { if (vol_plus == 0) { vol_plus_press_time = now; vol_plus_long_fired = 0; @@ -2144,11 +2322,13 @@ void AudioHwRemote2(streaming chanend c, chanend cc_mic_level, client interface } } prev_vol_plus = vol_plus; - } else if (vol_plus == 0 && !vol_plus_long_fired + } else if (!(combo_key_suppress & TX1_KEY_SUPPRESS_VOL_PLUS) + && vol_plus == 0 && !vol_plus_long_fired && (now - vol_plus_press_time) >= TX1_LONG_PRESS_TICKS) { vol_plus_long_fired = 1; } - if (vol_plus == 0 && vol_plus_long_fired) { + if (!(combo_key_suppress & TX1_KEY_SUPPRESS_VOL_PLUS) + && vol_plus == 0 && vol_plus_long_fired) { static unsigned last_vol_plus_trigger = 0; if ((now - last_vol_plus_trigger) >= TX1_VOL_REPEAT_TICKS) { last_vol_plus_trigger = now; @@ -2163,7 +2343,7 @@ void AudioHwRemote2(streaming chanend c, chanend cc_mic_level, client interface } /* 改动原因:VOL- 对齐 jok,结构同 VOL+ */ - if (vol_minus != prev_vol_minus) { + if (!(combo_key_suppress & TX1_KEY_SUPPRESS_VOL_MINUS) && vol_minus != prev_vol_minus) { if (vol_minus == 0) { vol_minus_press_time = now; vol_minus_long_fired = 0; @@ -2182,11 +2362,13 @@ void AudioHwRemote2(streaming chanend c, chanend cc_mic_level, client interface } } prev_vol_minus = vol_minus; - } else if (vol_minus == 0 && !vol_minus_long_fired + } else if (!(combo_key_suppress & TX1_KEY_SUPPRESS_VOL_MINUS) + && vol_minus == 0 && !vol_minus_long_fired && (now - vol_minus_press_time) >= TX1_LONG_PRESS_TICKS) { vol_minus_long_fired = 1; } - if (vol_minus == 0 && vol_minus_long_fired) { + if (!(combo_key_suppress & TX1_KEY_SUPPRESS_VOL_MINUS) + && vol_minus == 0 && vol_minus_long_fired) { static unsigned last_vol_minus_trigger = 0; if ((now - last_vol_minus_trigger) >= TX1_VOL_REPEAT_TICKS) { last_vol_minus_trigger = now;