#if UART_DEBUG || DEBUG_MEMORY_LOG_ENABLED
#define DEBUG_PRINT_ENABLE 1
#else
#define DEBUG_PRINT_ENABLE 0
#endif
//#define  DISABLE_REBOOT 1

#include <xs1.h>
#include <assert.h>
#include <platform.h>
#include "xassert.h"
#include "i2c.h"
#include "xua.h"
#include <print.h>
#include "xc_ptr.h"
#include "user_uart.h"
#include "debug_print.h"
#include "roleswitchflag.h"
#include "xua_hid_report.h"
#include "lfs_io.h"

#if defined (CODEC_AIC3204)
#include "eq_flash_storage.h"
#include "codec_ti3204.h"
#else
#error "No codec selected"
#endif

extern "C" {
    #include "sw_pll.h"
}

#include "xc_ptr.h"
unsigned g_ch0_level = 0;
unsigned g_ch1_level = 0;

#define NAU88C25 0

#if NAU88C25
#include "nau88c25.h"
#else
#include "nau88c21.h"
#endif

#if NAU88C25
#define NAU88_I2C_DEVICE_ADDR 0x15
#else
#define NAU88_I2C_DEVICE_ADDR 0x1B
#endif

#include "htr3236.h"
#include "led_control.h"
#include "xmath/scalar/f32.h"

#include "dnr_dsp_buf.h"

#include "xua_hid_report.h"

#if (XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM) && (XUA_I2S_N_BITS != 32)
#warning ADC only supports TDM operation at 32 bits
#endif

#ifndef I2S_LOOPBACK
#define I2S_LOOPBACK             (0)
#endif


#if UAC1
unsigned g_uac_mode = 1; // 2 for UAC2.0, 1 for UAC1.0
#else
unsigned g_uac_mode = 2; // 2 for UAC2.0, 1 for UAC1.0
#endif

unsafe client interface i2c_master_if i_i2c_client;
audio_sampling g_new_playback_format, g_playback_format;
audio_type g_new_audio_type, g_audio_type = 0;
unsigned g_mute_enable = 0;
unsigned g_mute_state = 0;
unsigned g_mute_state_old = 1;
unsigned g_unmute_dac_state, g_unmute_time,  g_format_time;
unsigned g_volume_level = 29, g_saved_volume_level = 29;
unsigned g_request_volume_set = 0;
unsigned g_init_saved_settings = 0;
unsigned g_host_volume = 0x0;
unsigned g_last_volume_level = 0xFF;  // 上次已上报的音量级别，0xFF表示初始化未完成
unsigned g_mic_volume_level = 37;     // 麦克风PGA增益级别（0=mute, 1-37=0dB~36dB，HID可见范围）
unsigned g_request_mic_volume_set = 0;
unsigned g_last_mic_volume_level = 0xFF;  // 上次已上报的麦克风增益级别，0xFF表示初始化未完成
unsigned g_dnr_strength = 100;            // AI降噪强度HID值（0=关，2-100=开，步进2；100→-200dB最强）
unsigned g_last_dnr_strength = 0xFF;      // 上次已上报的降噪强度，0xFF表示首次未上报（触发开机上报）
unsigned g_last_game_mode = 0xFF;         // 上次已上报的音效模式，0xFF表示首次未上报（触发开机上报）
unsigned g_request_dnr_strength_set = 0; // HID 0x85 SET_AI_NOISE_STRENGTH待处理标志
unsigned g_monitor_switch = 0;            // 耳返开关（0=关闭，1=开启），默认关闭
unsigned g_request_monitor_switch_set = 0; // HID 0x87 SET_MONITOR_SWITCH待处理标志
unsigned g_dac_m_gain = 0;
unsigned g_unmute_delay_time = 0;
unsigned g_format_delay_time = 0;
unsigned g_mclk_select = 0;
// 改动原因：添加LED开关全局变量，控制LED是否显示（0=关闭，1=开启）
unsigned g_led_enable = 1;  // LED开关，默认开启
// HID 0xB0 CMD_EXPAND_GAIN到达时由eq.c设置，button_task读取后更新footstep LED
// -1 (0xFFFFFFFF) 表示无待处理请求
unsigned g_hid_expand_gain_request = (unsigned)-1;
// HID 0xB0 CMD_LMT_THRESHOLD到达时由eq.c设置，button_task读取后保存到flash
// 存储值为-threshold (0~35)；-1 (0xFFFFFFFF) 表示无待处理请求
unsigned g_hid_lmt_threshold_request = (unsigned)-1;
// HID 0x84 FACTORY_RESET命令到达时由eq.c设置，button_task轮询后执行重启
unsigned g_request_factory_reset = 0;
uint32_t get_reference_time();
unsigned g_disable_i2c = 0;
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 mic
#define MIC_DET_UNMUTE     2  // 插入1s后恢复mic音量
#define MIC_DET_DAC_MUTE   3  // mic插入时mute DAC防pop
#define MIC_DET_DAC_UNMUTE 4  // 1s后恢复DAC音量

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])
#endif
// 改动原因：添加增益模式和滤波器模式的请求变量，用于HID命令设置模式
unsigned g_request_game_mode = -1;

#if EQ_EN
extern unsigned g_request_eq_mode, g_new_eq_mode;
#endif

// tile 1, 3d_on_off
#define LED_ON 0
#define LED_OFF 1
#define S3D_ON LED_ON
#define S3D_OFF LED_OFF

unsigned g_led_color = LED_OFF;
unsigned g_led_blink_count = 0;
unsigned g_led_blink_is_white = 0;

#define LED_OFF     0x7F  // 修改：清除最高位，只保留低7位
#define LED_RED     0b01011111  // 修改：清除最高位，只保留低7位
#define LED_GREEN   0b01101111  // 修改：清除最高位，只保留低7am
#define LED_BLUE    0b00111111  // 修改：清除最高位，只保留低7位
#define LED_YELLOW  (LED_RED & LED_GREEN)
#define LED_CYAN    (LED_GREEN & LED_BLUE)
#define LED_PURPLE  (LED_RED & LED_BLUE)
#define LED_WHITE   (LED_RED & LED_GREEN & LED_BLUE)
enum { OS_WIN = 1, OS_OTHERS = 2 };
// 改动原因：定义模式切换标志值，用于在SPATIAL_GAME、STEREO_8K、STEREO_2K、UAC1之间循环切换
#define MODE_F3_F4_FPS_UAC2         COAX_IN_FLAG   //1  SPATIAL_GAME模式标志
#define MODE_F5_MUSIC_UAC1          USB_IN_FLAG    // 2 F5 MUSIC
#define MODE_F1_MUSIC_UAC2          OPT_IN_FLAG    // 3 F1 MUSIC
#define MODE_F6_F7_FPS_UAC1         UAC1_IN_FLAG   // 4  STEREO_2K模式标志

/* All on tile[0] */
port p_scl = PORT_I2C_SCL;
port p_sda = PORT_I2C_SDA;

//out port p_htr3235_sdb = PORT_HTR3236_SDB; /* 连接到HTR3236的SDB引脚，用于控制其电源状态 */

out port p_ctl_mute = PORT_CTL_MUTE;
port p_ctl_det = PORT_CTL_DET;


/* Board setup for XU316 MC Audio (1v1) */
void board_setup()
{

}

// tile 0
// called on tile 0 - start
#define NAU88L21_PGA_GAIN_REG_MIN_USED_VALUE 0x0    // 0x1=1, 0dB (0x0, -1dB which is not used in this design)
#define NAU88L21_PGA_GAIN_REG_MAX_VALUE 0x25+1    // 0x25=37, 36dB. +1 is for extra 1.5dB digital gain
#define NAU88L21_PGA_GAIN_REG_DEFAULT_VALUE (NAU88L21_PGA_GAIN_REG_MAX_VALUE)

// DAC 监听音量控制范围: 共 30 级 (0~29)
// 0 = mute (全灭, reg 0x0034=0x0000), 1~29 = -28dB ~ 0dB，1dB/步
#define DAC_LEVEL_MIN  0   // mute，0 LEDs
#define DAC_LEVEL_MAX  29  // 0dB，15 LEDs
#define DAC_LEVEL_DEFAULT  DAC_LEVEL_MAX

static inline void NAU88C22_REGREAD(unsigned reg, unsigned &val, client interface i2c_master_if i2c)
{
    i2c_regop_res_t result;
    val = i2c.read_reg16(NAU88_I2C_DEVICE_ADDR, reg, result);
}

static inline i2c_regop_res_t NAU88C22_REGWRITE(unsigned reg, unsigned val, client interface i2c_master_if i2c)
{
    i2c_regop_res_t result = i2c.write_reg16(NAU88_I2C_DEVICE_ADDR, reg, val);

    if(result != I2C_REGOP_SUCCESS)
    {
        debug_printf("I2C write failed: reg=");
        printhex(reg);
        debug_printf(", val=");
        printhex(val);
        debug_printf("\n");
    }
    else
    {
        //debug_printf("I2C write success: reg=");
        //printhex(reg);
        //debug_printf(", val=");
        //printhex(val);
        //debug_printf("\n");
        //debug_printf(".");
    }

    return result;
}

void dac_volume(signed level)
{
    // 1dB/步: level 范围 -28 ~ 0，对应寄存器 0xcf-28=0xb3 ~ 0xcf
    unsigned tmp = 0xcf + level;
    unsafe {NAU88C22_REGWRITE(0x0034, (tmp<<8|tmp), (client interface i2c_master_if)i_i2c_client);}
}

void mic_volume(unsigned level)
{
    if (level == 0)
    {
        // mute: 关闭PGA和输出放大器
        unsafe {NAU88C22_REGWRITE(0x007E, 0, (client interface i2c_master_if)i_i2c_client);}
        unsafe {NAU88C22_REGWRITE(0x0035, 0, (client interface i2c_master_if)i_i2c_client);}
    }
    else if(level == NAU88L21_PGA_GAIN_REG_MAX_VALUE)
    {
        // 内部最大值 (reg=38, +1.5dB数字增益，仅firmware使用)
        // PGA设到最大(37=0x25)，数字增益额外+1.5dB
        unsafe {NAU88C22_REGWRITE(0x007E, (NAU88L21_PGA_GAIN_REG_MAX_VALUE-1) << 8, (client interface i2c_master_if)i_i2c_client);}
        unsafe {NAU88C22_REGWRITE(0x0035, (0xd2d2), (client interface i2c_master_if)i_i2c_client);}
    }
    else
    {
        // 1-37: 0dB ~ 36dB，1dB/步
        debug_printf("mic_volume write reg=%d\n", level);
        unsafe {NAU88C22_REGWRITE(0x007E, (level << 8), (client interface i2c_master_if)i_i2c_client);}
        unsafe {NAU88C22_REGWRITE(0x0035, (0xcfcf), (client interface i2c_master_if)i_i2c_client);}
    }
}

void codec_init(void)
{
	/*
     * Setup CODEC
     */
    uint16_t addr = 0, val;
    for (int i = 0; i < sizeof(nau88c22_registers) / sizeof(nau88c22_registers[0]); i++) {
        addr = nau88c22_registers[i][1];
        val = (nau88c22_registers[i][2] << 8) | nau88c22_registers[i][3];
        unsafe {NAU88C22_REGWRITE(addr, val, (client interface i2c_master_if)i_i2c_client);}
    }

    // ADCL PGA default setting
    if(NAU88L21_PGA_GAIN_REG_DEFAULT_VALUE == NAU88L21_PGA_GAIN_REG_MAX_VALUE)
        unsafe {NAU88C22_REGWRITE(0x007E, (NAU88L21_PGA_GAIN_REG_MAX_VALUE-1) << 8, (client interface i2c_master_if)i_i2c_client);}
    else
        unsafe {NAU88C22_REGWRITE(0x007E, NAU88L21_PGA_GAIN_REG_DEFAULT_VALUE << 8, (client interface i2c_master_if)i_i2c_client);}

    //debug_printfln("Codec init finished");
}

