support factory restore key

This commit is contained in:
Steven Dan
2026-03-27 23:26:03 +08:00
parent 9696395dcf
commit 8b56f5cd2d
2 changed files with 221 additions and 114 deletions

View File

@@ -16,6 +16,7 @@
#include "debug_print.h"
#include "roleswitchflag.h"
#include "xua_hid_report.h"
#include "lfs_io.h"
#if defined (CODEC_AIC3204)
#include "eq_flash_storage.h"
@@ -266,6 +267,9 @@ in port p_button_ai71_onoff = PORT_BUTTON_AI71_ONOFF; // 1M
#define KEY_POLLING_INTERVAL 10000000L // 100ms polling interval
#define TIMER_PERIOD (100000)
#define FACTORY_RESET_HOLD_TICKS 3000 // 3000 × 1ms = 3秒
#define FACTORY_RESET_BLINK_TICKS 400 // 每相400ms
#define BTN_COMBO_DELAY_TICKS 40 // 单键去抖/组合检测窗口50ms
unsigned g_windows_detect_done = 0;
@@ -388,6 +392,16 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
unsigned push_button_mic_mute_state_old = 1; // Active low
unsigned push_button_hp_mute_state_old = 1; // Active low
// 出厂恢复长按状态机:音乐+游戏同时长按3秒
unsigned factory_reset_hold_count = 0; // 两键同时按住计数×1ms
unsigned factory_reset_blink_state = 0; // 0=空闲1-6=闪烁相位
unsigned factory_reset_blink_tick = 0; // 当前相位内计数
// 组合键去抖:单键动作延迟 BTN_COMBO_DELAY_TICKS 后触发,期间若另一键也按下则切换为组合模式
unsigned btn_music_hold_ticks = 0; // music键连续按住计数
unsigned btn_game_hold_ticks = 0; // game键连续按住计数
unsigned btn_combo_active = 0; // 1=处于组合键模式(单键动作已抑制)
unsigned fr_inhibit = 0; // 1=出厂恢复重启后抑制状态,必须松键后才允许重新触发
int current_mic_led_pos = 0;
htr3236_t htr3236_dev;
@@ -427,22 +441,6 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
#if defined(UAC1_MODE)
delay_milliseconds(300);
GET_SHARED_GLOBAL(host_os, g_host_os);
if (saved_mode == 255) {
#if defined(F5_MUSIC_UAC1)
saved_mode = 1; // f5: default music mode
#else
saved_mode = 0; // f6/f7: default off
#endif
save_value(path, saved_mode);
debug_printf("Saved game_mode to flash: %d\n", saved_mode);
}
#else
if (saved_mode == 255) {
// 出厂默认AI7.1开启(mode=3)
saved_mode = 3;
save_value(path, saved_mode);
debug_printf("Saved game_mode to flash: %d\n", saved_mode);
}
#endif
printf("host_os: %d\n", host_os);
@@ -467,6 +465,25 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
g_windows_detect_done = 1;
#if defined(UAC1_MODE)
if (saved_mode == 255) {
#if defined(F5_MUSIC_UAC1)
saved_mode = 1; // f5: default music mode
#else
saved_mode = 0; // f6/f7: default off
#endif
save_value(path, saved_mode);
debug_printf("Saved game_mode to flash: %d\n", saved_mode);
}
#else
if (saved_mode == 255) {
// 出厂默认AI7.1开启(mode=3)
saved_mode = 3;
save_value(path, saved_mode);
debug_printf("Saved game_mode to flash: %d\n", saved_mode);
}
#endif
active_mode = (saved_mode <= 3) ? saved_mode : 0;
{
@@ -642,13 +659,22 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
last_ctrl_keys ^= KEY_MUTE;
// 启动时若两键同时按住,设置抑制标志,必须松开后才允许触发出厂恢复
{
unsigned music_init, game_init;
p_button_music_mode :> music_init;
p_button_game_mode :> game_init;
if (music_init == 0 && game_init == 0) {
fr_inhibit = 1;
btn_combo_active = 1;
debug_printf("Boot: both keys held, FR inhibited until release\n");
}
}
//hwtimer_set_trigger_time(timer, hwtimer_get_time(timer) + KEY_POLLING_INTERVAL);
tmr :> time; /* Input the time */
time += TIMER_PERIOD; /* Increment the time */
while (1) {
select
{
@@ -896,21 +922,108 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
unsigned mode_btn_change = 0;
unsigned need_reboot = 0;
if (button_music_mode == 0) {
if (push_button_music_mode_state_old == 1) {
// --- Music + Game 按键:组合检测 + 去抖 ---
// 两键同时按住3秒 → 出厂恢复;单键需持续 BTN_COMBO_DELAY_TICKS 后生效
// 50ms 窗口内若另一键也按下则进入组合模式,单键动作取消)
{
int music_is_down = (button_music_mode == 0);
int game_is_down = (button_game_mode == 0);
int factory_combo_is_down = ( music_is_down && game_is_down);
// 更新各键连续按住计数(断开则清零,用于去抖和窗口判断)
if (music_is_down && !factory_combo_is_down)
{
if (btn_music_hold_ticks < 0xFFFFu) btn_music_hold_ticks++;
debug_printf("btn_music_hold_ticks=%d\n", btn_music_hold_ticks);
}
else
{
btn_music_hold_ticks = 0;
}
if (game_is_down && !factory_combo_is_down)
{
if (btn_game_hold_ticks < 0xFFFFu)
{
btn_game_hold_ticks++;
}
debug_printf("btn_game_hold_ticks=%d\n", btn_game_hold_ticks);
}
else
{
btn_game_hold_ticks = 0;
}
// 场景1两键同时按住参照 fosi_ds1 else-if 结构)
if (factory_combo_is_down) {
btn_combo_active = 1; // 粘性锁定
// fr_inhibit=1 时(出厂恢复重启后):不计时,必须松键后重新按下才触发
if (factory_reset_blink_state == 0 && !fr_inhibit) {
factory_reset_hold_count++;
if (factory_reset_hold_count >= FACTORY_RESET_HOLD_TICKS) {
factory_reset_hold_count = 0;
factory_reset_blink_state = 1;
factory_reset_blink_tick = 0;
// 清除所有Flash设置并重启
debug_printf("Factory reset: clearing flash "
"and rebooting\n");
unsafe {
lfs_remove_file("game_mode");
lfs_remove_file("mic_vol");
lfs_remove_file("dac_vol");
lfs_remove_file("footstep");
}
led_on(&led_ctx, LED_MUSIC);
led_on(&led_ctx, LED_ANC);
led_on(&led_ctx, LED_FOOTSTEP_MODE);
led_on(&led_ctx, LED_AI7_1);
led_on(&led_ctx, LED_GAME_MODE);
led_update_all(&led_ctx);
debug_printf("Factory reset: 3s hold detected, starting blink\n");
}
}
}
// 场景2仅 Music 按住
else if (music_is_down) {
factory_reset_hold_count = 0;
if (!btn_combo_active) {
if (btn_music_hold_ticks == BTN_COMBO_DELAY_TICKS) {
debug_printf("========= Music button pressed for %d ticks\n", BTN_COMBO_DELAY_TICKS);
#if (F3_F4_FPS_UAC2 == 1)
// FPS firmware: switching to music needs different USB config
active_mode = 1;
need_reboot = 1;
SetRoleSwitchFlag(MODE_F1_MUSIC_UAC2);
active_mode = 1;
need_reboot = 1;
SetRoleSwitchFlag(MODE_F1_MUSIC_UAC2);
#else
// Music-only firmware: toggle music LED locally
active_mode = (active_mode == 1) ? 0 : 1;
mode_btn_change = 1;
active_mode = (active_mode == 1) ? 0 : 1;
mode_btn_change = 1;
#endif
}
}
}
// 场景3仅 Game 按住
else if (game_is_down) {
factory_reset_hold_count = 0;
if (!btn_combo_active) {
if (btn_game_hold_ticks == BTN_COMBO_DELAY_TICKS) {
debug_printf("========= Game button pressed for %d ticks\n", BTN_COMBO_DELAY_TICKS);
#if F1_MUSIC_UAC2 == 1
active_mode = 2;
need_reboot = 1;
SetRoleSwitchFlag(MODE_F3_F4_FPS_UAC2);
#else
active_mode = (active_mode == 2) ? 0 : 2;
mode_btn_change = 1;
#endif
}
}
}
// 场景4两键全松开 → 解除组合锁定及抑制标志
else {
factory_reset_hold_count = 0;
btn_combo_active = 0;
fr_inhibit = 0; // 松键后允许下次同时按下重新触发出厂恢复
}
}
push_button_music_mode_state_old = button_music_mode;
if (button_ai71_onoff == 0) {
if (push_button_ai71_onoff_state_old == 1) {
@@ -929,22 +1042,6 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
}
push_button_ai71_onoff_state_old = button_ai71_onoff;
if (button_game_mode == 0) {
if (push_button_game_mode_state_old == 1) {
#if F1_MUSIC_UAC2 == 1
// Music-only firmware: game needs FPS firmware
active_mode = 2;
need_reboot = 1;
SetRoleSwitchFlag(MODE_F3_F4_FPS_UAC2);
#else
// FPS firmware: switch algorithm locally (toggle off or activate)
active_mode = (active_mode == 2) ? 0 : 2;
mode_btn_change = 1;
#endif
}
}
push_button_game_mode_state_old = button_game_mode;
// 处理HID SET_SOUND_EFFECT_MODE (0xA4) 请求,等同于按键效果
if (!mode_btn_change && !need_reboot) {
unsigned hid_req_mode;
@@ -987,7 +1084,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
if (need_reboot) {
// Reboot: F5 will re-detect OS and route to correct firmware
debug_printf("Mode %d requires firmware switch, rebooting\n", active_mode);
delay_milliseconds(20);
delay_milliseconds(200);
device_reboot();
while (1);
}
@@ -1016,6 +1113,69 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
#endif
}
// 出厂恢复闪烁状态机5个按键LED闪3次后清除Flash并重启
if (factory_reset_blink_state > 0) {
factory_reset_blink_tick++;
if (factory_reset_blink_tick >= FACTORY_RESET_BLINK_TICKS) {
factory_reset_blink_tick = 0;
factory_reset_blink_state++;
if (factory_reset_blink_state > 6) {
#if 1
// 3次闪烁完成恢复原始LED显示
factory_reset_blink_state = 0;
led_off(&led_ctx, LED_MUSIC);
led_off(&led_ctx, LED_ANC);
led_off(&led_ctx, LED_FOOTSTEP_MODE);
led_off(&led_ctx, LED_AI7_1);
led_off(&led_ctx, LED_GAME_MODE);
switch (active_mode) {
case 1: led_on(&led_ctx, LED_MUSIC); break;
case 2: led_on(&led_ctx, LED_GAME_MODE); break;
case 3: led_on(&led_ctx, LED_AI7_1); break;
default: break;
}
if (flag_footsteps_enhancement == 1) led_on(&led_ctx, LED_FOOTSTEP_MODE);
else if (flag_footsteps_enhancement == 2) led_set_brightness(&led_ctx, LED_FOOTSTEP_MODE, 128);
if (flag_aidenoise_onoff) led_on(&led_ctx, LED_ANC);
led_update_all(&led_ctx);
// 等待松键,防止重启后再次触发出厂恢复循环
{
unsigned mw, gw;
do {
delay_milliseconds(10);
p_button_music_mode :> mw;
p_button_game_mode :> gw;
} while (mw == 0 || gw == 0);
delay_milliseconds(100);
}
#endif
// 出厂恢复默认AI7.1模式mode=3需要F3/F4固件
SetRoleSwitchFlag(MODE_F3_F4_FPS_UAC2);
delay_milliseconds(20);
device_reboot();
while (1);
} else if (factory_reset_blink_state % 2 == 0) {
// 偶数相:全灭
led_off(&led_ctx, LED_MUSIC);
led_off(&led_ctx, LED_ANC);
led_off(&led_ctx, LED_FOOTSTEP_MODE);
led_off(&led_ctx, LED_AI7_1);
led_off(&led_ctx, LED_GAME_MODE);
led_update_all(&led_ctx);
delay_milliseconds(200);
} else {
// 奇数相:全亮
led_on(&led_ctx, LED_MUSIC);
led_on(&led_ctx, LED_ANC);
led_on(&led_ctx, LED_FOOTSTEP_MODE);
led_on(&led_ctx, LED_AI7_1);
led_on(&led_ctx, LED_GAME_MODE);
led_update_all(&led_ctx);
delay_milliseconds(200);
}
}
}
#if USE_EX3D == 1
mode_change = 0;
if(button_footsteps_enhancement == 0)
@@ -1429,74 +1589,6 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
led_update_all(&led_ctx);
#endif
#if 0
curr_ctrl_keys = (port_in(p_ctrl_keys)) & KEY_BITS;
if (curr_ctrl_keys != last_ctrl_keys) {
debounce_cnt++;
if (debounce_cnt >= 2) {
debounce_cnt = 0;
keys_changed = curr_ctrl_keys ^ last_ctrl_keys;
tmp = 0;
switch (keys_changed) {
case KEY_MIC_VOL_DN:
case KEY_MIC_VOL_UP:
if ((isMute == 0) && ((curr_ctrl_keys & KEY_MIC_VOL_DN) == 0)) {
tmp = KEY_MIC_VOL_DN;
debug_printf("KEY_MIC_VOL_DN pressed\n");
} else {
if ((isMute == 0) && ((curr_ctrl_keys & KEY_MIC_VOL_UP) == 0)) {
tmp = KEY_MIC_VOL_UP;
debug_printf("KEY_MIC_VOL_UP pressed\n");
}
}
if (tmp) {
g_mic_vol_cmd_pending = (unsigned)tmp;
}
break;
case KEY_MUTE:
if ((curr_ctrl_keys & KEY_MUTE) == 0) {
// mute switch off (unmuted)
isMute = 0;
SET_SHARED_GLOBAL(g_mute_on_off_t0, MUTE_OFF); // 更新tile0静音状态
chan_out_byte(cc_mic_level, (uint8_t) UNMUTED_MIC);
debug_printf("MUTE: unmuted\n");
} else {
// mute switch on (muted)
isMute = 1;
SET_SHARED_GLOBAL(g_mute_on_off_t0, MUTE_ON); // 更新tile0静音状态
chan_out_byte(cc_mic_level, (uint8_t) MUTED_MIC);
debug_printf("MUTE: muted\n");
}
break;
#if (HID_CONTROLS == 1)
case KEY_PLAY_VOL_DN:
if ((curr_ctrl_keys & KEY_PLAY_VOL_DN) == 0) {
debug_printf("KEY_PLAY_VOL_DN pressed\n");
update_button(HID_CONTROL_VOLDN); // 更新HID报告
}
break;
case KEY_PLAY_VOL_UP:
if ((curr_ctrl_keys & KEY_PLAY_VOL_UP) == 0) {
update_button(HID_CONTROL_VOLUP); // 更新HID报告
}
break;
#endif
default:
break;
}
last_ctrl_keys = curr_ctrl_keys; // 更新上次按键状态
}
} else {
debounce_cnt = 0; // 状态未变化,重置防抖计数器
}
#endif
GET_SHARED_GLOBAL(uac_vol, g_uac_vol);
if (uac_vol != last_uac_vol) {
unsigned conv_vol = (0xffffffff - uac_vol + 1) >> 8;

View File

@@ -1,5 +1,18 @@
#ifndef _LFS_IO_H_
#define _LFS_IO_H_
#if __XC__
int lfs_init(void);
void lfs_deinit(void);
void lfs_read_config(unsigned char * unsafe config, unsigned char * unsafe buffer, unsigned size);
void lfs_write_config(unsigned char * unsafe config, unsigned char * unsafe buffer, unsigned size);
// EQ参数专用函数
void lfs_read_eq_config(const char * unsafe file_path, unsigned char * unsafe buffer, unsigned size);
void lfs_write_eq_config(const char * unsafe file_path, unsigned char * unsafe buffer, unsigned size);
int lfs_file_exists(const char * unsafe file_path);
int lfs_remove_file(const char * unsafe file_path);
int lfs_create_directory(const char * unsafe dir_path);
#else
int lfs_init(void);
void lfs_deinit(void);
void lfs_read_config(unsigned char * config, unsigned char * buffer, unsigned size);
@@ -10,4 +23,6 @@ void lfs_write_eq_config(const char * file_path, unsigned char * buffer, unsigne
int lfs_file_exists(const char * file_path);
int lfs_remove_file(const char * file_path);
int lfs_create_directory(const char * dir_path);
#endif
#endif