From ffa8f388f06ee567f642c1e26785c5a107a0f593 Mon Sep 17 00:00:00 2001 From: Steven Dan Date: Mon, 25 May 2026 17:26:42 +0800 Subject: [PATCH] fix pop noise of switch modes --- .../app_usb_aud_fosi_c1_v71/CMakeLists.txt | 6 +- .../src/extensions/audiohw.xc | 74 +++++++++++++++++-- .../src/extensions/tx1_led_helper.xc | 9 ++- 3 files changed, 77 insertions(+), 12 deletions(-) diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/CMakeLists.txt b/sw_usb_audio/app_usb_aud_fosi_c1_v71/CMakeLists.txt index 6f092bd..2eb5d39 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/CMakeLists.txt +++ b/sw_usb_audio/app_usb_aud_fosi_c1_v71/CMakeLists.txt @@ -73,7 +73,7 @@ set(APP_COMPILER_FLAGS_fact ${SW_FACT_AUDIO_FLAGS} -DI2S_CHANS_DAC=2 -# 改动原因:FPS71 独立 UAC2 固件;Windows 下 g_3d_fps=2 时加载(去掉 F3_F4) +# 改动原因:FPS71 独立 UAC2 固件;不做 Win 检测;由 game_uac1(Win+FPS71) RoleSwitch 跳入 set(APP_COMPILER_FLAGS_fps71_uac2 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2 -DI2S_CHANS_ADC=2 -DMIN_FREQ=48000 @@ -110,8 +110,8 @@ set(APP_COMPILER_FLAGS_game_uac1 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2 -DAUDIO_CLASS=1 -DMIN_FREQ=48000 -DMAX_FREQ=48000 - -DMCLK_441=512*44100 - -DMCLK_48=512*48000 + -DMCLK_441=1024*44100 + -DMCLK_48=1024*48000 -DUAC1_MODE=1 -DF5_MUSIC_UAC1=1 -DUSE_EX3D 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 6d7b06f..24192c7 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 @@ -107,6 +107,43 @@ unsigned g_request_factory_reset = 0; /* 改动原因:HTR3236 bringup 须在 codec_init 完成之后执行,避免与 NAU88 I2C 抢线/阻塞 */ unsigned g_audiohw_codec_init_done = 0; +/* 改动原因:p_ctl_mute 经 tile1 控制功放;低=静音、高=放音(与 jok ui_app 一致) */ +#define TX1_AMP_CTL_MUTE_VAL 0u +#define TX1_AMP_CTL_UNMUTE_VAL 1u +unsigned g_tx1_ctl_mute_pending = 0; +unsigned g_tx1_ctl_mute_value = TX1_AMP_CTL_MUTE_VAL; + +static void tx1_amp_ctl_mute_queue(unsigned value) +{ + SET_SHARED_GLOBAL(g_tx1_ctl_mute_value, value); + SET_SHARED_GLOBAL(g_tx1_ctl_mute_pending, 1); +} + +static void tx1_amp_ctl_mute_flush(client interface tx1_led_if led_if) +{ + unsigned pending, value; + GET_SHARED_GLOBAL(pending, g_tx1_ctl_mute_pending); + if (pending) { + GET_SHARED_GLOBAL(value, g_tx1_ctl_mute_value); + led_if.set_mute(value); + SET_SHARED_GLOBAL(g_tx1_ctl_mute_pending, 0); + } +} + +static void tx1_amp_ctl_mute_force(client interface tx1_led_if led_if, unsigned value) +{ + led_if.set_mute(value); + SET_SHARED_GLOBAL(g_tx1_ctl_mute_value, value); + SET_SHARED_GLOBAL(g_tx1_ctl_mute_pending, 0); +} + +/* 改动原因:RoleSwitch 重启前拉低 p_ctl_mute;HID/eq 与 AudioHwRemote 不同核,用 pending+延时等待 flush */ +static void tx1_amp_mute_before_reboot(void) +{ + tx1_amp_ctl_mute_queue(TX1_AMP_CTL_MUTE_VAL); + delay_milliseconds(80); +} + // CODEC I2C lines on tile[0]: port p_scl = PORT_I2C_SCL; on tile[0]: port p_sda = PORT_I2C_SDA; @@ -239,7 +276,7 @@ void switch_mode_by_c1_mode(unsigned game_mode, unsigned force_reboot) return; } SetRoleSwitchFlag(TX1_ROLE_GAME_UAC1); - delay_milliseconds(20); + tx1_amp_mute_before_reboot(); device_reboot(); while (1); return; @@ -265,8 +302,8 @@ void switch_mode_by_c1_mode(unsigned game_mode, unsigned force_reboot) if (reboot_need) { - /* 改动原因:game_uac1 按键切到 FPS71 且已判定为 Win 时,RoleSwitch 后必须重启才进入 fps71_uac2 */ - delay_milliseconds(20); + /* 改动原因:切固件前先功放静音,减轻 RoleSwitch 重启 pop */ + tx1_amp_mute_before_reboot(); device_reboot(); while (1); } @@ -785,13 +822,21 @@ unsigned char load_value(unsigned char * unsafe path); * 改动原因:与 jok on_game_short_press 一致——更新 g_3d_fps、g_tx1_azimuth_mode, * 供 tile1 ex3d_task 轮询下发 EX3D;persist=1 时写入 LFS(GAME 键/需记忆时)。 */ -static void tx1_sync_game_mode_state(unsigned mode, unsigned persist) +static void tx1_sync_game_mode_state(unsigned mode, unsigned persist, + client interface tx1_led_if led_if) { unsigned azimuth = TX1_AZIMUTH_MODE_FPS; if (mode > 3) { mode = 0; } + + if (persist) { + /* 改动原因:GAME 键/HID 切档前先拉低 p_ctl_mute,避免 EX3D/固件切换 pop */ + tx1_amp_ctl_mute_force(led_if, TX1_AMP_CTL_MUTE_VAL); + delay_milliseconds(50); + } + switch (mode) { case GAME_MODE_3A: azimuth = TX1_AZIMUTH_MODE_3A; @@ -811,6 +856,9 @@ static void tx1_sync_game_mode_state(unsigned mode, unsigned persist) tx1_save_game_mode((unsigned char)mode); /* 改动原因:GAME 键 persist——game_uac1 仅 Win+FPS71 重启进 fps71;fps71 切到非 FPS71 重启回 game_uac1 */ switch_mode_by_c1_mode(mode, 0); + /* 未 RoleSwitch 重启则恢复放音 */ + delay_milliseconds(30); + tx1_amp_ctl_mute_force(led_if, TX1_AMP_CTL_UNMUTE_VAL); } } @@ -988,10 +1036,13 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli /* 改动原因:仅预拉 SDB;完整 bringup 在 codec_init 完成后执行(见 tmr 分支) */ led_if.init(); + /* 改动原因:开机即拉低 p_ctl_mute,codec/HTR3236/音量/Win 检测完成后再在 tmr 里拉高 */ + tx1_amp_ctl_mute_force(led_if, TX1_AMP_CTL_MUTE_VAL); tx1_htr3236_sdb_enable(led_if); htr3236_init(&htr3236_dev, HTR3236_ADDR_GND); unsigned htr3236_bringup_done = 0; + unsigned tx1_amp_unmuted_after_boot = 0; // TX1 button previous state (active low: 0=pressed, 1=released) unsigned prev_fps = 1, prev_game = 1, prev_mic = 1; @@ -1035,7 +1086,7 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli { unsigned char saved_gm = tx1_load_game_mode(); game_mode = (tx1_game_mode_t)saved_gm; - tx1_sync_game_mode_state((unsigned)game_mode, 0); + tx1_sync_game_mode_state((unsigned)game_mode, 0, led_if); gpio_leds_dirty = 1; debug_printf("TX1: Loaded game_mode from flash: %u\n", (unsigned)game_mode); } @@ -1049,6 +1100,7 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli GET_SHARED_GLOBAL(boot_game_mode, g_3d_fps); debug_printf("WIN_OS_DETECTION host_os=%d g_3d_fps=%d\n", host_os, boot_game_mode); if (host_os == OS_WIN && boot_game_mode == GAME_MODE_FPS71) { + /* 改动原因:开机 Win+FPS71 切 fps71 前已静音,switch_mode 内会 reboot */ switch_mode_by_c1_mode(boot_game_mode, 0); } else { debug_printf("stay on game_uac1 (no fps71 role switch)\n"); @@ -1120,6 +1172,8 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli unsigned dac_vol, adc_vol, dac_mode, new_dac_mode; unsigned codec_init_done; + tx1_amp_ctl_mute_flush(led_if); + /* 改动原因:codec_init 经 chan 在本任务处理;完成后再做 HTR3236,避免假成功 */ if (!htr3236_bringup_done) { GET_SHARED_GLOBAL(codec_init_done, g_audiohw_codec_init_done); @@ -1130,6 +1184,14 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli } } + /* 改动原因:codec + HTR3236 + 开机流程结束后拉高 p_ctl_mute 放音 */ + if (htr3236_bringup_done && !tx1_amp_unmuted_after_boot) { + delay_milliseconds(20); + tx1_amp_ctl_mute_force(led_if, TX1_AMP_CTL_UNMUTE_VAL); + tx1_amp_unmuted_after_boot = 1; + debug_printf("TX1: AMP ctl_mute unmute after boot config\n"); + } + now = get_reference_time(); GET_SHARED_GLOBAL(unmute_dac_state, g_unmute_dac_state); @@ -1799,7 +1861,7 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli * 其余(非 Win 下 FPS71、UAC1 下其它档)仅改 g_3d_fps,不重启。 */ game_mode = (game_mode + 1) % 4; gpio_leds_dirty = 1; - tx1_sync_game_mode_state((unsigned)game_mode, 1); + tx1_sync_game_mode_state((unsigned)game_mode, 1, led_if); debug_printf("TX1: GAME short press - game_mode=%d saved\n", game_mode); } } diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_led_helper.xc b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_led_helper.xc index 67ce6e8..d0aef18 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_led_helper.xc +++ b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_led_helper.xc @@ -14,6 +14,9 @@ on tile[1]: out port p_led_d4_d7_d6 = PORT_LED_D4_7_6; // 4D: bit3=D4, bit2=D7, on tile[1]: out port p_htr3236_sdb = PORT_HTR3236_SDB; // 改动原因:与 jok.xn / xu316_qf60.xn 中 PORT_CTL_MUTE 一致 on tile[1]: out port p_ctl_mute = PORT_CTL_MUTE; +/* 改动原因:与 jok ui_app 一致——p_ctl_mute 拉低=功放静音,拉高=放音;切换模式/开机先低后高可抑制 pop */ +#define TX1_AMP_GPIO_MUTE 0 +#define TX1_AMP_GPIO_UNMUTE 1 // tile[1] LED helper task - controls tile[1] GPIO LED ports // Receives commands via tx1_led_if interface from AudioHwRemote2 on tile[0] @@ -34,7 +37,7 @@ void tx1_led_helper_task(server interface tx1_led_if led_if) p_led_d4_d7_d6 <: 0xF; /* 改动原因:上电即拉高 SDB,与 jok tile1_io_control_task 一致;勿长期拉低否则 I2C 配置无效 */ p_htr3236_sdb <: 1; - p_ctl_mute <: 1; // Muted initially + p_ctl_mute <: TX1_AMP_GPIO_MUTE; /* 改动原因:上电先拉低静音,等 tile0 codec/RGB 配置完再拉高 */ while (1) { @@ -105,7 +108,7 @@ void tx1_led_helper_task(server interface tx1_led_if led_if) break; case led_if.set_mute(unsigned value): - //p_ctl_mute <: value; + p_ctl_mute <: value; break; case led_if.init(void): @@ -115,7 +118,7 @@ void tx1_led_helper_task(server interface tx1_led_if led_if) p_led_d5 <: 1; p_led_d4_d7_d6 <: 0xF; p_htr3236_sdb <: 1; // Enable HTR3236 - //p_ctl_mute <: 1; // Muted + p_ctl_mute <: TX1_AMP_GPIO_MUTE; d1_state = 1; d2_state = 1; d3_state = 0xF; d5_state = 1; d4_d7_d6_state = 0xF; break;