in port p_mic_gain_encoder1 = PORT_MIC_GAIN_ENCODER1;   // 4F2
in port p_mic_gain_encoder2 = PORT_MIC_GAIN_ENCODER2;   // 4E2

in port p_hp_gain_encoder = PORT_HP_GAIN_ENCODER;   // 8D4, 8D5

in port p_button_music_mode = PORT_BUTTON_MUSIC_MODE;   // 1A
in port p_button_game_mode = PORT_BUTTON_GAME_MODE;   // 1L
in port p_button_ai71_onoff = PORT_BUTTON_AI71_ONOFF;   // 1M

// <!-- Mic Encoder -->
// <Port Location="XS1_PORT_4F"  Name="PORT_MIC_GAIN_ENCODER1"/> <!-- 4F1: FOOTSTEPS ENHANCEMENT; 4F2: MIC_GAIN_ENCODER_INPUT_1; 4F3: MIC MUTE -->
// <Port Location="XS1_PORT_4E"  Name="PORT_MIC_GAIN_ENCODER2"/> <!-- 4E2: MIC_GAIN_ENCODER_INPUT_2; 4E3: AI DENOISE ONOFF -->
// <!-- HP Encoder -->
// <Port Location="XS1_PORT_8D"  Name="PORT_HP_GAIN_ENCODER"/> <!-- 8D4: HP_GAIN_ENCODER_INPUT_1; 8D5: HP_GAIN_ENCODER_INPUT_2; 8D6: HP MUTE -->
// <!-- Buttons -->
// <Port Location="XS1_PORT_1A"  Name="PORT_BUTTON_MUSIC_MODE"/>
// <Port Location="XS1_PORT_1L"  Name="PORT_BUTTON_GAME_MODE"/>
// <Port Location="XS1_PORT_1M"  Name="PORT_BUTTON_AI71_ONOFF"/>

#define KEY_POLLING_INTERVAL 10000000L       // 100ms polling interval
#define     TIMER_PERIOD    (100000)
#define FACTORY_RESET_HOLD_TICKS  3000   // 3000 × 1ms = 3秒
#define FACTORY_RESET_BLINK_TICKS  400   // 每相400ms
#define MUTE_BLINK_HALF_PERIOD       500   // mute LED blink half period 250ms
#define BTN_COMBO_DELAY_TICKS      40    // 单键去抖/组合检测窗口（50ms）

unsigned g_windows_detect_done = 0;

#define MUTE_ON 1
#define MUTE_OFF 0

extern unsigned g_host_os;  // 1 -> Windows, 2 -> Others
extern unsigned g_mute_on_off_t0;
extern unsigned g_uac_vol;
extern void dnr_set_mode(unsigned char mode);
extern void dnr_set_strength_level(unsigned char strength);

extern void device_reboot(void);

void save_value(unsigned char * unsafe path, unsigned char value);
unsigned char load_value(unsigned char * unsafe path);

enum {IR_OFF=0, IR_GAME=1, IR_MUSIC=2, IR_MOVIE=3, IR_7_1_GAME=4, IR_7_1_MUSIC=5, IR_7_1_MOVIE=6};

#ifndef HID_MAX_DATA_BYTES
#define HID_MAX_DATA_BYTES ( 64 )
#endif
extern unsigned hidSendData[];

#if HID_DFU_EN
#include "dfu_upgrade.h"
/* 将HID收到的63字节固件升级START命令打包为16个unsigned word，
 * 通过uc_dfu streaming channel发送到button_task (tile[0])执行。
 * 从eq.c的process_send_params中对0xA7命令调用此函数。 */
void dfu_chan_forward(unsigned char data[], unsigned len)
{
    unsafe
    {
        for (int i = 0; i < 16; i++) {
            unsigned word = 0;
            for (int j = 0; j < 4; j++) {
                int idx = i * 4 + j;
                if (idx < 63) {
                    word |= ((unsigned)data[idx]) << (j * 8);
                }
            }
            uc_dfu <: word;
        }
    }
}
#endif

void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, chanend c_audiohw_rx
#if HID_DFU_EN
                 , streaming chanend c_dfu_rx
