fix high_perf toggle noise and USB stall from blocking LFS

Root cause: each GAME+MIC toggle ran two synchronous Flash writes (hi_perf + dac_vol) in the 20ms timer, blocking AudioHwRemote2. Now apply DAC with brief mute only, defer hi_perf Flash, and skip redundant dac_vol save when user level unchanged.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Steven Dan
2026-06-01 16:00:15 +08:00
parent 022a46fb6f
commit 7781eaebe6

View File

@@ -60,6 +60,8 @@ unsigned g_dnr_enable = 1;
unsigned g_3d_enable = 1;
/* 改动原因GAME+MIC 高性能模式0=DAC 在用户等级基础上减 6 格(约 -6dB)1=不减;默认 0 */
unsigned g_high_perf_mode = 0;
/* 改动原因high_perf 不在组合键回调里写 Flash避免 lfs_init/deinit 阻塞导致 USB 卡死 */
unsigned g_high_perf_save_pending = 0;
unsigned g_led_mode = 0;
unsigned g_fps_enable = 0;
uint32_t get_reference_time();
@@ -598,6 +600,34 @@ static void tx1_apply_dac_hid_level(unsigned hid_level)
SET_SHARED_GLOBAL(g_request_volume_set, 1);
}
/**
* 改动原因high_perf 切换时直接写 0x0034不经 g_request_volume_set避免同 tick 再写 Flash。
*/
static void tx1_write_dac_hw_reg(unsigned eff_hid, unsigned reg,
unsigned &old_dac_vol,
client interface i2c_master_if i2c)
{
SET_SHARED_GLOBAL(g_dac_vol, reg);
if (eff_hid == 0) {
unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, i2c); }
} else {
unsafe {
NAU88C22_REGWRITE(0x0034, ((reg & 0xff) << 8) | (reg & 0xff), i2c);
}
}
old_dac_vol = reg;
}
static void tx1_apply_dac_hw_from_user_level(unsigned user_hid, unsigned high_perf,
unsigned &old_dac_vol,
client interface i2c_master_if i2c)
{
unsigned eff_hid = tx1_effective_dac_hid_level(user_hid, high_perf);
unsigned reg = tx1_dac_reg_from_hid_level(eff_hid);
tx1_write_dac_hw_reg(eff_hid, reg, old_dac_vol, i2c);
}
/* 改动原因:统一把 MIC HID 等级写入 g_mic_volume_level/g_adc_vol定时器请求分支 mic_volume 写 ADC 并 Flash */
static void tx1_apply_mic_hid_level(unsigned hid_level)
{
@@ -1425,6 +1455,8 @@ void AudioHwRemote2(streaming chanend c, chanend cc_mic_level, client interface
unsigned factory_reset_6s_fired = 0;
unsigned factory_reset_10s_fired = 0;
unsigned factory_reset_done = 0;
/* 改动原因:仅用户真实改音量时写 tx1_dac_vol Flashhigh_perf 切换不重写 */
unsigned last_saved_dac_hid = 255;
// TX1 LED effect state for game mode indicators
unsigned gpio_leds_dirty = 1; // refresh LEDs on first tick
@@ -1491,6 +1523,7 @@ void AudioHwRemote2(streaming chanend c, chanend cc_mic_level, client interface
}
high_perf_mode = (unsigned)saved_hp;
SET_SHARED_GLOBAL(g_high_perf_mode, high_perf_mode);
last_saved_dac_hid = (unsigned)saved_dac;
tx1_apply_dac_hid_level((unsigned)saved_dac);
tx1_apply_mic_hid_level((unsigned)saved_mic);
feature_volume = tx1_hid_level_to_bar((unsigned)saved_mic);
@@ -1623,23 +1656,27 @@ void AudioHwRemote2(streaming chanend c, chanend cc_mic_level, client interface
if (user_hid <= TX1_DAC_HID_LEVEL_MAX) {
eff_hid = tx1_effective_dac_hid_level(user_hid, hp);
reg = tx1_dac_reg_from_hid_level(eff_hid);
SET_SHARED_GLOBAL(g_dac_vol, reg);
if (eff_hid == 0) {
unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, i2c); }
} else {
/* 改动原因:必须用 SY102 查表值直写 0x0034不能用 dac_volume 线性公式 */
unsafe {
NAU88C22_REGWRITE(0x0034,
((reg & 0xff) << 8) | (reg & 0xff), i2c);
}
}
old_dac_vol = reg;
tx1_write_dac_hw_reg(eff_hid, reg, old_dac_vol, i2c);
if (user_hid != last_saved_dac_hid) {
tx1_save_dac_volume((unsigned char)user_hid);
last_saved_dac_hid = user_hid;
}
debug_printf("HID/panel SET_VOLUME: user_hid=%u eff_hid=%u hp=%u reg=0x%x\n",
user_hid, eff_hid, hp, reg);
}
}
}
{
unsigned hp_save;
GET_SHARED_GLOBAL(hp_save, g_high_perf_save_pending);
if (hp_save) {
unsigned hp_val;
GET_SHARED_GLOBAL(hp_val, g_high_perf_mode);
tx1_save_high_perf_mode((unsigned char)hp_val);
SET_SHARED_GLOBAL(g_high_perf_save_pending, 0);
debug_printf("TX1: deferred save high_perf=%u\n", hp_val);
}
}
{
unsigned req_mic;
GET_SHARED_GLOBAL(req_mic, g_request_mic_volume_set);
@@ -2187,12 +2224,19 @@ void AudioHwRemote2(streaming chanend c, chanend cc_mic_level, client interface
if (current_combo != COMBO_NONE && !combo_triggered) {
combo_triggered = 1;
if (current_combo == COMBO_GAME_MIC) {
unsigned user_dac_hid;
GET_SHARED_GLOBAL(user_dac_hid, g_volume_level);
high_perf_mode = !high_perf_mode;
SET_SHARED_GLOBAL(g_high_perf_mode, high_perf_mode);
tx1_save_high_perf_mode((unsigned char)high_perf_mode);
SET_SHARED_GLOBAL(g_request_volume_set, 1);
SET_SHARED_GLOBAL(g_high_perf_save_pending, 1);
/* 改动原因:先静音再改 0x0034减轻 ±6dB 切换 pop不写 Flash/不置 request_volume */
tx1_amp_ctl_mute_force(led_if, TX1_AMP_CTL_MUTE_VAL);
tx1_apply_dac_hw_from_user_level(user_dac_hid, high_perf_mode,
old_dac_vol, i2c);
tx1_amp_ctl_mute_force(led_if, TX1_AMP_CTL_UNMUTE_VAL);
gpio_leds_dirty = 1;
debug_printf("TX1: GAME+MIC combo - high_perf_mode=%d\n", high_perf_mode);
debug_printf("TX1: GAME+MIC combo - high_perf_mode=%d user_hid=%u\n",
high_perf_mode, user_dac_hid);
} else if (current_combo == COMBO_VOL_UP_DOWN) {
/* 改动原因:无 BYPASS 档feature 空闲时 VOL 组合键可切换 RGB 装饰灯效 */
if (feature_mode == FEATURE_MODE_NONE) {