diff --git a/sw_usb_audio/app_usb_aud_phaten_golden/CMakeLists.txt b/sw_usb_audio/app_usb_aud_phaten_golden/CMakeLists.txt index 58f9879..fa9d147 100644 --- a/sw_usb_audio/app_usb_aud_phaten_golden/CMakeLists.txt +++ b/sw_usb_audio/app_usb_aud_phaten_golden/CMakeLists.txt @@ -8,7 +8,7 @@ set(APP_PCA_ENABLE ON) ###=========================================================================### set(TARGET_HW_PHATEN_GSV2 ON) -set(CODEC_IS_AIC3204 ON) +set(CODEC_IS_NAU88C21 ON) # Configure host os detection here... (Windows or Non-Windows) #-----------------------------------------------------------------------------# @@ -24,9 +24,9 @@ if (TARGET_HW_PHATEN_GSV2) endif() # CODEC IC -if (CODEC_IS_AIC3204) - message("-- DAC: AIC3204 ---") - set(CODEC_IC CODEC_AIC3204) +if (CODEC_IS_NAU88C21) + message("-- DAC: NAU88C21 ---") + set(CODEC_IC CODEC_NAU88C21) endif() # Host OS detection diff --git a/sw_usb_audio/app_usb_aud_phaten_golden/src/core/PHATEN_GS.xn b/sw_usb_audio/app_usb_aud_phaten_golden/src/core/PHATEN_GS.xn index 4c8dda3..5c58628 100644 --- a/sw_usb_audio/app_usb_aud_phaten_golden/src/core/PHATEN_GS.xn +++ b/sw_usb_audio/app_usb_aud_phaten_golden/src/core/PHATEN_GS.xn @@ -20,31 +20,36 @@ --> - + - - - - - - - - + + - - - - + + + + + + + + + + + + + + + - + diff --git a/sw_usb_audio/app_usb_aud_phaten_golden/src/core/xua_conf.h b/sw_usb_audio/app_usb_aud_phaten_golden/src/core/xua_conf.h index bcd4a43..7d6dcda 100644 --- a/sw_usb_audio/app_usb_aud_phaten_golden/src/core/xua_conf.h +++ b/sw_usb_audio/app_usb_aud_phaten_golden/src/core/xua_conf.h @@ -110,11 +110,11 @@ /*** Defines relating to audio frequencies ***/ /* Master clock defines (in Hz) */ #ifndef MCLK_441 -#define MCLK_441 (512*44100) /* 44.1, 88.2 etc */ +#define MCLK_441 (256*44100) /* 44.1, 88.2 etc */ #endif #ifndef MCLK_48 -#define MCLK_48 (512*48000) /* 48, 96 etc */ +#define MCLK_48 (256*48000) /* 48, 96 etc */ #endif /* Minumum sample frequency device runs at */ diff --git a/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/audiohw.xc b/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/audiohw.xc index 24987ba..3477c9b 100644 --- a/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/audiohw.xc +++ b/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/audiohw.xc @@ -15,12 +15,99 @@ #include "user_uart.h" #include "debug_print.h" -#if defined (CODEC_AIC3204) #include "eq_flash_storage.h" -#include "codec_ti3204.h" -#else -#error "No codec selected" -#endif + +/* NAU88C21 codec (Nuvoton), I2C address 0x1B, 16-bit reg/val */ +#define NAU88C21_I2C_ADDR 0x1B + +static const uint16_t nau88c22_registers[][4] = { +{0x00, 0x00, 0x00, 0x00}, +{0x00, 0x01, 0x0D, 0xFF}, +{0x00, 0x03, 0x20, 0x50}, +{0x00, 0x04, 0x00, 0x00}, +{0x00, 0x05, 0x00, 0xBC}, +{0x00, 0x06, 0x00, 0x08}, +{0x00, 0x07, 0x00, 0x10}, +{0x00, 0x08, 0x40, 0x00}, +{0x00, 0x09, 0x69, 0x00}, +{0x00, 0x0A, 0x00, 0x31}, +{0x00, 0x0B, 0x26, 0xE9}, +{0x00, 0x0D, 0xC0, 0x00}, +{0x00, 0x0F, 0x00, 0x00}, +{0x00, 0x10, 0x00, 0x00}, +{0x00, 0x11, 0x00, 0x00}, +{0x00, 0x12, 0xFF, 0xFF}, +{0x00, 0x13, 0x00, 0x00}, +{0x00, 0x1A, 0x00, 0x00}, +{0x00, 0x1B, 0x00, 0x00}, +{0x00, 0x1C, 0x00, 0x0E}, +{0x00, 0x1D, 0x20, 0x02}, +{0x00, 0x1E, 0x00, 0x00}, +{0x00, 0x1F, 0x00, 0x00}, +{0x00, 0x21, 0x00, 0x00}, +{0x00, 0x22, 0x00, 0x00}, +{0x00, 0x23, 0x00, 0x00}, +{0x00, 0x24, 0x00, 0x00}, +{0x00, 0x25, 0x00, 0x00}, +{0x00, 0x26, 0x00, 0x00}, +{0x00, 0x27, 0x00, 0x00}, +{0x00, 0x28, 0x00, 0x00}, +{0x00, 0x29, 0x00, 0x00}, +{0x00, 0x2A, 0x00, 0x00}, +{0x00, 0x2B, 0x40, 0x02}, +{0x00, 0x2C, 0x00, 0x82}, +{0x00, 0x2D, 0x00, 0x00}, +{0x00, 0x2F, 0x00, 0x00}, +{0x00, 0x30, 0x00, 0x40}, +{0x00, 0x31, 0x00, 0x00}, +{0x00, 0x32, 0x00, 0x00}, +{0x00, 0x34, 0xCF, 0xCF}, +{0x00, 0x35, 0xCF, 0xCF}, +{0x00, 0x36, 0x14, 0x86}, +{0x00, 0x37, 0x0F, 0x12}, +{0x00, 0x38, 0x25, 0xFF}, +{0x00, 0x39, 0x34, 0x57}, +{0x00, 0x3A, 0x14, 0x86}, +{0x00, 0x3B, 0x0F, 0x12}, +{0x00, 0x3C, 0x25, 0xF9}, +{0x00, 0x3D, 0x34, 0x57}, +{0x00, 0x41, 0x00, 0x00}, +{0x00, 0x42, 0x00, 0x00}, +{0x00, 0x43, 0x00, 0x00}, +{0x00, 0x44, 0x00, 0x00}, +{0x00, 0x45, 0x00, 0x00}, +{0x00, 0x46, 0x00, 0x00}, +{0x00, 0x47, 0x00, 0x00}, +{0x00, 0x48, 0x00, 0x00}, +{0x00, 0x49, 0x00, 0x00}, +{0x00, 0x4A, 0x00, 0x00}, +{0x00, 0x4B, 0x20, 0x07}, +{0x00, 0x4C, 0x00, 0x00}, +{0x00, 0x4D, 0x00, 0x00}, +{0x00, 0x53, 0x02, 0x78}, +{0x00, 0x54, 0x00, 0x02}, +{0x00, 0x55, 0x00, 0x00}, +{0x00, 0x58, 0x1B, 0x22}, +{0x00, 0x59, 0x20, 0x00}, +{0x00, 0x66, 0x00, 0x60}, +{0x00, 0x68, 0x00, 0x00}, +{0x00, 0x69, 0x00, 0x00}, +{0x00, 0x6A, 0x10, 0x03}, +{0x00, 0x6B, 0x00, 0x00}, +{0x00, 0x71, 0x00, 0x11}, +{0x00, 0x72, 0x04, 0x70}, +{0x00, 0x73, 0x33, 0x08}, +{0x00, 0x74, 0x15, 0x06}, +{0x00, 0x76, 0x31, 0x40}, +{0x00, 0x77, 0x00, 0x12}, +{0x00, 0x7E, 0x01, 0x01}, +{0x00, 0x7F, 0xC0, 0x3F}, +{0x00, 0x80, 0x07, 0x20}, +{0x00, 0x81, 0x00, 0x08}, +{0x00, 0x82, 0x00, 0x60}, +}; + +#include "keys.h" extern "C" { #include "sw_pll.h" @@ -96,137 +183,115 @@ unsigned g_led_color = LED_OFF; unsigned g_led_blink_count = 0; unsigned g_led_blink_is_white = 0; -port p_scl = PORT_I2C_SCL; -port p_sda = PORT_I2C_SDA; -port p_adc_rst = PORT_ADC_RST; -port p_ctrl = PORT_GPI; -on tile[0]: port p_ctrl_keys = XS1_PORT_8C; +/* ========================================================================= + * HTR3236 36-channel LED PWM driver (I2C addr 0x3C, AD=GND) + * ========================================================================= */ +#define HTR3236_I2C_ADDR 0x3C -/* Board setup for XU316 MC Audio (1v1) */ +/* Function LED HTR3236 OUT channels */ +#define LED_ANC_CH 1 /* OUT1 - AI denoise indicator */ +#define LED_MUSIC_CH 2 /* OUT2 - Music stereo mode */ +#define LED_FOOTSTEP_CH 3 /* OUT3 - Footstep enhancement */ +#define LED_AI71_CH 34 /* OUT34 - AI 7.1 virtual surround */ +#define LED_GAME_CH 35 /* OUT35 - Game/spatial mode */ + +/* L-series (mic volume bar): logical L1-L15 → physical HTR3236 OUT */ +static const uint8_t led_l_map[15] = {15,14,13,11,10,9,8,7,6,5,4,12,18,17,16}; +/* D-series (HP volume bar): logical D1-D15 → physical HTR3236 OUT */ +static const uint8_t led_d_map[15] = {21,20,19,26,33,32,31,30,29,28,27,25,24,23,22}; + +port p_scl = PORT_I2C_SCL; /* XS1_PORT_1P per SY102 HW */ +port p_sda = PORT_I2C_SDA; /* XS1_PORT_1O */ +on tile[0]: out port p_htr3236_sdb = PORT_HTR3236_SDB; /* XS1_PORT_1N - LED driver enable */ +on tile[0]: in port p_mic_enc1 = PORT_MIC_GAIN_ENCODER1; /* XS1_PORT_4F */ +on tile[0]: in port p_mic_enc2 = PORT_MIC_GAIN_ENCODER2; /* XS1_PORT_4E */ +on tile[0]: in port p_hp_enc = PORT_HP_GAIN_ENCODER; /* XS1_PORT_8D */ +on tile[0]: in port p_btn_music = PORT_BUTTON_MUSIC_MODE; /* XS1_PORT_1A */ +on tile[0]: in port p_btn_game = PORT_BUTTON_GAME_MODE; /* XS1_PORT_1L */ +on tile[0]: in port p_btn_ai71 = PORT_BUTTON_AI71_ONOFF; /* XS1_PORT_1M */ + +/* Board setup for SY102 hardware */ void board_setup() { - p_adc_rst <: 0; - p_ctrl <: 0; - + /* Assert HTR3236 SDB low briefly then bring high to enable LED driver */ + p_htr3236_sdb <: 0; delay_milliseconds(10); - - p_ctrl <: 0x90; //0XFF; - p_adc_rst <: 1; + p_htr3236_sdb <: 1; debug_printf("board_setup OK."); } -// 改动原因:原实现为void但包含`return 0;`,且未正确回写val(还写反了 data[0] = val), -// 这会引入未定义行为/潜在栈破坏,导致调用方(如button_task)在I2C访问后异常卡死。 -// 这里改为返回i2c_regop_res_t并正确回填val,调用方可选择检查返回值。 -i2c_regop_res_t CODEC_IC_REGREAD(unsigned reg, unsigned &val) +/* Write a 16-bit register on the NAU88C21 codec (reg and val are both 16-bit) */ +static void CODEC_NAU_REGWRITE(uint16_t reg, uint16_t val) { - i2c_regop_res_t result; - - uint8_t a_reg[1] = {reg}; - uint8_t data[1] = {0}; + uint8_t buf[4] = {(uint8_t)(reg >> 8), (uint8_t)(reg & 0xFF), + (uint8_t)(val >> 8), (uint8_t)(val & 0xFF)}; size_t n; - i2c_res_t res; - - unsafe - { - res = i_i2c_client.write(CODEC_I2C_DEVICE_ADDR, a_reg, 1, n, 0); - - if (n != 1) - { - result = I2C_REGOP_DEVICE_NACK; // 改动原因:写寄存器地址阶段未成功(无ACK/不完整) - i_i2c_client.send_stop_bit(); - return result; - } - - res = i_i2c_client.read(CODEC_I2C_DEVICE_ADDR, data, 1, 1); - } - // 改动原因:修复方向错误,应将读到的data[0]写回到val。 - val = data[0]; - - debug_printf("CODEC_IC_REGREAD reg: %d, val: %d\n", reg, data[0]); - if (res == I2C_ACK) - { - result = I2C_REGOP_SUCCESS; - } - else - { - result = I2C_REGOP_DEVICE_NACK; - } - return result; -} -// 改动原因:原实现为void但返回了I2C_REGOP_*值,属于未定义行为,可能破坏返回地址/栈,导致button_task在mic按键后卡死。 -// 这里将返回类型改为i2c_regop_res_t,语义与实现一致。 -i2c_regop_res_t CODEC_IC_REGWRITE(unsigned reg, unsigned val) -{ - uint8_t a_data[2] = {reg, val}; - size_t n; - - unsafe - { - debug_printf("CODEC_IC_REGWRITE reg: %d, val: %d\n", reg, val); - i_i2c_client.write(CODEC_I2C_DEVICE_ADDR, a_data, 2, n, 1); - } - if (n == 0) - { - debug_printf("CODEC_IC_REGWRITE n: %d\n", n); - return I2C_REGOP_DEVICE_NACK; - } - if (n < 2) - { - debug_printf("CODEC_IC_REGWRITE n: %d\n", n); - return I2C_REGOP_INCOMPLETE; - } - - debug_printf("CODEC_IC_REGWRITE === reg: %d, val: %d\n", reg, val); - return I2C_REGOP_SUCCESS; + unsafe { i_i2c_client.write(NAU88C21_I2C_ADDR, buf, 4, n, 1); } } -// tile 1 -uint8_t mic_vol = 60; //84; // default +42dB as 20250408 //56; //0x2b; -#define MIN_MIC_VOL_LEVEL 0 -#define MAX_MIC_VOL_LEVEL 84 // max +42dB as 20250408 //0x37 -#define MIC_VOL_STEP 4 -#define MIC_VOL_THRD MIC_VOL_STEP - 1 +/* NAU88C21 mic PGA gain: reg 0x7E, value = (level << 8), range 1..38 */ +uint8_t mic_vol = 19; /* default mid gain (~+18dB) */ +#define MIN_MIC_VOL_LEVEL 1 +#define MAX_MIC_VOL_LEVEL 38 +#define MIC_VOL_STEP 1 +#define MIC_VOL_THRD 0 + int i2c_codec_mic_vol_up(void) { -#if defined (CODEC_AIC3204) - //delay_milliseconds(20); - if (mic_vol < MAX_MIC_VOL_LEVEL) { - mic_vol=mic_vol+MIC_VOL_STEP; - if (mic_vol > MAX_MIC_VOL_LEVEL) { - mic_vol = MAX_MIC_VOL_LEVEL; - } - CODEC_IC_REGWRITE(AIC3204_PAGE_CTRL, 1); - CODEC_IC_REGWRITE(0x3c, mic_vol); - } - debug_printf("vol %d\n", mic_vol); - delay_milliseconds(10); -#endif - return 0; + if (mic_vol < MAX_MIC_VOL_LEVEL) { + mic_vol++; + CODEC_NAU_REGWRITE(0x007E, (uint16_t)mic_vol << 8); + } + return 0; } + int i2c_codec_mic_vol_down(void) { -#if defined (CODEC_AIC3204) - //delay_milliseconds(20); - if ((mic_vol > MIN_MIC_VOL_LEVEL) && (mic_vol > MIC_VOL_THRD)) { -// if (mic_vol == MAX_MIC_VOL_LEVEL) { -// mic_vol = MAX_MIC_VOL_LEVEL - 3; -// } else { - mic_vol=mic_vol-MIC_VOL_STEP; -// } - CODEC_IC_REGWRITE(AIC3204_PAGE_CTRL, 1); - CODEC_IC_REGWRITE(0x3c, mic_vol); - } - debug_printf("vol %d\n", mic_vol); - delay_milliseconds(10); -#endif - return 0; + if (mic_vol > MIN_MIC_VOL_LEVEL) { + mic_vol--; + CODEC_NAU_REGWRITE(0x007E, (uint16_t)mic_vol << 8); + } + return 0; } +/* ========================================================================= + * HTR3236 helper functions (use shared i_i2c_client) + * ========================================================================= */ +static void htr3236_write_reg(uint8_t reg, uint8_t val) +{ + uint8_t buf[2] = {reg, val}; + size_t n; + unsafe { i_i2c_client.write(HTR3236_I2C_ADDR, buf, 2, n, 1); } +} + +static void htr3236_led_init(void) +{ + htr3236_write_reg(0x00, 0x01); /* software wake: normal op */ + htr3236_write_reg(0x4B, 0x01); /* set PWM frequency to 22kHz */ + /* Configure all 35 channels: IMAX/2 current, enable=1, PWM=0 */ + for (int ch = 1; ch <= 35; ch++) { + htr3236_write_reg((uint8_t)(0x25 + ch), 0x03); /* LED ctrl reg */ + htr3236_write_reg((uint8_t)ch, 0); /* PWM = 0 */ + } + htr3236_write_reg(0x25, 0x00); /* latch update */ +} + +static void htr3236_led_on(uint8_t ch) { htr3236_write_reg(ch, 1); } +static void htr3236_led_off(uint8_t ch) { htr3236_write_reg(ch, 0); } +static void htr3236_do_update(void) { htr3236_write_reg(0x25, 0x00); } + +/* Map mic_vol (0..MAX_MIC_VOL_LEVEL) to LED bar count (0..15) */ +static int mic_vol_to_led_count(int v) +{ + if (v <= 0) return 0; + if (v >= MAX_MIC_VOL_LEVEL) return 15; + return v * 15 / MAX_MIC_VOL_LEVEL; +} + // tile 0 -#define KEY_POLLING_INTERVAL 10000000L // 100ms polling interval +#define KEY_POLLING_INTERVAL 100000 /* 1ms polling — required for encoder responsiveness */ #ifndef HID_MAX_DATA_BYTES #define HID_MAX_DATA_BYTES (64) @@ -263,127 +328,34 @@ extern "C" { void codec_init(void) { - unsigned page_ctrl; - { - CODEC_IC_REGWRITE(AIC3204_PAGE_CTRL, 0x00); - - // Initiate SW reset (PLL is powered off as part of reset) - CODEC_IC_REGWRITE(AIC3204_SW_RST, 0x01); - delay_milliseconds(10); - - // Program clock settings - - // Default is CODEC_CLKIN is from MCLK pin. Don't need to change this. - // Power up NDAC and set to 1 - CODEC_IC_REGWRITE(AIC3204_NDAC, 0x81); - - CODEC_IC_REGREAD(AIC3204_NDAC, page_ctrl); - debug_printf("page_ctrl: %d\n", page_ctrl); - // Power up MDAC and set to 4 - CODEC_IC_REGWRITE(AIC3204_MDAC, 0x84); - // Power up NADC and set to 1 - CODEC_IC_REGWRITE(AIC3204_NADC, 0x81); - // Power up MADC and set to 4 - CODEC_IC_REGWRITE(AIC3204_MADC, 0x84); - // Program DOSR = 128 - CODEC_IC_REGWRITE(AIC3204_DOSR_LSB, 0x80); - // Program AOSR = 128 - CODEC_IC_REGWRITE(AIC3204_AOSR, 0x80); - // Set Audio Interface Config: I2S, 24 bits, slave mode, DOUT always driving. - CODEC_IC_REGWRITE(AIC3204_CODEC_IF, 0x20); - // Program the DAC processing block to be used - PRB_P1 - CODEC_IC_REGWRITE(AIC3204_DAC_SIG_PROC, 0x01); - // Program the ADC processing block to be used - PRB_R1 - CODEC_IC_REGWRITE(AIC3204_ADC_SIG_PROC, 0x01); // 3D------------------------- - - // Select Page 1 - CODEC_IC_REGWRITE(AIC3204_PAGE_CTRL, 0x01); - // Enable the internal AVDD_LDO: - CODEC_IC_REGWRITE(AIC3204_LDO_CTRL, 0x09); - - // - // Program Analog Blocks - // --------------------- - // - // Disable Internal Crude AVdd in presence of external AVdd supply or before powering up internal AVdd LDO - CODEC_IC_REGWRITE(AIC3204_PWR_CFG, 0x08); - // Enable Master Analog Power Control - CODEC_IC_REGWRITE(AIC3204_LDO_CTRL, 0x01); - // Set Common Mode voltages: Full Chip CM to 0.9V and Output Common Mode for Headphone to 1.65V and HP powered from LDOin @ 3.3V. - CODEC_IC_REGWRITE(AIC3204_CM_CTRL, 0x33); - // Set PowerTune Modes - // Set the Left & Right DAC PowerTune mode to PTM_P3/4. Use Class-AB driver. - CODEC_IC_REGWRITE(AIC3204_PLAY_CFG1, 0x00); - CODEC_IC_REGWRITE(AIC3204_PLAY_CFG2, 0x00); - // Set ADC PowerTune mode PTM_R4. - CODEC_IC_REGWRITE(AIC3204_ADC_PTM, 0x00); - // Set MicPGA startup delay to 3.1ms - CODEC_IC_REGWRITE(AIC3204_AN_IN_CHRG, 0x31); - // Set the REF charging time to 40ms - CODEC_IC_REGWRITE(AIC3204_REF_STARTUP, 0x01); - // HP soft stepping settings for optimal pop performance at power up - // Rpop used is 6k with N = 6 and soft step = 20usec. This should work with 47uF coupling - // capacitor. Can try N=5,6 or 7 time constants as well. Trade-off delay vs “pop” sound. - CODEC_IC_REGWRITE(AIC3204_HP_START, 0x25); - // Route Left DAC to HPL - CODEC_IC_REGWRITE(AIC3204_HPL_ROUTE, 0x08); - // Route Right DAC to HPR - CODEC_IC_REGWRITE(AIC3204_HPR_ROUTE, 0x08); - CODEC_IC_REGWRITE(0x0e, 0x08); - CODEC_IC_REGWRITE(0x0f, 0x08); - CODEC_IC_REGWRITE(0x12, 0x3a); - CODEC_IC_REGWRITE(0x13, 0x3a); // Gain-0DB - // We are using Line input with low gain for PGA so can use 40k input R but lets stick to 20k for now. - // Route IN2_L to LEFT_P with 20K input impedance - CODEC_IC_REGWRITE(AIC3204_LPGA_P_ROUTE, 0x20); //--- - // Route IN2_R to LEFT_M with 20K input impedance - CODEC_IC_REGWRITE(AIC3204_LPGA_N_ROUTE, 0x20); //--- - // Route IN1_R to RIGHT_P with 20K input impedance - CODEC_IC_REGWRITE(AIC3204_RPGA_P_ROUTE, 0x80); //--- - // Route IN1_L to RIGHT_M with 20K input impedance - CODEC_IC_REGWRITE(AIC3204_RPGA_N_ROUTE, 0x20); //--- - // Unmute HPL and set gain to 0dB - CODEC_IC_REGWRITE(AIC3204_HPL_GAIN, 0x06); - // Unmute HPR and set gain to 0dB - CODEC_IC_REGWRITE(AIC3204_HPR_GAIN, 0x06); - // Unmute Left MICPGA, Set Gain to 0dB. - CODEC_IC_REGWRITE(AIC3204_LPGA_VOL, 0x00); - // Unmute Right MICPGA, Set Gain to 0dB. - CODEC_IC_REGWRITE(AIC3204_RPGA_VOL, 0x00); - // Power up HPL and HPR drivers - CODEC_IC_REGWRITE(AIC3204_OP_PWR_CTRL, 0x30); // HP powerUp - // CODEC_REGWRITE(AIC3204_OP_PWR_CTRL, 0x0C); // LO powerUP - // Wait for 2.5 sec for soft stepping to take effect - // vTaskDelay(pdMS_TO_TICKS(2500)); - delay_milliseconds(20); - - CODEC_IC_REGWRITE(AIC3204_PAGE_CTRL, 0x00); - // Power up the Left and Right DAC Channels. Route Left data to Left DAC and Right data to Right DAC. - // DAC Vol control soft step 1 step per DAC word clock. - CODEC_IC_REGWRITE(AIC3204_DAC_CH_SET1, 0xd4); - // Power up Left and Right ADC Channels, ADC vol ctrl soft step 1 step per ADC word clock. - CODEC_IC_REGWRITE(AIC3204_ADC_CH_SET, 0xc0); - // Unmute Left and Right DAC digital volume control - CODEC_IC_REGWRITE(AIC3204_DAC_CH_SET2, 0x00); - // Unmute Left and Right ADC Digital Volume Control. - CODEC_IC_REGWRITE(AIC3204_ADC_FGA_MUTE, 0x00); - - CODEC_IC_REGWRITE(AIC3204_PAGE_CTRL, 1); // page1 - CODEC_IC_REGWRITE(0x47, 0x32); // analog input quick charging configure - CODEC_IC_REGWRITE(0x7b, 0x01); // power up config - CODEC_IC_REGWRITE(0x33, 0x60); //---------0x78 used fail-------jian added ----MICBIAS - CODEC_IC_REGWRITE(0x37, 0x80); - CODEC_IC_REGWRITE(0x39, 0x20); // IN1L to RIGHT MICPGA with 20k ohm - - CODEC_IC_REGWRITE(0x3c, mic_vol /*40*/); // Right MICPGA VOL --5a-45DB 5e--47db :3d--ap实际测试25DB增益---跟客户样品一致 (一般30DB) - CODEC_IC_REGWRITE(AIC3204_PAGE_CTRL, 0); // page0 - CODEC_IC_REGWRITE(0x51, 0xc0); // - CODEC_IC_REGWRITE(0x52, 0x00); // - //CODEC_IC_REGWRITE(AIC3204_ADC_CH1_SET, 0x0C); // ADC L_CH vol - //CODEC_IC_REGWRITE(AIC3204_ADC_CH2_SET, 0x0C); // ADC R_CH vol - } + /* Write all NAU88C21 registers from the init table */ + int n = sizeof(nau88c22_registers) / sizeof(nau88c22_registers[0]); + for (int i = 0; i < n; i++) { + uint16_t reg = nau88c22_registers[i][1]; + uint16_t val = ((uint16_t)nau88c22_registers[i][2] << 8) | nau88c22_registers[i][3]; + CODEC_NAU_REGWRITE(reg, val); + } + /* Set default mic PGA gain */ + CODEC_NAU_REGWRITE(0x007E, (uint16_t)mic_vol << 8); + delay_milliseconds(20); } +/* + * button_task — SY102 hardware port layout: + * + * Mic gain encoder: phase A = p_mic_enc1 bit2 (PORT_4F), phase B = p_mic_enc2 bit2 (PORT_4E) + * Mic mute button: p_mic_enc1 bit3 (PORT_4F), active low + * AI denoise toggle: p_mic_enc2 bit3 (PORT_4E), active low + * Footstep toggle: p_mic_enc1 bit1 (PORT_4F), active low + * + * HP gain encoder: phase A = p_hp_enc bit4 (PORT_8D), phase B = p_hp_enc bit5 (PORT_8D) + * HP mute button: p_hp_enc bit6 (PORT_8D), active low + * + * Mode buttons (1-bit ports, active low): + * p_btn_music (PORT_1A) = music stereo mode + * p_btn_game (PORT_1L) = game/spatial mode + * p_btn_ai71 (PORT_1M) = AI 7.1 virtual surround on/off + */ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol) { timer tmr; @@ -392,15 +364,33 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol) #if EQ_EN static unsigned eq_sync_counter = 0; #endif - unsigned port_ctrl_keys = 0, curr_ctrl_keys = 0, last_ctrl_keys = 0, keys_changed = 0; - int debounce_cnt = 0; - static unsigned isMute = 0; - unsigned char tmp = 0; unsigned hidData0; + /* Mic encoder B-trigger state (3-sample debounce) */ + uint8_t mic_prev_enc_a = 0, mic_rotation_active = 0, mic_sample_count = 0; + + /* HP encoder B-trigger state (3-sample debounce) */ + uint8_t hp_prev_enc_a = 0, hp_rotation_active = 0, hp_sample_count = 0; + + /* Debounce counters */ + int mic_mute_cnt = 0, hp_mute_cnt = 0; + int btn_music_cnt = 0, btn_game_cnt = 0, btn_ai71_cnt = 0; + + /* Mode/function LED state flags */ + unsigned flag_music_mode = 0, flag_game_mode = 0, flag_ai71_onoff = 0; + + /* HP volume tracking for LED bar (local counter, same scale as mic_vol) */ + int hp_vol = 0; + + static unsigned isMicMute = 0; + static unsigned isHpMute = 0; + delay_milliseconds(20); codec_init(); + /* Initialize HTR3236 LED driver over shared I2C bus */ + htr3236_led_init(); + delay_milliseconds(500); debug_printf("button task start\n"); @@ -422,24 +412,36 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol) SET_SHARED_GLOBAL(g_game_mode, saved_mode); debug_printf("Set new g_game_mode to %d\n", saved_mode); - // 音频模式传输命令(byte协议,与hid_button_task的chan_in_byte对应,不带END token) + /* 音频模式传输命令 */ xc_chan_out_byte(cc_mic_level, 0xFC); xc_chan_out_byte(cc_mic_level, (unsigned char)saved_mode); debug_printf("Sent audio_mode %d to hid_button_task via cc_mic_level channel\n", saved_mode); - p_ctrl_keys :> port_ctrl_keys; - if ((port_ctrl_keys & KEY_MUTE) == 0) { - debug_printf("unmuted\n"); - isMute = 0; - SET_SHARED_GLOBAL(g_mute_on_off_t0, MUTE_OFF); - } else { - debug_printf("muted\n"); - isMute = 1; - SET_SHARED_GLOBAL(g_mute_on_off_t0, MUTE_ON); + /* Light initial mode LED (exclusive: only one mode LED on) */ + if (saved_mode == 0) { htr3236_led_on(LED_MUSIC_CH); flag_music_mode = 1; } + else if (saved_mode == 1) { htr3236_led_on(LED_GAME_CH); flag_game_mode = 1; } + else if (saved_mode == 2) { htr3236_led_on(LED_AI71_CH); flag_ai71_onoff = 1; } + /* Light initial mic volume LED bar */ + { + int led_cnt = mic_vol_to_led_count(mic_vol); + for (int i = 0; i < led_cnt; i++) htr3236_led_on(led_l_map[i]); + } + htr3236_do_update(); + + /* Read initial mic mute state from hardware */ + { + unsigned enc1_init; + p_mic_enc1 :> enc1_init; + if ((enc1_init & KEY_MIC_MUTE) == 0) { + isMicMute = 1; + SET_SHARED_GLOBAL(g_mute_on_off_t0, MUTE_ON); + } else { + isMicMute = 0; + SET_SHARED_GLOBAL(g_mute_on_off_t0, MUTE_OFF); + } + /* B-trigger encoder needs no seeding */ } - last_ctrl_keys = (port_ctrl_keys & KEY_BITS); - last_ctrl_keys ^= KEY_MUTE; tmr :> t_val; t_val += KEY_POLLING_INTERVAL; @@ -474,65 +476,239 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol) case tmr when timerafter(t_val) :> void: t_val += KEY_POLLING_INTERVAL; { - unsigned curr; - p_ctrl_keys :> curr; - curr_ctrl_keys = curr & KEY_BITS; + unsigned enc1, enc2, hp; + unsigned btn_m, btn_g, btn_a; - // 防抖:连续2次检测到相同变化才响应 - if (curr_ctrl_keys != last_ctrl_keys) { - debounce_cnt++; - if (debounce_cnt >= 2) { - debounce_cnt = 0; - keys_changed = curr_ctrl_keys ^ last_ctrl_keys; - tmp = 0; - switch (keys_changed) { - case KEY_MIC_VOL_DN: - case KEY_MIC_VOL_UP: - if ((isMute == 0) && ((curr_ctrl_keys & KEY_MIC_VOL_DN) == 0)) { - i2c_codec_mic_vol_down(); - debug_printf("KEY_MIC_VOL_DN pressed\n"); - } else { - if ((isMute == 0) && ((curr_ctrl_keys & KEY_MIC_VOL_UP) == 0)) { + p_mic_enc1 :> enc1; + p_mic_enc2 :> enc2; + p_hp_enc :> hp; + p_btn_music :> btn_m; + p_btn_game :> btn_g; + p_btn_ai71 :> btn_a; + + /* --- Mic gain encoder (B-trigger, 3-sample debounce) --- */ + /* B low = rotating; A at trigger determines CW(1) or CCW(2) */ + { + uint8_t mic_b = ((enc2 & KEY_MIC_ENC_B) == 0); + uint8_t mic_a = ((enc1 & KEY_MIC_ENC_A) != 0); + + if (mic_b) { + if (!mic_rotation_active) { + mic_prev_enc_a = mic_a; + mic_sample_count = 1; + mic_rotation_active = 1; + } else { + mic_sample_count++; + if (mic_sample_count >= 3 && mic_a != mic_prev_enc_a) { + if (mic_a) { /* CW: vol up */ + if (isMicMute == 0) { + uint8_t old_cnt = (uint8_t)mic_vol_to_led_count(mic_vol); i2c_codec_mic_vol_up(); - debug_printf("KEY_MIC_VOL_UP pressed\n"); + uint8_t new_cnt = (uint8_t)mic_vol_to_led_count(mic_vol); + if (new_cnt > old_cnt) { + htr3236_led_on(led_l_map[new_cnt - 1]); + htr3236_do_update(); + } + } + } else { /* CCW: vol down */ + if (isMicMute == 0) { + uint8_t old_cnt = (uint8_t)mic_vol_to_led_count(mic_vol); + i2c_codec_mic_vol_down(); + uint8_t new_cnt = (uint8_t)mic_vol_to_led_count(mic_vol); + if (new_cnt < old_cnt) { + htr3236_led_off(led_l_map[old_cnt - 1]); + htr3236_do_update(); + } } } - break; - case KEY_MUTE: - if ((curr_ctrl_keys & KEY_MUTE) == 0) { - isMute = 0; - SET_SHARED_GLOBAL(g_mute_on_off_t0, MUTE_OFF); - xc_chan_out_byte(cc_mic_level, UNMUTED_MIC); - debug_printf("MUTE: unmuted\n"); - } else { - isMute = 1; - SET_SHARED_GLOBAL(g_mute_on_off_t0, MUTE_ON); - xc_chan_out_byte(cc_mic_level, MUTED_MIC); - debug_printf("MUTE: muted\n"); - } - break; -#if (HID_CONTROLS == 1) - case KEY_PLAY_VOL_DN: - if ((curr_ctrl_keys & KEY_PLAY_VOL_DN) == 0) { - debug_printf("KEY_PLAY_VOL_DN pressed\n"); - update_button(HID_CONTROL_VOLDN); - } - break; - case KEY_PLAY_VOL_UP: - if ((curr_ctrl_keys & KEY_PLAY_VOL_UP) == 0) { - update_button(HID_CONTROL_VOLUP); - } - break; -#endif - default: - break; + mic_rotation_active = 0; + mic_sample_count = 0; + } } - last_ctrl_keys = curr_ctrl_keys; + } else { + mic_rotation_active = 0; + mic_sample_count = 0; } - } else { - debounce_cnt = 0; } + /* --- HP gain encoder (B-trigger, 3-sample debounce) --- */ + { + uint8_t hp_b = ((hp & KEY_HP_ENC_B) == 0); + uint8_t hp_a = ((hp & KEY_HP_ENC_A) != 0); + + if (hp_b) { + if (!hp_rotation_active) { + hp_prev_enc_a = hp_a; + hp_sample_count = 1; + hp_rotation_active = 1; + } else { + hp_sample_count++; + if (hp_sample_count >= 3 && hp_a != hp_prev_enc_a) { + if (hp_a) { /* CW: HP vol up */ + if (isHpMute == 0) { + uint8_t old_cnt = (uint8_t)mic_vol_to_led_count(hp_vol); + hp_vol += MIC_VOL_STEP; + if (hp_vol > MAX_MIC_VOL_LEVEL) hp_vol = MAX_MIC_VOL_LEVEL; + uint8_t new_cnt = (uint8_t)mic_vol_to_led_count(hp_vol); + if (new_cnt > old_cnt) { + htr3236_led_on(led_d_map[new_cnt - 1]); + htr3236_do_update(); + } + } +#if (HID_CONTROLS == 1) + if (isHpMute == 0) update_button(HID_CONTROL_VOLUP); +#endif + } else { /* CCW: HP vol down */ + if (isHpMute == 0) { + uint8_t old_cnt = (uint8_t)mic_vol_to_led_count(hp_vol); + hp_vol -= MIC_VOL_STEP; + if (hp_vol < 0) hp_vol = 0; + uint8_t new_cnt = (uint8_t)mic_vol_to_led_count(hp_vol); + if (new_cnt < old_cnt) { + htr3236_led_off(led_d_map[old_cnt - 1]); + htr3236_do_update(); + } + } +#if (HID_CONTROLS == 1) + if (isHpMute == 0) update_button(HID_CONTROL_VOLDN); +#endif + } + hp_rotation_active = 0; + hp_sample_count = 0; + } + } + } else { + hp_rotation_active = 0; + hp_sample_count = 0; + } + } + + /* --- Mic mute button (debounced, active low on 4F bit3) --- */ + if ((enc1 & KEY_MIC_MUTE) == 0) { + mic_mute_cnt++; + if (mic_mute_cnt == 2) { + isMicMute = !isMicMute; + if (isMicMute) { + SET_SHARED_GLOBAL(g_mute_on_off_t0, MUTE_ON); + xc_chan_out_byte(cc_mic_level, MUTED_MIC); + /* Turn off L-series bar */ + { + int led_cnt = mic_vol_to_led_count(mic_vol); + for (int i = 0; i < led_cnt; i++) htr3236_led_off(led_l_map[i]); + htr3236_do_update(); + } + debug_printf("Mic MUTED\n"); + } else { + SET_SHARED_GLOBAL(g_mute_on_off_t0, MUTE_OFF); + xc_chan_out_byte(cc_mic_level, UNMUTED_MIC); + /* Restore L-series bar */ + { + int led_cnt = mic_vol_to_led_count(mic_vol); + for (int i = 0; i < led_cnt; i++) htr3236_led_on(led_l_map[i]); + htr3236_do_update(); + } + debug_printf("Mic UNMUTED\n"); + } + } + } else { + mic_mute_cnt = 0; + } + + /* --- HP mute button (debounced, active low on 8D bit6) --- */ + if ((hp & KEY_HP_MUTE) == 0) { + hp_mute_cnt++; + if (hp_mute_cnt == 2) { + isHpMute = !isHpMute; + if (isHpMute) { + int led_cnt = mic_vol_to_led_count(hp_vol); + for (int i = 0; i < led_cnt; i++) htr3236_led_off(led_d_map[i]); + htr3236_do_update(); + } else { + int led_cnt = mic_vol_to_led_count(hp_vol); + for (int i = 0; i < led_cnt; i++) htr3236_led_on(led_d_map[i]); + htr3236_do_update(); + } +#if (HID_CONTROLS == 1) + update_button(HID_CONTROL_MUTE); +#endif + debug_printf("HP mute toggled: %d\n", isHpMute); + } + } else { + hp_mute_cnt = 0; + } + + /* --- Mode buttons (debounced, 1-bit ports, active low) --- */ + /* Music stereo mode — exclusive radio button with LED */ + if (btn_m == 0) { + btn_music_cnt++; + if (btn_music_cnt == 2) { + flag_music_mode = 1; flag_game_mode = 0; flag_ai71_onoff = 0; + htr3236_led_on(LED_MUSIC_CH); + htr3236_led_off(LED_GAME_CH); + htr3236_led_off(LED_AI71_CH); + htr3236_do_update(); + unsigned new_mode = 0; + SET_SHARED_GLOBAL(g_game_mode, new_mode); + { + unsigned char path2[] = "game_mode"; + save_value(path2, (unsigned char)new_mode); + } + xc_chan_out_byte(cc_mic_level, 0xFC); + xc_chan_out_byte(cc_mic_level, (unsigned char)new_mode); + debug_printf("Mode: music stereo (0)\n"); + } + } else { + btn_music_cnt = 0; + } + + /* Game / spatial mode — exclusive radio button with LED */ + if (btn_g == 0) { + btn_game_cnt++; + if (btn_game_cnt == 2) { + flag_music_mode = 0; flag_game_mode = 1; flag_ai71_onoff = 0; + htr3236_led_off(LED_MUSIC_CH); + htr3236_led_on(LED_GAME_CH); + htr3236_led_off(LED_AI71_CH); + htr3236_do_update(); + unsigned new_mode = 1; + SET_SHARED_GLOBAL(g_game_mode, new_mode); + { + unsigned char path2[] = "game_mode"; + save_value(path2, (unsigned char)new_mode); + } + xc_chan_out_byte(cc_mic_level, 0xFC); + xc_chan_out_byte(cc_mic_level, (unsigned char)new_mode); + debug_printf("Mode: game spatial (1)\n"); + } + } else { + btn_game_cnt = 0; + } + + /* AI 7.1 virtual surround — exclusive radio button with LED */ + if (btn_a == 0) { + btn_ai71_cnt++; + if (btn_ai71_cnt == 2) { + flag_music_mode = 0; flag_game_mode = 0; flag_ai71_onoff = 1; + htr3236_led_off(LED_MUSIC_CH); + htr3236_led_off(LED_GAME_CH); + htr3236_led_on(LED_AI71_CH); + htr3236_do_update(); + unsigned new_mode = 2; + SET_SHARED_GLOBAL(g_game_mode, new_mode); + { + unsigned char path2[] = "game_mode"; + save_value(path2, (unsigned char)new_mode); + } + xc_chan_out_byte(cc_mic_level, 0xFC); + xc_chan_out_byte(cc_mic_level, (unsigned char)new_mode); + debug_printf("Mode: AI7.1 (2)\n"); + } + } else { + btn_ai71_cnt = 0; + } + + + /* --- Host volume sync --- */ GET_SHARED_GLOBAL(uac_vol, g_uac_vol); if (uac_vol != last_uac_vol) { unsigned conv_vol = (0xffffffff - uac_vol + 1) >> 8; diff --git a/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/audiostream.xc b/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/audiostream.xc index 99937ce..adf5304 100644 --- a/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/audiostream.xc +++ b/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/audiostream.xc @@ -1,6 +1,5 @@ #include -on tile[0]: out port p_leds = XS1_PORT_4F; void UserAudioStreamStart(void) { diff --git a/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/dsp.c b/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/dsp.c index afd07c4..815b75a 100644 --- a/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/dsp.c +++ b/sw_usb_audio/app_usb_aud_phaten_golden/src/extensions/dsp.c @@ -847,17 +847,6 @@ void update_button(unsigned char b) #define BLINK_COUNT 3 // LED闪烁次数:3次 #endif -// add LED flashing when muted -#define MUTED_LED_ON 4 // 400ms on -#define MUTED_LED_OFF 10 // 600ms off - -#define LED_DNR_ON_71_ON 0b11111100 -#define LED_DNR_ON_71_OFF 0b11111101 -#define LED_DNR_OFF_71_ON 0b11111110 -#define LED_DNR_OFF_71_OFF 0b11111111 -// 改动原因:将LED引脚宏定义改为更明确的名称,LED_3D_PIN改为BLUE_LED_PIN,LED_DNR_PIN改为GREEN_LED_PIN -#define GREEN_LED_PIN 1 // DNR LED (绿色LED) - bit 1 of leds2_val, 0b11111101 -#define BLUE_LED_PIN 0 // 3D LED (蓝色LED) - bit 0 of leds2_val, 0b11111110 // 改动原因:定义模式切换标志值,用于在SPATIAL_GAME、STEREO_8K、STEREO_2K、UAC1之间循环切换 #define MODE_STEREO_2K UAC1_IN_FLAG // 4 STEREO_2K模式标志 @@ -866,43 +855,22 @@ void update_button(unsigned char b) #define MODE_UAC1 USB_IN_FLAG // 2 UAC1模式标志 extern uint8_t mic_vol; -//Tile 1 +//Tile 1 — 按键和LED已移至 audiohw.xc(UAC2_920 配置),本函数只负责算法控制和HID协议 void hid_button_task(chanend_t cc_mic_level, chanend_t c_hidRcvData, chanend_t c_hidSendData, chanend_t c_uac_vol) { - port_t p_keys = XS1_PORT_1F; - port_t p_leds = XS1_PORT_1G; - port_t p_leds2 = XS1_PORT_4D; - // set spatial audio on; LED on -#if defined (IR_SWITCHING_MODE) +#if defined(IR_SWITCHING_MODE) static uint32_t is_3d_on = IR_OFF; #else static uint32_t is_3d_on = A3D_OFF; #endif static uint32_t is_dnr_on = DNR_OFF; - static uint8_t leds2_val = LED_DNR_OFF_71_OFF; - static uint8_t leds1_val = 1; // LED off - static uint8_t is_mute_t1 = 0; - static uint8_t mute_tmr; - unsigned key_enable = 0; uint8_t tmp = 0; - static uint8_t is_stable = 1; - static uint8_t press_hold_cnt = 0; - // 改动原因:添加LED闪烁相关变量,用于保存原始LED状态 - static uint8_t saved_leds2_val = 0; // 保存原始leds2_val状态 - static uint8_t saved_leds1_val = 0; // 保存原始leds1_val状态 - // 改动原因:添加模式变量,用于存储从button_task接收的模式值,判断是否在无音效模式或UAC1模式 - static unsigned game_mode_t1 = 0; // tile1上的模式值,用于判断是否在无音效模式或UAC1模式 - static unsigned is_no_effect_mode = 0; // 是否为无音效模式标志(模式3) - static unsigned is_uac1_mode = 0; // 是否为UAC1模式标志(模式4) - static unsigned actual_mode_for_led = 0; // UAC1模式下的实际模式值(0=STEREO_2K, 1=SPATIAL_GAME, 2=SPATIAL_MOVIE),用于LED闪烁 - // 改动原因:添加当前模式变量,用于短按切换模式(0=无音效,1=STEREO_2K,2=SPATIAL_GAME,3=SPATIAL_MOVIE) - static unsigned current_mode_local = 0; // 当前模式值(0-3) - // 改动原因:添加LED闪烁相关变量,用于SPATIAL_MOVIE模式的蓝灯闪烁 - static unsigned blink_counter = 0; // LED闪烁计数器(每100ms递增) - int ret = 0; + // 当前模式值(从 audiohw.xc button_task 通过 cc_mic_level 接收) + // 0=NO_EFFECT, 1=STEREO_2K, 2=SPATIAL_GAME, 3=SPATIAL_MOVIE + static unsigned current_mode_local = 1; + hwtimer_t timer = hwtimer_alloc(); - // init mic level static unsigned mic_level = DEFAULT_MIC_LEVEL; unsigned char RcvData[64] = {0}; unsigned SendData[HID_MAX_DATA_BYTES / 4]; @@ -910,30 +878,11 @@ void hid_button_task(chanend_t cc_mic_level, chanend_t c_hidRcvData, chanend_t c SendData[0] = 1; for (unsigned char i=1; i<(HID_MAX_DATA_BYTES / 4); i++) SendData[i] = 0; - // 改动原因:从button_task接收模式值(通过cc_mic_level channel传输) - // 初始化时先设置默认值,模式值将在event_mic_vol中接收 - // 这样可以避免阻塞按键轮询 - is_no_effect_mode = 0; - is_uac1_mode = 0; - game_mode_t1 = 0; - // 改动原因:初始默认模式值,将从button_task通过channel接收(0xFC命令) - current_mode_local = 1; // 默认STEREO_2K模式,等待从button_task接收 + current_mode_local = 1; debug_printf("hid_button_task init: waiting for audio_mode from button_task\n"); SET_SHARED_GLOBAL(g_mic_level_t1, mic_level); - port_enable(p_keys); - port_enable(p_leds); - port_enable(p_leds2); - // 改动原因:初始化时LED保持默认状态(灯灭),等待从button_task接收模式值后再设置 - // LED初始状态:所有LED都关闭 - leds2_val |= (1< 3) { - current_mode_local = 0; // 如果值无效,重置为STEREO_2K - } + if (current_mode_local > 3) current_mode_local = 0; + debug_printf("hid_button_task received audio_mode: %d\n", current_mode_local); - debug_printf("hid_button_task received audio_mode: %d (0=NO_EFFECT, 1=STEREO_2K, 2=SPATIAL_GAME, 3=SPATIAL_MOVIE)\n", current_mode_local); - - // 改动原因:根据接收到的模式值初始化LED和算法状态 + // 根据模式控制算法 if (current_mode_local == 0) { - // 无音效模式:灯灭,算法关闭 audio_ex3d_onoff(0); #if IR_SWITCHING_MODE is_3d_on = IR_OFF; #else is_3d_on = A3D_OFF; #endif - SET_SHARED_GLOBAL(g_3d_on_off_t1, is_3d_on); - leds2_val |= (1< 0) { - // 改动原因:短按切换模式(0=无音效,1=STEREO_2K,2=SPATIAL_GAME,3=SPATIAL_MOVIE) - // 循环切换:0→1→2→3→0 -#if !UAC1_MODE - unsigned old_mode = current_mode_local; - current_mode_local = (current_mode_local + 1) % 4; // 循环切换 0→1→2→3→0 - debug_printf("Short press: switching mode from %d to %d\n", old_mode, current_mode_local); - // 改动原因:根据模式控制算法和LED - if (current_mode_local == 0) { - // 无音效模式:灯灭,算法关闭 - audio_ex3d_onoff(0); -#if IR_SWITCHING_MODE - is_3d_on = IR_OFF; -#else - is_3d_on = A3D_OFF; -#endif - SET_SHARED_GLOBAL(g_3d_on_off_t1, is_3d_on); - leds2_val |= (1< 0)) { - press_hold_cnt--; - if (press_hold_cnt == 0) { - // 改动原因:长按检测到时,在UAC1模式下切换等效模式并保存,其他模式切换固件模式 - // 保存当前LED状态 - // saved_leds2_val = leds2_val; - // saved_leds1_val = leds1_val; - // debug_printf("Long press detected\n"); + // 检查 host app 是否通过 HID 改变了音场状态 + uint32_t host_app_sf; + GET_SHARED_GLOBAL(host_app_sf, g_3d_on_off_t1); + if (host_app_sf != is_3d_on) { + is_3d_on = host_app_sf; + audio_ex3d_onoff(is_3d_on != IR_OFF); - } + if (is_3d_on == IR_OFF) current_mode_local = 0; + else if (is_3d_on == IR_GAME) current_mode_local = 1; + else if (is_3d_on == IR_7_1_GAME) current_mode_local = 2; + else if (is_3d_on == IR_7_1_MOVIE) current_mode_local = 3; + + switch (is_3d_on) { + case IR_GAME: printf("Stereo Game on\n"); break; + case IR_MUSIC: printf("Stereo Music on\n"); break; + case IR_MOVIE: printf("Stereo Movie on\n"); break; + case IR_7_1_GAME: printf("3d Game on\n"); break; + case IR_7_1_MUSIC:printf("3d Music on\n"); break; + case IR_7_1_MOVIE:printf("3d Movie on\n"); break; + case IR_OFF: printf("3d off\n"); break; + default: break; } + SET_SHARED_GLOBAL(g_3d_on_off_t1, is_3d_on); } - last_status = key_in; - - // 改动原因:SPATIAL_MOVIE模式下,蓝灯闪烁(每500ms切换一次状态) - if (current_mode_local == 3) { - blink_counter++; - if (blink_counter >= 5) { // 5 * 100ms = 500ms - blink_counter = 0; - // 切换蓝灯状态 - if (leds2_val & (1<