#endif
                 , chanend c_mic_det
                )
{
    //hwtimer_t timer = hwtimer_alloc();
    unsigned time = 0;
    timer tmr;

    static int uac_vol=0, last_uac_vol=0;
#if EQ_EN

    static unsigned eq_sync_counter = 0;  // EQ参数存储计数器（每100ms递增，5次后保存）
#endif
    // port_t p_ctrl_keys = XS1_PORT_8C;

    uint32_t port_ctrl_keys = 0, curr_ctrl_keys = 0, last_ctrl_keys = 0, keys_changed = 0;
    uint32_t port_ctrl_keys2 = 0, curr_ctrl_keys2 = 0, last_ctrl_keys2 = 0, keys_changed2 = 0;

    int debounce_cnt = 0;
    static unsigned isMute = 0;
    uint8_t tmp = 0;

    // port_t p_button_music_mode = PORT_BUTTON_MUSIC_MODE;
    // port_t p_button_game_mode = PORT_BUTTON_GAME_MODE;
    // port_t p_button_ai71_onoff = PORT_BUTTON_AI71_ONOFF;

    //port_enable(p_button_music_mode);

    // 出厂默认：麦克风21dB (reg=22), 监听-14dB (level=15)
    int codec_adc_pga_gain_reg_value = 22;  // 21dB

    int dac_level = 15;  // -14dB (DAC_LEVEL_MAX - 14 = 29 - 14 = 15)

    // mic endcoder 变量
    uint8_t prev_encode_input1 = 0;
    uint8_t rotation_active = 0;
    uint8_t sample_count = 0;
    uint8_t last_valid_direction = 0;
    uint8_t fast_rotation_mode = 0;  // 快速旋转模式
    uint8_t consecutive_same_dir = 0; // 连续相同方向计数

    // hp endcoder 变量
    uint8_t hp_prev_encode_input1 = 0;
    uint8_t hp_rotation_active = 0;
    uint8_t hp_sample_count = 0;
    uint8_t hp_last_valid_direction = 0;
    uint8_t hp_fast_rotation_mode = 0;  // 快速旋转模式
    uint8_t hp_consecutive_same_dir = 0; // 连续相同方向计数



    // active_mode: 0=off, 1=music (LED_MUSIC, no algorithm),
    //              2=game (LED_GAME_MODE, IR_GAME), 3=AI7.1 (LED_AI7_1, IR_7_1_GAME)
    unsigned active_mode = 0;
    // 脚步增强3档状态: 0=关(0dB), 1=中亮/6dB, 2=高亮/12dB；出厂默认开启(12dB)
    unsigned flag_footsteps_enhancement = 2;
    // 出厂默认：AI降噪开启
    unsigned flag_aidenoise_onoff = 1;
    unsigned dnr_strength_saved = 100;  // AI降噪重新开启时恢复的强度（0x85可更新）
    unsigned last_footstep_expand = 0xFF;  // 上次已上报的脚步增强增益值，0xFF表示初始化未完成

    // Buttons state
    unsigned push_button_music_mode_state_old = 1; // Active low
    unsigned push_button_ai71_onoff_state_old = 1; // Active low
    unsigned push_button_game_mode_state_old = 1; // Active low
    unsigned push_button_footsteps_enhancement_state_old = 0; // Active low
    unsigned push_button_aidenoise_onoff_state_old = 1; // Active low
    unsigned char saved_footstep = 0;



    unsigned flag_mic_mute = 0;
    unsigned flag_hp_mute = 0;
    unsigned mic_det_muted = 0;  // mic检测导致的mute（不影响LED和g_mic_volume_level）
    unsigned dac_det_muted = 0;  // mic插入时临时mute DAC防pop（不影响LED）

    unsigned push_button_mic_mute_state_old = 1; // Active low
    unsigned push_button_hp_mute_state_old = 1; // Active low

    // 出厂恢复长按状态机：音乐+游戏同时长按3秒
    unsigned factory_reset_hold_count = 0;   // 两键同时按住计数（×1ms）
    unsigned factory_reset_blink_state = 0;  // 0=空闲，1-6=闪烁相位
    unsigned factory_reset_blink_tick = 0;   // 当前相位内计数
    unsigned mic_mute_blink_tick = 0;
    unsigned hp_mute_blink_tick = 0;
    // 组合键去抖：单键动作延迟 BTN_COMBO_DELAY_TICKS 后触发，期间若另一键也按下则切换为组合模式
    unsigned btn_music_hold_ticks = 0;  // music键连续按住计数
    unsigned btn_game_hold_ticks = 0;   // game键连续按住计数
    unsigned btn_combo_active = 0;      // 1=处于组合键模式（单键动作已抑制）
    unsigned fr_inhibit = 0;            // 1=出厂恢复重启后抑制状态，必须松键后才允许重新触发

    int current_mic_led_pos = 0;

    htr3236_t htr3236_dev;

    // LED控制上下文
    led_control_t led_ctx;


    // saved_mode / active_mode: 0=off, 1=music, 2=game (IR_GAME), 3=AI7.1 (IR_7_1_GAME)
    unsigned /* char */ saved_mode;
    unsigned char saved_uac1_mode = 0;
    unsigned char path[] = "game_mode";
    unsigned char mic_vol_path[] = "mic_vol";
    unsigned char dac_vol_path[] = "dac_vol";
    unsigned char mic_mute_path[] = "mic_mute";
    unsigned char hp_mute_path[] = "hp_mute";
    unsigned char monitor_sw_path[] = "monitor_sw";
    unsigned host_os = OS_OTHERS;
#if DNR_ENABLE
    unsigned dnr_init_flag = 0;
    while (dnr_init_flag == 0)
    {
        GET_SHARED_GLOBAL(dnr_init_flag, g_dnr_init_flag);
        asm("nop");
    }
#endif
#if USE_EX3D == 1
    unsigned ex3d_key_verified = 0;
    while (ex3d_key_verified == 0)
    {
        GET_SHARED_GLOBAL(ex3d_key_verified, g_ex3d_key_verified);
        asm("nop");
    }
#endif

    delay_milliseconds(10);
    saved_mode = load_value(path);
    debug_printf("Loaded game_mode from flash: %d\n", saved_mode);

#if USE_EX3D == 1
    // 加载脚步增强状态（保存值为expand_gain: 0/6/12）
    {
        unsigned char footstep_path[] = "footstep";
        saved_footstep = load_value(footstep_path);
        debug_printf("Loaded footstep gain from flash: %d\n", saved_footstep);
        if (saved_footstep == 0) {
            flag_footsteps_enhancement = 0;
        } else if (saved_footstep <= 6) {
            flag_footsteps_enhancement = 1;
        } else if (saved_footstep <= 20) {
            flag_footsteps_enhancement = 2;
        } else {
            // 未初始化(255)或异常值：出厂默认脚步增强开启(12dB)，写入flash
            saved_footstep = 12;
            flag_footsteps_enhancement = 2;
            save_value(footstep_path, (unsigned char)12);
            debug_printf("Saved footstep gain to flash: %d\n", saved_footstep);
        }
        debug_printf("Loaded footstep gain from flash: %d, state=%d\n", saved_footstep, flag_footsteps_enhancement);
    }
#endif

#if defined(UAC1_MODE)
    for(int i = 0; i < 500; i++)
    {
        GET_SHARED_GLOBAL(host_os, g_host_os);
        if (host_os == OS_WIN) {
            break;
        }
        delay_milliseconds(1);
    }

    if (host_os == OS_WIN) {
        printf("Detected Windows OS (OS_WIN)  saved_mode: %d\n", saved_mode);
        unsigned flag = (saved_mode <= 1) ? MODE_F1_MUSIC_UAC2 : MODE_F3_F4_FPS_UAC2;
        SetRoleSwitchFlag(flag);
#ifndef DISABLE_REBOOT
        device_reboot();
        while (1);
#endif
    }
    else
    {
#if F5_MUSIC_UAC1
      if (saved_mode >= 2) {
        SetRoleSwitchFlag(MODE_F6_F7_FPS_UAC1);
#ifndef DISABLE_REBOOT
        device_reboot();
        while (1);
#endif
      }
#elif F6_F7_FPS_UAC1
      if (saved_mode <= 1) {
        SetRoleSwitchFlag(MODE_F5_MUSIC_UAC1);
#ifndef DISABLE_REBOOT
        device_reboot();
        while (1);
#endif
      }
#endif
    }
#endif


#if defined(UAC1_MODE)
    if (saved_mode == 255) {
#if defined(F5_MUSIC_UAC1)
        saved_mode = 1; // f5: default music mode
#elif defined(F6_F7_FPS_UAC1)
        saved_mode = 2; // f6/f7: default game mode
#else
        saved_mode = 1; // default off
#endif
        save_value(path, saved_mode);
        debug_printf("Saved game_mode to flash: %d\n", saved_mode);
    }
#else
    if (saved_mode == 255) {
        // 出厂默认：AI7.1开启(mode=3)
        saved_mode = 3;
        save_value(path, saved_mode);
        debug_printf("Saved game_mode to flash: %d\n", saved_mode);
    }
#endif


    active_mode = (saved_mode <= 3) ? saved_mode : 0;
    {
        SET_SHARED_GLOBAL(g_game_mode, active_mode);
        debug_printf("active_mode=%d\n", active_mode);
    }



    // 初始化硬件
    htr3236_init(&htr3236_dev, HTR3236_ADDR_GND);
    htr3236_hw_enable(&htr3236_dev);
    //p_htr3235_sdb <: 1;

    unsafe
    {
        while(htr3236_software_wake(&htr3236_dev, (client interface i2c_master_if)i_i2c_client) != 0) {
            // 错误处理
            debug_printf("HTR3236 LED driver wake failed\n");
            //return;
        }
    }
    debug_printf("HTR3236 LED driver wake success 9\n");

    // 设置PWM频率为22kHz (避免可闻噪声)
    //htr3236_set_frequency(i2c, HTR3236_FREQ_22KHZ);
    unsafe
    {
        while(htr3236_set_frequency(&htr3236_dev, (client interface i2c_master_if)i_i2c_client, HTR3236_FREQ_22KHZ) != 0)
        {
            debug_printf("HTR3236 set frequency failed\n");
        }
    }
    debug_printf("HTR3236 set frequency success 9\n");

    // 初始化LED控制
    unsafe{led_control_init(&led_ctx, &htr3236_dev, (client interface i2c_master_if)i_i2c_client);}

    // led_on(&led_ctx, led_l_physical_map[0]);
    // delay_milliseconds(100);
    // led_update_all(&led_ctx);

    // led_on(&led_ctx, led_l_physical_map[1]);
    // delay_milliseconds(100);
    // led_update_all(&led_ctx);

    // led_on(&led_ctx, led_l_physical_map[2]);
    // delay_milliseconds(100);
    // led_update_all(&led_ctx);

    //led_waterfall(&led_ctx, 50);


    // 从 Flash 恢复 mic/dac 音量
    {
        unsigned char saved_mic = load_value(mic_vol_path);
        if(saved_mic >= NAU88L21_PGA_GAIN_REG_MIN_USED_VALUE && saved_mic <= NAU88L21_PGA_GAIN_REG_MAX_VALUE)
            codec_adc_pga_gain_reg_value = saved_mic;
        else
            save_value(mic_vol_path, (unsigned char)codec_adc_pga_gain_reg_value); // 出厂默认22(21dB)

        unsigned char saved_dac = load_value(dac_vol_path);
        if(saved_dac <= DAC_LEVEL_MAX)
            dac_level = saved_dac;
        else
            save_value(dac_vol_path, (unsigned char)dac_level); // 出厂默认15(-14dB)

        // 从Flash恢复耳返开关（默认关闭）
        unsigned char saved_monitor_sw = load_value(monitor_sw_path);
        if(saved_monitor_sw == 1)
            g_monitor_switch = 1;
        else if(saved_monitor_sw == 255) {
            // 未初始化：出厂默认关闭
            g_monitor_switch = 0;
            save_value(monitor_sw_path, (unsigned char)0);
        } else {
            g_monitor_switch = 0;
        }
        debug_printf("Loaded monitor_switch from flash: %d\n", g_monitor_switch);

        // 从Flash恢复mic_mute状态（默认关闭=未静音）
        unsigned char saved_mic_mute = load_value(mic_mute_path);
        if(saved_mic_mute == 1)
            flag_mic_mute = 1;
        else {
            flag_mic_mute = 0;
            if(saved_mic_mute == 255)
                save_value(mic_mute_path, (unsigned char)0);
        }
        debug_printf("Loaded mic_mute from flash: %d\n", flag_mic_mute);

        // 从Flash恢复hp_mute状态（默认关闭=未静音）
        unsigned char saved_hp_mute = load_value(hp_mute_path);
        if(saved_hp_mute == 1)
            flag_hp_mute = 1;
        else {
            flag_hp_mute = 0;
            if(saved_hp_mute == 255)
                save_value(hp_mute_path, (unsigned char)0);
        }
        debug_printf("Loaded hp_mute from flash: %d\n", flag_hp_mute);
    }

    codec_init();
    // 同步全局音量变量与从Flash恢复的dac_level / codec_adc_pga_gain_reg_value
    g_volume_level = dac_level;
    // 麦克风HID范围上限37 (register=38的+1.5dB仅firmware内部使用)
    g_mic_volume_level = (codec_adc_pga_gain_reg_value <= 37) ? codec_adc_pga_gain_reg_value : 37;

    // ADCL PGA default setting（mic_volume内部已根据g_monitor_switch决定是否启用耳返通路）
    // 若mic_mute已从flash恢复为1，则此处先以正常gain调用，再用mute覆盖
    mic_volume(codec_adc_pga_gain_reg_value);
    {
        int mic_led_count = flag_mic_mute ? 15 : mic_gain_to_led[codec_adc_pga_gain_reg_value];
        for(int i = 0; i < 15; i++)
        {
            if (i < mic_led_count)
                led_on(&led_ctx, led_l_physical_map[i]);
            else
                led_off(&led_ctx, led_l_physical_map[i]);
        }
    }
    // 应用从flash恢复的mic_mute状态
    if(flag_mic_mute) {
        mic_volume(0);
        g_mic_volume_level = 0;
        mic_mute_blink_tick = 1;
    }

    // 硬件耳返通路已禁用，改为数字监听（在tile1 UserBufferManagement中实现）
    // 初始化同步在上方已通过 cc_mic_level <: 0xFE 完成

    // DAC 默认音量（mute 时写 0x0000）
    if(dac_level == DAC_LEVEL_MIN)
        unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); }
    else
        dac_volume(dac_level - DAC_LEVEL_MAX);
    {
        int dac_led_count = flag_hp_mute ? 15 : dac_gain_to_led[dac_level];
        for(int i = 0; i < 15; i++)
        {
            if (i < dac_led_count)
                led_on(&led_ctx, led_d_physical_map[i]);
            else
                led_off(&led_ctx, led_d_physical_map[i]);
        }
    }
    // 应用从flash恢复的hp_mute状态
    if(flag_hp_mute) {
        unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); }
        g_volume_level = 0;
        hp_mute_blink_tick = 1;
    }
    // Initialize mode button LEDs: at most one may be lit at a time
    led_off(&led_ctx, LED_MUSIC);
    led_off(&led_ctx, LED_GAME_MODE);
    led_off(&led_ctx, LED_AI7_1);
    switch (active_mode) {
        case 1: led_on(&led_ctx, LED_MUSIC);     break;
        case 2: led_on(&led_ctx, LED_GAME_MODE); break;
        case 3: led_on(&led_ctx, LED_AI7_1);     break;
        default: break;
    }
    led_update_all(&led_ctx);


    unsigned hidData0;
    delay_milliseconds(200);

    debug_printf("button task start\n");


       {
       cc_mic_level <: 0xFC;
       cc_mic_level <: active_mode;
       debug_printf("Sent sound_effect_mode %d to hid_button_task\n", active_mode);
   }

#if USE_EX3D == 1
    // 发送初始脚步增强expand_gain到tile1
    {
        cc_mic_level <: 0xFD;
        cc_mic_level <: (unsigned) saved_footstep;
        debug_printf("set init expand_gain %d to hid_button_task\n", saved_footstep);
    }

    // 加载枪声阈值并同步到tile1
    // 存储格式: -threshold (0~35, 0=threshold=0dB), 255=未初始化
    {
        unsigned char lmt_thresh_path[] = "lmt_thresh";
        unsigned char raw = load_value(lmt_thresh_path);
        int init_threshold;
        if (raw == 255) {
            // 未初始化，使用默认值-15
            init_threshold = -15;
            save_value(lmt_thresh_path, (unsigned char)15);
        } else if (raw <= 36) {
            // raw=0~35 全部有效: 0=threshold=0dB(不限幅), 35=threshold=-35dB(最大限幅)
            init_threshold = -(int)(raw - 1);
        } else {
            init_threshold = -15;
        }
        cc_mic_level <: 0xFA;
        cc_mic_level <: (unsigned)init_threshold;
        debug_printf("Loaded lmt_threshold=%d from flash (raw=%d), sent to tile1\n", init_threshold, raw);
    }

    // 恢复脚步增强LED初始状态
    if (flag_footsteps_enhancement == 1) {
        led_on(&led_ctx, LED_FOOTSTEP_MODE);
        led_update_all(&led_ctx);
    } else if (flag_footsteps_enhancement == 2) {
        led_set_brightness(&led_ctx, LED_FOOTSTEP_MODE, 128);
        led_update_all(&led_ctx);
    }
#endif

    // 初始化数字监听开关同步到tile1
    cc_mic_level <: 0xFE;
    cc_mic_level <: (unsigned)g_monitor_switch;
    debug_printf("Init monitor sync: sw=%d\n", g_monitor_switch);

    // 出厂默认：AI降噪开启，初始化LED和算法
#if DNR_ENABLE == 1
    if (flag_aidenoise_onoff) {
        led_on(&led_ctx, LED_ANC);
        led_update_all(&led_ctx);
        dnr_set_mode(1);
    }
