From 88454f11ce2ca45051f942c4a85cb0775a0cf9c9 Mon Sep 17 00:00:00 2001 From: Steven Dan Date: Tue, 12 May 2026 11:46:09 +0800 Subject: [PATCH] volume savings --- .../src/extensions/audiohw.xc | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/audiohw.xc b/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/audiohw.xc index 2ab062a..2e548b5 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/audiohw.xc +++ b/sw_usb_audio/app_usb_aud_fosi_c1/src/extensions/audiohw.xc @@ -111,6 +111,21 @@ timer tm; #define C1_MODE_VALUE_MIN 0 #define C1_MODE_VALUE_MAX 1 +// 改动原因:DAC 音量单独持久化路径,与 mode 的 c1_mode 文件分离,避免互相覆盖且便于维护。 +#define C1_DAC_VOL_INFO_PATH "c1_dac_vol" +// 改动原因:与 FORMAT_DELAY(30000000) 相同时间基准(get_reference_time 滴答),用户停止调节 300ms 后再写 Flash,减少磨损并满足需求。 +#define C1_DAC_VOL_SAVE_DELAY (30000000) + +// 改动原因:判断 Flash 读出字节是否为合法 NAU88C22 DAC 音量码:0x00 表示按键规则下的 mute,0x4B~0xCF 为正常衰减范围。 +static unsigned c1_saved_dac_vol_is_valid(unsigned char v) +{ + if (v == C1_DAC_MUTE) + return 1; + if (v >= C1_DAC_VOL_MIN && v <= C1_DAC_VOL_MAX) + return 1; + return 0; +} + // 改动原因:mode值与面板LED颜色索引不是同一编码,封装转换避免业务代码散落魔数映射关系。 static inline unsigned c1_mode_to_led_color_idx(unsigned mode_value) { @@ -373,6 +388,9 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli unsigned old_dac_vol = 0; unsigned old_adc_vol = 0; unsigned old_dac_mode = 0; + // 改动原因:记录上次用于防抖持久化的 g_dac_vol;deadline=0 表示当前无待写入 Flash 的定时保存任务。 + unsigned dac_vol_persist_snapshot = 0; + unsigned dac_vol_persist_deadline = 0; // 改动原因:按DS1按键状态机思路保存每个按键按下时长;mode/mic 仍用短/长按窗口区分,音量键仅用于释放时短按去抖(不支持长按连调)。 unsigned mode_press_ticks = 0; unsigned vol_down_press_ticks = 0; @@ -400,6 +418,21 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli save_value(C1_MODE_INFO_PATH, c1_mode); } + // 改动原因:开机从 LittleFS 恢复 DAC 音量寄存器码;无效或未写过时用最大音量 C1_DAC_VOL_MAX,避免误用默认值或垃圾数据。 + { + unsigned char loaded_dac_vol = load_value(C1_DAC_VOL_INFO_PATH); + unsigned init_dac_vol; + if (c1_saved_dac_vol_is_valid(loaded_dac_vol) == 0) + init_dac_vol = C1_DAC_VOL_MAX; + else + init_dac_vol = loaded_dac_vol; + SET_SHARED_GLOBAL(g_dac_vol, init_dac_vol); + // 改动原因:强制首轮定时器路径执行 NAU88C22 写音量(含 mute=0 时 old_dac_vol 初值也为 0 的情况)。 + old_dac_vol = ~init_dac_vol; + dac_vol_persist_snapshot = init_dac_vol; + dac_vol_persist_deadline = 0; + } + // 改动原因:开机后立即按Flash恢复的mode值设置面板灯色,避免首次按键前灯态与保存状态不一致。 i_c1_led_ctrl.set_mode_led_color(c1_mode_to_led_color_idx(c1_mode)); @@ -511,6 +544,20 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli debug_printf("set old_dac_vol %d audio_type %d \n", old_dac_vol, audio_type); } + // 改动原因:音量键/HID/UART 任一修改 g_dac_vol 后不立即写 Flash;仅当读回值相对 persist_snapshot 稳定满 300ms 再 save_value,满足防抖与关机保存。 + { + if (dac_vol != dac_vol_persist_snapshot) + { + dac_vol_persist_snapshot = dac_vol; + dac_vol_persist_deadline = now + C1_DAC_VOL_SAVE_DELAY; + } + else if (dac_vol_persist_deadline != 0 && timeafter(now, dac_vol_persist_deadline)) + { + save_value(C1_DAC_VOL_INFO_PATH, (unsigned char)(dac_vol & 0xff)); + dac_vol_persist_deadline = 0; + } + } + if (old_adc_vol != effective_adc_vol) { if ((effective_adc_vol <= 0xff) && (effective_adc_vol >= 0))