update mic mute button for only support mic mute and dnr enable

This commit is contained in:
Steven Dan
2026-06-12 08:59:34 +08:00
parent 3315b2396e
commit 71c9a7fb47
7 changed files with 154 additions and 258 deletions

View File

@@ -118,8 +118,6 @@ timer tm;
#define C1_KEY_LONG_TICKS 50 #define C1_KEY_LONG_TICKS 50
// 改动原因:规格要求 mic 键长按 1.5s 切换 g_dnr_enableAI 通话降噪/DNR20ms*75=1.5s,与 mode 键 LONG 解耦,避免误触。 // 改动原因:规格要求 mic 键长按 1.5s 切换 g_dnr_enableAI 通话降噪/DNR20ms*75=1.5s,与 mode 键 LONG 解耦,避免误触。
#define C1_KEY_MIC_DNR_LONG_TICKS 75 #define C1_KEY_MIC_DNR_LONG_TICKS 75
// 改动原因:双击第二下需在首击释放后约 500ms 内按下否则判为单击静音20ms*25=500ms。
#define C1_MIC_DOUBLE_DEFER_TICKS 25
// 改动原因新增C1模式持久化文件路径使用LittleFS保存mode按键状态保证断电重启后可恢复。 // 改动原因新增C1模式持久化文件路径使用LittleFS保存mode按键状态保证断电重启后可恢复。
#define C1_MODE_VALUE_PATH "c1_mode_value" #define C1_MODE_VALUE_PATH "c1_mode_value"
@@ -130,9 +128,8 @@ timer tm;
// 改动原因DAC 音量单独持久化路径,与 mode 的 c1_mode 文件分离,避免互相覆盖且便于维护。 // 改动原因DAC 音量单独持久化路径,与 mode 的 c1_mode 文件分离,避免互相覆盖且便于维护。
#define C1_DAC_VOL_INFO_PATH "c1_dac_vol" #define C1_DAC_VOL_INFO_PATH "c1_dac_vol"
// 改动原因:麦克风按键三种状态(静音/变声/DNR均需断电保存上电恢复并同步LED显示。 // 改动原因:规格表仅保留静音与 DNR 断电记忆mic 指示灯只反映静音(红灯/灭DNR 由 APP 显示。
#define C1_MIC_MUTE_INFO_PATH "c1_mic_mute" #define C1_MIC_MUTE_INFO_PATH "c1_mic_mute"
#define C1_VOICE_FX_INFO_PATH "c1_voice_fx"
#define C1_DNR_EN_INFO_PATH "c1_dnr_en" #define C1_DNR_EN_INFO_PATH "c1_dnr_en"
// 改动原因:与 FORMAT_DELAY(30000000) 相同时间基准get_reference_time 滴答),用户停止调节 300ms 后再写 Flash减少磨损并满足需求。 // 改动原因:与 FORMAT_DELAY(30000000) 相同时间基准get_reference_time 滴答),用户停止调节 300ms 后再写 Flash减少磨损并满足需求。
#define C1_DAC_VOL_SAVE_DELAY (30000000) #define C1_DAC_VOL_SAVE_DELAY (30000000)
@@ -292,6 +289,7 @@ unsigned g_led_blink_is_white = 0;
extern unsigned char g_hid_pass_data[64]; extern unsigned char g_hid_pass_data[64];
static unsigned g_last_dac_vol = 0xFF; // 改动原因改为检测g_dac_vol的变化初始化为0xFF表示未初始化 static unsigned g_last_dac_vol = 0xFF; // 改动原因改为检测g_dac_vol的变化初始化为0xFF表示未初始化
static unsigned g_last_mute_switch = 0xFF; // 改动原因检测静音开关变化并上报0xB20xFF=未初始化 static unsigned g_last_mute_switch = 0xFF; // 改动原因检测静音开关变化并上报0xB20xFF=未初始化
static unsigned g_last_dnr_enable = 0xFF; // 改动原因检测AI通话降噪(g_dnr_enable)变化并上报0xB50xFF=未初始化
static unsigned g_last_adc_loop = 0xFF; // 改动原因:检测监听开关(g_adc_loop)变化并上报0xB40xFF=未初始化 static unsigned g_last_adc_loop = 0xFF; // 改动原因:检测监听开关(g_adc_loop)变化并上报0xB40xFF=未初始化
static unsigned g_last_audio_type = 0xFF; // 改动原因上次检测到的音频类型初始化为0xFF表示未初始化用于LED颜色判断 static unsigned g_last_audio_type = 0xFF; // 改动原因上次检测到的音频类型初始化为0xFF表示未初始化用于LED颜色判断
static unsigned g_last_led_status = 0xFF; // 上次检测到的LED状态初始化为0xFF表示未初始化 static unsigned g_last_led_status = 0xFF; // 上次检测到的LED状态初始化为0xFF表示未初始化
@@ -567,12 +565,8 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
unsigned vol_down_press_ticks = 0; unsigned vol_down_press_ticks = 0;
unsigned mic_mute_press_ticks = 0; unsigned mic_mute_press_ticks = 0;
unsigned vol_up_press_ticks = 0; unsigned vol_up_press_ticks = 0;
// 改动原因:mic 键双击需延迟首轮短按的静音动作,用 stage1=等超时单击 / stage2=已收到第二下按下等释放;与长按 DNR 互斥靠 mic_dnr_long_fired // 改动原因:规格取消双击变声mic_dnr_long_fired 用于长按 DNR 后屏蔽同次松手的短按静音
unsigned mic_dbl_stage = 0;
unsigned mic_defer_left = 0;
unsigned mic_dnr_long_fired = 0; unsigned mic_dnr_long_fired = 0;
// 改动原因:变声/美声仅按键+灯tile0 保存状态供 set_mic_voice_fx 下发 mic 橙灯。
unsigned c1_mic_voice_fx = 0;
// 改动原因mic mute红灯通过interface下发到tile1仅在状态变化时发送减少无意义跨tile调用。 // 改动原因mic mute红灯通过interface下发到tile1仅在状态变化时发送减少无意义跨tile调用。
unsigned last_mute_switch_for_led = 0xFFFFFFFF; unsigned last_mute_switch_for_led = 0xFFFFFFFF;
unsigned host_os = 0; unsigned host_os = 0;
@@ -649,32 +643,24 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
} }
// 改动原因:三种 mic 状态(静音/变声/DNR均需断电保存上电从 Flash 读取并恢复;无效値(非 0/1时使用默认値 // 改动原因:规格仅保留静音与 DNR 断电记忆;上电恢复后 mic 灯只同步静音态(红灯/灭)
{ {
unsigned char loaded_mute = load_value(C1_MIC_MUTE_INFO_PATH); unsigned char loaded_mute = load_value(C1_MIC_MUTE_INFO_PATH);
unsigned init_mute = (loaded_mute == 0 || loaded_mute == 1) ? (unsigned)loaded_mute : 1u; unsigned init_mute = (loaded_mute == 0 || loaded_mute == 1) ? (unsigned)loaded_mute : 1u;
SET_SHARED_GLOBAL(g_mute_switch, init_mute); SET_SHARED_GLOBAL(g_mute_switch, init_mute);
} }
{
unsigned char loaded_vfx = load_value(C1_VOICE_FX_INFO_PATH);
c1_mic_voice_fx = (loaded_vfx == 1) ? 1u : 0u;
}
{ {
unsigned char loaded_dnr = load_value(C1_DNR_EN_INFO_PATH); unsigned char loaded_dnr = load_value(C1_DNR_EN_INFO_PATH);
unsigned init_dnr = (loaded_dnr == 0 || loaded_dnr == 1) ? (unsigned)loaded_dnr : 1u; unsigned init_dnr = (loaded_dnr == 0 || loaded_dnr == 1) ? (unsigned)loaded_dnr : 1u;
SET_SHARED_GLOBAL(g_dnr_enable, init_dnr); SET_SHARED_GLOBAL(g_dnr_enable, init_dnr);
} }
// 改动原因tile1 上电已硬件全灯;先下发三种mic状态再下发 mode使首帧 apply 时 mic 正确。 // 改动原因tile1 上电已硬件全灯;先下发 mic 静音灯再下发 mode使首帧 apply 时 mic 正确。
{ {
unsigned init_mute_for_led; unsigned init_mute_for_led;
unsigned init_dnr_for_led;
GET_SHARED_GLOBAL(init_mute_for_led, g_mute_switch); GET_SHARED_GLOBAL(init_mute_for_led, g_mute_switch);
GET_SHARED_GLOBAL(init_dnr_for_led, g_dnr_enable);
i_c1_led_ctrl.set_mic_mute_state(init_mute_for_led); i_c1_led_ctrl.set_mic_mute_state(init_mute_for_led);
i_c1_led_ctrl.set_mode_led_color(c1_mode_to_tile_mode_led_code(c1_mode)); i_c1_led_ctrl.set_mode_led_color(c1_mode_to_tile_mode_led_code(c1_mode));
i_c1_led_ctrl.set_mic_voice_fx(c1_mic_voice_fx);
i_c1_led_ctrl.set_mic_dnr_state(init_dnr_for_led);
last_mute_switch_for_led = init_mute_for_led; last_mute_switch_for_led = init_mute_for_led;
} }
@@ -921,51 +907,8 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
vol_up_pressed = ((button_state & C1_KEY_VOL_UP_MASK) == 0); vol_up_pressed = ((button_state & C1_KEY_VOL_UP_MASK) == 0);
pressed_count = mode_pressed + vol_down_pressed + mic_mute_pressed + vol_up_pressed; pressed_count = mode_pressed + vol_down_pressed + mic_mute_pressed + vol_up_pressed;
// 改动原因mic 首击短按后延迟 500ms 再静音,以便识别双击;仅 mic 松开时递减 mic_defer_left到 0 执行单击静音。
if (mic_dbl_stage == 1 && mic_defer_left > 0)
{
unsigned mic_released_now = ((button_state & C1_KEY_MIC_MUTE_MASK) != 0);
if (mic_released_now)
{
mic_defer_left--;
if (mic_defer_left == 0)
{
unsigned current_mute_switch;
unsigned effective_adc_vol;
GET_SHARED_GLOBAL(effective_adc_vol, g_adc_vol);
GET_SHARED_GLOBAL(current_mute_switch, g_mute_switch);
current_mute_switch = (current_mute_switch == 0) ? 1 : 0;
if (current_mute_switch == 0)
{
mic_volume(0, i2c);
// 改动原因:同步 old_adc_vol避免定时器下一轮仍按旧值误判或与按键写入冲突。
old_adc_vol = 0;
}
else
{
mic_volume(effective_adc_vol, i2c);
old_adc_vol = effective_adc_vol;
}
SET_SHARED_GLOBAL(g_mute_switch, current_mute_switch);
// 改动原因静音状态变化后立即保存到Flash保证断电后恢复正确的静音灯状态。
save_value(C1_MIC_MUTE_INFO_PATH, (unsigned char)current_mute_switch);
i_c1_led_ctrl.set_mic_mute_state(current_mute_switch);
last_mute_switch_for_led = current_mute_switch;
debug_printf("C1 key mic mute toggle (deferred single): %d\n", current_mute_switch);
mic_dbl_stage = 0;
}
}
}
if (pressed_count == 1) if (pressed_count == 1)
{ {
// 改动原因mic 双击等待期间若用户去按 mode/音量键,应取消延迟单击静音,避免误切 g_mute_switch。
if (!mic_mute_pressed)
{
mic_dbl_stage = 0;
mic_defer_left = 0;
}
if (mode_pressed) if (mode_pressed)
{ {
mode_press_ticks++; mode_press_ticks++;
@@ -984,22 +927,14 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
} }
else if (mic_mute_pressed) else if (mic_mute_pressed)
{ {
// 改动原因:双击窗口内第二下按下,取消延迟单击静音,改为等待释放后判双击变声。
if (mic_dbl_stage == 1)
{
mic_defer_left = 0;
mic_dbl_stage = 2;
}
mic_mute_press_ticks++; mic_mute_press_ticks++;
// 改动原因:按住满 1.5s 翻转 g_dnr_enableextra_i2s 中 GET_SHARED_GLOBAL 决定是否走 DNR松手时靠 mic_dnr_long_fired 屏蔽短按/双击 // 改动原因:规格长按1.5s切换AI通话降噪无指示灯保存Flashg_dnr_enable变化由定时器路径HID 0xB5上报APP
if (mic_mute_press_ticks == C1_KEY_MIC_DNR_LONG_TICKS) if (mic_mute_press_ticks == C1_KEY_MIC_DNR_LONG_TICKS)
{ {
unsigned dnr_enable; unsigned dnr_enable;
GET_SHARED_GLOBAL(dnr_enable, g_dnr_enable); GET_SHARED_GLOBAL(dnr_enable, g_dnr_enable);
dnr_enable = (dnr_enable != 0) ? 0 : 1; dnr_enable = (dnr_enable != 0) ? 0 : 1;
SET_SHARED_GLOBAL(g_dnr_enable, dnr_enable); SET_SHARED_GLOBAL(g_dnr_enable, dnr_enable);
// 改动原因DNR状态变化后立即下发LED开亮蓝灯/关灯并保存到Flash供断电恢复。
i_c1_led_ctrl.set_mic_dnr_state(dnr_enable);
save_value(C1_DNR_EN_INFO_PATH, (unsigned char)dnr_enable); save_value(C1_DNR_EN_INFO_PATH, (unsigned char)dnr_enable);
mic_dnr_long_fired = 1; mic_dnr_long_fired = 1;
debug_printf("C1 mic DNR toggle (hold 1.5s): %d\n", dnr_enable); debug_printf("C1 mic DNR toggle (hold 1.5s): %d\n", dnr_enable);
@@ -1056,33 +991,34 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
} }
} }
// 改动原因:mic短按静音延迟单击防双击双击变声 mic 橙灯长按1.5s 切 g_dnr_enable 无灯;长按与短/双互斥 // 改动原因:规格短按立即切换静音(红灯/灭灯长按1.5s已切DNR则屏蔽同次松手短按
{ {
unsigned mic_snap = mic_mute_press_ticks; unsigned mic_snap = mic_mute_press_ticks;
if (mic_snap > 0) if (mic_snap > 0)
{ {
if ((mic_snap >= C1_KEY_MIC_DNR_LONG_TICKS) || mic_dnr_long_fired) if ((mic_snap >= C1_KEY_SHORT_TICKS) && (mic_snap < C1_KEY_MIC_DNR_LONG_TICKS) && !mic_dnr_long_fired)
{ {
if (mic_dbl_stage == 2) unsigned current_mute_switch;
mic_dbl_stage = 0; unsigned effective_adc_vol;
} GET_SHARED_GLOBAL(effective_adc_vol, g_adc_vol);
else if ((mic_snap >= C1_KEY_SHORT_TICKS) && (mic_snap < C1_KEY_MIC_DNR_LONG_TICKS)) GET_SHARED_GLOBAL(current_mute_switch, g_mute_switch);
{ current_mute_switch = (current_mute_switch == 0) ? 1 : 0;
if (mic_dbl_stage == 2)
if (current_mute_switch == 0)
{ {
c1_mic_voice_fx = (c1_mic_voice_fx ? 0 : 1); mic_volume(0, i2c);
i_c1_led_ctrl.set_mic_voice_fx(c1_mic_voice_fx); old_adc_vol = 0;
// 改动原因变声状态变化后立即保存到Flash保证断电后恢复正确的变声灯状态。
save_value(C1_VOICE_FX_INFO_PATH, (unsigned char)c1_mic_voice_fx);
mic_dbl_stage = 0;
mic_defer_left = 0;
debug_printf("C1 mic voice/beautifier toggle: %d\n", c1_mic_voice_fx);
} }
else else
{ {
mic_dbl_stage = 1; mic_volume(effective_adc_vol, i2c);
mic_defer_left = C1_MIC_DOUBLE_DEFER_TICKS; old_adc_vol = effective_adc_vol;
} }
SET_SHARED_GLOBAL(g_mute_switch, current_mute_switch);
save_value(C1_MIC_MUTE_INFO_PATH, (unsigned char)current_mute_switch);
i_c1_led_ctrl.set_mic_mute_state(current_mute_switch);
last_mute_switch_for_led = current_mute_switch;
debug_printf("C1 key mic mute toggle (short press): %d\n", current_mute_switch);
} }
mic_dnr_long_fired = 0; mic_dnr_long_fired = 0;
} }
@@ -1112,13 +1048,6 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
} }
} }
} }
else if (pressed_count > 1)
{
// 改动原因:多键同按时取消 mic 双击等待,避免组合键松手后误触发延迟静音。
mic_dbl_stage = 0;
mic_defer_left = 0;
}
// 改动原因:多键同时按下不映射功能,立即清除本轮计时,避免组合键抖动误触发单键动作。 // 改动原因:多键同时按下不映射功能,立即清除本轮计时,避免组合键抖动误触发单键动作。
mode_press_ticks = 0; mode_press_ticks = 0;
vol_down_press_ticks = 0; vol_down_press_ticks = 0;
@@ -1254,6 +1183,26 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
g_last_mute_switch = current_mute; g_last_mute_switch = current_mute;
} }
// 改动原因规格DNR无指示灯按键长按切换后通过HID 0xB5主动上报APP与0xB4监听开关上报方式一致
{
unsigned current_dnr;
GET_SHARED_GLOBAL(current_dnr, g_dnr_enable);
if (g_last_dnr_enable != current_dnr && g_last_dnr_enable != 0xFF)
{
unsafe
{
unsigned char * unsafe reportPtr = g_hid_pass_data;
reportPtr[0] = 0x77;
reportPtr[1] = 0xB5; // GET_DNR_ENABLE
reportPtr[2] = (unsigned char)current_dnr;
for (int i = 3; i < 63; i++) reportPtr[i] = 0x00;
hidSetChangePending(0x1);
}
debug_printf("DNR enable changed: %d -> %d, HID 0xB5 report prepared\n", g_last_dnr_enable, current_dnr);
}
g_last_dnr_enable = current_dnr;
}
// 改动原因:检测监听开关(g_adc_loop)状态变化如果变化则通过HID上报0xB4格式参考eq_hid_protocol.md // 改动原因:检测监听开关(g_adc_loop)状态变化如果变化则通过HID上报0xB4格式参考eq_hid_protocol.md
{ {
unsigned current_adc_loop; unsigned current_adc_loop;
@@ -1979,9 +1928,8 @@ static inline void c1_panel_leds_force_all_off_hw(void)
} }
// 改动原因c1_mode 与灯索引一致1=灯 2=蓝 3=绿 4=橙(R+G) 5=紫(R+B);仅驱动 mode 区p_leds bit2/3 + p_mode_led_blue不受 mic 变声影响。 // 改动原因c1_mode 与灯索引一致1=灯 2=蓝 3=绿 4=橙(R+G) 5=紫(R+B);仅驱动 mode 区p_leds bit2/3 + p_mode_led_blue不受 mic 变声影响。
// 改动原因mic 区灯优先级:静音=只亮红灯(覆盖变声/DNR非静音时变声=橙(p_mic_mute_led_red+R+bit0绿)DNR=蓝(p_leds bit1) // 改动原因:规格 mic 区灯仅反映静音——静音红灯常亮非静音含DNR开/关全灭DNR状态由APP显示。
// 两者同开=橙+蓝混合,两者均关=全灯。 static inline void apply_c1_panel_leds(unsigned mode_led_color_idx, unsigned mic_mute_switch, unsigned &led_shadow)
static inline void apply_c1_panel_leds(unsigned mode_led_color_idx, unsigned mic_mute_switch, unsigned mic_voice_fx_on, unsigned mic_dnr_on, unsigned &led_shadow)
{ {
unsigned mode_red = 0; unsigned mode_red = 0;
unsigned mode_green = 0; unsigned mode_green = 0;
@@ -1990,17 +1938,11 @@ static inline void apply_c1_panel_leds(unsigned mode_led_color_idx, unsigned mic
unsigned mic_green = 0; unsigned mic_green = 0;
unsigned mic_blue = 0; unsigned mic_blue = 0;
// 改动原因:静音优先——静音(mic_mute_switch==0)时只亮红灯屏蔽变声橙灯和DNR蓝灯 // 改动原因:规格表——开启静音红灯常亮,关闭静音/正常工作无指示灯。
// 关闭静音后恢复为变声/DNR/混合/全灯的组合状态,满足“关闭静音时回到其他模式的灯颜色”需求。
if (mic_mute_switch == 0) { if (mic_mute_switch == 0) {
mic_red = 1; mic_red = 1;
mic_green = 0; mic_green = 0;
mic_blue = 0; mic_blue = 0;
} else {
// 改动原因:变声=橙(R+G)DNR=蓝,两者同时开=橙+蓝混合,两者均关=全灯。
mic_red = mic_voice_fx_on ? 1 : 0;
mic_green = mic_voice_fx_on ? 1 : 0;
mic_blue = mic_dnr_on ? 1 : 0;
} }
if (mode_led_color_idx == 1) { if (mode_led_color_idx == 1) {
@@ -2024,7 +1966,7 @@ static inline void apply_c1_panel_leds(unsigned mode_led_color_idx, unsigned mic
} }
// 改动原因:硬件 mic/mode RGB 对调后,低四位 bit0~3 分别为 mic mute绿、mic mute蓝、mode红、mode绿统一刷新。 // 改动原因:硬件 mic/mode RGB 对调后,低四位 bit0~3 分别为 mic mute绿、mic mute蓝、mode红、mode绿统一刷新。
// 改动原因p_mic_mute_led_red 由 mic_red 驱动,静音/变声时亮红灯输出0=亮DNR 蓝灯改由 p_leds bit1 驱动 // 改动原因p_mic_mute_led_red 由 mic_red 驱动输出0=亮mic 区绿/蓝仅规格静音态使用,非静音恒灭
p_mic_mute_led_red <: (mic_red ? 0 : 1); p_mic_mute_led_red <: (mic_red ? 0 : 1);
led_shadow &= ~0xF; led_shadow &= ~0xF;
led_shadow |= (mic_green ? 0x0 : 0x1); led_shadow |= (mic_green ? 0x0 : 0x1);
@@ -2041,10 +1983,6 @@ void app_control_slave(server interface c1_led_ctrl_if i_c1_led_ctrl)
unsigned led_shadow = 0xF; unsigned led_shadow = 0xF;
unsigned mode_led_color_idx = 1; unsigned mode_led_color_idx = 1;
unsigned mic_mute_switch = 1; unsigned mic_mute_switch = 1;
// 改动原因:变声/美声开时 p_mic_mute_led_red + p_leds bit0 显橙,与 set_mode_led_color 下发的 mode 灯独立;此处状态与 tile0 set_mic_voice_fx 同步。
unsigned mic_voice_fx_on = 0;
// 改动原因AI通话降噪DNR开时点亮 p_leds bit1 mic mute 蓝灯;与变声同时开时橙+蓝混合;静音优先在 apply 内部处理。
unsigned mic_dnr_on = 0;
c1_panel_leds_force_all_off_hw(); c1_panel_leds_force_all_off_hw();
unsigned eq_mode_time = 0; unsigned eq_mode_time = 0;
@@ -2067,20 +2005,11 @@ void app_control_slave(server interface c1_led_ctrl_if i_c1_led_ctrl)
mode_led_color_idx = color_idx; mode_led_color_idx = color_idx;
if (mode_led_color_idx > 5 || mode_led_color_idx < 1) if (mode_led_color_idx > 5 || mode_led_color_idx < 1)
mode_led_color_idx = C1_MODE_VALUE_DEFAULT; mode_led_color_idx = C1_MODE_VALUE_DEFAULT;
apply_c1_panel_leds(mode_led_color_idx, mic_mute_switch, mic_voice_fx_on, mic_dnr_on, led_shadow); apply_c1_panel_leds(mode_led_color_idx, mic_mute_switch, led_shadow);
break; break;
case i_c1_led_ctrl.set_mic_mute_state(unsigned mute_state): case i_c1_led_ctrl.set_mic_mute_state(unsigned mute_state):
mic_mute_switch = (mute_state != 0) ? 1 : 0; mic_mute_switch = (mute_state != 0) ? 1 : 0;
apply_c1_panel_leds(mode_led_color_idx, mic_mute_switch, mic_voice_fx_on, mic_dnr_on, led_shadow); apply_c1_panel_leds(mode_led_color_idx, mic_mute_switch, led_shadow);
break;
case i_c1_led_ctrl.set_mic_voice_fx(unsigned voice_fx_enabled):
mic_voice_fx_on = (voice_fx_enabled != 0) ? 1 : 0;
apply_c1_panel_leds(mode_led_color_idx, mic_mute_switch, mic_voice_fx_on, mic_dnr_on, led_shadow);
break;
case i_c1_led_ctrl.set_mic_dnr_state(unsigned dnr_enabled):
// 改动原因:接收 tile0 按键逻辑下发的 DNR 状态,刷新 mic 区蓝灯;静音优先在 apply 内部处理。
mic_dnr_on = (dnr_enabled != 0) ? 1 : 0;
apply_c1_panel_leds(mode_led_color_idx, mic_mute_switch, mic_voice_fx_on, mic_dnr_on, led_shadow);
break; break;
} }
} }