#endif

    // port_enable(p_ctrl_keys);
    port_ctrl_keys = 0;//port_in(p_ctrl_keys);
    if ((port_ctrl_keys & KEY_MUTE) == 0) {
        // mute switch off (unmuted)
        debug_printf("unmuted\n");
        isMute = 0;
        SET_SHARED_GLOBAL(g_mute_on_off_t0, MUTE_OFF);  // 初始化tile0静音状态
    } else {
        // mute switch on (muted)
        debug_printf("muted\n");
        isMute = 1;
        SET_SHARED_GLOBAL(g_mute_on_off_t0, MUTE_ON);  // 初始化tile0静音状态
    }

    last_ctrl_keys = ((port_ctrl_keys) & KEY_BITS);
    last_ctrl_keys ^= KEY_MUTE;


    // 启动时若两键同时按住，设置抑制标志，必须松开后才允许触发出厂恢复
    {
        unsigned music_init, game_init;
        p_button_music_mode :> music_init;
        p_button_game_mode  :> game_init;
        if (music_init == 0 && game_init == 0) {
            fr_inhibit = 1;
            btn_combo_active = 1;
            debug_printf("Boot: both keys held, FR inhibited until release\n");
        }
    }

    //hwtimer_set_trigger_time(timer, hwtimer_get_time(timer) + KEY_POLLING_INTERVAL);
    tmr :> time;                          /* Input the time */
    time += TIMER_PERIOD;                 /* Increment the time */

    g_windows_detect_done = 1;
    while (1) {
        select
        {
            case c_hidSendData :> hidData0:
            {
                if (hidData0 == 0xffffffff) {
                    debug_printf("receive end data\n");

                    // 注意：UAC1模式下不会收到此命令（hid_button_task不发送）
                    // 读取当前g_game_mode值
                    unsigned current_mode;// = chan_in_word(c_hidSendData);
                    c_hidSendData :> current_mode;


                    // 循环切换模式：0(STEREO_2K) -> 1(SPATIAL_GAME) -> 2(SPATIAL_MOVIE) -> 3(无音效) -> 0
                    unsigned new_mode;
                    unsigned mode_flag;
                    debug_printf("current_mode: %d\n", current_mode);
                    if (current_mode == 0) {
                        // 当前是STEREO_2K，切换到STEREO_2K
                        new_mode = 1;
#if IR_SWITCHING_MODE
                        mode_flag = IR_GAME;
#else
                    //    mode_flag = MODE_STEREO_2K;
#endif
                        debug_printf("Switching from STEREO_2K (0) to  STEREO_2K (1)\n");
                    } else if (current_mode == 1) {
                        // 当前是STEREO_2K，切换到SPATIAL_GAME
                        new_mode = 2;
#if IR_SWITCHING_MODE
                        mode_flag = IR_7_1_GAME;
#else
                    //    mode_flag = MODE_SPATIAL_GAME;
#endif
                        debug_printf("Switching from STEREO_2K (1) to SPATIAL_GAME (2)\n");
                    } else if (current_mode == 2) {
                        // 当前是SPATIAL_GAME，切换到SPATIAL_MOVIE
                        new_mode = 3;
#if IR_SWITCHING_MODE
                        mode_flag = IR_7_1_MOVIE;
#else
                     //   mode_flag = MODE_SPATIAL_MOVIE;  // SPATIAL_MOVIE模式使用SPATIAL_MOVIE固件
#endif
                        debug_printf("Switching from SPATIAL_GAME (2) to SPATIAL_MOVIE (3)\n");
                    }                     // 更新g_game_mode
                    else if(current_mode == 3) {
                        new_mode = 0;
#if IR_SWITCHING_MODE
                        mode_flag = IR_OFF;
#else
                     //   mode_flag = MODE_STEREO_2K;
#endif
                        debug_printf("Switching from SPATIAL_MOVIE (3) to STEREO_2K (0)\n");
                    }


                    unsigned char path[] = "game_mode";
                    save_value(path, (unsigned char)new_mode);
                    debug_printf("Saved game_mode %d to flash\n", new_mode);
                    delay_milliseconds(20);


                    // 只有在需要切换固件时才reboot，同一固件内的模式切换（如0<->1）只更新模式和算法状态
#if !UAC1_MODE

#if IR_SWITCHING_MODE
                        debug_printf("Same firmware mode (0x%04X), updating mode and algorithm state without reboot\n", mode_flag);
                        SET_SHARED_GLOBAL(g_game_mode, new_mode);
                        //chan_out_byte(cc_mic_level, 0xFC);  // 音频模式传输命令
                        //chan_out_byte(cc_mic_level, new_mode);  // 音频模式值
                        cc_mic_level <: 0xFC;
                        cc_mic_level <: new_mode;
                        debug_printf("Sent audio_mode %d to hid_button_task via cc_mic_level channel\n", new_mode);
#else
                    if (new_mode != 1) {

                        debug_printf("Set role switch flag: 0x%04X, switching firmware, rebooting...\n", mode_flag);
                        SetRoleSwitchFlag(mode_flag);
                        delay_milliseconds(20);
#ifndef DISABLE_REBOOT
                        device_reboot();
                        while (1);
#endif
                    } else {

                        debug_printf("Same firmware mode (0x%04X), updating mode and algorithm state without reboot\n", mode_flag);
                        SET_SHARED_GLOBAL(g_game_mode, new_mode);

                        // chan_out_byte(cc_mic_level, 0xFC);  // 音频模式传输命令
                        // chan_out_byte(cc_mic_level, new_mode);  // 音频模式值
                        cc_mic_level <: 0xFC;
                        cc_mic_level <: new_mode;
                        debug_printf("Sent audio_mode %d to hid_button_task via cc_mic_level channel\n", new_mode);
                    }
#endif
#endif
                    break;
                }

#if HID_DFU_EN
                if (!g_in_fw_upgrade)
#endif
                {
#if (HID_CONTROLS == 1)
                    unsigned *reportData = hidSendData;
                    reportData[0] = hidData0;
                    for (int i=1; i<(HID_MAX_DATA_BYTES/4); i++) {
                        c_hidSendData :> reportData[i];
                    }
                    hidSetChangePending(1);
#endif
                }
                break;
            }

            case c_audiohw_rx :> unsigned new_samfreq:
            {
                // 采样率变化通知，来自AudioHwConfig (tile[1])，通过uc_audiohw专用通道传递
                unsigned new_dsd_mode;
                c_audiohw_rx :> new_dsd_mode;
                debug_printf("SampRate->tile0: %uHz dsd=%u\n", new_samfreq, new_dsd_mode);

                unsafe {
#if !UAC1_MODE
                    switch (new_samfreq) {
                        case 192000:
                        case 176400:
                            NAU88C22_REGWRITE(0x0003, 0x00D0, (client interface i2c_master_if)i_i2c_client);
                            NAU88C22_REGWRITE(0x002B, 0x4000, (client interface i2c_master_if)i_i2c_client);

                            NAU88C22_REGWRITE(0x002C, 0x0082, (client interface i2c_master_if)i_i2c_client);
                            break;
                        case 96000:
                        case 88200:
                            NAU88C22_REGWRITE(0x0003, 0x0092, (client interface i2c_master_if)i_i2c_client);
                            NAU88C22_REGWRITE(0x002B, 0x4001, (client interface i2c_master_if)i_i2c_client);
                            NAU88C22_REGWRITE(0x002C, 0x0082, (client interface i2c_master_if)i_i2c_client);
                            break;
                        case 44100:
                        case 48000:
                        default:
                            NAU88C22_REGWRITE(0x0003, 0x0053, (client interface i2c_master_if)i_i2c_client);
                            NAU88C22_REGWRITE(0x002B, 0x4002, (client interface i2c_master_if)i_i2c_client);
                            NAU88C22_REGWRITE(0x002C, 0x0082, (client interface i2c_master_if)i_i2c_client);
                            break;
                    }
#endif
#if 0
                    unsigned val;

                    NAU88C22_REGREAD(0x0003, val, (client interface i2c_master_if)i_i2c_client);
                    debug_printf("NAU88C22_REGREAD(0x0003): 0x%08x\n", val);
                    NAU88C22_REGREAD(0x002B, val, (client interface i2c_master_if)i_i2c_client);
                    debug_printf("NAU88C22_REGREAD(0x002B): 0x%08x\n", val);
                    NAU88C22_REGREAD(0x002C, val, (client interface i2c_master_if)i_i2c_client);
                    debug_printf("NAU88C22_REGREAD(0x002C): 0x%08x\n", val);
#endif
                }
                c_audiohw_rx <: 0xff;

#if HID_CONTROLS > 0
#if HID_DFU_EN
                if (!g_in_fw_upgrade)
#endif
                {
                    unsafe {
                        unsigned char * unsafe ptr = (unsigned char * unsafe)hidSendData;
                        ptr[0] = 1;
                        ptr[1] = 0x77;
                        ptr[2] = 0x9F;
                        ptr[3] = (unsigned char)(new_samfreq & 0xFF);
                        ptr[4] = (unsigned char)((new_samfreq >> 8) & 0xFF);
                        ptr[5] = (unsigned char)((new_samfreq >> 16) & 0xFF);
                        ptr[6] = (unsigned char)((new_samfreq >> 24) & 0xFF);
                        ptr[7] = (unsigned char)new_dsd_mode;
                        for (int i = 8; i < HID_MAX_DATA_BYTES; i++)
                            ptr[i] = 0x00;
                    }
                    hidSetChangePending(0x1);
                }
#endif
                break;
            }

#if HID_DFU_EN
            case c_dfu_rx :> unsigned dfu_first_word:
            {
                // 接收来自tile[1] hid_button_task转发的固件升级START命令（16个word）
                unsigned dfu_words[16];
                dfu_words[0] = dfu_first_word;
                for (int i = 1; i < 16; i++)
                    c_dfu_rx :> dfu_words[i];
                unsigned char cmd_buf[63];
                for (int i = 0; i < 63; i++)
                    cmd_buf[i] = (dfu_words[i / 4] >> ((i % 4) * 8)) & 0xFF;
                if (cmd_buf[1] == FIRMWARE_UPGRADE_START)
                    handle_firmware_upgrade_start(cmd_buf, 63);
                break;
            }
#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);
                    }
                } else if (mic_det_cmd == MIC_DET_DAC_MUTE) {
                    dac_det_muted = 1;
                    // mute DAC硬件，不改变dac_level/g_volume_level和LED
                    unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); }
                    debug_printf("mic_det: dac mute\n");
                } else if (mic_det_cmd == MIC_DET_DAC_UNMUTE) {
                    dac_det_muted = 0;
                    // 恢复DAC音量，但如果用户手动hp_mute或dac_level==0则不恢复
                    if (!flag_hp_mute && dac_level > DAC_LEVEL_MIN) {
                        dac_volume(dac_level - DAC_LEVEL_MAX);
                        debug_printf("mic_det: dac unmute -> level=%d\n", dac_level);
                    }
                }
                break;
            }

            case tmr when timerafter(time) :> void :
            {
                //hwtimer_change_trigger_time(timer, hwtimer_get_time(timer) + KEY_POLLING_INTERVAL);
                time += TIMER_PERIOD;


                //hidData0 = 0;

// port_t p_button_music_mode = PORT_BUTTON_MUSIC_MODE;
// port_t p_button_game_mode = PORT_BUTTON_GAME_MODE;
// port_t p_button_ai71_onoff = PORT_BUTTON_AI71_ONOFF;

//p_button_music_mode :> button_music_mode;    // 1A

                unsigned mic_encoder1, mic_encoder2, hp_encoder;
                unsigned button_mic_mute, button_hp_mute;
                unsigned button_music_mode, button_ai71_onoff, button_game_mode, button_footsteps_enhancement, button_aidenoise_onoff;
                unsigned mode_change = 0;

                //button_music_mode = port_in(p_button_music_mode);
                p_button_music_mode :> button_music_mode;    // 1A
                p_button_game_mode :> button_game_mode;    // 1L
                p_button_ai71_onoff :> button_ai71_onoff;    // 1M

                p_mic_gain_encoder1 :> mic_encoder1;    // 4F2
                p_mic_gain_encoder2 :> mic_encoder2;    // 4E2

                button_mic_mute = ((mic_encoder1 & 0b1000) != 0);    // 4F3
                //button_hp_mute = ((hp_encoder & 0b01000000) != 0);    // 8D6

                button_footsteps_enhancement = ((mic_encoder1 & 0b0010) != 0);    // 4F1
                button_aidenoise_onoff = ((mic_encoder2 & 0b1000) != 0);    // 4E3

                // --- Mode button handling ---
                // active_mode: 0=off, 1=music, 2=game (IR_GAME), 3=AI7.1 (IR_7_1_GAME)
                //
                // Boot chain: power-on → F5 → OS detect → route to F1/F3/F4/F5/F6/F7
                //
                // Music-only firmware (F1, F5): USE_EX3D not set
                //   Music btn: toggle LED locally (no reboot)
                //   Game/AI7.1 btn: save mode + reboot (F5 will route to FPS firmware)
                //
                // FPS firmware (F3/F4, F6/F7): USE_EX3D set
                //   Music btn: save mode=1 + reboot (F5 will route to music firmware)
                //   Game/AI7.1 btn: switch IR algorithm locally (no reboot)

                unsigned mode_btn_change = 0;
                unsigned need_reboot = 0;

                // --- Music + Game 按键：组合检测 + 去抖 ---
                // 两键同时按住3秒 → 出厂恢复；单键需持续 BTN_COMBO_DELAY_TICKS 后生效
                // （50ms 窗口内若另一键也按下则进入组合模式，单键动作取消）
                {
                    int music_is_down = (button_music_mode == 0);
                    int game_is_down  = (button_game_mode == 0);
                    int factory_combo_is_down = ( music_is_down && game_is_down);

                    // 更新各键连续按住计数（断开则清零，用于去抖和窗口判断）
                    if (music_is_down && !factory_combo_is_down)
                    {
                        if (btn_music_hold_ticks < 0xFFFFu) btn_music_hold_ticks++;
                        debug_printf("btn_music_hold_ticks=%d\n", btn_music_hold_ticks);
                    }
                    else
                    {
                        btn_music_hold_ticks = 0;
                    }
                    if (game_is_down && !factory_combo_is_down)
                    {
                        if (btn_game_hold_ticks < 0xFFFFu)
                        {
                            btn_game_hold_ticks++;
                        }
                        debug_printf("btn_game_hold_ticks=%d\n", btn_game_hold_ticks);
                    }
                    else
                    {
                        btn_game_hold_ticks = 0;
                    }

                    // 场景1：两键同时按住（参照 fosi_ds1 else-if 结构）
                    if (factory_combo_is_down) {
                        btn_combo_active = 1;  // 粘性锁定
                        // fr_inhibit=1 时（出厂恢复重启后）：不计时，必须松键后重新按下才触发
                        if (factory_reset_blink_state == 0 && !fr_inhibit) {
                            factory_reset_hold_count++;
                            if (factory_reset_hold_count >= FACTORY_RESET_HOLD_TICKS) {
                                factory_reset_hold_count = 0;
                                factory_reset_blink_state = 1;
                                factory_reset_blink_tick = 0;
                                // 清除所有Flash设置并重启
                                debug_printf("Factory reset: clearing flash "
                                             "and rebooting\n");
                                unsafe {
                                  lfs_format_all();
                                }

                                led_on(&led_ctx, LED_MUSIC);
                                led_on(&led_ctx, LED_ANC);
                                led_on(&led_ctx, LED_FOOTSTEP_MODE);
                                led_on(&led_ctx, LED_AI7_1);
                                led_on(&led_ctx, LED_GAME_MODE);
                                led_update_all(&led_ctx);
                                debug_printf("Factory reset: 3s hold detected, starting blink\n");
                            }
                        }
                    }
                    // 场景2：仅 Music 按住
                    else if (music_is_down) {
                        factory_reset_hold_count = 0;
                        if (!btn_combo_active) {
                            if (btn_music_hold_ticks == BTN_COMBO_DELAY_TICKS) {
                                debug_printf("Music button pressed for %d ticks\n", BTN_COMBO_DELAY_TICKS);
#if (F3_F4_FPS_UAC2 == 1)
                                active_mode = 1;
                                need_reboot = 1;
                                SetRoleSwitchFlag(MODE_F1_MUSIC_UAC2);
#elif (F6_F7_FPS_UAC1 == 1)
                                // UAC1 FPS firmware: music needs F5, reboot if not already music
                                if (active_mode != 1) {
                                    active_mode = 1;
                                    need_reboot = 1;
                                    SetRoleSwitchFlag(MODE_F5_MUSIC_UAC1);
                                }
#elif (F5_MUSIC_UAC1 == 1)
                                // UAC1 Music firmware: already on music FW, toggle locally
                                if (active_mode != 1) {
                                    active_mode = 1;
                                    mode_btn_change = 1;
                                }
#else
                                if (active_mode != 1) {
                                    active_mode = 1;
                                    mode_btn_change = 1;
                                }
#endif
                            }
                        }
                    }
                    // 场景3：仅 Game 按住
                    else if (game_is_down) {
                        factory_reset_hold_count = 0;
                        if (!btn_combo_active) {
                            if (btn_game_hold_ticks == BTN_COMBO_DELAY_TICKS) {
                                debug_printf("Game button pressed for %d ticks\n", BTN_COMBO_DELAY_TICKS);
#if F1_MUSIC_UAC2 == 1
                                active_mode = 2;
                                need_reboot = 1;
                                SetRoleSwitchFlag(MODE_F3_F4_FPS_UAC2);
#elif (F5_MUSIC_UAC1 == 1)
                                // UAC1 Music firmware: game needs F6/F7, reboot if not already game
                                if (active_mode != 2) {
                                    active_mode = 2;
                                    need_reboot = 1;
                                    SetRoleSwitchFlag(MODE_F6_F7_FPS_UAC1);
                                }
#elif (F6_F7_FPS_UAC1 == 1)
                                // UAC1 FPS firmware: already on FPS FW, switch locally (IR_OFF)
                                if (active_mode != 2) {
                                    active_mode = 2;
                                    mode_btn_change = 1;
                                }
#else
                                if (active_mode != 2) {
                                    active_mode = 2;
                                    mode_btn_change = 1;
                                }
#endif
                            }
                        }
                    }
                    // 场景4：两键全松开 → 解除组合锁定及抑制标志
                    else {
                        factory_reset_hold_count = 0;
                        btn_combo_active = 0;
                        fr_inhibit = 0;  // 松键后允许下次同时按下重新触发出厂恢复
                    }
                }

                if (button_ai71_onoff == 0) {
                    if (push_button_ai71_onoff_state_old == 1) {
#if (F1_MUSIC_UAC2 == 1)
                        // Music-only firmware: AI7.1 needs FPS firmware
                        active_mode = 3;
                        need_reboot = 1;
                        SetRoleSwitchFlag(MODE_F3_F4_FPS_UAC2);
#elif (F5_MUSIC_UAC1 == 1)
                        // UAC1 Music firmware: AI71 needs F6/F7 FPS, reboot if not already AI71
                        if (active_mode != 3) {
                            active_mode = 3;
                            need_reboot = 1;
                            SetRoleSwitchFlag(MODE_F6_F7_FPS_UAC1);
                        }
#elif (F6_F7_FPS_UAC1 == 1)
                        // UAC1 FPS firmware: already on FPS FW, switch locally (IR_GAME)
                        if (active_mode != 3) {
                            active_mode = 3;
                            mode_btn_change = 1;
                        }
#else
                        // FPS firmware: switch algorithm locally (activate if not already)
                        if (active_mode != 3) {
                            active_mode = 3;
                            mode_btn_change = 1;
                        }
#endif
                    }
                }
                push_button_ai71_onoff_state_old = button_ai71_onoff;

                // 处理HID SET_SOUND_EFFECT_MODE (0xA4) 请求，等同于按键效果
                if (!mode_btn_change && !need_reboot) {
                    unsigned hid_req_mode;
                    GET_SHARED_GLOBAL(hid_req_mode, g_request_game_mode);
                    if (hid_req_mode != (unsigned)-1) {
                        SET_SHARED_GLOBAL(g_request_game_mode, (unsigned)-1);
                        unsigned target = (hid_req_mode <= 3) ? hid_req_mode : 0;
#if (F3_F4_FPS_UAC2 == 1)
                        if (target == 1) {
                            active_mode = target;
                            need_reboot = 1;
                            SetRoleSwitchFlag(MODE_F1_MUSIC_UAC2);
                        } else {
                            active_mode = target;
                            mode_btn_change = 1;
                        }
#elif (F1_MUSIC_UAC2 == 1)
                        if (target >= 2) {
                            active_mode = target;
                            need_reboot = 1;
                            SetRoleSwitchFlag(MODE_F3_F4_FPS_UAC2);
                        } else {
                            active_mode = target;
                            mode_btn_change = 1;
                        }
#elif (F5_MUSIC_UAC1 == 1)
                        // UAC1 Music FW: mode 1 local, mode 2/3 need F6/F7 reboot
                        if (target >= 2) {
                            active_mode = target;
                            need_reboot = 1;
                            SetRoleSwitchFlag(MODE_F6_F7_FPS_UAC1);
                        } else if (target != active_mode) {
                            active_mode = target;
                            mode_btn_change = 1;
                        }
#elif (F6_F7_FPS_UAC1 == 1)
                        // UAC1 FPS FW: mode 2/3 local, mode 1 needs F5 reboot
                        if (target <= 1) {
                            active_mode = target;
                            need_reboot = 1;
                            SetRoleSwitchFlag(MODE_F5_MUSIC_UAC1);
                        } else if (target != active_mode) {
                            active_mode = target;
                            mode_btn_change = 1;
                        }
#else
                        active_mode = target;
                        mode_btn_change = 1;
#endif
                    }
                }

                if (mode_btn_change || need_reboot) {
                    // Always persist mode to flash so boot chain restores it
                    {
                        unsigned char save_path[] = "game_mode";
                        save_value(save_path, (unsigned char)active_mode);
                    }

                    if (need_reboot) {
                        // Reboot: F5 will re-detect OS and route to correct firmware
                        debug_printf("Mode %d requires firmware switch, rebooting\n", active_mode);
                        delay_milliseconds(200);
#ifndef DISABLE_REBOOT
                        device_reboot();
                        while (1);
#endif
                    }

                    // Local update path (no reboot): update LEDs and DSP algorithm
                    led_off(&led_ctx, LED_MUSIC);
                    led_off(&led_ctx, LED_GAME_MODE);
                    led_off(&led_ctx, LED_AI7_1);
                    switch (active_mode) {
                        case 1: led_on(&led_ctx, LED_MUSIC);     break;
                        case 2: led_on(&led_ctx, LED_GAME_MODE); break;
                        case 3: led_on(&led_ctx, LED_AI7_1);     break;
                        default: break;
                    }
                    led_update_all(&led_ctx);

                    // Always update g_game_mode so 0xA5 reads correctly
                    SET_SHARED_GLOBAL(g_game_mode, active_mode);
#if USE_EX3D == 1
                    {
                        // sound_effect_mode: 0=无音效, 1=音乐, 2=游戏, 3=AI7.1
                        cc_mic_level <: 0xFC;
                        cc_mic_level <: active_mode;
                        debug_printf("Mode changed: active_mode=%d\n", active_mode);
                    }
#endif
                }

                // 出厂恢复闪烁状态机：5个按键LED闪3次后清除Flash并重启
                if (factory_reset_blink_state > 0) {
                    factory_reset_blink_tick++;
                    if (factory_reset_blink_tick >= FACTORY_RESET_BLINK_TICKS) {
                        factory_reset_blink_tick = 0;
                        factory_reset_blink_state++;
                        if (factory_reset_blink_state > 6) {
#if 1
                            // 3次闪烁完成：恢复原始LED显示
                            factory_reset_blink_state = 0;
                            led_off(&led_ctx, LED_MUSIC);
                            led_off(&led_ctx, LED_ANC);
                            led_off(&led_ctx, LED_FOOTSTEP_MODE);
                            led_off(&led_ctx, LED_AI7_1);
                            led_off(&led_ctx, LED_GAME_MODE);
                            switch (active_mode) {
                                case 1: led_on(&led_ctx, LED_MUSIC);     break;
                                case 2: led_on(&led_ctx, LED_GAME_MODE); break;
                                case 3: led_on(&led_ctx, LED_AI7_1);     break;
                                default: break;
                            }
                            if (flag_footsteps_enhancement == 1) led_on(&led_ctx, LED_FOOTSTEP_MODE);
                            else if (flag_footsteps_enhancement == 2) led_set_brightness(&led_ctx, LED_FOOTSTEP_MODE, 128);
                            if (flag_aidenoise_onoff) led_on(&led_ctx, LED_ANC);
                            led_update_all(&led_ctx);
                            // 等待松键，防止重启后再次触发出厂恢复循环
                            {
                                unsigned mw, gw;
                                do {
                                    delay_milliseconds(10);
                                    p_button_music_mode :> mw;
                                    p_button_game_mode  :> gw;
                                } while (mw == 0 || gw == 0);
                                delay_milliseconds(100);
                            }
#endif
                            // 出厂恢复默认AI7.1模式（mode=3），需要F3/F4固件
                            SetRoleSwitchFlag(MODE_F3_F4_FPS_UAC2);
                            delay_milliseconds(20);
#ifndef DISABLE_REBOOT
                            device_reboot();
                            while (1);
#endif
                        } else if (factory_reset_blink_state % 2 == 0) {
                            // 偶数相：全灭
                            led_off(&led_ctx, LED_MUSIC);
                            led_off(&led_ctx, LED_ANC);
                            led_off(&led_ctx, LED_FOOTSTEP_MODE);
                            led_off(&led_ctx, LED_AI7_1);
                            led_off(&led_ctx, LED_GAME_MODE);
                            led_update_all(&led_ctx);
                            delay_milliseconds(200);
                        } else {
                            // 奇数相：全亮
                            led_on(&led_ctx, LED_MUSIC);
                            led_on(&led_ctx, LED_ANC);
                            led_on(&led_ctx, LED_FOOTSTEP_MODE);
                            led_on(&led_ctx, LED_AI7_1);
                            led_on(&led_ctx, LED_GAME_MODE);
                            led_update_all(&led_ctx);
                            delay_milliseconds(200);
                        }
                    }
                }

#if USE_EX3D == 1
                mode_change = 0;
                if(button_footsteps_enhancement == 0)
                {
                    if(push_button_footsteps_enhancement_state_old == 1)
                    {
                        // 3档循环: 0(关/0dB) → 1(中亮/6dB) → 2(高亮/12dB) → 0
                        flag_footsteps_enhancement = (flag_footsteps_enhancement + 1) % 3;
                        mode_change = 1;
                        debug_printf("Footstep mode changed: %d -> %d\n", flag_footsteps_enhancement, flag_footsteps_enhancement + 1);
                    }
                }
                push_button_footsteps_enhancement_state_old = button_footsteps_enhancement;
                if(mode_change)
                {
                    if(flag_footsteps_enhancement == 0)
                    {
                        saved_footstep = 0;
                        led_off(&led_ctx, LED_FOOTSTEP_MODE);
                    }
                    else if(flag_footsteps_enhancement == 1)
                    {
                        saved_footstep = 6;
                        led_on(&led_ctx, LED_FOOTSTEP_MODE);
                    }
                    else
                    {
                        saved_footstep = 12;
                        led_set_brightness(&led_ctx, LED_FOOTSTEP_MODE, 128);
                    }
                    led_update_all(&led_ctx);
                    // 发送expand_gain到tile1执行
                    cc_mic_level <: 0xFD;
                    cc_mic_level <: (unsigned)saved_footstep;
                    // 掉电保存
                    unsigned char footstep_path[] = "footstep";
                    save_value(footstep_path, (unsigned char)saved_footstep);
                    debug_printf("Footstep state=%d, expand_gain=%d\n", flag_footsteps_enhancement, saved_footstep);
                }

                // HID 0xB0 CMD_EXPAND_GAIN请求：同步footstep LED状态
                {
                    unsigned hid_gain_req;
                    GET_SHARED_GLOBAL(hid_gain_req, g_hid_expand_gain_request);
                    if (hid_gain_req != (unsigned)-1) {
                        SET_SHARED_GLOBAL(g_hid_expand_gain_request, (unsigned)-1);
                        // 将增益值映射到footstep档位
                        unsigned new_state;
                        if (hid_gain_req == 0) {
                            new_state = 0;
                        } else if (hid_gain_req <= 6) {
                            new_state = 1;
                        } else {
                            new_state = 2;
                        }
                        if (new_state != (unsigned)flag_footsteps_enhancement) {
                            flag_footsteps_enhancement = (int)new_state;
                            if (flag_footsteps_enhancement == 0) {
                                led_off(&led_ctx, LED_FOOTSTEP_MODE);
                            } else if (flag_footsteps_enhancement == 1) {
                                led_on(&led_ctx, LED_FOOTSTEP_MODE);
                            } else {
                                led_set_brightness(&led_ctx, LED_FOOTSTEP_MODE, 128);
                            }
                            led_update_all(&led_ctx);
                        }

                        unsigned char fp[] = "footstep";
                        save_value(fp, (unsigned char)hid_gain_req);
                        saved_footstep = hid_gain_req;
                        debug_printf("HID set footstep gain=%d, state=%d\n", hid_gain_req, flag_footsteps_enhancement);
                    }
                }

                // HID 0xB0 CMD_LMT_THRESHOLD请求：保存阈值到flash
                // eq.c以(-threshold+1)编码存入shared global，范围1~36；此处解码后存flash (0~35)
                {
                    unsigned hid_thresh_req;
                    GET_SHARED_GLOBAL(hid_thresh_req, g_hid_lmt_threshold_request);
                    if (hid_thresh_req != (unsigned)-1) {
                        SET_SHARED_GLOBAL(g_hid_lmt_threshold_request, (unsigned)-1);
                        if (hid_thresh_req >= 1 && hid_thresh_req <= 36) {
                            unsigned char lmt_thresh_path[] = "lmt_thresh";
                            unsigned char flash_raw = (unsigned char)(hid_thresh_req - 1);
                            save_value(lmt_thresh_path, flash_raw);
                            debug_printf("HID set lmt_threshold=-%d, saved to flash\n", (int)(hid_thresh_req - 1));
                        }
                    }
                }
#endif

                mode_change = 0;
                if(button_aidenoise_onoff == 0)
                {
                    if(push_button_aidenoise_onoff_state_old == 1)
                    {
                        flag_aidenoise_onoff ^= 1;
                        mode_change = 1;
                    }
                }
                push_button_aidenoise_onoff_state_old = button_aidenoise_onoff;
#if DNR_ENABLE == 1
                if(mode_change)
                    if(flag_aidenoise_onoff)
                    {
                        led_on(&led_ctx, LED_ANC);
                        dnr_set_strength_level((unsigned char)dnr_strength_saved);
                        SET_SHARED_GLOBAL(g_dnr_strength, dnr_strength_saved);
                    }
                    else
                    {
                        led_off(&led_ctx, LED_ANC);
                        dnr_set_strength_level(0);
                        SET_SHARED_GLOBAL(g_dnr_strength, 0);
                    }

                //led_update_all(&led_ctx);
#endif

                // 检查HID 0x84 FACTORY_RESET请求
                {
                    unsigned factory_reset_req;
                    GET_SHARED_GLOBAL(factory_reset_req, g_request_factory_reset);
                    if (factory_reset_req) {
                        SET_SHARED_GLOBAL(g_request_factory_reset, 0);
                        debug_printf("Factory reset: rebooting...\n");
                        unsafe {
                                  lfs_format_all();
                        }
                        delay_milliseconds(500);
#ifndef DISABLE_REBOOT
                        device_reboot();
                        while (1);
#endif
                    }
                }

                mode_change = 0;
                if(button_mic_mute == 0)
                {
                    if(push_button_mic_mute_state_old == 1)
                    {
                        flag_mic_mute ^= 1;
                        mode_change = 1;
                    }
                }
                push_button_mic_mute_state_old = button_mic_mute;
                if(mode_change)
                {
                    save_value(mic_mute_path, (unsigned char)flag_mic_mute);
                    debug_printf("mic_mute changed: %d, saved to flash\n", flag_mic_mute);
                }
                if(mode_change)
                    if(flag_mic_mute)
                    {
                        mic_volume(0);
                        g_mic_volume_level = 0;
                        for(int i = 0; i < 15; i++)
                            led_on(&led_ctx, led_l_physical_map[i]);
                        mic_mute_blink_tick = 1;
                    }
                    else
                    {
                        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++)
                            led_off(&led_ctx, led_l_physical_map[i]);
                        current_mic_led_pos = mic_gain_to_led[codec_adc_pga_gain_reg_value] - 1;
                        for(int i = 0; i <= current_mic_led_pos; i++)
                        {
                            if ((i < 15) && (i >= 0))
                                led_on(&led_ctx, led_l_physical_map[i]);
                        }
                    }
                uint8_t rotating = (mic_encoder2 & 0b0100) == 0;    // 4E2
                uint8_t encode_input1 = ((mic_encoder1 & 0b0100) != 0); // 4F2

                if(rotating) {
                    if(!rotation_active) {
                        // 旋转开始
                        prev_encode_input1 = encode_input1;
                        sample_count = 1;
                        rotation_active = 1;

                        // 根据上次方向预判
                        if(fast_rotation_mode) {
                            // 快速模式只需要2次采样
                            sample_count = 2;
                        }
                    } else {
                        sample_count++;

                        // 动态调整采样次数：快速模式用2次，普通模式用3次
                        uint8_t required_samples = fast_rotation_mode ? 2 : 3;

                        if(sample_count >= required_samples) {
                            if(encode_input1 != prev_encode_input1) {
                                uint8_t current_dir = encode_input1 ? 1 : 2;

                                // 执行音量调节
                                if(current_dir == 1) {  // 顺时针
                                    if((codec_adc_pga_gain_reg_value < NAU88L21_PGA_GAIN_REG_MAX_VALUE) && (flag_mic_mute == 0)) {
                                        uint8_t old_led_count = mic_gain_to_led[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);
                                        uint8_t new_led_count = mic_gain_to_led[codec_adc_pga_gain_reg_value];

                                        // 如果LED数增加，点亮新增的那个LED
                                        if(new_led_count > old_led_count) {
                                            // 新点亮的LED索引 = new_led_count - 1
                                            led_on(&led_ctx, led_l_physical_map[new_led_count - 1]);
                                            led_update_all(&led_ctx);
                                        }
                                    }
                                } else {  // 逆时针
                                    if((codec_adc_pga_gain_reg_value > 0) && (flag_mic_mute == 0)) {
                                        uint8_t old_led_count = mic_gain_to_led[codec_adc_pga_gain_reg_value];

                                        --codec_adc_pga_gain_reg_value;

                                        if (!mic_det_muted) {
                                            if (codec_adc_pga_gain_reg_value == 0)
                                                mic_volume(0);
                                            else
                                                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);

                                        uint8_t new_led_count = mic_gain_to_led[codec_adc_pga_gain_reg_value];

                                        // 如果LED数减少，关闭减少的那个LED
                                        if(new_led_count < old_led_count) {
                                            // 关闭的LED索引 = old_led_count - 1
                                            led_off(&led_ctx, led_l_physical_map[old_led_count - 1]);
                                            led_update_all(&led_ctx);
                                        }
                                    }
                                }

                                // 检测是否快速旋转
                                if(current_dir == last_valid_direction) {
                                    consecutive_same_dir++;
                                    if(consecutive_same_dir >= 3) {
                                        fast_rotation_mode = 1;  // 进入快速模式
                                    }
                                } else {
                                    consecutive_same_dir = 0;
                                    fast_rotation_mode = 0;  // 方向变化，退出快速模式
                                }

                                last_valid_direction = current_dir;
                                rotation_active = 0;
                                sample_count = 0;
                            }
                        }
                    }
                } else {
                    rotation_active = 0;
                    sample_count = 0;
                    // 停止旋转一段时间后退出快速模式
                    static uint16_t idle_count = 0;
                    idle_count++;
                    if(idle_count > 50) {  // 50ms无旋转
                        fast_rotation_mode = 0;
                        consecutive_same_dir = 0;
                        idle_count = 0;
                    }
                }

