mic detection

This commit is contained in:
Steven Dan
2026-04-09 14:30:04 +08:00
parent f1c0084325
commit 35846cffd3
3 changed files with 108 additions and 13 deletions

View File

@@ -53,7 +53,7 @@
<Port Location="XS1_PORT_1A" Name="PORT_I2S_ADC0"/> <!-- orig 1I, Synido 1A -->
<Port Location="XS1_PORT_4A" Name="PORT_CTL_MUTE"/> <!-- Tile1 4D0 -->
<Port Location="XS1_PORT_4D" Name="PORT_CTL_MUTE2"/> <!-- Tile1 4D0 -->
<Port Location="XS1_PORT_4D" Name="PORT_CTL_DET"/> <!-- Tile1 4D0 -->
</Tile>
</Node>

View File

@@ -107,6 +107,10 @@ unsigned g_dac_mode = 10;
unsigned g_new_dac_mode = 0;
unsigned g_samfreq = 48000;
unsigned g_dsd_mode = 0;
// mic detect events: mute_handler (tile[1]) → button_task (tile[0])
#define MIC_DET_MUTE 1 // mic插入或全拔出立即mute
#define MIC_DET_UNMUTE 2 // 插入1s后恢复音量
unsafe chanend uc_audiohw; // tile[1] end: AudioHwConfig → button_task (tile[0])
#if HID_DFU_EN
unsafe streaming chanend uc_dfu; // tile[1] send end: hid_button_task → button_task (tile[0])
@@ -150,7 +154,7 @@ port p_sda = PORT_I2C_SDA;
//out port p_htr3235_sdb = PORT_HTR3236_SDB; /* 连接到HTR3236的SDB引脚用于控制其电源状态 */
out port p_ctl_mute = PORT_CTL_MUTE;
out port p_ctl_mute2 = PORT_CTL_MUTE2;
in port p_ctl_det = PORT_CTL_DET;
/* Board setup for XU316 MC Audio (1v1) */
@@ -328,6 +332,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
#if HID_DFU_EN
, streaming chanend c_dfu_rx
#endif
, chanend c_mic_det
)
{
//hwtimer_t timer = hwtimer_alloc();
@@ -397,6 +402,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
unsigned flag_mic_mute = 0;
unsigned flag_hp_mute = 0;
unsigned mic_det_muted = 0; // mic检测导致的mute不影响LED和g_mic_volume_level
unsigned push_button_mic_mute_state_old = 1; // Active low
unsigned push_button_hp_mute_state_old = 1; // Active low
@@ -943,6 +949,24 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
}
#endif
case c_mic_det :> unsigned mic_det_cmd:
{
if (mic_det_cmd == MIC_DET_MUTE) {
mic_det_muted = 1;
// 仅mute硬件不改变g_mic_volume_level和LED
mic_volume(0);
debug_printf("mic_det: mute (det)\n");
} else if (mic_det_cmd == MIC_DET_UNMUTE) {
mic_det_muted = 0;
// 恢复音量但如果用户手动mute了则不恢复
if (!flag_mic_mute) {
mic_volume(codec_adc_pga_gain_reg_value);
debug_printf("mic_det: unmute -> pga=%d\n", codec_adc_pga_gain_reg_value);
}
}
break;
}
case tmr when timerafter(time) :> void :
{
//hwtimer_change_trigger_time(timer, hwtimer_get_time(timer) + KEY_POLLING_INTERVAL);
@@ -1389,7 +1413,8 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
}
else
{
mic_volume(codec_adc_pga_gain_reg_value);
if (!mic_det_muted)
mic_volume(codec_adc_pga_gain_reg_value);
g_mic_volume_level = (codec_adc_pga_gain_reg_value <= 37) ? codec_adc_pga_gain_reg_value : 37;
mic_mute_blink_tick = 0;
for(int i = 0; i < 15; i++)
@@ -1432,7 +1457,9 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
uint8_t old_led_count = mic_gain_to_led[codec_adc_pga_gain_reg_value];
// 增加音量
mic_volume(++codec_adc_pga_gain_reg_value);
++codec_adc_pga_gain_reg_value;
if (!mic_det_muted)
mic_volume(codec_adc_pga_gain_reg_value);
g_mic_volume_level = (codec_adc_pga_gain_reg_value <= 37) ? codec_adc_pga_gain_reg_value : 37;
debug_printf("volume up %d\n", codec_adc_pga_gain_reg_value);
save_value(mic_vol_path, codec_adc_pga_gain_reg_value);
@@ -1450,7 +1477,9 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
uint8_t old_led_count = mic_gain_to_led[codec_adc_pga_gain_reg_value];
// 减小音量
mic_volume(--codec_adc_pga_gain_reg_value);
--codec_adc_pga_gain_reg_value;
if (!mic_det_muted)
mic_volume(codec_adc_pga_gain_reg_value);
g_mic_volume_level = (codec_adc_pga_gain_reg_value <= 37) ? codec_adc_pga_gain_reg_value : 37;
debug_printf("volume down %d\n", codec_adc_pga_gain_reg_value);
save_value(mic_vol_path, codec_adc_pga_gain_reg_value);
@@ -1714,7 +1743,8 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
new_led_count = 0;
} else {
codec_adc_pga_gain_reg_value = new_mic_level;
mic_volume(codec_adc_pga_gain_reg_value);
if (!mic_det_muted)
mic_volume(codec_adc_pga_gain_reg_value);
new_led_count = mic_gain_to_led[codec_adc_pga_gain_reg_value];
}
save_value(mic_vol_path, (unsigned char)codec_adc_pga_gain_reg_value);
@@ -1910,6 +1940,7 @@ void AudioHwRemote(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vo
#if HID_DFU_EN
, streaming chanend c_dfu_rx
#endif
, chanend c_mic_det
)
{
i2c_master_if i2c[1];
@@ -1922,6 +1953,7 @@ void AudioHwRemote(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vo
#if HID_DFU_EN
, c_dfu_rx
#endif
, c_mic_det
);
}
}
@@ -1973,11 +2005,72 @@ void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned s
}
void mute_handler()
void mute_handler(chanend c_mic_det)
{
// 开机mute sequence
p_ctl_mute <: 0;
p_ctl_mute2 <: 0;
delay_milliseconds(1000);
p_ctl_mute <: 0xf;
p_ctl_mute2 <: 0xf;
// mic detect: bit1=mic1 (插入=高, 拔出=低), bit2=mic2 (插入=低, 拔出=高)
unsigned det_val;
p_ctl_det :> det_val;
unsigned mic1_in = (det_val >> 1) & 1; // bit1: 1=inserted
unsigned mic2_in = ((det_val >> 2) & 1) ^ 1; // bit2: 0=inserted, invert
unsigned any_mic_in = mic1_in || mic2_in;
unsigned prev_any_mic_in = any_mic_in;
// 如果开机时全拔出发送mute
if (!any_mic_in) {
c_mic_det <: (unsigned)MIC_DET_MUTE;
}
timer tmr;
unsigned time;
tmr :> time;
#define MIC_DET_POLL_MS 10
time += MIC_DET_POLL_MS * 100000; // 10ms in 100MHz ticks
while (1) {
select {
case tmr when timerafter(time) :> void:
{
time += MIC_DET_POLL_MS * 100000;
p_ctl_det :> det_val;
mic1_in = (det_val >> 1) & 1;
mic2_in = ((det_val >> 2) & 1) ^ 1;
any_mic_in = mic1_in || mic2_in;
if (any_mic_in != prev_any_mic_in) {
// 状态变化立即mute防止pop音
c_mic_det <: (unsigned)MIC_DET_MUTE;
debug_printf("mic det change: mic1=%d mic2=%d -> mute\n", mic1_in, mic2_in);
// 等1s让插拔稳定
delay_milliseconds(1000);
// 重新读取稳定状态
p_ctl_det :> det_val;
mic1_in = (det_val >> 1) & 1;
mic2_in = ((det_val >> 2) & 1) ^ 1;
any_mic_in = mic1_in || mic2_in;
if (any_mic_in) {
// 有mic插入恢复音量
c_mic_det <: (unsigned)MIC_DET_UNMUTE;
debug_printf("mic stable inserted -> unmute\n");
}
// 全拔出则保持mute不发UNMUTE
prev_any_mic_in = any_mic_in;
// 重新同步timer
tmr :> time;
time += MIC_DET_POLL_MS * 100000;
}
break;
}
}
}
}