View File

@@ -147,6 +147,7 @@ static struct {
bool is_get_firmware_version_request; // 改动原因添加获取固件版本请求标志用于GET_FIRMWARE_VERSION (0xA6) bool is_get_firmware_version_request; // 改动原因添加获取固件版本请求标志用于GET_FIRMWARE_VERSION (0xA6)
bool is_get_mute_switch_request; // 改动原因添加获取静音开关请求标志用于GET_MUTE_SWITCH (0xB2)值由MCU通过UART 0x5F返回 bool is_get_mute_switch_request; // 改动原因添加获取静音开关请求标志用于GET_MUTE_SWITCH (0xB2)值由MCU通过UART 0x5F返回
bool is_get_listen_switch_request; // 改动原因添加获取监听开关请求标志用于GET_LISTEN_SWITCH (0xB4),直接读 g_adc_loop bool is_get_listen_switch_request; // 改动原因添加获取监听开关请求标志用于GET_LISTEN_SWITCH (0xB4),直接读 g_adc_loop
bool is_get_dnr_enable_request; // 改动原因添加获取AI通话降噪请求标志用于GET_DNR_ENABLE (0xB5),直接读 g_dnr_enable
int32_t post_gain_db; int32_t post_gain_db;
} read_request = {0}; } read_request = {0};
@@ -1525,6 +1526,14 @@ unsigned char process_send_params(uint8_t data[], uint16_t len) {
return true; return true;
} }
// 处理获取AI通话降噪开关命令 (0xB5) - GET_DNR_ENABLE
// 改动原因:规格 mic 键长按切换 DNR 无指示灯APP 通过 HID 0xB5 读取/接收主动上报 g_dnr_enable
if (data[1] == 0xB5) {
debug_printf("Received get DNR enable command (GET_DNR_ENABLE) via HID 0xB5\n");
read_request.is_get_dnr_enable_request = true;
return true;
}
// 处理获取当前UAC模式命令 (0x9C) - GET_CURRENT_UAC_MODE // 处理获取当前UAC模式命令 (0x9C) - GET_CURRENT_UAC_MODE
// 改动原因添加当前UAC模式查询命令返回当前UAC模式值和名称 // 改动原因添加当前UAC模式查询命令返回当前UAC模式值和名称
if (data[1] == 0x9C) { if (data[1] == 0x9C) {
@@ -3146,6 +3155,21 @@ unsigned char process_read_params(uint8_t response[]) {
return true; return true;
} }
// 处理获取AI通话降噪开关请求 (0xB5) - GET_DNR_ENABLE
// 改动原因:直接读取 g_dnr_enable 返回;按键长按切换后 audiohw 主动上报同格式 0x77 0xB5 + 1字节
if (read_request.is_get_dnr_enable_request == true) {
unsigned dnr_en;
extern unsigned g_dnr_enable;
GET_SHARED_GLOBAL(dnr_en, g_dnr_enable);
response[0] = 0x77;
response[1] = 0xB5;
response[2] = (uint8_t)(dnr_en & 0xFF); // 0=关 1=开
for (int i = 3; i < 63; i++) response[i] = 0x00;
read_request.is_get_dnr_enable_request = false;
debug_printf("Building 0xB5 response (GET_DNR_ENABLE), g_dnr_enable=%u\n", dnr_en);
return true;
}
if (read_request.is_read_request == true) { if (read_request.is_read_request == true) {
#if 1 // 改动原因fosi_c1 使用 -DUAC1=1 编译,原 #if !UAC1 导致 0x8E 读EQ参数在 HID GET_REPORT 时永不组包eq_designer 收到全零响应 #if 1 // 改动原因fosi_c1 使用 -DUAC1=1 编译,原 #if !UAC1 导致 0x8E 读EQ参数在 HID GET_REPORT 时永不组包eq_designer 收到全零响应
debug_printf("Read request information:\n"); debug_printf("Read request information:\n");

View File

@@ -10,13 +10,8 @@
interface c1_led_ctrl_if { interface c1_led_ctrl_if {
// 改动原因:与 c1_mode 同值下发 tile11=灭 2=蓝 3=绿 4=橙 5=紫(灯索引即 mode // 改动原因:与 c1_mode 同值下发 tile11=灭 2=蓝 3=绿 4=橙 5=紫(灯索引即 mode
void set_mode_led_color(unsigned color_idx); void set_mode_led_color(unsigned color_idx);
void set_mic_mute_state(unsigned mute_switch); // mute_switch: 0=静音(亮红), 1=非静音(灭红) // 改动原因:规格 mic 指示灯仅反映静音——0=静音红灯常亮1=非静音全灭DNR 无灯由 APP 显示。
// 改动原因:硬件 mic/mode RGB 对调后,变声/美声开时 tile1 点亮 mic 区p_mic_mute_led_red 红 + p_leds bit0 绿(橙);关时仅按静音规则驱动 mic 区熄灭。 void set_mic_mute_state(unsigned mute_switch);
// 改动原因:参数名不能用 xC 保留字 onon tile[:]: 语法),否则编译器在解析 interface 时报 parse error before "on"。
void set_mic_voice_fx(unsigned voice_fx_enabled);
// 改动原因麦克风键长按1.5s切换AI通话降噪(DNR),开时点亮 p_leds bit1 mic mute 蓝灯;
// 与变声同时开时橙+蓝混合静音优先静音时所有mic灯被红灯取代。断电需保存。
void set_mic_dnr_state(unsigned dnr_enabled);
}; };
void switch_handler(void); void switch_handler(void);
void flag_handler(); void flag_handler();

View File

@@ -139,11 +139,11 @@ set(APP_COMPILER_FLAGS_bypass_uac1 ${SW_USB_AUDIO_FLAGS} -DXUA_SPDIF_RX
-DXMOS_FPS_EN=0 -DXMOS_FPS_EN=0
-DUAC1=1 -DUAC1=1
-DHID_CONTROLS=1 -DHID_CONTROLS=1
-DDNR_50MS=1 #-DDNR_50MS=1
-DLOW_POWER_EN=1 -DLOW_POWER_EN=1
-DCHAN_BUFF_CTRL=1 -DCHAN_BUFF_CTRL=1
-DXUD_PRIORITY_HIGH=1 -DXUD_PRIORITY_HIGH=1
-ldnr_50ms #-ldnr_50ms
-DDEBUG_MEMORY_LOG_ENABLED=1 -DDEBUG_MEMORY_LOG_ENABLED=1
-DNO_LOG_TIMESTAPS=0 -DNO_LOG_TIMESTAPS=0
-DI2S_CHANS_ADC=2) -DI2S_CHANS_ADC=2)

View File

@@ -118,8 +118,6 @@ timer tm;
#define C1_KEY_LONG_TICKS 50 #define C1_KEY_LONG_TICKS 50
// 改动原因:规格要求 mic 键长按 1.5s 切换 g_dnr_enableAI 通话降噪/DNR20ms*75=1.5s,与 mode 键 LONG 解耦,避免误触。 // 改动原因:规格要求 mic 键长按 1.5s 切换 g_dnr_enableAI 通话降噪/DNR20ms*75=1.5s,与 mode 键 LONG 解耦,避免误触。
#define C1_KEY_MIC_DNR_LONG_TICKS 75 #define C1_KEY_MIC_DNR_LONG_TICKS 75
// 改动原因:双击第二下需在首击释放后约 500ms 内按下否则判为单击静音20ms*25=500ms。
#define C1_MIC_DOUBLE_DEFER_TICKS 25
// 改动原因新增C1模式持久化文件路径使用LittleFS保存mode按键状态保证断电重启后可恢复。 // 改动原因新增C1模式持久化文件路径使用LittleFS保存mode按键状态保证断电重启后可恢复。
#define C1_MODE_VALUE_PATH "c1_mode_value" #define C1_MODE_VALUE_PATH "c1_mode_value"
@@ -130,9 +128,8 @@ timer tm;
// 改动原因DAC 音量单独持久化路径,与 mode 的 c1_mode 文件分离,避免互相覆盖且便于维护。 // 改动原因DAC 音量单独持久化路径,与 mode 的 c1_mode 文件分离,避免互相覆盖且便于维护。
#define C1_DAC_VOL_INFO_PATH "c1_dac_vol" #define C1_DAC_VOL_INFO_PATH "c1_dac_vol"
// 改动原因:麦克风按键三种状态(静音/变声/DNR均需断电保存上电恢复并同步LED显示。 // 改动原因:规格表仅保留静音与 DNR 断电记忆mic 指示灯只反映静音(红灯/灭DNR 由 APP 显示。
#define C1_MIC_MUTE_INFO_PATH "c1_mic_mute" #define C1_MIC_MUTE_INFO_PATH "c1_mic_mute"
#define C1_VOICE_FX_INFO_PATH "c1_voice_fx"
#define C1_DNR_EN_INFO_PATH "c1_dnr_en" #define C1_DNR_EN_INFO_PATH "c1_dnr_en"
// 改动原因:与 FORMAT_DELAY(30000000) 相同时间基准get_reference_time 滴答),用户停止调节 300ms 后再写 Flash减少磨损并满足需求。 // 改动原因:与 FORMAT_DELAY(30000000) 相同时间基准get_reference_time 滴答),用户停止调节 300ms 后再写 Flash减少磨损并满足需求。
#define C1_DAC_VOL_SAVE_DELAY (30000000) #define C1_DAC_VOL_SAVE_DELAY (30000000)
@@ -292,6 +289,7 @@ unsigned g_led_blink_is_white = 0;
extern unsigned char g_hid_pass_data[64]; extern unsigned char g_hid_pass_data[64];
static unsigned g_last_dac_vol = 0xFF; // 改动原因改为检测g_dac_vol的变化初始化为0xFF表示未初始化 static unsigned g_last_dac_vol = 0xFF; // 改动原因改为检测g_dac_vol的变化初始化为0xFF表示未初始化
static unsigned g_last_mute_switch = 0xFF; // 改动原因检测静音开关变化并上报0xB20xFF=未初始化 static unsigned g_last_mute_switch = 0xFF; // 改动原因检测静音开关变化并上报0xB20xFF=未初始化
static unsigned g_last_dnr_enable = 0xFF; // 改动原因检测AI通话降噪(g_dnr_enable)变化并上报0xB50xFF=未初始化
static unsigned g_last_adc_loop = 0xFF; // 改动原因:检测监听开关(g_adc_loop)变化并上报0xB40xFF=未初始化 static unsigned g_last_adc_loop = 0xFF; // 改动原因:检测监听开关(g_adc_loop)变化并上报0xB40xFF=未初始化
static unsigned g_last_audio_type = 0xFF; // 改动原因上次检测到的音频类型初始化为0xFF表示未初始化用于LED颜色判断 static unsigned g_last_audio_type = 0xFF; // 改动原因上次检测到的音频类型初始化为0xFF表示未初始化用于LED颜色判断
static unsigned g_last_led_status = 0xFF; // 上次检测到的LED状态初始化为0xFF表示未初始化 static unsigned g_last_led_status = 0xFF; // 上次检测到的LED状态初始化为0xFF表示未初始化
@@ -567,12 +565,8 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
unsigned vol_down_press_ticks = 0; unsigned vol_down_press_ticks = 0;
unsigned mic_mute_press_ticks = 0; unsigned mic_mute_press_ticks = 0;
unsigned vol_up_press_ticks = 0; unsigned vol_up_press_ticks = 0;
// 改动原因:mic 键双击需延迟首轮短按的静音动作,用 stage1=等超时单击 / stage2=已收到第二下按下等释放;与长按 DNR 互斥靠 mic_dnr_long_fired // 改动原因:规格取消双击变声mic_dnr_long_fired 用于长按 DNR 后屏蔽同次松手的短按静音
unsigned mic_dbl_stage = 0;
unsigned mic_defer_left = 0;
unsigned mic_dnr_long_fired = 0; unsigned mic_dnr_long_fired = 0;
// 改动原因:变声/美声仅按键+灯tile0 保存状态供 set_mic_voice_fx 下发 mic 橙灯。
unsigned c1_mic_voice_fx = 0;
// 改动原因mic mute红灯通过interface下发到tile1仅在状态变化时发送减少无意义跨tile调用。 // 改动原因mic mute红灯通过interface下发到tile1仅在状态变化时发送减少无意义跨tile调用。
unsigned last_mute_switch_for_led = 0xFFFFFFFF; unsigned last_mute_switch_for_led = 0xFFFFFFFF;
unsigned host_os = 0; unsigned host_os = 0;
@@ -652,32 +646,24 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
} }
// 改动原因:三种 mic 状态(静音/变声/DNR均需断电保存上电从 Flash 读取并恢复;无效値(非 0/1时使用默认値 // 改动原因:规格仅保留静音与 DNR 断电记忆;上电恢复后 mic 灯只同步静音态(红灯/灭)
{ {
unsigned char loaded_mute = load_value(C1_MIC_MUTE_INFO_PATH); unsigned char loaded_mute = load_value(C1_MIC_MUTE_INFO_PATH);
unsigned init_mute = (loaded_mute == 0 || loaded_mute == 1) ? (unsigned)loaded_mute : 1u; unsigned init_mute = (loaded_mute == 0 || loaded_mute == 1) ? (unsigned)loaded_mute : 1u;
SET_SHARED_GLOBAL(g_mute_switch, init_mute); SET_SHARED_GLOBAL(g_mute_switch, init_mute);
} }
{
unsigned char loaded_vfx = load_value(C1_VOICE_FX_INFO_PATH);
c1_mic_voice_fx = (loaded_vfx == 1) ? 1u : 0u;
}
{ {
unsigned char loaded_dnr = load_value(C1_DNR_EN_INFO_PATH); unsigned char loaded_dnr = load_value(C1_DNR_EN_INFO_PATH);
unsigned init_dnr = (loaded_dnr == 0 || loaded_dnr == 1) ? (unsigned)loaded_dnr : 1u; unsigned init_dnr = (loaded_dnr == 0 || loaded_dnr == 1) ? (unsigned)loaded_dnr : 1u;
SET_SHARED_GLOBAL(g_dnr_enable, init_dnr); SET_SHARED_GLOBAL(g_dnr_enable, init_dnr);
} }
// 改动原因tile1 上电已硬件全灯;先下发三种mic状态再下发 mode使首帧 apply 时 mic 正确。 // 改动原因tile1 上电已硬件全灯;先下发 mic 静音灯再下发 mode使首帧 apply 时 mic 正确。
{ {
unsigned init_mute_for_led; unsigned init_mute_for_led;
unsigned init_dnr_for_led;
GET_SHARED_GLOBAL(init_mute_for_led, g_mute_switch); GET_SHARED_GLOBAL(init_mute_for_led, g_mute_switch);
GET_SHARED_GLOBAL(init_dnr_for_led, g_dnr_enable);
i_c1_led_ctrl.set_mic_mute_state(init_mute_for_led); i_c1_led_ctrl.set_mic_mute_state(init_mute_for_led);
i_c1_led_ctrl.set_mode_led_color(c1_mode_to_tile_mode_led_code(c1_mode)); i_c1_led_ctrl.set_mode_led_color(c1_mode_to_tile_mode_led_code(c1_mode));
i_c1_led_ctrl.set_mic_voice_fx(c1_mic_voice_fx);
i_c1_led_ctrl.set_mic_dnr_state(init_dnr_for_led);
last_mute_switch_for_led = init_mute_for_led; last_mute_switch_for_led = init_mute_for_led;
} }
@@ -924,51 +910,8 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
vol_up_pressed = ((button_state & C1_KEY_VOL_UP_MASK) == 0); vol_up_pressed = ((button_state & C1_KEY_VOL_UP_MASK) == 0);
pressed_count = mode_pressed + vol_down_pressed + mic_mute_pressed + vol_up_pressed; pressed_count = mode_pressed + vol_down_pressed + mic_mute_pressed + vol_up_pressed;
// 改动原因mic 首击短按后延迟 500ms 再静音,以便识别双击;仅 mic 松开时递减 mic_defer_left到 0 执行单击静音。
if (mic_dbl_stage == 1 && mic_defer_left > 0)
{
unsigned mic_released_now = ((button_state & C1_KEY_MIC_MUTE_MASK) != 0);
if (mic_released_now)
{
mic_defer_left--;
if (mic_defer_left == 0)
{
unsigned current_mute_switch;
unsigned effective_adc_vol;
GET_SHARED_GLOBAL(effective_adc_vol, g_adc_vol);
GET_SHARED_GLOBAL(current_mute_switch, g_mute_switch);
current_mute_switch = (current_mute_switch == 0) ? 1 : 0;
if (current_mute_switch == 0)
{
mic_volume(0, i2c);
// 改动原因:同步 old_adc_vol避免定时器下一轮仍按旧值误判或与按键写入冲突。
old_adc_vol = 0;
}
else
{
mic_volume(effective_adc_vol, i2c);
old_adc_vol = effective_adc_vol;
}
SET_SHARED_GLOBAL(g_mute_switch, current_mute_switch);
// 改动原因静音状态变化后立即保存到Flash保证断电后恢复正确的静音灯状态。
save_value(C1_MIC_MUTE_INFO_PATH, (unsigned char)current_mute_switch);
i_c1_led_ctrl.set_mic_mute_state(current_mute_switch);
last_mute_switch_for_led = current_mute_switch;
debug_printf("C1 key mic mute toggle (deferred single): %d\n", current_mute_switch);
mic_dbl_stage = 0;
}
}
}
if (pressed_count == 1) if (pressed_count == 1)
{ {
// 改动原因mic 双击等待期间若用户去按 mode/音量键,应取消延迟单击静音,避免误切 g_mute_switch。
if (!mic_mute_pressed)
{
mic_dbl_stage = 0;
mic_defer_left = 0;
}
if (mode_pressed) if (mode_pressed)
{ {
mode_press_ticks++; mode_press_ticks++;
@@ -987,22 +930,14 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
} }
else if (mic_mute_pressed) else if (mic_mute_pressed)
{ {
// 改动原因:双击窗口内第二下按下,取消延迟单击静音,改为等待释放后判双击变声。
if (mic_dbl_stage == 1)
{
mic_defer_left = 0;
mic_dbl_stage = 2;
}
mic_mute_press_ticks++; mic_mute_press_ticks++;
// 改动原因:按住满 1.5s 翻转 g_dnr_enableextra_i2s 中 GET_SHARED_GLOBAL 决定是否走 DNR松手时靠 mic_dnr_long_fired 屏蔽短按/双击 // 改动原因:规格长按1.5s切换AI通话降噪无指示灯保存Flashg_dnr_enable变化由定时器路径HID 0xB5上报APP
if (mic_mute_press_ticks == C1_KEY_MIC_DNR_LONG_TICKS) if (mic_mute_press_ticks == C1_KEY_MIC_DNR_LONG_TICKS)
{ {
unsigned dnr_enable; unsigned dnr_enable;
GET_SHARED_GLOBAL(dnr_enable, g_dnr_enable); GET_SHARED_GLOBAL(dnr_enable, g_dnr_enable);
dnr_enable = (dnr_enable != 0) ? 0 : 1; dnr_enable = (dnr_enable != 0) ? 0 : 1;
SET_SHARED_GLOBAL(g_dnr_enable, dnr_enable); SET_SHARED_GLOBAL(g_dnr_enable, dnr_enable);
// 改动原因DNR状态变化后立即下发LED开亮蓝灯/关灯并保存到Flash供断电恢复。
i_c1_led_ctrl.set_mic_dnr_state(dnr_enable);
save_value(C1_DNR_EN_INFO_PATH, (unsigned char)dnr_enable); save_value(C1_DNR_EN_INFO_PATH, (unsigned char)dnr_enable);
mic_dnr_long_fired = 1; mic_dnr_long_fired = 1;
debug_printf("C1 mic DNR toggle (hold 1.5s): %d\n", dnr_enable); debug_printf("C1 mic DNR toggle (hold 1.5s): %d\n", dnr_enable);
@@ -1059,33 +994,34 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
} }
} }
// 改动原因:mic短按静音延迟单击防双击双击变声 mic 橙灯长按1.5s 切 g_dnr_enable 无灯;长按与短/双互斥 // 改动原因:规格短按立即切换静音(红灯/灭灯长按1.5s已切DNR则屏蔽同次松手短按
{ {
unsigned mic_snap = mic_mute_press_ticks; unsigned mic_snap = mic_mute_press_ticks;
if (mic_snap > 0) if (mic_snap > 0)
{ {
if ((mic_snap >= C1_KEY_MIC_DNR_LONG_TICKS) || mic_dnr_long_fired) if ((mic_snap >= C1_KEY_SHORT_TICKS) && (mic_snap < C1_KEY_MIC_DNR_LONG_TICKS) && !mic_dnr_long_fired)
{ {
if (mic_dbl_stage == 2) unsigned current_mute_switch;
mic_dbl_stage = 0; unsigned effective_adc_vol;
} GET_SHARED_GLOBAL(effective_adc_vol, g_adc_vol);
else if ((mic_snap >= C1_KEY_SHORT_TICKS) && (mic_snap < C1_KEY_MIC_DNR_LONG_TICKS)) GET_SHARED_GLOBAL(current_mute_switch, g_mute_switch);
{ current_mute_switch = (current_mute_switch == 0) ? 1 : 0;
if (mic_dbl_stage == 2)
if (current_mute_switch == 0)
{ {
c1_mic_voice_fx = (c1_mic_voice_fx ? 0 : 1); mic_volume(0, i2c);
i_c1_led_ctrl.set_mic_voice_fx(c1_mic_voice_fx); old_adc_vol = 0;
// 改动原因变声状态变化后立即保存到Flash保证断电后恢复正确的变声灯状态。
save_value(C1_VOICE_FX_INFO_PATH, (unsigned char)c1_mic_voice_fx);
mic_dbl_stage = 0;
mic_defer_left = 0;
debug_printf("C1 mic voice/beautifier toggle: %d\n", c1_mic_voice_fx);
} }
else else
{ {
mic_dbl_stage = 1; mic_volume(effective_adc_vol, i2c);
mic_defer_left = C1_MIC_DOUBLE_DEFER_TICKS; old_adc_vol = effective_adc_vol;
} }
SET_SHARED_GLOBAL(g_mute_switch, current_mute_switch);
save_value(C1_MIC_MUTE_INFO_PATH, (unsigned char)current_mute_switch);
i_c1_led_ctrl.set_mic_mute_state(current_mute_switch);
last_mute_switch_for_led = current_mute_switch;
debug_printf("C1 key mic mute toggle (short press): %d\n", current_mute_switch);
} }
mic_dnr_long_fired = 0; mic_dnr_long_fired = 0;
} }
@@ -1115,13 +1051,6 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
} }
} }
} }
else if (pressed_count > 1)
{
// 改动原因:多键同按时取消 mic 双击等待,避免组合键松手后误触发延迟静音。
mic_dbl_stage = 0;
mic_defer_left = 0;
}
// 改动原因:多键同时按下不映射功能,立即清除本轮计时,避免组合键抖动误触发单键动作。 // 改动原因:多键同时按下不映射功能,立即清除本轮计时,避免组合键抖动误触发单键动作。
mode_press_ticks = 0; mode_press_ticks = 0;
vol_down_press_ticks = 0; vol_down_press_ticks = 0;
@@ -1257,6 +1186,26 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli
g_last_mute_switch = current_mute; g_last_mute_switch = current_mute;
} }
// 改动原因规格DNR无指示灯按键长按切换后通过HID 0xB5主动上报APP与0xB4监听开关上报方式一致
{
unsigned current_dnr;
GET_SHARED_GLOBAL(current_dnr, g_dnr_enable);
if (g_last_dnr_enable != current_dnr && g_last_dnr_enable != 0xFF)
{
unsafe
{
unsigned char * unsafe reportPtr = g_hid_pass_data;
reportPtr[0] = 0x77;
reportPtr[1] = 0xB5; // GET_DNR_ENABLE
reportPtr[2] = (unsigned char)current_dnr;
for (int i = 3; i < 63; i++) reportPtr[i] = 0x00;
hidSetChangePending(0x1);
}
debug_printf("DNR enable changed: %d -> %d, HID 0xB5 report prepared\n", g_last_dnr_enable, current_dnr);
}
g_last_dnr_enable = current_dnr;
}
// 改动原因:检测监听开关(g_adc_loop)状态变化如果变化则通过HID上报0xB4格式参考eq_hid_protocol.md // 改动原因:检测监听开关(g_adc_loop)状态变化如果变化则通过HID上报0xB4格式参考eq_hid_protocol.md
{ {
unsigned current_adc_loop; unsigned current_adc_loop;
@@ -1982,9 +1931,8 @@ static inline void c1_panel_leds_force_all_off_hw(void)
} }
// 改动原因c1_mode 与灯索引一致1=灯 2=蓝 3=绿 4=橙(R+G) 5=紫(R+B);仅驱动 mode 区p_leds bit2/3 + p_mode_led_blue不受 mic 变声影响。 // 改动原因c1_mode 与灯索引一致1=灯 2=蓝 3=绿 4=橙(R+G) 5=紫(R+B);仅驱动 mode 区p_leds bit2/3 + p_mode_led_blue不受 mic 变声影响。
// 改动原因mic 区灯优先级:静音=只亮红灯(覆盖变声/DNR非静音时变声=橙(p_mic_mute_led_red+R+bit0绿)DNR=蓝(p_leds bit1) // 改动原因:规格 mic 区灯仅反映静音——静音红灯常亮非静音含DNR开/关全灭DNR状态由APP显示。
// 两者同开=橙+蓝混合,两者均关=全灯。 static inline void apply_c1_panel_leds(unsigned mode_led_color_idx, unsigned mic_mute_switch, unsigned &led_shadow)
static inline void apply_c1_panel_leds(unsigned mode_led_color_idx, unsigned mic_mute_switch, unsigned mic_voice_fx_on, unsigned mic_dnr_on, unsigned &led_shadow)
{ {
unsigned mode_red = 0; unsigned mode_red = 0;
unsigned mode_green = 0; unsigned mode_green = 0;
@@ -1993,17 +1941,11 @@ static inline void apply_c1_panel_leds(unsigned mode_led_color_idx, unsigned mic
unsigned mic_green = 0; unsigned mic_green = 0;
unsigned mic_blue = 0; unsigned mic_blue = 0;
// 改动原因:静音优先——静音(mic_mute_switch==0)时只亮红灯屏蔽变声橙灯和DNR蓝灯 // 改动原因:规格表——开启静音红灯常亮,关闭静音/正常工作无指示灯。
// 关闭静音后恢复为变声/DNR/混合/全灯的组合状态,满足“关闭静音时回到其他模式的灯颜色”需求。
if (mic_mute_switch == 0) { if (mic_mute_switch == 0) {
mic_red = 1; mic_red = 1;
mic_green = 0; mic_green = 0;
mic_blue = 0; mic_blue = 0;
} else {
// 改动原因:变声=橙(R+G)DNR=蓝,两者同时开=橙+蓝混合,两者均关=全灯。
mic_red = mic_voice_fx_on ? 1 : 0;
mic_green = mic_voice_fx_on ? 1 : 0;
mic_blue = mic_dnr_on ? 1 : 0;
} }
if (mode_led_color_idx == 1) { if (mode_led_color_idx == 1) {
@@ -2027,7 +1969,7 @@ static inline void apply_c1_panel_leds(unsigned mode_led_color_idx, unsigned mic
} }
// 改动原因:硬件 mic/mode RGB 对调后,低四位 bit0~3 分别为 mic mute绿、mic mute蓝、mode红、mode绿统一刷新。 // 改动原因:硬件 mic/mode RGB 对调后,低四位 bit0~3 分别为 mic mute绿、mic mute蓝、mode红、mode绿统一刷新。
// 改动原因p_mic_mute_led_red 由 mic_red 驱动,静音/变声时亮红灯输出0=亮DNR 蓝灯改由 p_leds bit1 驱动 // 改动原因p_mic_mute_led_red 由 mic_red 驱动输出0=亮mic 区绿/蓝仅规格静音态使用,非静音恒灭
p_mic_mute_led_red <: (mic_red ? 0 : 1); p_mic_mute_led_red <: (mic_red ? 0 : 1);
led_shadow &= ~0xF; led_shadow &= ~0xF;
led_shadow |= (mic_green ? 0x0 : 0x1); led_shadow |= (mic_green ? 0x0 : 0x1);
@@ -2044,10 +1986,6 @@ void app_control_slave(server interface c1_led_ctrl_if i_c1_led_ctrl, chanend c_
unsigned led_shadow = 0xF; unsigned led_shadow = 0xF;
unsigned mode_led_color_idx = 1; unsigned mode_led_color_idx = 1;
unsigned mic_mute_switch = 1; unsigned mic_mute_switch = 1;
// 改动原因:变声/美声开时 p_mic_mute_led_red + p_leds bit0 显橙,与 set_mode_led_color 下发的 mode 灯独立;此处状态与 tile0 set_mic_voice_fx 同步。
unsigned mic_voice_fx_on = 0;
// 改动原因AI通话降噪DNR开时点亮 p_leds bit1 mic mute 蓝灯;与变声同时开时橙+蓝混合;静音优先在 apply 内部处理。
unsigned mic_dnr_on = 0;
c1_panel_leds_force_all_off_hw(); c1_panel_leds_force_all_off_hw();
unsigned eq_mode_time = 0; unsigned eq_mode_time = 0;
@@ -2070,20 +2008,11 @@ void app_control_slave(server interface c1_led_ctrl_if i_c1_led_ctrl, chanend c_
mode_led_color_idx = color_idx; mode_led_color_idx = color_idx;
if (mode_led_color_idx > 5 || mode_led_color_idx < 1) if (mode_led_color_idx > 5 || mode_led_color_idx < 1)
mode_led_color_idx = C1_MODE_VALUE_DEFAULT; mode_led_color_idx = C1_MODE_VALUE_DEFAULT;
apply_c1_panel_leds(mode_led_color_idx, mic_mute_switch, mic_voice_fx_on, mic_dnr_on, led_shadow); apply_c1_panel_leds(mode_led_color_idx, mic_mute_switch, led_shadow);
break; break;
case i_c1_led_ctrl.set_mic_mute_state(unsigned mute_state): case i_c1_led_ctrl.set_mic_mute_state(unsigned mute_state):
mic_mute_switch = (mute_state != 0) ? 1 : 0; mic_mute_switch = (mute_state != 0) ? 1 : 0;
apply_c1_panel_leds(mode_led_color_idx, mic_mute_switch, mic_voice_fx_on, mic_dnr_on, led_shadow); apply_c1_panel_leds(mode_led_color_idx, mic_mute_switch, led_shadow);
break;
case i_c1_led_ctrl.set_mic_voice_fx(unsigned voice_fx_enabled):
mic_voice_fx_on = (voice_fx_enabled != 0) ? 1 : 0;
apply_c1_panel_leds(mode_led_color_idx, mic_mute_switch, mic_voice_fx_on, mic_dnr_on, led_shadow);
break;
case i_c1_led_ctrl.set_mic_dnr_state(unsigned dnr_enabled):
// 改动原因:接收 tile0 按键逻辑下发的 DNR 状态,刷新 mic 区蓝灯;静音优先在 apply 内部处理。
mic_dnr_on = (dnr_enabled != 0) ? 1 : 0;
apply_c1_panel_leds(mode_led_color_idx, mic_mute_switch, mic_voice_fx_on, mic_dnr_on, led_shadow);
break; break;
} }
} }

View File

@@ -147,6 +147,7 @@ static struct {
bool is_get_firmware_version_request; // 改动原因添加获取固件版本请求标志用于GET_FIRMWARE_VERSION (0xA6) bool is_get_firmware_version_request; // 改动原因添加获取固件版本请求标志用于GET_FIRMWARE_VERSION (0xA6)
bool is_get_mute_switch_request; // 改动原因添加获取静音开关请求标志用于GET_MUTE_SWITCH (0xB2)值由MCU通过UART 0x5F返回 bool is_get_mute_switch_request; // 改动原因添加获取静音开关请求标志用于GET_MUTE_SWITCH (0xB2)值由MCU通过UART 0x5F返回
bool is_get_listen_switch_request; // 改动原因添加获取监听开关请求标志用于GET_LISTEN_SWITCH (0xB4),直接读 g_adc_loop bool is_get_listen_switch_request; // 改动原因添加获取监听开关请求标志用于GET_LISTEN_SWITCH (0xB4),直接读 g_adc_loop
bool is_get_dnr_enable_request; // 改动原因添加获取AI通话降噪请求标志用于GET_DNR_ENABLE (0xB5),直接读 g_dnr_enable
int32_t post_gain_db; int32_t post_gain_db;
} read_request = {0}; } read_request = {0};
@@ -1525,6 +1526,14 @@ unsigned char process_send_params(uint8_t data[], uint16_t len) {
return true; return true;
} }
// 处理获取AI通话降噪开关命令 (0xB5) - GET_DNR_ENABLE
// 改动原因:规格 mic 键长按切换 DNR 无指示灯APP 通过 HID 0xB5 读取/接收主动上报 g_dnr_enable
if (data[1] == 0xB5) {
debug_printf("Received get DNR enable command (GET_DNR_ENABLE) via HID 0xB5\n");
read_request.is_get_dnr_enable_request = true;
return true;
}
// 处理获取当前UAC模式命令 (0x9C) - GET_CURRENT_UAC_MODE // 处理获取当前UAC模式命令 (0x9C) - GET_CURRENT_UAC_MODE
// 改动原因添加当前UAC模式查询命令返回当前UAC模式值和名称 // 改动原因添加当前UAC模式查询命令返回当前UAC模式值和名称
if (data[1] == 0x9C) { if (data[1] == 0x9C) {
@@ -3146,6 +3155,21 @@ unsigned char process_read_params(uint8_t response[]) {
return true; return true;
} }
// 处理获取AI通话降噪开关请求 (0xB5) - GET_DNR_ENABLE
// 改动原因:直接读取 g_dnr_enable 返回;按键长按切换后 audiohw 主动上报同格式 0x77 0xB5 + 1字节
if (read_request.is_get_dnr_enable_request == true) {
unsigned dnr_en;
extern unsigned g_dnr_enable;
GET_SHARED_GLOBAL(dnr_en, g_dnr_enable);
response[0] = 0x77;
response[1] = 0xB5;
response[2] = (uint8_t)(dnr_en & 0xFF); // 0=关 1=开
for (int i = 3; i < 63; i++) response[i] = 0x00;
read_request.is_get_dnr_enable_request = false;
debug_printf("Building 0xB5 response (GET_DNR_ENABLE), g_dnr_enable=%u\n", dnr_en);
return true;
}
if (read_request.is_read_request == true) { if (read_request.is_read_request == true) {
#if 1 // 改动原因fosi_c1 使用 -DUAC1=1 编译,原 #if !UAC1 导致 0x8E 读EQ参数在 HID GET_REPORT 时永不组包eq_designer 收到全零响应 #if 1 // 改动原因fosi_c1 使用 -DUAC1=1 编译,原 #if !UAC1 导致 0x8E 读EQ参数在 HID GET_REPORT 时永不组包eq_designer 收到全零响应
debug_printf("Read request information:\n"); debug_printf("Read request information:\n");

View File

@@ -9,13 +9,8 @@
interface c1_led_ctrl_if { interface c1_led_ctrl_if {
// 改动原因:与 c1_mode 同值下发 tile11=灭 2=蓝 3=绿 4=橙 5=紫(灯索引即 mode // 改动原因:与 c1_mode 同值下发 tile11=灭 2=蓝 3=绿 4=橙 5=紫(灯索引即 mode
void set_mode_led_color(unsigned color_idx); void set_mode_led_color(unsigned color_idx);
void set_mic_mute_state(unsigned mute_switch); // mute_switch: 0=静音(亮红), 1=非静音(灭红) // 改动原因:规格 mic 指示灯仅反映静音——0=静音红灯常亮1=非静音全灭DNR 无灯由 APP 显示。
// 改动原因:硬件 mic/mode RGB 对调后,变声/美声开时 tile1 点亮 mic 区p_mic_mute_led_red 红 + p_leds bit0 绿(橙);关时仅按静音规则驱动 mic 区熄灭。 void set_mic_mute_state(unsigned mute_switch);
// 改动原因:参数名不能用 xC 保留字 onon tile[:]: 语法),否则编译器在解析 interface 时报 parse error before "on"。
void set_mic_voice_fx(unsigned voice_fx_enabled);
// 改动原因麦克风键长按1.5s切换AI通话降噪(DNR),开时点亮 p_leds bit1 mic mute 蓝灯;
// 与变声同时开时橙+蓝混合静音优先静音时所有mic灯被红灯取代。断电需保存。
void set_mic_dnr_state(unsigned dnr_enabled);
}; };
void switch_handler(void); void switch_handler(void);
void flag_handler(); void flag_handler();