#if 1
                // HP Encoder
                p_hp_gain_encoder :> hp_encoder;    // 8D4, 8D5

                uint8_t hp_rotating = ((hp_encoder & 0b00100000) == 0);   // 8D5
                uint8_t hp_encode_input1 = ((hp_encoder & 0b00010000) != 0);    // 8D4

                if(hp_rotating) {
                    if(!hp_rotation_active) {
                        // 旋转开始
                        hp_prev_encode_input1 = hp_encode_input1;
                        hp_sample_count = 1;
                        hp_rotation_active = 1;

                        // 根据上次方向预判
                        if(hp_fast_rotation_mode) {
                            // 快速模式只需要2次采样
                            hp_sample_count = 2;
                        }
                    } else {
                        hp_sample_count++;

                        // 动态调整采样次数：快速模式用2次，普通模式用3次
                        uint8_t hp_required_samples = hp_fast_rotation_mode ? 2 : 3;

                        if(hp_sample_count >= hp_required_samples) {
                            if(hp_encode_input1 != hp_prev_encode_input1) {
                                uint8_t hp_current_dir = hp_encode_input1 ? 1 : 2;

                                // 执行音量调节
                                if(hp_current_dir == 1) {  // 顺时针
                                    if(dac_level < DAC_LEVEL_MAX && flag_hp_mute == 0) {
                                        uint8_t old_led_count = dac_gain_to_led[dac_level];

                                        // 增加音量
                                        ++dac_level;
                                        g_volume_level = dac_level;
                                        if (!dac_det_muted)
                                            dac_volume(dac_level - DAC_LEVEL_MAX);
                                        save_value(dac_vol_path, dac_level);

                                        uint8_t new_led_count = dac_gain_to_led[dac_level];

                                        // 如果LED数增加，点亮新增的那个LED
                                        if(new_led_count > old_led_count) {
                                            // 新点亮的LED索引 = new_led_count - 1
                                            led_on(&led_ctx, led_d_physical_map[new_led_count - 1]);
                                            led_update_all(&led_ctx);
                                        }
                                    }
                                } else {  // 逆时针
                                    if(dac_level > DAC_LEVEL_MIN && flag_hp_mute == 0) {
                                        uint8_t old_led_count = dac_gain_to_led[dac_level];

                                        // 减小音量
                                        --dac_level;
                                        g_volume_level = dac_level;
                                        if (!dac_det_muted) {
                                            if(dac_level == DAC_LEVEL_MIN)
                                                unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); }
                                            else
                                                dac_volume(dac_level - DAC_LEVEL_MAX);
                                        }
                                        save_value(dac_vol_path, dac_level);

                                        uint8_t new_led_count = dac_gain_to_led[dac_level];

                                        // 如果LED数减少，关闭减少的那个LED
                                        if(new_led_count < old_led_count) {
                                            // 关闭的LED索引 = old_led_count - 1
                                            led_off(&led_ctx, led_d_physical_map[old_led_count - 1]);
                                            led_update_all(&led_ctx);
                                        }
                                    }
                                }

                                // 检测是否快速旋转
                                if(hp_current_dir == hp_last_valid_direction) {
                                    hp_consecutive_same_dir++;
                                    if(hp_consecutive_same_dir >= 3) {
                                        hp_fast_rotation_mode = 1;  // 进入快速模式
                                    }
                                } else {
                                    hp_consecutive_same_dir = 0;
                                    hp_fast_rotation_mode = 0;  // 方向变化，退出快速模式
                                }

                                hp_last_valid_direction = hp_current_dir;
                                hp_rotation_active = 0;
                                hp_sample_count = 0;
                            }
                        }
                    }
                } else {
                    hp_rotation_active = 0;
                    hp_sample_count = 0;
                    // 停止旋转一段时间后退出快速模式
                    static uint16_t hp_idle_count = 0;
                    hp_idle_count++;
                    if(hp_idle_count > 50) {  // 50ms无旋转
                        hp_fast_rotation_mode = 0;
                        hp_consecutive_same_dir = 0;
                        hp_idle_count = 0;
                    }
                }

                button_hp_mute = ((hp_encoder & 0b01000000) != 0);    // 8D6

                mode_change = 0;
                if(button_hp_mute == 0)
                {
                    if(push_button_hp_mute_state_old == 1)
                    {
                        flag_hp_mute ^= 1;
                        mode_change = 1;
                    }
                }
                push_button_hp_mute_state_old = button_hp_mute;
                if(mode_change)
                {
                    save_value(hp_mute_path, (unsigned char)flag_hp_mute);
                    debug_printf("hp_mute changed: %d, saved to flash\n", flag_hp_mute);
                }
                if(mode_change)
                    if(flag_hp_mute)
                    {
                        unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); }
                        g_volume_level = 0;
                        for(int i = 0; i < 15; i++)
                            led_on(&led_ctx, led_d_physical_map[i]);
                        hp_mute_blink_tick = 1;
                    }
                    else
                    {
                        if (!dac_det_muted) {
                            if(dac_level == DAC_LEVEL_MIN)
                                unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); }
                            else
                                dac_volume(dac_level - DAC_LEVEL_MAX);
                        }
                        g_volume_level = dac_level;
                        hp_mute_blink_tick = 0;
                        for(int i = 0; i < 15; i++)
                            led_off(&led_ctx, led_d_physical_map[i]);
                        current_mic_led_pos = dac_gain_to_led[dac_level] - 1;
                        for(int i = 0; i <= current_mic_led_pos; i++)
                        {
                            if ((i < 15) && (i >= 0))
                                led_on(&led_ctx, led_d_physical_map[i]);
                        }
                    }

                // mute blink: 250ms on / 250ms off
                if(mic_mute_blink_tick > 0)
                {
                    mic_mute_blink_tick++;
                    if(mic_mute_blink_tick >= MUTE_BLINK_HALF_PERIOD * 2)
                        mic_mute_blink_tick = 1;
                    if(mic_mute_blink_tick == 1)
                        for(int i = 0; i < 15; i++) led_on(&led_ctx, led_l_physical_map[i]);
                    else if(mic_mute_blink_tick == MUTE_BLINK_HALF_PERIOD + 1)
                        for(int i = 0; i < 15; i++) led_off(&led_ctx, led_l_physical_map[i]);
                }
                if(hp_mute_blink_tick > 0)
                {
                    hp_mute_blink_tick++;
                    if(hp_mute_blink_tick >= MUTE_BLINK_HALF_PERIOD * 2)
                        hp_mute_blink_tick = 1;
                    if(hp_mute_blink_tick == 1)
                        for(int i = 0; i < 15; i++) led_on(&led_ctx, led_d_physical_map[i]);
                    else if(hp_mute_blink_tick == MUTE_BLINK_HALF_PERIOD + 1)
                        for(int i = 0; i < 15; i++) led_off(&led_ctx, led_d_physical_map[i]);
                }
                led_update_all(&led_ctx);