View File

@@ -432,9 +432,9 @@ extern int dsp_worker_tile(chanend c_dsp_to_ex3d, int worker_id);
extern void ex3d_task();
extern void hid_button_task(chanend cc_mic_level, chanend c_hid, chanend c_hidSendData, chanend c_uac_vol, chanend c_ex3d_hid_cmd);
#if HID_DFU_EN
extern void AudioHwRemote(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, chanend c_audiohw_rx, streaming chanend c_dfu_rx);
extern void AudioHwRemote(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, chanend c_audiohw_rx, streaming chanend c_dfu_rx, chanend c_mic_det);
#else
extern void AudioHwRemote(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, chanend c_audiohw_rx);
extern void AudioHwRemote(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, chanend c_audiohw_rx, chanend c_mic_det);
#endif
extern void dnr_dsp_proc_task(void);
@@ -447,7 +447,7 @@ extern unsafe streaming chanend uc_dfu;
#endif
extern void key_sender(chanend c_key);
extern void key_receiver(chanend c_key);
extern void mute_handler();
extern void mute_handler(chanend c_mic_det);
/* Main for USB Audio Applications */
@@ -551,6 +551,7 @@ int main()
chan c_eq_data;
chan c_uac_vol;
chan c_ex3d_hid_cmd;
chan c_mic_det;
par
{
@@ -579,7 +580,7 @@ int main()
}
}
on tile[1]: mute_handler();
on tile[1]: mute_handler(c_mic_det);
on tile[0] : {
par {
@@ -591,6 +592,7 @@ int main()
#if HID_DFU_EN
, c_dfu
#endif
, c_mic_det
);
}
}