#endif

                GET_SHARED_GLOBAL(uac_vol, g_uac_vol);
                if (uac_vol != last_uac_vol) {
                    unsigned conv_vol = (0xffffffff - uac_vol + 1) >> 8;
                    //debug_printf("vol: - %d\n", conv_vol);
                    //chan_out_word(c_uac_vol, conv_vol);
                    c_uac_vol <: conv_vol;
                    last_uac_vol = uac_vol;
                }

                // 处理HID SET_VOLUME (0x93) 请求：应用新音量到DAC和LED
                if (g_request_volume_set) {
                    g_request_volume_set = 0;
                    unsigned new_level = g_volume_level;
                    if (new_level <= DAC_LEVEL_MAX) {
                        uint8_t new_led_count;
                        dac_level = new_level;
                        if (!dac_det_muted) {
                            if (dac_level == DAC_LEVEL_MIN)
                                unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); }
                            else
                                dac_volume(dac_level - DAC_LEVEL_MAX);
                        }
                        save_value(dac_vol_path, (unsigned char)dac_level);
                        // 更新DAC音量指示LED
                        new_led_count = dac_gain_to_led[dac_level];
                        for (int i = 0; i < 15; i++) {
                            if (i < new_led_count)
                                led_on(&led_ctx, led_d_physical_map[i]);
                            else
                                led_off(&led_ctx, led_d_physical_map[i]);
                        }
                        led_update_all(&led_ctx);
                        debug_printf("HID SET_VOLUME: dac_level=%d\n", dac_level);
                    }
                }

                // 处理HID SET_MIC_VOLUME (0x82) 请求：应用新麦克风增益到硬件和LED
                if (g_request_mic_volume_set) {
                    g_request_mic_volume_set = 0;
                    unsigned new_mic_level = g_mic_volume_level;
                    if (new_mic_level <= 37) {  // 0=mute, 1-37=0dB~36dB
                        uint8_t new_led_count;
                        if (new_mic_level == 0) {
                            // mute: 静音硬件，codec_adc_pga_gain_reg_value设为0（与编码器静音一致）
                            mic_volume(0);
                            codec_adc_pga_gain_reg_value = 0;
                            new_led_count = 0;
                        } else {
                            codec_adc_pga_gain_reg_value = new_mic_level;
                            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);
                        // 更新麦克风增益指示LED（L系列）
                        for (int i = 0; i < 15; i++) {
                            if (i < new_led_count)
                                led_on(&led_ctx, led_l_physical_map[i]);
                            else
                                led_off(&led_ctx, led_l_physical_map[i]);
                        }
                        led_update_all(&led_ctx);
                        debug_printf("HID SET_MIC_VOLUME: level=%d pga=%d\n", new_mic_level, codec_adc_pga_gain_reg_value);
                    }
                }

                // 处理HID SET_MONITOR_SWITCH (0x87) 请求：设置耳返开关
                if (g_request_monitor_switch_set) {
                    g_request_monitor_switch_set = 0;
                    unsigned new_mon = g_monitor_switch;
                    // 同步数字监听开关到tile1
                    cc_mic_level <: 0xFE;
                    cc_mic_level <: (unsigned)new_mon;
                    debug_printf("HID monitor sync: sw=%d\n", new_mon);
                    save_value(monitor_sw_path, (unsigned char)new_mon);
                    debug_printf("HID SET_MONITOR_SWITCH: %d\n", new_mon);
                }

                // 处理HID SET_AI_NOISE_STRENGTH (0x85) 请求
                {
                    unsigned dnr_req;
                    GET_SHARED_GLOBAL(dnr_req, g_request_dnr_strength_set);
                    if (dnr_req) {
                        SET_SHARED_GLOBAL(g_request_dnr_strength_set, 0);
                        unsigned new_strength;
                        GET_SHARED_GLOBAL(new_strength, g_dnr_strength);
#if DNR_ENABLE == 1
                        dnr_set_strength_level((unsigned char)new_strength);
#endif
                        if (new_strength == 0) {
                            flag_aidenoise_onoff = 0;
                            led_off(&led_ctx, LED_ANC);
                        } else {
                            flag_aidenoise_onoff = 1;
                            dnr_strength_saved = new_strength;
                            led_on(&led_ctx, LED_ANC);
                        }
                        led_update_all(&led_ctx);
                        debug_printf("HID SET_AI_NOISE_STRENGTH: strength=%d\n", new_strength);
                    }
                }

#if HID_CONTROLS == 1
                // HID监听音量变化主动上报（编码器旋转或HID命令导致的音量变化）
                {
                    unsigned current_volume_level = g_volume_level;
#if HID_DFU_EN
                    if (!g_in_fw_upgrade)
#endif
                    if (g_last_volume_level != current_volume_level && g_last_volume_level != 0xFF) {
                        unsafe {
                            unsigned char * unsafe ptr = (unsigned char * unsafe)hidSendData;
                            ptr[0] = 1;
                            ptr[1] = 0x77;
                            ptr[2] = 0x94;
                            ptr[3] = (unsigned char)current_volume_level;
                            for (int i = 4; i < HID_MAX_DATA_BYTES; i++)
                                ptr[i] = 0x00;
                        }
                        hidSetChangePending(0x1);
                        debug_printf("Volume changed: %d -> %d, HID report sent\n",
                                     g_last_volume_level, current_volume_level);
                    }
                    g_last_volume_level = current_volume_level;
                }

                // HID麦克风增益变化主动上报
                {
                    unsigned current_mic_level = g_mic_volume_level;
#if HID_DFU_EN
                    if (!g_in_fw_upgrade)
#endif
                    if (g_last_mic_volume_level != current_mic_level && g_last_mic_volume_level != 0xFF) {
                        unsafe {
                            unsigned char * unsafe ptr = (unsigned char * unsafe)hidSendData;
                            ptr[0] = 1;
                            ptr[1] = 0x77;
                            ptr[2] = 0x83;
                            ptr[3] = (unsigned char)current_mic_level;
                            for (int i = 4; i < HID_MAX_DATA_BYTES; i++)
                                ptr[i] = 0x00;
                        }
                        hidSetChangePending(0x1);
                        debug_printf("Mic volume changed: %d -> %d, HID report sent\n",
                                     g_last_mic_volume_level, current_mic_level);
                    }
                    g_last_mic_volume_level = current_mic_level;
                }

                // HID AI降噪强度变化主动上报（含首次开机上报：g_last_dnr_strength初始为0xFF）
#if DNR_ENABLE == 1
                {
                    unsigned current_dnr_strength;
                    GET_SHARED_GLOBAL(current_dnr_strength, g_dnr_strength);
#if HID_DFU_EN
                    if (!g_in_fw_upgrade)
#endif
                    if (g_last_dnr_strength != current_dnr_strength) {
                        unsafe {
                            unsigned char * unsafe ptr = (unsigned char * unsafe)hidSendData;
                            ptr[0] = 1;
                            ptr[1] = 0x77;
                            ptr[2] = 0x86;
                            ptr[3] = (unsigned char)current_dnr_strength;
                            for (int i = 4; i < HID_MAX_DATA_BYTES; i++)
                                ptr[i] = 0x00;
                        }
                        hidSetChangePending(0x1);
                        debug_printf("DNR strength changed: %d -> %d, HID report sent\n",
                                     g_last_dnr_strength, current_dnr_strength);
                    }
                    g_last_dnr_strength = current_dnr_strength;
                }
#endif

                // HID音效模式变化主动上报（按键切换或0xA4命令导致的模式变化，含首次开机上报）
                {
                    unsigned current_game_mode;
                    GET_SHARED_GLOBAL(current_game_mode, g_game_mode);
#if HID_DFU_EN
                    if (!g_in_fw_upgrade)
#endif
                    if (g_last_game_mode != current_game_mode) {
                        unsafe {
                            unsigned char * unsafe ptr = (unsigned char * unsafe)hidSendData;
                            ptr[0] = 1;
                            ptr[1] = 0x77;
                            ptr[2] = 0xA5;
                            ptr[3] = (unsigned char)current_game_mode;
                            for (int i = 4; i < HID_MAX_DATA_BYTES; i++)
                                ptr[i] = 0x00;
                        }
                        hidSetChangePending(0x1);
                        debug_printf("Game mode changed: %d -> %d, HID report sent\n",
                                     g_last_game_mode, current_game_mode);
                    }
                    g_last_game_mode = current_game_mode;
                }

#if USE_EX3D == 1
                // HID脚步增强状态变化主动上报（按键切换或HID 0xB0命令导致的变化，含首次开机上报）
                {
#if HID_DFU_EN
                    if (!g_in_fw_upgrade)
#endif
                    if (last_footstep_expand != saved_footstep ) {
                        unsafe {
                            unsigned char * unsafe ptr = (unsigned char * unsafe)hidSendData;
                            ptr[0] = 1;
                            ptr[1] = 0x77;
                            ptr[2] = 0xB1;
                            // EX3D GET CMD_EXPAND_GAIN = 0x193 (little-endian)
                            ptr[3] = 0x93; ptr[4] = 0x01; ptr[5] = 0x00; ptr[6] = 0x00;
                            // 返回值: expand_gain (uint32, little-endian)
                            ptr[7] = (unsigned char)saved_footstep;
                            ptr[8] = 0x00; ptr[9] = 0x00; ptr[10] = 0x00;
                            for (int i = 11; i < HID_MAX_DATA_BYTES; i++) ptr[i] = 0x00;
                        }
                        hidSetChangePending(0x1);
                        debug_printf("Footstep expand_gain changed: %d -> %d, HID 0xB1 report sent\n",
                                     last_footstep_expand, saved_footstep);
                    }
                    last_footstep_expand = saved_footstep;
                }
#endif
#endif

#if EQ_EN

                {
                    unsigned request_eq_mode, new_eq_mode;
                    unsigned force_request_mode_change;
                    GET_SHARED_GLOBAL(request_eq_mode, g_request_eq_mode);
                    GET_SHARED_GLOBAL(new_eq_mode, g_new_eq_mode);
                    GET_SHARED_GLOBAL(force_request_mode_change, g_force_request_eq_mode_change);
                    if (new_eq_mode != request_eq_mode)
                    {
                        // debug_printf("new eq mode != request eq mode\n");
                        SET_SHARED_GLOBAL(g_new_eq_mode, request_eq_mode);
                    }

                    if (force_request_mode_change == 1)
                    {
                        debug_printf("force request mode change\n");
                        SET_SHARED_GLOBAL(g_force_eq_mode_change, 1);
                        SET_SHARED_GLOBAL(g_force_request_eq_mode_change, 0);
                    }
                }


                eq_sync_counter++;
                if (eq_sync_counter >= 5) {  // 5 * 100ms = 500ms
                    eq_sync_counter = 0;

                    // 使用单参数存储系统保存脏参数（独立保存EQ参数）
                    if (eq_save_dirty_params() == 0) {
                       //debug_printf("Single EQ parameters synced to Flash successfully\n");
                    } else {
                        //debug_printf("Failed to sync single EQ parameters to Flash\n");
                    }

                    // 独立保存脏的增益
                    if (eq_save_dirty_gain() == 0) {
                       // debug_printf("Gain synced to Flash successfully\n");
                    } else {
                        //debug_printf("Failed to sync gain to Flash\n");
                    }

                    // 独立保存脏的模式名称
                    if (eq_save_dirty_names() == 0) {
                       // debug_printf("Mode names synced to Flash successfully\n");
                    } else {
                        //debug_printf("Failed to sync mode names to Flash\n");
                    }
                }
#endif

#if UAC1_MODE == 1
                GET_SHARED_GLOBAL(host_os, g_host_os);
                if (host_os == OS_WIN) {
                    unsigned flag = (saved_mode <= 1) ? MODE_F1_MUSIC_UAC2 : MODE_F3_F4_FPS_UAC2;
                    SetRoleSwitchFlag(flag);
#ifndef DISABLE_REBOOT
                    device_reboot();
                    while (1);
#endif
                }
#endif
                break;
            }
        }
    }
}

void AudioHwRemote(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, chanend c_audiohw_rx
#if HID_DFU_EN
                   , streaming chanend c_dfu_rx
#endif
                   , chanend c_mic_det
                  )
{
	i2c_master_if i2c[1];
	board_setup();
	par {
		i2c_master(i2c, 1, p_scl, p_sda, 300);
		{
			unsafe {i_i2c_client = i2c[0];}
			button_task(c_hidSendData, cc_mic_level, c_uac_vol, c_audiohw_rx
#if HID_DFU_EN
                        , c_dfu_rx
#endif
                        , c_mic_det
                       );
		}
	}
}


/* Configures the external audio hardware at startup */
void AudioHwInit()
{
   // p_ctl_mute <: 0;
	int result=0;

    sw_pll_fixed_clock(MCLK_48);



    // Wait for power supply to come up.
    delay_milliseconds(200);
}

/* Configures the external audio hardware for the required sample frequency */
void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC)
{
#if UAC1_MODE == 1
    static unsigned count = 1;
#else
    static unsigned count = 0;
#endif
   // p_ctl_mute <: 0;
	g_samfreq = samFreq;
    delay_milliseconds(2);
    {
        sw_pll_fixed_clock(mClk);
    }
    // 通知tile0 (button_task) 采样率已变化，用于配置NAU88C22寄存器
    unsafe {uc_audiohw <: samFreq; }
    unsafe {uc_audiohw <: dsdMode; }

    if (count++ > 0)
    {
      //  p_ctl_mute <: 1;
    }
    else
    {
        debug_printf("don't unmute at boot\n");
    }

    unsafe {uc_audiohw :> dsdMode; }
}


void mute_handler(chanend c_mic_det)
{
    // 开机mute sequence
    p_ctl_mute <: 0;
#if UAC1_MODE == 1
    delay_milliseconds(3000);
#else
    delay_milliseconds(1000);
#endif
    p_ctl_mute <: 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_mic1_in = mic1_in;
    unsigned prev_mic2_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;

                // 检测单个mic插拔事件
                unsigned mic1_changed = (mic1_in != prev_mic1_in);
                unsigned mic2_changed = (mic2_in != prev_mic2_in);
                unsigned any_changed = mic1_changed || mic2_changed;

                if (any_changed) {
                    // 状态变化：立即mute mic和DAC防止pop音
                    p_ctl_mute <: 0;
                    c_mic_det <: (unsigned)MIC_DET_MUTE;
                   // c_mic_det <: (unsigned)MIC_DET_DAC_MUTE;

                    // 配置ADC
                    //c_mic_det <: (unsigned)MIC_DET_REINIT_CODEC;
                    p_ctl_det <: 0;
                    delay_milliseconds(100);

                    //debug_printf("mic det change: mic1=%d mic2=%d -> mute all & reconfig\n", mic1_in, mic2_in);
                    p_ctl_det :> det_val;

                    // 等1s让插拔稳定
                    delay_milliseconds(900);
                    p_ctl_mute <: 0xf;

                    // 重新读取稳定状态
                    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;

                    // 恢复DAC状态
                    c_mic_det <: (unsigned)MIC_DET_DAC_UNMUTE;

                    if (any_mic_in) {
                        // 有mic插入，恢复mic音量状态
                        c_mic_det <: (unsigned)MIC_DET_UNMUTE;
                        debug_printf("mic stable -> unmute\n");
                    }
                    // 全拔出则保持mic mute

                    prev_mic1_in = mic1_in;
                    prev_mic2_in = mic2_in;
                    prev_any_mic_in = any_mic_in;

                    // 重新同步timer
                    tmr :> time;
                    time += MIC_DET_POLL_MS * 100000;
                }
                break;
            }
        }
    }
}
