30 Commits

Author SHA1 Message Date
Steven Dan
8d54f2a01a disable uac1 dfu 2026-06-10 16:05:02 +08:00
Steven Dan
a9327e8e38 1.2.2 2026-06-10 15:30:07 +08:00
Steven Dan
c33b1a4b3d disable log 2026-06-10 15:28:01 +08:00
Steven Dan
e28072657b 3m flash size 2026-06-08 19:09:36 +08:00
Steven Dan
ecba7b4863 udpate head file of dfu_flash_interface 2026-06-08 18:55:52 +08:00
Steven Dan
d48858e4e9 disable DISABLE_REBOOT 2026-06-08 18:53:45 +08:00
Steven Dan
f0daa4f62e update flash size 3200k 2026-06-08 18:53:25 +08:00
Steven Dan
bc3ba14a65 f1 playing bak working 2026-06-05 17:00:04 +08:00
Steven Dan
0e3d9ed7c5 f1 recording working 2026-06-05 16:31:17 +08:00
Steven Dan
344e04aa33 add F1 ssrc 2026-06-05 15:22:06 +08:00
Steven Dan
307aee89d9 update f2 music 192khz 2026-06-04 17:43:36 +08:00
Steven Dan
716f60fabb 1.2.1 2026-06-04 17:32:05 +08:00
Steven Dan
8b39245372 update flash size 2026-06-04 17:15:19 +08:00
Steven Dan
4e31f7e0e0 update bats 2026-06-04 17:09:37 +08:00
Steven Dan
1b0815a956 disable f3f4 2026-06-04 17:00:52 +08:00
Steven Dan
9eb6adc8d4 seperate f3 and f4 mode 2026-06-04 16:58:18 +08:00
Steven Dan
303bb6a244 disable disable reboot 2026-06-04 16:20:29 +08:00
Steven Dan
50ae1a5550 update debug log report id 2026-06-04 12:26:25 +08:00
Steven Dan
f63a6e0653 disable volume of f6_f7_fps_uac1 2026-06-04 10:08:11 +08:00
Steven Dan
b8f93ea5f5 make footsteps enhancement to two steps, 0, and 15db. and default is 15db 2026-06-04 10:04:35 +08:00
Steven Dan
9205b48882 1.2.0 2026-05-20 16:15:11 +08:00
Steven Dan
f4faefc8e5 increase 4d adc gain 2026-05-20 16:14:52 +08:00
Steven Dan
85e8bf04f0 1.1.15 2026-05-07 10:17:07 +08:00
Steven Dan
3ebd834450 1.1.14 2026-05-05 14:13:39 +08:00
Steven Dan
a42d5ec059 update default volume level 2026-05-05 14:13:18 +08:00
Steven Dan
782a487479 1.1.13 2026-04-30 17:05:59 +08:00
Steven Dan
320155bb6a update mic dac volume mapping 2026-04-30 17:04:56 +08:00
Steven Dan
aa57b8143a fix mic detection for only mic insertion 2026-04-30 15:28:27 +08:00
Steven Dan
920cb576f4 1.1.12 2026-04-29 16:23:32 +08:00
Steven Dan
f9ee4b7523 update log switch 2026-04-29 16:20:40 +08:00
28 changed files with 1283 additions and 342 deletions

View File

@@ -23,7 +23,7 @@
*/
#ifndef FLASH_MAX_UPGRADE_SIZE
//#define FLASH_MAX_UPGRADE_SIZE (512 * 1024)
#define FLASH_MAX_UPGRADE_SIZE (2200 * 1024)
#define FLASH_MAX_UPGRADE_SIZE (3000 * 1024)
#endif
#define FLASH_ERROR() do {} while(0)

View File

@@ -50,6 +50,7 @@ XUD_Result_t HidInterfaceClassRequests(
#endif
#if DEBUG_MEMORY_LOG_ENABLED
unsigned log_switch;
buffer[0] = 0x1;
GET_SHARED_GLOBAL(log_switch, g_log_switch);
if (log_switch) {

View File

@@ -37,8 +37,8 @@ endif()
# Firmware version (maps to BCD_DEVICE_J.M.N in USB descriptor)
set(FW_VER_J 1)
set(FW_VER_M 1)
set(FW_VER_N 11)
set(FW_VER_M 2)
set(FW_VER_N 2)
set(FW_VERSION "v${FW_VER_J}.${FW_VER_M}.${FW_VER_N}")
set(SW_USB_AUDIO_FLAGS ${EXTRA_BUILD_FLAGS} -Os
@@ -129,7 +129,7 @@ set(APP_COMPILER_FLAGS_fact ${SW_USB_FACT_FLAGS} -DI2S_CHANS_DAC=2
-DMIN_VOLUME=0xE000
-DINPUT_VOLUME_CONTROL=0
-DOUTPUT_VOLUME_CONTROL=0
-DDEBUG_MEMORY_LOG_ENABLED=1
#-DDEBUG_MEMORY_LOG_ENABLED=1
-DHID_DFU_EN=1
-DXUA_DFU_EN=1
#-DIR_SWITCHING_MODE
@@ -139,7 +139,7 @@ set(APP_COMPILER_FLAGS_fact ${SW_USB_FACT_FLAGS} -DI2S_CHANS_DAC=2
set(APP_COMPILER_FLAGS_f1_music_uac2 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2
-DI2S_CHANS_ADC=2
-DMIN_FREQ=44100
-DMIN_FREQ=192000
-DMAX_FREQ=192000
-DF1_MUSIC_UAC2=1
-DSTREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS=24
@@ -151,7 +151,8 @@ set(APP_COMPILER_FLAGS_f1_music_uac2 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC
#-DUSE_EX3D
-DMIXER=0
-DUAC2_MODE=1
#-ldnr_50ms
-ldnr_50ms
-DDNR_ENABLE=1
#-llib_ex3d_all
-DEQ_EN=1
#-DEX3D_SF_NUM=3
@@ -168,35 +169,35 @@ set(APP_COMPILER_FLAGS_f1_music_uac2 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC
-DHID_CONTROLS=1)
set(APP_COMPILER_FLAGS_f3_f4_fps_uac2 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2
-DI2S_CHANS_ADC=2
-DMIN_FREQ=48000
-DMAX_FREQ=48000
-DUSE_EX3D=1
-DF3_F4_FPS_UAC2=1
-DMIXER=0
-DUAC2_MODE=1
-ldnr_50ms
-llib_ex3d_all
-DEQ_EN=1
-DDNR_ENABLE=1
-DSTREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS=16
-DSTREAM_FORMAT_INPUT_1_RESOLUTION_BITS=16
-DINPUT_FORMAT_COUNT=1
-DOUTPUT_FORMAT_COUNT=1
-DEX3D_SF_NUM=3
-DNUM_USB_CHAN_OUT=8
-DNUM_USB_CHAN_IN=2
-DNUM_EX3D_CHAN_OUT=2
-DMIN_VOLUME=0xE000
-DINPUT_VOLUME_CONTROL=1
-DOUTPUT_VOLUME_CONTROL=1
#-DDEBUG_MEMORY_LOG_ENABLED=1
-DXUA_DFU_EN=1
-DHID_DFU_EN=1
-DIR_SWITCHING_MODE
-DHID_CONTROLS=1)
#set(APP_COMPILER_FLAGS_f3_f4_fps_uac2 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2
# -DI2S_CHANS_ADC=2
# -DMIN_FREQ=48000
# -DMAX_FREQ=48000
# -DUSE_EX3D=1
# -DF3_F4_FPS_UAC2=1
# -DMIXER=0
# -DUAC2_MODE=1
# -ldnr_50ms
# -llib_ex3d_all
# -DEQ_EN=1
# -DDNR_ENABLE=1
# -DSTREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS=16
# -DSTREAM_FORMAT_INPUT_1_RESOLUTION_BITS=16
# -DINPUT_FORMAT_COUNT=1
# -DOUTPUT_FORMAT_COUNT=1
# -DEX3D_SF_NUM=3
# -DNUM_USB_CHAN_OUT=8
# -DNUM_USB_CHAN_IN=2
# -DNUM_EX3D_CHAN_OUT=2
# -DMIN_VOLUME=0xE000
# -DINPUT_VOLUME_CONTROL=1
# -DOUTPUT_VOLUME_CONTROL=1
# #-DDEBUG_MEMORY_LOG_ENABLED=1
# -DXUA_DFU_EN=1
# -DHID_DFU_EN=1
# -DIR_SWITCHING_MODE
# -DHID_CONTROLS=1)
#
set(APP_COMPILER_FLAGS_f6_f7_fps_uac1 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2
-DI2S_CHANS_ADC=2
-DAUDIO_CLASS=1
@@ -221,8 +222,8 @@ set(APP_COMPILER_FLAGS_f6_f7_fps_uac1 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2
-DNUM_USB_CHAN_IN=2
-DNUM_EX3D_CHAN_OUT=2
-DMIN_VOLUME=0xE000
-DINPUT_VOLUME_CONTROL=1
-DOUTPUT_VOLUME_CONTROL=1
-DINPUT_VOLUME_CONTROL=0
-DOUTPUT_VOLUME_CONTROL=0
#-DDEBUG_MEMORY_LOG_ENABLED=1
-DXUA_DFU_EN=1
-DHID_DFU_EN=1
@@ -230,7 +231,7 @@ set(APP_COMPILER_FLAGS_f6_f7_fps_uac1 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2
-DIR_SWITCHING_MODE
-DHID_CONTROLS=1)
set(APP_INCLUDES src src/core src/extensions ../../lib_dnr/lib_dnr)
set(APP_INCLUDES src src/core src/extensions src/extensions/ssrc ../../lib_dnr/lib_dnr)
set(XMOS_SANDBOX_DIR ${CMAKE_CURRENT_LIST_DIR}/../..)
XMOS_REGISTER_APP()

View File

@@ -1,3 +1,2 @@
xflash bin/fact/app_usb_aud_sy102_fact.xe --loader loader.o --upgrade 2 bin/f5_music_uac1/app_usb_aud_sy102_f5_music_uac1.xe --upgrade 3 bin/f1_music_uac2/app_usb_aud_sy102_f1_music_uac2.xe --upgrade 1 bin/f3_f4_fps_uac2/app_usb_aud_sy102_f3_f4_fps_uac2.xe --upgrade 4 bin/f6_f7_fps_uac1/app_usb_aud_sy102_f6_f7_fps_uac1.xe -o %1
rem --upgrade 4 bin/f6_f7_fps_uac1/app_usb_aud_sy102_f6_f7_fps_uac1.xe
rem 改动原因F3/F4 拆分——slot1=F3 Gameslot5=F4 AI7.1
xflash bin/fact/app_usb_aud_sy102_fact.xe --loader loader.o --upgrade 2 bin/f5_music_uac1/app_usb_aud_sy102_f5_music_uac1.xe --upgrade 3 bin/f1_music_uac2/app_usb_aud_sy102_f1_music_uac2.xe --upgrade 1 ..\..\..\csl_sy102\sw_usb_audio\app_usb_aud_phaten_golden_6ch\bin/f3_fps_uac2/app_usb_aud_sy102_f3_fps_uac2.xe --upgrade 4 bin/f6_f7_fps_uac1/app_usb_aud_sy102_f6_f7_fps_uac1.xe --upgrade 5 ..\..\..\csl_sy102\sw_usb_audio\app_usb_aud_phaten_golden_6ch\bin/f4_fps_uac2/app_usb_aud_sy102_f4_fps_uac2.xe -o %1

View File

@@ -1 +1 @@
xflash --factory-version 15.3 --target-file src/core/synido.xn --upgrade 2 bin/f5_music_uac1/app_usb_aud_sy102_f5_music_uac1.xe --upgrade 3 bin/f1_music_uac2/app_usb_aud_sy102_f1_music_uac2.xe --upgrade 1 bin/f3_f4_fps_uac2/app_usb_aud_sy102_f3_f4_fps_uac2.xe --upgrade 4 bin/f6_f7_fps_uac1/app_usb_aud_sy102_f6_f7_fps_uac1.xe -o %1
xflash --factory-version 15.3 --target-file src/core/synido.xn --upgrade 2 bin/f5_music_uac1/app_usb_aud_sy102_f5_music_uac1.xe --upgrade 3 ..\..\..\csl_sy102\sw_usb_audio\app_usb_aud_phaten_golden_6ch\bin/f1_music_uac2/app_usb_aud_sy102_f1_music_uac2.xe --upgrade 1 ..\..\..\csl_sy102\sw_usb_audio\app_usb_aud_phaten_golden_6ch\bin/f3_fps_uac2/app_usb_aud_sy102_f3_fps_uac2.xe --upgrade 4 ..\..\..\csl_sy102\sw_usb_audio\app_usb_aud_phaten_golden_6ch\bin/f6_f7_fps_uac1/app_usb_aud_sy102_f6_f7_fps_uac1.xe --upgrade 5 ..\..\..\csl_sy102\sw_usb_audio\app_usb_aud_phaten_golden_6ch\bin/f4_fps_uac2/app_usb_aud_sy102_f4_fps_uac2.xe -o %1

View File

@@ -147,8 +147,8 @@
#ifndef PID_AUDIO_2
#if defined(F1_MUSIC_UAC2)
#define PID_AUDIO_2 (0x2000) /* F1: Music, UAC2, Windows */
#elif defined(F3_F4_FPS_UAC2)
#define PID_AUDIO_2 (0x2001) /* F3/F4: FPS/AI7.1, UAC2, Windows */
#elif defined(F3_FPS_UAC2) || defined(F4_FPS_UAC2)
#define PID_AUDIO_2 (0x2001) /* F3 Game / F4 AI7.1, UAC2, Windows */
#else
#define PID_AUDIO_2 (0x2000)
#endif
@@ -167,7 +167,7 @@
#if defined(F1_MUSIC_UAC2) || defined(F5_MUSIC_UAC1)
#define PRODUCT_STR_A2 "SY102 Music"
#define PRODUCT_STR_A1 "SY102 Music"
#elif defined(F3_F4_FPS_UAC2) || defined(F6_F7_FPS_UAC1)
#elif defined(F3_FPS_UAC2) || defined(F4_FPS_UAC2) || defined(F6_F7_FPS_UAC1)
#define PRODUCT_STR_A2 "SY102 AI Game"
#define PRODUCT_STR_A1 "SY102 AI Game"
#else

View File

@@ -78,12 +78,14 @@ 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;
// 改动原因DAC音量协议扩展到49级0~48默认值同步到最大级48。
unsigned g_volume_level = 24, g_saved_volume_level = 24;
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~36dBHID可见范围
// 改动原因麦克风HID等级调整为49级0~48并将最大模拟增益限制到24dB。
unsigned g_mic_volume_level = 24; // 麦克风音量等级0=mute, 1~48=0~24dB0.5dB/级)
unsigned g_request_mic_volume_set = 0;
unsigned g_last_mic_volume_level = 0xFF; // 上次已上报的麦克风增益级别0xFF表示初始化未完成
unsigned g_dnr_strength = 100; // AI降噪强度HID值1-100=档位步进1100→-200dB最强关断由g_dnr_on控制此处不再用0表示强度
@@ -211,11 +213,19 @@ unsigned g_led_blink_is_white = 0;
#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模式标志
// 改动原因:F3/F4拆分为独立固件——Game键切F3(COAX/slot1)AI7.1键切F4(BT/slot5)
#define MODE_F3_FPS_UAC2 COAX_IN_FLAG // F3 Game (upgrade slot 1)
#define MODE_F5_MUSIC_UAC1 USB_IN_FLAG // F5 Music UAC1 (upgrade slot 2)
#define MODE_F1_MUSIC_UAC2 OPT_IN_FLAG // F1 Music UAC2 (upgrade slot 3)
#define MODE_F6_F7_FPS_UAC1 UAC1_IN_FLAG // F6/F7 FPS UAC1 (upgrade slot 4)
#define MODE_F4_FPS_UAC2 BT_IN_FLAG // F4 AI7.1 (upgrade slot 5)
// 改动原因:按 game_mode(2=Game/3=AI7.1) 选择 F3 或 F4 固件标志,供启动链与 HID 复用
static unsigned get_fps_firmware_flag(unsigned mode)
{
if (mode == 3) return MODE_F4_FPS_UAC2;
return MODE_F3_FPS_UAC2; // mode==2 或其它 FPS 模式默认 F3 Game
}
/* All on tile[0] */
port p_scl = PORT_I2C_SCL;
@@ -235,14 +245,34 @@ 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)
// 改动原因协议层改为49级(0~48)硬件仍是1dB步进通过“2个等级映射1dB”实现24dB上限。
#define MIC_HID_LEVEL_MIN 0
#define MIC_HID_LEVEL_MAX 48
#define MIC_HID_LEVEL_DEFAULT 24 // 24dB保持原默认听感接近
#define DAC_HID_LEVEL_DEFAULT 24 // 24dB保持原默认听感接近
// DAC 监听音量控制范围: 共 30 级 (0~29)
// 0 = mute (全灭, reg 0x0034=0x0000), 1~29 = -28dB ~ 0dB1dB/步
#define NAU88L21_PGA_GAIN_REG_MIN_USED_VALUE 0x0 // 0=mute
#define NAU88L21_PGA_GAIN_REG_MAX_VALUE 0x18 // 24dB上限
#define NAU88L21_PGA_GAIN_REG_DEFAULT_VALUE 0x16 // 22dB默认
// 改动原因49级HID等级(0.5dB/级)需映射到Codec 1dB步进寄存器避免改动底层codec写寄存器逻辑。
static inline unsigned mic_hid_level_to_codec_gain(unsigned hid_level)
{
if (hid_level == 0) {
return 0;
}
// ceil(hid_level / 2)把两档HID映射到1dB硬件步进
unsigned codec_gain = (hid_level + 1) >> 1;
if (codec_gain > NAU88L21_PGA_GAIN_REG_MAX_VALUE) {
codec_gain = NAU88L21_PGA_GAIN_REG_MAX_VALUE;
}
return codec_gain;
}
// 改动原因:按 SY102dac对应表.csv将DAC HID范围扩展为49级(0~48)。
// 0 = mute1~48 = 有效音量等级LED按csv映射显示
#define DAC_LEVEL_MIN 0 // mute0 LEDs
#define DAC_LEVEL_MAX 29 // 0dB15 LEDs
#define DAC_LEVEL_MAX 48 // max level15 LEDs
#define DAC_LEVEL_DEFAULT DAC_LEVEL_MAX
static inline void NAU88C22_REGREAD(unsigned reg, unsigned &val, client interface i2c_master_if i2c)
@@ -265,6 +295,7 @@ static inline i2c_regop_res_t NAU88C22_REGWRITE(unsigned reg, unsigned val, clie
}
else
{
debug_printf("I2C write success: reg=%08x, val=%08x\n", reg, val);
//debug_printf("I2C write success: reg=");
//printhex(reg);
//debug_printf(", val=");
@@ -276,10 +307,73 @@ static inline i2c_regop_res_t NAU88C22_REGWRITE(unsigned reg, unsigned val, clie
return result;
}
void dac_volume(signed level)
// 改动原因:按 SY102dac对应表.csv 建立 0~48 级到 DAC 寄存器值的精确映射,
// 修复旧线性公式导致的 dB 对应错误(例如 47级应为-0.5dB46级应为-1dB
static const uint8_t dac_level_to_reg[49] = {
0x0E, // [0] mute调用方通常直接写0x0000
0x4B, // [1] -66dB
0x4F, // [2] -64dB
0x53, // [3] -62dB
0x57, // [4] -60dB
0x5B, // [5] -58dB
0x5F, // [6] -56dB
0x63, // [7] -54dB
0x67, // [8] -52dB
0x6B, // [9] -50dB
0x6F, // [10] -48dB
0x73, // [11] -46dB
0x77, // [12] -44dB
0x7B, // [13] -42dB
0x7F, // [14] -40dB
0x83, // [15] -38dB
0x87, // [16] -36dB
0x8B, // [17] -34dB
0x8F, // [18] -32dB
0x93, // [19] -30dB
0x97, // [20] -28dB
0x9B, // [21] -26dB
0x9F, // [22] -24dB
0xA3, // [23] -22dB
0xA7, // [24] -20dB
0xA9, // [25] -19dB
0xAB, // [26] -18dB
0xAD, // [27] -17dB
0xAF, // [28] -16dB
0xB1, // [29] -15dB
0xB3, // [30] -14dB
0xB5, // [31] -13dB
0xB7, // [32] -12dB
0xB9, // [33] -11dB
0xBB, // [34] -10dB
0xBD, // [35] -9dB
0xBF, // [36] -8dB
0xC1, // [37] -7dB
0xC3, // [38] -6dB
0xC5, // [39] -5dB
0xC7, // [40] -4dB
0xC8, // [41] -3.5dB
0xC9, // [42] -3dB
0xCA, // [43] -2.5dB
0xCB, // [44] -2dB
0xCC, // [45] -1.5dB
0xCD, // [46] -1dB
0xCE, // [47] -0.5dB
0xCF // [48] 0dB
};
void dac_volume(unsigned level)
{
// 1dB/步: level 范围 -28 ~ 0对应寄存器 0xcf-28=0xb3 ~ 0xcf
unsigned tmp = 0xcf + level;
if (level > DAC_LEVEL_MAX) {
level = DAC_LEVEL_MAX;
}
unsigned tmp = dac_level_to_reg[level];
#if 0
int half_db = ((int)tmp - 0xCF); // 以 0.5dB 为单位(负数表示衰减)
int sign = (half_db < 0) ? -1 : 1;
int abs_half_db = (half_db < 0) ? -half_db : half_db;
debug_printf("dac_volume write level=%d reg=0x%02X db=%s%d.%d\n",
level, tmp, (sign < 0) ? "-" : "", abs_half_db / 2, (abs_half_db & 1) ? 5 : 0);
#endif
unsafe {NAU88C22_REGWRITE(0x0034, (tmp<<8|tmp), (client interface i2c_master_if)i_i2c_client);}
}
@@ -290,19 +384,13 @@ void mic_volume(unsigned level)
// 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);}
debug_printf("mic_volume mute\n");
}
else
{
// 1-37: 0dB ~ 36dB1dB/步
// 改动原因移除旧版37~38寄存器额外数字增益路径最大限制到24dB1~241dB/步)。
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(0x007E, ((level + 4) << 8), (client interface i2c_master_if)i_i2c_client);}
unsafe {NAU88C22_REGWRITE(0x0035, (0xcfcf), (client interface i2c_master_if)i_i2c_client);}
}
}
@@ -320,10 +408,7 @@ void codec_init(void)
}
// 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);}
unsafe {NAU88C22_REGWRITE(0x007E, NAU88L21_PGA_GAIN_REG_DEFAULT_VALUE << 8, (client interface i2c_master_if)i_i2c_client);}
//debug_printfln("Codec init finished");
}
@@ -430,10 +515,12 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
//port_enable(p_button_music_mode);
// 出厂默认麦克风21dB (reg=22), 监听-14dB (level=15)
int codec_adc_pga_gain_reg_value = 22; // 21dB
// 改动原因麦克风默认值改为49级中的44级约22dB上限受24dB约束。
// 改动原因本变量改为保存“49级HID音量等级”(0~48),便于旋钮/HID统一一套等级语义。
int codec_adc_pga_gain_reg_value = MIC_HID_LEVEL_DEFAULT;
int dac_level = 15; // -14dB (DAC_LEVEL_MAX - 14 = 29 - 14 = 15)
// 改动原因默认监听音量从旧30级体系迁移到49级体系保持中高音量默认值。
int dac_level = DAC_HID_LEVEL_DEFAULT;
// mic endcoder 变量
uint8_t prev_encode_input1 = 0;
@@ -456,8 +543,8 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
// 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;
// 改动原因脚步增强改为2档——0=关(0dB)1=开(15dB);出厂默认开启(15dB)
unsigned flag_footsteps_enhancement = 1;
// 出厂默认AI降噪开启
unsigned flag_aidenoise_onoff = 1;
unsigned dnr_strength_saved = 100; // AI降噪重新开启时恢复的强度0x85可更新
@@ -469,7 +556,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
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 char saved_footstep = 15; // 改动原因与出厂默认15dB一致flash加载前临时初值
@@ -536,22 +623,26 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
debug_printf("Loaded game_mode from flash: %d\n", saved_mode);
#if USE_EX3D == 1
// 加载脚步增强状态(保存值为expand_gain: 0/6/12
// 改动原因:加载脚步增强2档 expand_gain: 0/15旧固件6/12等非零值迁移为15
{
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) {
} else if (saved_footstep == 15) {
flag_footsteps_enhancement = 1;
} else if (saved_footstep <= 20) {
flag_footsteps_enhancement = 2;
} else if (saved_footstep > 0 && saved_footstep <= 20) {
// 旧3档(6/12)或其它历史非零增益统一迁移为15dB开档
saved_footstep = 15;
flag_footsteps_enhancement = 1;
save_value(footstep_path, (unsigned char)15);
debug_printf("Migrated footstep gain to flash: %d\n", saved_footstep);
} else {
// 未初始化(255)或异常值:出厂默认脚步增强开启(12dB)写入flash
saved_footstep = 12;
flag_footsteps_enhancement = 2;
save_value(footstep_path, (unsigned char)12);
// 未初始化(255)或异常值:出厂默认脚步增强开启(15dB)写入flash
saved_footstep = 15;
flag_footsteps_enhancement = 1;
save_value(footstep_path, (unsigned char)15);
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);
@@ -583,7 +674,8 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
if (host_os == OS_WIN) {
debug_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;
// 改动原因Windows 下 mode2→F3 Gamemode3→F4 AI7.1,不再共用 F3_F4 合并固件
unsigned flag = (saved_mode <= 1) ? MODE_F1_MUSIC_UAC2 : get_fps_firmware_flag(saved_mode);
SetRoleSwitchFlag(flag);
#ifndef DISABLE_REBOOT
device_reboot();
@@ -690,10 +782,10 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
// 从 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)
if(saved_mic >= MIC_HID_LEVEL_MIN && saved_mic <= MIC_HID_LEVEL_MAX)
codec_adc_pga_gain_reg_value = saved_mic;
else
save_value(mic_vol_path, (unsigned char)codec_adc_pga_gain_reg_value); // 出厂默认22(21dB)
save_value(mic_vol_path, (unsigned char)codec_adc_pga_gain_reg_value); // 出厂默认44级约22dB
unsigned char saved_dac = load_value(dac_vol_path);
if(saved_dac <= DAC_LEVEL_MAX)
@@ -783,12 +875,12 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
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;
// 改动原因g_mic_volume_level 直接使用49级HID等级避免旧版37级上限截断。
g_mic_volume_level = (codec_adc_pga_gain_reg_value <= MIC_HID_LEVEL_MAX) ? codec_adc_pga_gain_reg_value : MIC_HID_LEVEL_MAX;
// ADCL PGA default settingmic_volume内部已根据g_monitor_switch决定是否启用耳返通路
// 若mic_mute已从flash恢复为1则此处先以正常gain调用再用mute覆盖
mic_volume(codec_adc_pga_gain_reg_value);
mic_volume(mic_hid_level_to_codec_gain(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++)
@@ -813,7 +905,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
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);
dac_volume(dac_level);
{
int dac_led_count = flag_hp_mute ? 15 : dac_gain_to_led[dac_level];
for(int i = 0; i < 15; i++)
@@ -893,13 +985,10 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
}
}
// 恢复脚步增强LED初始状态
// 改动原因2档脚步增强——仅开档(15dB)点亮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
@@ -945,7 +1034,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
{
unsigned music_init, game_init;
p_button_music_mode :> music_init;
p_button_game_mode :> game_init;
p_button_game_mode :> game_init;//
if (music_init == 0 && game_init == 0) {
fr_inhibit = 1;
btn_combo_active = 1;
@@ -1171,8 +1260,15 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
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);
// 改动原因(关键修复):
// codec_adc_pga_gain_reg_value 在当前版本保存的是 49级HID音量等级(0~48)不是Codec寄存器原始值。
// 这里之前直接写 mic_volume(codec_adc_pga_gain_reg_value) 会绕过统一映射逻辑,
// 造成“插拔后恢复增益”与“旋钮/HID设置增益”不一致表现为录音音量异常偏小/不稳定)。
// 必须与其它路径保持一致,先做 HID->Codec PGA 映射再写寄存器。
unsigned codec_gain = mic_hid_level_to_codec_gain(codec_adc_pga_gain_reg_value);
mic_volume(codec_gain);
debug_printf("mic_det: unmute -> hid=%d codec_pga=%d\n",
codec_adc_pga_gain_reg_value, codec_gain);
}
} else if (mic_det_cmd == MIC_DET_DAC_MUTE) {
dac_det_muted = 1;
@@ -1183,7 +1279,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
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);
dac_volume(dac_level);
debug_printf("mic_det: dac unmute -> level=%d\n", dac_level);
}
}
@@ -1232,9 +1328,10 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
// 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
// FPS firmware (F3 Game / F4 AI7.1, 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)
// F3: Game 本地切 mode2AI7.1 需重启切 F4
// F4: AI7.1 本地切 mode3Game 需重启切 F3
unsigned mode_btn_change = 0;
unsigned need_reboot = 0;
@@ -1303,7 +1400,8 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
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)
#if (F3_FPS_UAC2 == 1) || (F4_FPS_UAC2 == 1)
// 改动原因F3/F4 FPS 固件按 Music 键切回 F1 Music
active_mode = 1;
need_reboot = 1;
SetRoleSwitchFlag(MODE_F1_MUSIC_UAC2);
@@ -1336,9 +1434,10 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
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
// 改动原因Music 固件按 Game 键启动 F3 Game 固件
active_mode = 2;
need_reboot = 1;
SetRoleSwitchFlag(MODE_F3_F4_FPS_UAC2);
SetRoleSwitchFlag(MODE_F3_FPS_UAC2);
#elif (F5_MUSIC_UAC1 == 1)
// UAC1 Music firmware: game needs F6/F7, reboot if not already game
if (active_mode != 2) {
@@ -1352,11 +1451,17 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
active_mode = 2;
mode_btn_change = 1;
}
#else
#elif (F3_FPS_UAC2 == 1)
// 改动原因:已在 F3 Game 固件Game 键仅本地切 mode2
if (active_mode != 2) {
active_mode = 2;
mode_btn_change = 1;
}
#elif (F4_FPS_UAC2 == 1)
// 改动原因F4 AI7.1 固件按 Game 键需重启加载 F3 Game 固件
active_mode = 2;
need_reboot = 1;
SetRoleSwitchFlag(MODE_F3_FPS_UAC2);
#endif
}
}
@@ -1372,10 +1477,10 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
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
// 改动原因Music 固件按 AI7.1 键启动 F4 AI7.1 固件
active_mode = 3;
need_reboot = 1;
SetRoleSwitchFlag(MODE_F3_F4_FPS_UAC2);
SetRoleSwitchFlag(MODE_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) {
@@ -1389,12 +1494,17 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
active_mode = 3;
mode_btn_change = 1;
}
#else
// FPS firmware: switch algorithm locally (activate if not already)
#elif (F4_FPS_UAC2 == 1)
// 改动原因:已在 F4 AI7.1 固件AI7.1 键仅本地切 mode3
if (active_mode != 3) {
active_mode = 3;
mode_btn_change = 1;
}
#elif (F3_FPS_UAC2 == 1)
// 改动原因F3 Game 固件按 AI7.1 键需重启加载 F4 AI7.1 固件
active_mode = 3;
need_reboot = 1;
SetRoleSwitchFlag(MODE_F4_FPS_UAC2);
#endif
}
}
@@ -1407,20 +1517,40 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
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 (F3_FPS_UAC2 == 1) || (F4_FPS_UAC2 == 1)
// 改动原因HID 0xA4 在 F3/F4 间切换需跨固件重启,同固件则本地切算法
if (target == 1) {
active_mode = target;
need_reboot = 1;
SetRoleSwitchFlag(MODE_F1_MUSIC_UAC2);
} else {
active_mode = target;
mode_btn_change = 1;
} else if (target == 2) {
#if (F3_FPS_UAC2 == 1)
if (active_mode != 2) {
active_mode = 2;
mode_btn_change = 1;
}
#else
active_mode = 2;
need_reboot = 1;
SetRoleSwitchFlag(MODE_F3_FPS_UAC2);
#endif
} else if (target == 3) {
#if (F4_FPS_UAC2 == 1)
if (active_mode != 3) {
active_mode = 3;
mode_btn_change = 1;
}
#else
active_mode = 3;
need_reboot = 1;
SetRoleSwitchFlag(MODE_F4_FPS_UAC2);
#endif
}
#elif (F1_MUSIC_UAC2 == 1)
if (target >= 2) {
active_mode = target;
need_reboot = 1;
SetRoleSwitchFlag(MODE_F3_F4_FPS_UAC2);
SetRoleSwitchFlag(get_fps_firmware_flag(target));
} else {
active_mode = target;
mode_btn_change = 1;
@@ -1514,8 +1644,8 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
case 3: led_on(&led_ctx, LED_AI7_1); break;
default: break;
}
// 改动原因2档脚步增强开档(15dB)恢复全亮LED
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);
// 等待松键,防止重启后再次触发出厂恢复循环
@@ -1529,8 +1659,8 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
delay_milliseconds(100);
}
#endif
// 出厂恢复默认AI7.1模式(mode=3需要F3/F4固件
SetRoleSwitchFlag(MODE_F3_F4_FPS_UAC2);
// 改动原因:出厂默认 AI7.1(mode=3),启动 F4 AI7.1 固件
SetRoleSwitchFlag(MODE_F4_FPS_UAC2);
delay_milliseconds(20);
#ifndef DISABLE_REBOOT
device_reboot();
@@ -1564,10 +1694,10 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
{
if(push_button_footsteps_enhancement_state_old == 1)
{
// 3档循环: 0(关/0dB) 1(中亮/6dB) → 2(高亮/12dB) → 0
flag_footsteps_enhancement = (flag_footsteps_enhancement + 1) % 3;
// 改动原因2档循环: 0(关/0dB) 1(/15dB)
flag_footsteps_enhancement = (flag_footsteps_enhancement + 1) % 2;
mode_change = 1;
debug_printf("Footstep mode changed: %d -> %d\n", flag_footsteps_enhancement, flag_footsteps_enhancement + 1);
debug_printf("Footstep mode changed to state=%d\n", flag_footsteps_enhancement);
}
}
push_button_footsteps_enhancement_state_old = button_footsteps_enhancement;
@@ -1575,18 +1705,13 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
{
if(flag_footsteps_enhancement == 0)
{
saved_footstep = 0;
saved_footstep = 0; // 改动原因:关档 0dB
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);
saved_footstep = 15; // 改动原因:开档 15dB唯一增强档
led_on(&led_ctx, LED_FOOTSTEP_MODE);
}
led_update_all(&led_ctx);
// 发送expand_gain到tile1执行
@@ -1604,30 +1729,29 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
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档位
// 改动原因HID增益映射到2档——0=关非0=开(15dB)
unsigned new_state;
unsigned char gain_to_save;
if (hid_gain_req == 0) {
new_state = 0;
} else if (hid_gain_req <= 6) {
new_state = 1;
gain_to_save = 0;
} else {
new_state = 2;
new_state = 1;
gain_to_save = 15;
}
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_on(&led_ctx, LED_FOOTSTEP_MODE);
}
led_update_all(&led_ctx);
}
unsigned char fp[] = "footstep";
save_value(fp, (unsigned char)hid_gain_req);
saved_footstep = hid_gain_req;
save_value(fp, gain_to_save);
saved_footstep = gain_to_save;
debug_printf("HID set footstep gain=%d, state=%d\n", hid_gain_req, flag_footsteps_enhancement);
}
}
@@ -1748,8 +1872,8 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
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_volume(mic_hid_level_to_codec_gain(codec_adc_pga_gain_reg_value));
g_mic_volume_level = (codec_adc_pga_gain_reg_value <= MIC_HID_LEVEL_MAX) ? codec_adc_pga_gain_reg_value : MIC_HID_LEVEL_MAX;
mic_mute_blink_tick = 0;
for(int i = 0; i < 15; i++)
led_off(&led_ctx, led_l_physical_map[i]);
@@ -1787,14 +1911,17 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
// 执行音量调节
if(current_dir == 1) { // 顺时针
if((codec_adc_pga_gain_reg_value < NAU88L21_PGA_GAIN_REG_MAX_VALUE) && (flag_mic_mute == 0)) {
if((codec_adc_pga_gain_reg_value < MIC_HID_LEVEL_MAX) && (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;
codec_adc_pga_gain_reg_value = codec_adc_pga_gain_reg_value + 2;
if (codec_adc_pga_gain_reg_value > MIC_HID_LEVEL_MAX) {
codec_adc_pga_gain_reg_value = MIC_HID_LEVEL_MAX;
}
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_volume(mic_hid_level_to_codec_gain(codec_adc_pga_gain_reg_value));
g_mic_volume_level = (codec_adc_pga_gain_reg_value <= MIC_HID_LEVEL_MAX) ? codec_adc_pga_gain_reg_value : MIC_HID_LEVEL_MAX;
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];
@@ -1810,15 +1937,18 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
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;
codec_adc_pga_gain_reg_value = codec_adc_pga_gain_reg_value - 2;
if (codec_adc_pga_gain_reg_value < 0) {
codec_adc_pga_gain_reg_value = 0;
}
if (!mic_det_muted) {
if (codec_adc_pga_gain_reg_value == 0)
mic_volume(0);
else
mic_volume(codec_adc_pga_gain_reg_value);
mic_volume(mic_hid_level_to_codec_gain(codec_adc_pga_gain_reg_value));
}
g_mic_volume_level = (codec_adc_pga_gain_reg_value <= 37) ? codec_adc_pga_gain_reg_value : 37;
g_mic_volume_level = (codec_adc_pga_gain_reg_value <= MIC_HID_LEVEL_MAX) ? codec_adc_pga_gain_reg_value : MIC_HID_LEVEL_MAX;
debug_printf("volume down %d\n", codec_adc_pga_gain_reg_value);
save_value(mic_vol_path, codec_adc_pga_gain_reg_value);
@@ -1898,10 +2028,13 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
uint8_t old_led_count = dac_gain_to_led[dac_level];
// 增加音量
++dac_level;
dac_level = dac_level + 2;
if (dac_level > DAC_LEVEL_MAX) {
dac_level = DAC_LEVEL_MAX;
}
g_volume_level = dac_level;
if (!dac_det_muted)
dac_volume(dac_level - DAC_LEVEL_MAX);
dac_volume(dac_level);
save_value(dac_vol_path, dac_level);
uint8_t new_led_count = dac_gain_to_led[dac_level];
@@ -1918,13 +2051,16 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
uint8_t old_led_count = dac_gain_to_led[dac_level];
// 减小音量
--dac_level;
dac_level = dac_level - 2;
if (dac_level < DAC_LEVEL_MIN) {
dac_level = DAC_LEVEL_MIN;
}
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);
dac_volume(dac_level);
}
save_value(dac_vol_path, dac_level);
@@ -2001,7 +2137,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
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);
dac_volume(dac_level);
}
g_volume_level = dac_level;
hp_mute_blink_tick = 0;
@@ -2059,7 +2195,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
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);
dac_volume(dac_level);
}
save_value(dac_vol_path, (unsigned char)dac_level);
// 更新DAC音量指示LED
@@ -2079,7 +2215,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
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
if (new_mic_level <= MIC_HID_LEVEL_MAX) { // 0=mute, 1~48=0~24dB0.5dB/级)
uint8_t new_led_count;
if (new_mic_level == 0) {
// mute: 静音硬件codec_adc_pga_gain_reg_value设为0与编码器静音一致
@@ -2089,7 +2225,7 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
} else {
codec_adc_pga_gain_reg_value = new_mic_level;
if (!mic_det_muted)
mic_volume(codec_adc_pga_gain_reg_value);
mic_volume(mic_hid_level_to_codec_gain(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);
@@ -2190,8 +2326,8 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
ptr[i] = 0x00;
}
hidSetChangePending(0x1);
debug_printf("Mic volume changed: %d -> %d, HID report sent\n",
g_last_mic_volume_level, current_mic_level);
// 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;
}
@@ -2333,7 +2469,8 @@ void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol,
#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;
// 改动原因:运行时 OS 检测为 Windows 时按 mode 路由 F1/F3/F4
unsigned flag = (saved_mode <= 1) ? MODE_F1_MUSIC_UAC2 : get_fps_firmware_flag(saved_mode);
SetRoleSwitchFlag(flag);
#ifndef DISABLE_REBOOT
device_reboot();
@@ -2442,12 +2579,12 @@ void mute_handler(chanend c_mic_det)
// 如果开机时全拔出发送mute
if (((det_val & 0b1110) == 0b1110) || ((det_val & 0b1110) == 0b1010) || ((det_val & 0b1110) == 0b0010)) {
if (((det_val & 0b1110) == 0b1110) || ((det_val & 0b1110) == 0b1010) || ((det_val & 0b1110) == 0b0010) || ((det_val & 0b1110) == 0b1000)) {
// 有mic插入恢复mic音量状态
c_mic_det <: (unsigned)MIC_DET_UNMUTE;
debug_printf("mic stable -> unmute\n");
}
timer tmr;
unsigned time;
tmr :> time;
@@ -2512,7 +2649,7 @@ void mute_handler(chanend c_mic_det)
#endif
if (((det_val & 0b1110) == 0b1110) || ((det_val & 0b1110) == 0b1010) || ((det_val & 0b1110) == 0b0010)) {
if (((det_val & 0b1110) == 0b1110) || ((det_val & 0b1110) == 0b1010) || ((det_val & 0b1110) == 0b0010) || ((det_val & 0b1110) == 0b1000)) {
// 有mic插入恢复mic音量状态
c_mic_det <: (unsigned)MIC_DET_UNMUTE;
debug_printf("mic stable -> unmute\n");

View File

@@ -9,25 +9,38 @@
#include <xs1.h>
#include <xcore/chanend.h>
#include <xcore/channel.h>
#include <xcore/channel_streaming.h>
#include "xc_ptr.h"
#include "xua_conf.h"
#include "share_buffer.h"
extern uint32_t init_eq_data(unsigned sample_freq);
#if F1_MUSIC_UAC2 == 1 && DNR_ENABLE == 1
/* 改动原因3 streaming chan + 1 普通 chan 传 us 192kHz跨 tile 静态内存不共享) */
uint32_t uc_ssrc_ds_in; /* tile[0]→tile[1] 192kHz mic */
uint32_t uc_ssrc_ds_out; /* tile[1]→tile[0] 48kHz 降采样结果 */
uint32_t uc_ssrc_us_in; /* tile[0]→tile[1] 48kHz DNR 后 */
uint32_t uc_ssrc_us_out; /* tile[1]→tile[0] 192kHz 升采样结果普通chan */
#endif
void dnr_exchange_buffer(int32_t *data);
// sample_freq 作为首字发送给 tile[0] 的 dsp_main用于采样率变化检测和 EQ 初始化
void buffer_exchange(chanend_t c_data, unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[], unsigned sample_freq) {
chan_out_word(c_data, sample_freq);
chan_out_buf_word (c_data, sampsFromUsbToAudio, 2);
chan_in_buf_word (c_data , sampsFromUsbToAudio, 2);
#if DNR_ENABLE == 1
chan_out_buf_word (c_data, sampsFromAudioToUsb, 2);
chan_in_buf_word (c_data , sampsFromAudioToUsb, 2);
#endif
unsigned data_in[4] = {0,0,0,0};
unsigned data_out[4] = {0,0,0,0};
data_in[0] = sampsFromUsbToAudio[0];
data_in[1] = sampsFromUsbToAudio[1];
data_in[2] = sampsFromAudioToUsb[0];
data_in[3] = sampsFromAudioToUsb[1];
chan_out_buf_word (c_data, data_in, 4);
chan_in_buf_word (c_data , data_out, 4);
sampsFromUsbToAudio[0] = data_out[0];
sampsFromUsbToAudio[1] = data_out[1];
sampsFromAudioToUsb[0] = data_out[2];
sampsFromAudioToUsb[1] = data_out[3];
}
@@ -38,40 +51,111 @@ void dsp_main (chanend_t c_data) {
int mic_output[I2S_CHANS_ADC];
int count = 0;
unsigned ch[1] = {2};
unsigned data_in[4] = {0,0,0,0};
unsigned data_out[4] = {0,0,0,0};
#if F1_MUSIC_UAC2 == 1
unsigned current_sample_freq = 0;
unsigned current_sample_freq = 192000;
#else
unsigned current_sample_freq = 48000;
#endif
while (1) {
unsigned sample_freq = (unsigned)chan_in_word(c_data);
chan_in_buf_word (c_data , play_input, 2);
// 采样率变化:重新初始化 EQ 系数并清空 ring buffer避免残留状态污染
if (sample_freq != current_sample_freq && sample_freq != 0) {
current_sample_freq = sample_freq;
init_eq_data(sample_freq);
clear_ring_buffer(0);
clear_ring_buffer(1);
clear_ring_buffer(2);
clear_ring_buffer(3);
play_output[0] = 0;
play_output[1] = 0;
#if F1_MUSIC_UAC2 == 1 && DNR_ENABLE == 1
static int mic_48k[2] = {0, 0};
static int us_cache[4][2] = {{0}};
static int us_cache_idx = 4; /* 4=无有效缓存输出静音0-3=当前消费 pair 索引 */
static int ds_tick = 0; /* 每拍+1满4拍处理一次 48kHz */
/* 改动原因:第一个 tick4 时 us_out 还没有数据,不能阻塞读;
* 之后每个 tick4 先读上一批(已就绪)再触发下一批,规避同拍等待 us_stereo 计算延迟 */
static int us_first_batch = 1;
#endif
init_eq_data(current_sample_freq);
clear_ring_buffer(0);
clear_ring_buffer(1);
clear_ring_buffer(2);
clear_ring_buffer(3);
#if F1_MUSIC_UAC2 == 1 && DNR_ENABLE == 1
/* 改动原因:采样率变化时复位所有 SSRC 状态,下一批重新从头开始 */
ds_tick = 0;
us_cache_idx = 4;
us_first_batch = 1;
#endif
while (1) {
chan_in_buf_word(c_data, data_in, 4);
chan_out_buf_word(c_data, data_out, 4);
#if EQ_ENABLE == 1
write_to_ring_buffer(0, data_in[0]);
write_to_ring_buffer(1, data_in[1]);
data_out[0] = read_from_ring_buffer(2);
data_out[1] = read_from_ring_buffer(3);
// data_out[0] = data_in[0];
// data_out[1] = data_in[1];
#else
data_out[0] = data_in[0];
data_out[1] = data_in[1];
#endif
#if DNR_ENABLE == 1
#if F1_MUSIC_UAC2 == 1
/* F1: 192kHz→48kHz(DS)→DNR→48kHz→192kHz(US)
*
* 时序优化说明:
* 原设计在 tick4 同一拍内"发 us_in → 等 us_stereo 计算 → 读8个 us_out"
* us_stereo 在 tile[1] 独立线程运算需 2-5µs导致 tick4 总延迟超过 5.2µs
* (192kHz 单拍周期)buffer_exchange 响应超时引发噪音。
*
* 当前设计:每个 tick4 先读上一批已就绪的 8 个 us_out 字us_rec_output_core
* 在前 3 拍期间已完成并阻塞等待消费,读取近乎零延迟),再触发本批 ds→DNR→us_in。
* 代价:录音延迟增加约 20.8µs一个 48kHz 周期),人耳不可感知。
*/
s_chan_out_word((chanend_t)uc_ssrc_ds_in, (uint32_t)data_in[2]);
s_chan_out_word((chanend_t)uc_ssrc_ds_in, (uint32_t)data_in[3]);
ds_tick++;
if (ds_tick >= 4) {
ds_tick = 0;
if (!us_first_batch) {
/* 读上一批 us_stereo 已生产的 4 对 192kHz近乎无延迟*/
us_cache[0][0] = (int)chan_in_word((chanend_t)uc_ssrc_us_out);
us_cache[0][1] = (int)chan_in_word((chanend_t)uc_ssrc_us_out);
us_cache[1][0] = (int)chan_in_word((chanend_t)uc_ssrc_us_out);
us_cache[1][1] = (int)chan_in_word((chanend_t)uc_ssrc_us_out);
us_cache[2][0] = (int)chan_in_word((chanend_t)uc_ssrc_us_out);
us_cache[2][1] = (int)chan_in_word((chanend_t)uc_ssrc_us_out);
us_cache[3][0] = (int)chan_in_word((chanend_t)uc_ssrc_us_out);
us_cache[3][1] = (int)chan_in_word((chanend_t)uc_ssrc_us_out);
us_cache_idx = 0;
}
/* 处理当前批ds→DNR→us_in结果在下一个 tick4 读取 */
mic_48k[0] = (int)s_chan_in_word((chanend_t)uc_ssrc_ds_out);
mic_48k[1] = (int)s_chan_in_word((chanend_t)uc_ssrc_ds_out);
dnr_exchange_buffer(mic_48k);
s_chan_out_word((chanend_t)uc_ssrc_us_in, (uint32_t)mic_48k[0]);
s_chan_out_word((chanend_t)uc_ssrc_us_in, (uint32_t)mic_48k[1]);
us_first_batch = 0;
}
chan_out_buf_word (c_data , play_output, I2S_CHANS_DAC);
#if DNR_ENABLE == 1
chan_in_buf_word (c_data , mic_input, 2) ;
chan_out_buf_word (c_data , mic_output, I2S_CHANS_ADC);
#endif
write_to_ring_buffer(0, play_input[0]);
write_to_ring_buffer(1, play_input[1]);
play_output[0] = read_from_ring_buffer(2);
play_output[1] = read_from_ring_buffer(3);
#if DNR_ENABLE == 1
dnr_exchange_buffer(mic_input);
mic_output[0] = mic_input[0];
mic_output[1] = mic_input[1];
if (us_cache_idx < 4) {
data_out[2] = us_cache[us_cache_idx][0];
data_out[3] = us_cache[us_cache_idx][1];
us_cache_idx++;
} else {
data_out[2] = 0;
data_out[3] = 0;
}
#else
dnr_exchange_buffer((int32_t *)&data_in[2]);
data_out[2] = data_in[2];
data_out[3] = data_in[3];
#endif
#else
data_out[2] = data_in[2];
data_out[3] = data_in[3];
#endif
}
}

View File

@@ -8,15 +8,12 @@
#include <xclib.h>
#include <stdio.h>
#include "debug_print.h"
#include "dfu_upgrade.h"
#include "xua.h"
#if HID_DFU_EN
#ifndef DFU_FLASH_MAX_UPGRADE_SIZE
#define DFU_FLASH_MAX_UPGRADE_SIZE (2200 * 1024)
#endif
#define DFU_FLASH_ERROR()
static int dfu_flash_device_open = 0;

View File

@@ -95,7 +95,7 @@ unsigned char handle_firmware_upgrade_start(uint8_t data[], uint16_t len)
debug_printf("g_first_page_write_executed: %d\n", g_first_page_write_executed);
if (firmware_size == 0 || firmware_size > FLASH_MAX_UPGRADE_SIZE) {
if (firmware_size == 0 || firmware_size > DFU_FLASH_MAX_UPGRADE_SIZE) {
debug_printf("Firmware upgrade error: invalid size %lu\n", firmware_size);
response[0] = STATUS_SIZE_INVALID;
send_firmware_upgrade_response(FIRMWARE_UPGRADE_START, response, 1);

View File

@@ -44,7 +44,11 @@ typedef enum {
// 数据包格式:同步头(1) + 命令码(1) + 块序号(2) + 数据长度(1) + 数据(N) + Checksum(1)
// 所以最大数据长度 = 63 - 5(头部) - 1(Checksum) = 57字节
#define MAX_DATA_BLOCK_SIZE 57 // 最大数据块大小63字节HID数据包 - 5字节头部 - 1字节Checksum
#define FLASH_MAX_UPGRADE_SIZE (2000 * 1024) // 最大固件大小1400KB
#ifndef DFU_FLASH_MAX_UPGRADE_SIZE
#define DFU_FLASH_MAX_UPGRADE_SIZE (3000 * 1024)
#endif
// 页缓冲区结构
typedef struct {

View File

@@ -53,7 +53,7 @@ static volatile int g_runtime_angle_written = 0;
// 通过该标志判断EX3D是否已完成初始化若已完成则在收到0xF9时立即应用角度。
static volatile int g_ex3d_init_done = 0;
// audio_ex3d_init会覆盖Ex3dExpandGain为库默认值用此变量保存0xFD boot sync收到的值
static volatile int32_t g_boot_footstep_expand_gain_value = 12;
static volatile int32_t g_boot_footstep_expand_gain_value = 15; // 改动原因脚步增强默认15dB2档0/15
static volatile int32_t g_boot_lmt_threshold_value = -5;
static volatile uint32_t g_boot_angle_values[8] = {315, 45, 0, 0, 225, 135, 270, 90};
@@ -299,6 +299,7 @@ void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudi
#elif DNR_ENABLE == 1
buffer_exchange(uc_eq_data, sampsFromUsbToAudio, sampsFromAudioToUsb, ubm_sample_freq);
#endif
GET_SHARED_GLOBAL(is_monitor, g_monitor_switch_t1);
if (is_monitor) {
sampsFromUsbToAudio[0] += (unsigned)((((int)sampsFromAudioToUsb[0]) >> 1));
@@ -1175,7 +1176,8 @@ void ex3d_task(){
}
// audio_ex3d_init内部会将Ex3dExpandGain重置为库默认值(6),这里始终用保存值恢复
Ex3dExpandGain = g_boot_footstep_expand_gain_loaded ? g_boot_footstep_expand_gain_value : 12;
// 改动原因无flash/boot同步时脚步增强默认15dB原12dB为旧3档高亮档
Ex3dExpandGain = g_boot_footstep_expand_gain_loaded ? g_boot_footstep_expand_gain_value : 15;
Ex3dLimiterThreshold = g_boot_lmt_threshold_loaded ? g_boot_lmt_threshold_value : -15;
EX3DAudio_SetOnGain(Ex3dOnGain);

View File

@@ -1,5 +1,5 @@
#if DEBUG_MEMORY_LOG_ENABLED
#define DEBUG_PRINT_ENABLE 1
#define DEBUG_PRINT_ENABLE 0
#else
#define DEBUG_PRINT_ENABLE 0
#endif

View File

@@ -15,7 +15,12 @@ extern void device_reboot(void);
// 常量定义
#define EQ_DISABLED_MODE 10 // 禁用EQ的模式编号
#if DEBUG_MEMORY_LOG_ENABLED
unsigned g_log_switch = 1;
#else
unsigned g_log_switch = 0;
#endif
#include "xmath/filter.h"
#include "eq.h"
@@ -631,12 +636,12 @@ unsigned char process_send_params(uint8_t data[], uint16_t len) {
}
// 处理设置麦克风增益命令 (0x82) - SET_MIC_VOLUME
// 范围: 0-37 (0=mute, 1-37=0dB~36dB, 1dB/步; register=38的+1.5dB仅firmware内部)
// 改动原因麦克风协议升级为49级0~48最大增益由36dB收敛到24dB0.5dB/级)。
if (data[1] == 0x82) {
uint8_t mic_level = data[2];
// 参数验证: 0-37
if (mic_level > 37) {
// 参数验证: 0-48
if (mic_level > 48) {
return false;
}
@@ -705,13 +710,13 @@ unsigned char process_send_params(uint8_t data[], uint16_t len) {
}
// 处理设置音量命令 (0x93) - SET_VOLUME
// 范围: 0-15 (0=静音, 1-15=-28dB~0dB, 2dB/步)
// 改动原因DAC音量协议与旋钮统一扩展到49级0~48与SY102dac对应表一致。
if (data[1] == 0x93) {
// 获取音量级别
uint8_t volume_level = data[2];
// 参数验证: 0-29 (0=mute, 1-29=-28dB~0dB, 1dB/步)
if (volume_level > 29) {
// 参数验证: 0-48
if (volume_level > 48) {
return false;
}

View File

@@ -615,9 +615,10 @@ class EQDesigner(QMainWindow):
volume_control_layout = QHBoxLayout()
self.volume_label = QLabel("监听音量 (0x93/0x94):")
self.volume_spin = QSpinBox()
self.volume_spin.setRange(0, 29)
self.volume_spin.setValue(29)
self.volume_spin.setSuffix(" (0=静音, 29=0dB)")
# 改动原因与固件0x93协议保持一致DAC监听音量改为49级(0~48)。
self.volume_spin.setRange(0, 48)
self.volume_spin.setValue(48)
self.volume_spin.setSuffix(" (0=静音, 48=0dB)")
volume_control_layout.addWidget(self.volume_label)
volume_control_layout.addWidget(self.volume_spin)
volume_layout.addRow(volume_control_layout)
@@ -636,9 +637,10 @@ class EQDesigner(QMainWindow):
mic_vol_control_layout = QHBoxLayout()
self.mic_volume_label = QLabel("麦克风增益 (0x82/0x83):")
self.mic_volume_spin = QSpinBox()
self.mic_volume_spin.setRange(0, 37)
self.mic_volume_spin.setValue(37)
self.mic_volume_spin.setSuffix(" (0=静音, 1=0dB, 37=36dB)")
# 改动原因与固件0x82协议保持一致MIC增益改为49级(0~48)2级=1dB最大24dB。
self.mic_volume_spin.setRange(0, 48)
self.mic_volume_spin.setValue(48)
self.mic_volume_spin.setSuffix(" (0=静音, 2级=1dB, 48=24dB)")
mic_vol_control_layout.addWidget(self.mic_volume_label)
mic_vol_control_layout.addWidget(self.mic_volume_spin)
volume_layout.addRow(mic_vol_control_layout)
@@ -2298,7 +2300,7 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{
log_message(LOG_LEVEL_ERROR, f"设置并保存EQ模式时出错: {str(e)}", self.log_level)
def on_set_volume(self):
"""设置监听音量级别发送0x93命令范围0-290=静音1=-28dB29=0dB1dB/步"""
"""设置监听音量级别发送0x93命令范围0-48按SY102dac对应表映射"""
if self.device_combo.currentData() is None:
log_message(LOG_LEVEL_ERROR, "请先选择设备", self.log_level)
return
@@ -2309,7 +2311,7 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{
self,
"确认设置监听音量",
f"将要设置监听音量级别为: {volume_level}\n\n"
f"音量范围: 0-29 (0=静音, 1=-28dB, ..., 29=0dB, 1dB/步)\n\n"
f"音量范围: 0-48 (0=静音, 1=-66dB, ..., 47=-0.5dB, 48=0dB按SY102dac对应表)\n\n"
f"是否继续?",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No
@@ -2325,7 +2327,7 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{
data = bytearray(63)
data[0] = 0x77
data[1] = 0x93 # SET_VOLUME
data[2] = volume_level # 0-29
data[2] = volume_level # 0-48
log_message(LOG_LEVEL_INFO, f"正在设置监听音量级别为 {volume_level}...", self.log_level)
h.write([0x01] + list(data))
@@ -2367,7 +2369,7 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{
QMessageBox.information(
self, "监听音量级别",
f"当前监听音量级别: {volume_level}\n\n"
f"音量范围: 0-29 (0=静音, 1=-28dB, ..., 29=0dB, 1dB/步)"
f"音量范围: 0-48 (0=静音, 1=-66dB, ..., 47=-0.5dB, 48=0dB按SY102dac对应表)"
)
else:
log_message(LOG_LEVEL_ERROR, f"无效的0x94响应同步头: 0x{reply[1]:02x} 0x{reply[2]:02x}", self.log_level)
@@ -2380,7 +2382,7 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{
log_message(LOG_LEVEL_ERROR, f"读取监听音量时出错: {str(e)}", self.log_level)
def on_set_mic_volume(self):
"""设置麦克风增益级别发送0x82命令范围0-370=静音1=0dB37=36dB1dB/步"""
"""设置麦克风增益级别发送0x82命令范围0-482级=1dB48=24dB"""
if self.device_combo.currentData() is None:
log_message(LOG_LEVEL_ERROR, "请先选择设备", self.log_level)
return
@@ -2391,7 +2393,7 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{
self,
"确认设置麦克风增益",
f"将要设置麦克风增益级别为: {mic_level}\n\n"
f"增益范围: 0-37 (0=静音, 1=0dB, ..., 37=36dB, 1dB/步)\n\n"
f"增益范围: 0-48 (0=静音, 2级=1dB, ..., 48=24dB)\n\n"
f"是否继续?",
QMessageBox.Yes | QMessageBox.No,
QMessageBox.No
@@ -2407,7 +2409,7 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{
data = bytearray(63)
data[0] = 0x77
data[1] = 0x82 # SET_MIC_VOLUME
data[2] = mic_level # 0-37
data[2] = mic_level # 0-48
log_message(LOG_LEVEL_INFO, f"正在设置麦克风增益级别为 {mic_level}...", self.log_level)
h.write([0x01] + list(data))
@@ -2449,7 +2451,7 @@ eq_mode_data_t sEQ_data_{int(fs)}HZ[NUM_EQ_MODES][NUM_EQ_CHANS] = {{
QMessageBox.information(
self, "麦克风增益级别",
f"当前麦克风增益级别: {mic_level}\n\n"
f"增益范围: 0-37 (0=静音, 1=0dB, ..., 37=36dB, 1dB/步)"
f"增益范围: 0-48 (0=静音, 2级=1dB, ..., 48=24dB)"
)
else:
log_message(LOG_LEVEL_ERROR, f"无效的0x83响应同步头: 0x{reply[1]:02x} 0x{reply[2]:02x}", self.log_level)

View File

@@ -8,8 +8,8 @@
### 1.2 支持的指令列表
| 指令码 | 命令名称 | 功能 | 方向 | 描述 |
|--------|----------|------|------|------|
| 0x82 | SET_MIC_VOLUME | 设置麦克风增益级别 | 主机→设备 | 设置麦克风PGA增益0=静音, 1-37=0dB~36dB, 1dB/步 |
| 0x83 | GET_MIC_VOLUME | 获取麦克风增益级别 | 主机→设备 | 读取当前麦克风PGA增益级别0=静音, 1-37=0dB~36dB |
| 0x82 | SET_MIC_VOLUME | 设置麦克风增益级别 | 主机→设备 | 设置麦克风增益0=静音, 1-48=0~24dB, 2级=1dB |
| 0x83 | GET_MIC_VOLUME | 获取麦克风增益级别 | 主机→设备 | 读取当前麦克风增益级别0=静音, 1-48=0~24dB, 2级=1dB |
| 0x84 | FACTORY_RESET | 恢复出厂默认设置 | 主机→设备 | 删除Flash中所有已保存参数设备重启后自动恢复出厂默认值 |
| 0x85 | SET_AI_NOISE_STRENGTH | 设置AI降噪强度 | 主机→设备 | 设置AI降噪强度0=关闭2-100偶数=强度级别步进2100对应最强-200dB |
| 0x86 | GET_AI_NOISE_STRENGTH | 获取AI降噪强度 | 主机→设备 | 读取当前AI降噪强度强度变化含按键切换、开机初始值时设备主动上报 |
@@ -24,8 +24,8 @@
| 0x90 | RESET_EQ_PARAMS | 复位EQ参数 | 主机→设备 | 删除Flash中的EQ参数并恢复头文件预设参数 |
| 0x91 | GET_EQ_MODE_COUNT | 获取EQ模式总数 | 主机→设备 | 返回预定义加用户模式的总数(不包含禁用模式) |
| 0x92 | SET_AND_SAVE_EQ_MODE | 设置并保存EQ模式 | 主机→设备 | 设置当前EQ模式(0-9)并保存到Flash开机时自动恢复 |
| 0x93 | SET_VOLUME | 设置监听音量级别 | 主机→设备 | 设置设备监听音量级别0=静音, 1-29=-28dB~0dB, 1dB/步 |
| 0x94 | GET_VOLUME | 获取监听音量级别 | 主机→设备 | 读取设备当前监听音量级别0=静音, 1-29=-28dB~0dB, 1dB/步 |
| 0x93 | SET_VOLUME | 设置监听音量级别 | 主机→设备 | 设置设备监听音量级别0=静音, 1-48按SY102dac对应表映射到-66dB~0dB |
| 0x94 | GET_VOLUME | 获取监听音量级别 | 主机→设备 | 读取设备当前监听音量级别0=静音, 1-48按SY102dac对应表映射 |
| 0x9D | SET_EQ_ENABLE | 设置EQ使能开关 | 主机→设备 | 设置EQ使能开关ON/OFF禁用时保存当前模式启用时恢复之前模式 |
| 0x9E | GET_EQ_ENABLE | 获取EQ使能开关 | 主机→设备 | 读取EQ使能开关状态ON/OFF |
| 0x9F | GET_SAMPLE_FORMAT | 获取采样率和格式 | 主机→设备 | 读取当前采样率、DSD模式和DAC采样分辨率 |
@@ -59,20 +59,20 @@
---------|------|------|------
0 | 1 | 0x77 | 同步头1
1 | 1 | 0x82 | 命令码
2 | 1 | uint8 | 增益级别 (0=静音, 1-37=0dB~36dB, 1dB/步)
2 | 1 | uint8 | 增益级别 (0=静音, 1-48=0~24dB, 2级=1dB)
3-62 | 60 | 0x00 | 保留字节
```
**参数说明**:
- **增益级别范围:** 0-37共38级)
- **增益级别范围:** 0-48共49级)
- **对应硬件**NAU88C22 ADC PGA增益寄存器reg 0x007E+ 输出放大器reg 0x0035
- 0静音mute同时清零 reg 0x007E 和 0x0035
- 10dB最小有效增益
- 1约0.5dB按2级=1dB映射
- 21dB
- ...1dB/步
- 3736dB最大HID可设置增益
- **注意**内部寄存器值38约+1.5dB数字增益为firmware保留HID可设置
- >37 为无效值,固件将拒绝设置
- ...2级=1dB
- 47约23.5dB
- 4824dB最大HID可设置增益)
- >48 为无效值,固件将拒绝设置
**设备端处理**:
- 设置后立即应用到ADC PGA硬件
@@ -102,12 +102,12 @@
0 | 1 | 0x01 | Report ID
1 | 1 | 0x77 | 同步头1
2 | 1 | 0x83 | 同步头2
3 | 1 | uint8 | 当前增益级别 (0=静音, 1-37=0dB~36dB)
3 | 1 | uint8 | 当前增益级别 (0=静音, 1-48=0~24dB, 2级=1dB)
4-62 | 59 | 0x00 | 保留字节
```
**主动上报说明**:
- 编码器旋转导致增益变化时,设备主动向主机上报当前增益(最大上报37内部38时上报37
- 编码器旋转导致增益变化时,设备主动向主机上报当前增益(范围0~48
- HID SET_MIC_VOLUME0x82命令成功执行后设备也主动上报新增益
### 2.0c 0x84 - FACTORY_RESET (恢复出厂默认设置)
@@ -127,8 +127,8 @@
|------|-----------|------|
| AI7.1音效模式 | 3 (AI7.1开启) | 音效模式 0=无音效, 1=音乐, 2=游戏, 3=AI7.1 |
| 脚步增强 | 12dB (全亮, 状态2) | LED全亮, 扩展增益12dB |
| 麦克风音量 | 22 (21dB) | PGA寄存器值22 = 21dB |
| 监听音量 | 15 (-14dB) | DAC level 15 = 0dB - 14 = -14dB |
| 麦克风音量 | 44 (约22dB) | 49级中的44级按2级=1dB映射 |
| 监听音量 | 30 (-14dB) | 49级中的30级按SY102dac对应表映射 |
| EQ参数 | 头文件预设 | 删除所有用户EQ参数恢复固件内置预设 |
| AI降噪 | 开启 | 每次上电默认开启不保存到Flash |
| 耳返开关 | 0 (关闭) | ADC→耳机监听通路默认关闭 |
@@ -532,25 +532,27 @@
---------|------|------|------
0 | 1 | 0x77 | 同步头1
1 | 1 | 0x93 | 命令码
2 | 1 | uint8 | 音量级别 (0-29: 0=静音, 1=-28dB, ..., 29=0dB)
2 | 1 | uint8 | 音量级别 (0-48: 0=静音, 1=-66dB, ..., 48=0dB按SY102dac对应表)
3-62 | 60 | 0x00 | 保留字节
```
**参数说明**:
- **音量级别范围:** 0-29共30级)
- **音量级别范围:** 0-48共49级)
- **说明:** 控制设备监听输出DAC/耳机)音量级别
- 0: 静音muteDAC完全静音
- 1: -28dB最小有效音量
- 2: -27dB
- ...每级1dB步进)
- 29: 0dB最大音量
- **对应硬件**NAU88C22 DAC音量寄存器reg 0x003430级精度1dB/步)
- 1: -66dB最小有效音量
- 2: -64dB
- ...`SY102dac对应表.csv` 的非线性步进)
- 46: -1dB
- 47: -0.5dB
- 48: 0dB最大音量
- **对应硬件**NAU88C22 DAC音量寄存器reg 0x003449级查表映射
**设备端处理**:
- 设置后立即应用到DAC硬件
- 同步更新前面板LEDD系列15个LED反映当前音量级别每2级对应1个LED
- 保存到Flashdac_vol路径断电重启后自动恢复
- 如果参数超出范围(>29),固件将拒绝设置
- 如果参数超出范围(>48),固件将拒绝设置
**返回值**:
无直接返回值。如需确认音量是否设置成功请使用GET_VOLUME命令读取当前音量。设备端音量变化含编码器旋转引起的变化会主动通过0x94格式上报。
@@ -574,7 +576,7 @@
0 | 1 | 0x01 | Report ID
1 | 1 | 0x77 | 同步头1
2 | 1 | 0x94 | 同步头2
3 | 1 | uint8 | 当前音量级别 (0-29: 0=静音, 1-29=-28dB~0dB, 1dB/步)
3 | 1 | uint8 | 当前音量级别 (0-48: 0=静音, 1-48按SY102dac对应表映射到-66dB~0dB)
4-62 | 59 | 0x00 | 保留字节
```

View File

@@ -87,82 +87,112 @@ const uint8_t led_d_physical_map[15] = {
22, // LED_D15 -> OUT22
};
const uint8_t mic_gain_to_led[39] = {
0, // [-1] 增益-1: 0个LED这个设计未启用
1, // [0] 增益0: 0个LED
1, // [1] 增益1: 0个LED
1, // [2] 增益2: 0个LED
1, // [3] 增益3: 1个LED
2, // [4] 增益4: 1个LED
2, // [5] 增益5: 1个LED
2, // [6] 增益6: 2个LED
2, // [7] 增益7: 2个LED
3, // [8] 增益8: 2个LED
3, // [9] 增益9: 3个LED
3, // [10] 增益10: 3个LED
3, // [11] 增益11: 3个LED
4, // [12] 增益12: 4个LED
4, // [13] 增益13: 4个LED
4, // [14] 增益14: 4个LED
5, // [15] 增益15: 5个LED
5, // [16] 增益16: 5个LED
6, // [17] 增益17: 6个LED
6, // [18] 增益18: 6个LED
7, // [19] 增益19: 7个LED
7, // [20] 增益20: 7个LED
8, // [21] 增益21: 8个LED
8, // [22] 增益22: 8个LED
9, // [23] 增益23: 9个LED
9, // [24] 增益24: 9个LED
10, // [25] 增益25: 10个LED
10, // [26] 增益26: 10个LED
11, // [27] 增益27: 11个LED
11, // [28] 增益28: 11个LED
12, // [29] 增益29: 12个LED
12, // [30] 增益30: 12个LED
13, // [31] 增益31: 13个LED
13, // [32] 增益32: 13个LED
14, // [33] 增益33: 14个LED
14, // [34] 增益34: 14个LED
15, // [35] 增益35: 15个LED
15, // [36] 增益36: 15个LED
15 // [37] 增益36+1.5 digitial gain: 15个LED
// 改动原因:按 SY102mic音量对应表.csv将麦克风音量等级改为 49 级(0~48),最大增益改为 24dB
// LED档位按表中“旋钮刻度49级 + LED灯15个”的分段阈值重建。
const uint8_t mic_gain_to_led[49] = {
0, // [0] mute
1, // [1]
1, // [2]
1, // [3]
2, // [4]
2, // [5]
2, // [6]
3, // [7]
3, // [8]
3, // [9]
4, // [10]
4, // [11]
4, // [12]
5, // [13]
5, // [14]
5, // [15]
6, // [16]
6, // [17]
6, // [18]
7, // [19]
7, // [20]
7, // [21]
8, // [22]
8, // [23]
8, // [24]
9, // [25]
9, // [26]
9, // [27]
10, // [28]
10, // [29]
10, // [30]
11, // [31]
11, // [32]
11, // [33]
12, // [34]
12, // [35]
12, // [36]
13, // [37]
13, // [38]
13, // [39]
13, // [40]
14, // [41]
14, // [42]
14, // [43]
14, // [44]
15, // [45]
15, // [46]
15, // [47]
15 // [48] max 24dB
};
// DAC监听音量增益到LED数量的映射表
// 索引 0 = 静音 (0个LED, reg 0x0034=0x0000)
// 索引 1~29: -28dB ~ 0dB1dB/步每2个dB对应1个LED最后1dB独占15号LED
const uint8_t dac_gain_to_led[30] = {
0, // [0] mute: 0 LEDs
1, // [1] -28dB: 1 LED
1, // [2] -27dB: 1 LED
2, // [3] -26dB: 2 LEDs
2, // [4] -25dB: 2 LEDs
3, // [5] -24dB: 3 LEDs
3, // [6] -23dB: 3 LEDs
4, // [7] -22dB: 4 LEDs
4, // [8] -21dB: 4 LEDs
5, // [9] -20dB: 5 LEDs
5, // [10] -19dB: 5 LEDs
6, // [11] -18dB: 6 LEDs
6, // [12] -17dB: 6 LEDs
7, // [13] -16dB: 7 LEDs
7, // [14] -15dB: 7 LEDs
8, // [15] -14dB: 8 LEDs
8, // [16] -13dB: 8 LEDs
9, // [17] -12dB: 9 LEDs
9, // [18] -11dB: 9 LEDs
10, // [19] -10dB: 10 LEDs
10, // [20] -9dB: 10 LEDs
11, // [21] -8dB: 11 LEDs
11, // [22] -7dB: 11 LEDs
12, // [23] -6dB: 12 LEDs
12, // [24] -5dB: 12 LEDs
13, // [25] -4dB: 13 LEDs
13, // [26] -3dB: 13 LEDs
14, // [27] -2dB: 14 LEDs
14, // [28] -1dB: 14 LEDs
15, // [29] 0dB: 15 LEDs
// 改动原因:按 SY102dac对应表.csv将DAC音量等级改为 49 级(0~48)
// LED分段阈值按“旋钮48格 + 15灯”映射重建确保HID 0x93新范围显示一致。
const uint8_t dac_gain_to_led[49] = {
0, // [0] mute
1, // [1]
1, // [2]
1, // [3]
2, // [4]
2, // [5]
2, // [6]
3, // [7]
3, // [8]
3, // [9]
4, // [10]
4, // [11]
4, // [12]
5, // [13]
5, // [14]
5, // [15]
6, // [16]
6, // [17]
6, // [18]
7, // [19]
7, // [20]
7, // [21]
8, // [22]
8, // [23]
8, // [24]
9, // [25]
9, // [26]
9, // [27]
10, // [28]
10, // [29]
10, // [30]
11, // [31]
11, // [32]
11, // [33]
12, // [34]
12, // [35]
12, // [36]
13, // [37]
13, // [38]
13, // [39]
13, // [40]
14, // [41]
14, // [42]
14, // [43]
14, // [44]
15, // [45]
15, // [46]
15, // [47]
15, // [48]
};
/*=========================================================================

View File

@@ -65,8 +65,10 @@ typedef struct {
extern const uint8_t led_l_physical_map[15];
extern const uint8_t led_d_physical_map[15];
extern const uint8_t mic_gain_to_led[39];
extern const uint8_t dac_gain_to_led[30];
// 改动原因麦克风音量协议从旧版38级(0~37)扩展为49级(0~48)LED映射表长度同步扩展。
extern const uint8_t mic_gain_to_led[49];
// 改动原因:按 SY102dac对应表.csvDAC音量协议从30级(0~29)扩展为49级(0~48)LED映射表长度同步扩展。
extern const uint8_t dac_gain_to_led[49];
/*=========================================================================
基础控制API

View File

@@ -22,7 +22,7 @@ swlock_t flash_lock = SWLOCK_INITIAL_VALUE;
static rtos_qspi_flash_t qspi_flash_ctx_s;
#define FLASH_CLKBLK XS1_CLKBLK_3
#ifndef FS_BASE_ADDR
#define FS_BASE_ADDR (2500 * 1024)
#define FS_BASE_ADDR (3500 * 1024)
#endif
#define SECTOR_SIZE 4096
rtos_qspi_flash_t *qspi_flash_ctx = &qspi_flash_ctx_s;

View File

@@ -2,6 +2,16 @@
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
#include "xua.h" /* Device specific defines */
#if F1_MUSIC_UAC2 == 1 && DNR_ENABLE == 1
#include "ssrc_rec_core.h"
/* 改动原因3 streaming + 1 普通 chanus 192kHz 走普通 chan跨 tile 内存不共享) */
extern uint32_t uc_ssrc_ds_in;
extern uint32_t uc_ssrc_ds_out;
extern uint32_t uc_ssrc_us_in;
extern uint32_t uc_ssrc_us_out;
#endif
#ifdef EXCLUDE_USB_AUDIO_MAIN
/**
@@ -540,6 +550,14 @@ int main()
USER_MAIN_DECLARATIONS
#if F1_MUSIC_UAC2 == 1 && DNR_ENABLE == 1
/* 改动原因streaming chan 有 tile 配额上限us 192kHz 用普通 chan 传 8 word/块 */
streaming chan c_ssrc_ds_in;
streaming chan c_ssrc_ds_out;
streaming chan c_ssrc_us_in;
chan c_ssrc_us_out;
#endif
chan c_dsp_to_ex3d[DSP_WORKER_COUNT];
chan cc_mic_level;
chan c_audiohw;
@@ -582,6 +600,11 @@ int main()
}
}
on tile[1]: mute_handler(c_mic_det);
#if F1_MUSIC_UAC2 == 1 && DNR_ENABLE == 1
on tile[1] : ds_rec_core(c_ssrc_ds_in, c_ssrc_ds_out);
on tile[1] : us_rec_core(c_ssrc_us_in);
on tile[1] : us_rec_output_core(c_ssrc_us_out);
#endif
on tile[0] : {
par {
@@ -611,7 +634,17 @@ int main()
dsp_core0();
}
}
on tile[0] : { dsp_main(c_eq_data); }
on tile[0] : {
#if F1_MUSIC_UAC2 == 1 && DNR_ENABLE == 1
unsafe {
uc_ssrc_ds_in = (uint32_t)(unsigned)(streaming chanend)c_ssrc_ds_in;
uc_ssrc_ds_out = (uint32_t)(unsigned)(streaming chanend)c_ssrc_ds_out;
uc_ssrc_us_in = (uint32_t)(unsigned)(streaming chanend)c_ssrc_us_in;
uc_ssrc_us_out = (uint32_t)(unsigned)(chanend)c_ssrc_us_out;
}
#endif
dsp_main(c_eq_data);
}
#endif
#if DNR_ENABLE == 1

View File

@@ -0,0 +1,187 @@
#define FUNCTION_NAME ds_stereo
/*
void ds_stereo(
int32_t final_shr,
int32_t * coefs,
int32_t * data,
chanend_t c_in,
chanend_t c_out,
int32_t num_phase);
*/
#define NSTACKWORDS 32
#define S_LEFT 0
#define S_RIGHT 1
#define S_LOOP_COUNT 2
#define S_COEF_BASE_POINTER 3
.cc_top FUNCTION_NAME.function
.type FUNCTION_NAME,@function
.issue_mode dual
.align 4
#define ONE 0x40000000
zeros:
.word 0, 0, 0, 0, 0, 0, 0, 0
left_chan:
.word 0, 0, 0, 0, ONE, ONE, ONE, ONE
right_chan:
.word ONE, ONE, ONE, ONE, 0, 0, 0, 0
.align 16
.globl FUNCTION_NAME
.globl FUNCTION_NAME.nstackwords
.set FUNCTION_NAME.nstackwords, 32
FUNCTION_NAME:
{ dualentsp NSTACKWORDS;}
stw r4, sp[20]
stw r5, sp[21]
stw r6, sp[22]
stw r7, sp[23]
stw r8, sp[24]
stw r9, sp[25]
stw r10, sp[26]
ldw r4, sp[NSTACKWORDS+1]
stw r4, sp[27]
//{mov r0, r0; mov r1, r1}
//{mov r2, r2; mov r3, r3}
#define CHANNELS 2
#define MACCRS_PER_PHASE 4
#define BYTES_PER_WORD 4
#define WORDS_PER_VECTOR 8
#define BYTES_PER_VECTOR (WORDS_PER_VECTOR*BYTES_PER_WORD)
ldc r10, (BYTES_PER_VECTOR+BYTES_PER_WORD)
ldc r9, BYTES_PER_VECTOR
ldc r8, (2*MACCRS_PER_PHASE-1)*BYTES_PER_VECTOR - 4 + (BYTES_PER_VECTOR+BYTES_PER_WORD) + 4
ldc r7, MACCRS_PER_PHASE*BYTES_PER_VECTOR
ldc r6, ((1<<(BYTES_PER_WORD*CHANNELS))-1)
//load number of phases - 1 to r11
ldw r11, sp[NSTACKWORDS+2]
sub r11, r11, 1
// jump to passthrough loop if num of phases is 1
bf r11, passthrough_loop
std r1, r11, sp[1]
//store the final_shr for the VLSAT
std r0, r0, sp[2]
std r0, r0, sp[3]
std r0, r0, sp[4]
std r0, r0, sp[5]
ldc r11, (MACCRS_PER_PHASE-1)*BYTES_PER_VECTOR - 4 + 4 //the final +4 is for the padding at the origin
{add r2, r2, r11; nop }
outer_loop:
ldc r11, (MACCRS_PER_PHASE-1)*BYTES_PER_VECTOR
{vclrdr ; add r11, r2, 0} //clear accu and reset data pointer
ldd r1, r4, sp[1] // set loop counter and coef base pointer
phase_loop:
//{nop; nop}
//{nop; nop}
//{nop; nop}
//MACCR 1 left
{vldc r11[0]; add r11, r11, BYTES_PER_WORD}
{vlmaccr r1[0]; add r1, r1, r9}
{vstc r11[0]; sub r11, r11, r10}
//MACCR 2 left
{vldc r11[0]; add r11, r11, BYTES_PER_WORD}
{vlmaccr r1[0]; add r1, r1, r9}
{vstc r11[0]; sub r11, r11, r10}
//MACCR 3 left
{vldc r11[0]; add r11, r11, BYTES_PER_WORD}
{vlmaccr r1[0]; add r1, r1, r9}
{vstc r11[0]; sub r11, r11, r10}
{testct r0, res[r3]; nop}
{bt r0, exit; nop}
{in r0, res[r3] ; nop } //fetch data from channel, then get the other one too
{stw r0, r11[0] ; in r5, res[r3] } //store to start of phase
//MACCR 4 left
{vldc r11[0]; add r11, r11, BYTES_PER_WORD}
{vlmaccr r1[0]; add r1, r1, r9}
{vstc r11[0]; sub r11, r11, r10}
//rewind r1 by MACCRS_PER_PHASE * BYTES_PER_VECTOR
{sub r1, r1, r7; add r11, r11, r8 }
//now do the right channel
{vldc r11[0]; add r11, r11, BYTES_PER_WORD}
{vlmaccr r1[0]; add r1, r1, r9}
{vstc r11[0]; sub r11, r11, r10} //r10 = 32 + 1
//MACCR 2 right
{vldc r11[0]; add r11, r11, BYTES_PER_WORD}
{vlmaccr r1[0]; add r1, r1, r9}
{vstc r11[0]; sub r11, r11, r10}
//MACCR 3 right
{vldc r11[0]; add r11, r11, BYTES_PER_WORD}
{vlmaccr r1[0]; add r1, r1, r9}
{vstc r11[0]; sub r11, r11, r10}
{stw r5, r11[0] ; nop } //store to start of phase
//MACCR 4 right
{vldc r11[0]; add r11, r11, BYTES_PER_WORD}
{vlmaccr r1[0]; add r1, r1, r9}
{vstc r11[0]; sub r11, r11, r10}
{nop; add r11, r11, r8 } //advance to next phase
{bt r4, phase_loop; sub r4, r4, 1}
ldaw r11, sp[4]
{vlsat r11[0]; nop} //turn all accumulators into 32 bits
ldaw r11, sp[12]
{vstr r11[0]; nop}
{vldc r11[0];ldap r11, right_chan}
{vclrdr; nop}
{vlmaccr r11[0];ldap r11, left_chan}
{vlmaccr r11[0]; ldap r11, zeros}
{vlsat r11[0]; ldaw r11, sp[0]}
vstrpv r11[0], r6
ldd r11, r4, sp[0]
// load c_out from stack to r1
ldw r1, sp[27]
{out res[r1], r4; nop}
{bu outer_loop;out res[r1], r11}
passthrough_loop:
{testct r11, res[r3]; nop}
{bt r11, exit; nop}
{in r11, res[r3]; nop}
{out res[r4], r11; nop}
{in r11, res[r3]; nop}
{bu passthrough_loop; out res[r4], r11}
exit:
{inct r0, res[r3]; nop}
ldw r4, sp[20]
ldw r5, sp[21]
ldw r6, sp[22]
ldw r7, sp[23]
ldw r8, sp[24]
ldw r9, sp[25]
ldw r10, sp[26]
retsp NSTACKWORDS
.cc_bottom FUNCTION_NAME.function

View File

@@ -0,0 +1,53 @@
#ifndef _SSRC_COEFS_H_
#define _SSRC_COEFS_H_
#include <stdint.h>
/* Downsample ratio=4, 48kHz base — 128 coefficients */
static int32_t ds4_48000_coefs[128] = {
4192603, -2703925, 1667738, -971500, 525063, -255689, 105964, 5666,
147741797, -66167732, 40186648, -26923243, 18716201, -13134162, 9159092, -6278295,
-8394794, 12071368, -17195979, 24612481, -36235752, 57613909, -114155284, 1046129870,
-80960, 208765, -445117, 844122, -1474686, 2422662, -3794257, 5724570,
11257906, -7331064, 4577066, -2707960, 1493638, -748452, 324772, -145564,
502280711, -186846312, 108570992, -71571731, 49475933, -34709734, 24277296, -16731888,
-18415916, 26595074, -37942809, 54167579, -78966289, 122300118, -223331678, 840288039,
-149225, 407138, -899861, 1748155, -3108937, 5178122, -8198765, 12476764,
12476764, -8198765, 5178122, -3108937, 1748155, -899861, 407138, -149225,
840288039, -223331678, 122300118, -78966289, 54167579, -37942809, 26595074, -18415916,
-16731888, 24277296, -34709734, 49475933, -71571731, 108570992, -186846312, 502280711,
-145564, 324772, -748452, 1493638, -2707960, 4577066, -7331064, 11257906,
5724570, -3794257, 2422662, -1474686, 844122, -445117, 208765, -80960,
1046129870, -114155284, 57613909, -36235752, 24612481, -17195979, 12071368, -8394794,
-6278295, 9159092, -13134162, 18716201, -26923243, 40186648, -66167732, 147741797,
5666, 105964, -255689, 525063, -971500, 1667738, -2703925, 4192603,
};
/* Upsample ratio=4, 48kHz base — 128 coefficients */
static int32_t us4_48000_coefs[128] = {
-80960, 208765, -445117, 844122, -1474686, 2422662, -3794257, 5724570,
-149225, 407138, -899861, 1748155, -3108937, 5178122, -8198765, 12476764,
-8394794, 12071368, -17195979, 24612481, -36235752, 57613909, -114155284, 1046129870,
147741797, -66167732, 40186648, -26923243, 18716201, -13134162, 9159092, -6278295,
4192603, -2703925, 1667738, -971500, 525063, -255689, 105964, 5666,
11257906, -7331064, 4577066, -2707960, 1493638, -748452, 324772, -145564,
-145564, 324772, -748452, 1493638, -2707960, 4577066, -7331064, 11257906,
5666, 105964, -255689, 525063, -971500, 1667738, -2703925, 4192603,
-16731888, 24277296, -34709734, 49475933, -71571731, 108570992, -186846312, 502280711,
-6278295, 9159092, -13134162, 18716201, -26923243, 40186648, -66167732, 147741797,
502280711, -186846312, 108570992, -71571731, 49475933, -34709734, 24277296, -16731888,
-18415916, 26595074, -37942809, 54167579, -78966289, 122300118, -223331678, 840288039,
12476764, -8198765, 5178122, -3108937, 1748155, -899861, 407138, -149225,
5724570, -3794257, 2422662, -1474686, 844122, -445117, 208765, -80960,
1046129870, -114155284, 57613909, -36235752, 24612481, -17195979, 12071368, -8394794,
-6278295, 9159092, -13134162, 18716201, -26923243, 40186648, -66167732, 147741797,
};
#define SSRC_DS4_48K_FINAL_SHR 2
#define SSRC_US4_FINAL_SHR 0
#define SSRC_US4_HISTORY_OFFSET (32*4)
#define SSRC_US4_NUM_PHASE 4
#define SSRC_US4_PHASE_SIZE 4
#define SSRC_RB_SIZE (2*32*5+32)
#endif

View File

@@ -0,0 +1,33 @@
#ifndef _SSRC_REC_CORE_H_
#define _SSRC_REC_CORE_H_
#if F1_MUSIC_UAC2 == 1
#include <xs1.h>
#include <platform.h>
/**
* Downsample recording core — runs on tile[1]
* Uses two streaming channels (ds_stereo.S 需要独立 c_in/c_out不能别名):
* - c_from_tile0: tile[0]→tile[1] 192kHz stereo input
* - c_to_tile0: tile[1]→tile[0] 48kHz stereo output
*/
void ds_rec_core(streaming chanend c_from_tile0, streaming chanend c_to_tile0);
/**
* Upsample recording core — runs on tile[1]
* 改动原因us_stereo.S 是持续运行函数,只会在控制 token 时返回;
* 因此本 core 只负责把 48kHz 输入升采样写入 tile[1] 本地 ring buffer。
*/
void us_rec_core(streaming chanend c_us_in);
/**
* Upsample output sender — runs on tile[1]
* 改动原因:从 us_rec_core 写入的 tile[1] 本地 ring buffer 取 192kHz 数据,
* 通过普通 channel 发回 tile[0],避免等待 us_stereo.S 返回导致死锁。
*/
void us_rec_output_core(chanend c_us_out);
#endif
#endif

View File

@@ -0,0 +1,128 @@
#if F1_MUSIC_UAC2 == 1
#include "ssrc_rec_core.h"
#include <xs1.h>
#include <platform.h>
#include <string.h>
#include "ssrc_coefs.h"
#include "ssrc_us_share_buf.h"
#ifndef SET_SAMPLE_FREQ
#define SET_SAMPLE_FREQ 1
#endif
#ifndef NUM_USB_CHAN_OUT
#define NUM_USB_CHAN_OUT 2
#endif
/* Assembly function declarations */
extern unsigned char ds_stereo(
int32_t final_shr,
int32_t *coefs,
int32_t *data,
streaming chanend c_in,
streaming chanend c_out,
int32_t num_phase);
extern unsigned char us_stereo(
int32_t *coefs,
int32_t *l_history,
int32_t *r_history,
streaming chanend c_in,
int32_t history_offset,
uint32_t ring_buffer_addr,
uint32_t tail_addr,
int32_t ring_buffer_size,
int32_t num_phase,
int32_t phase_size,
int32_t final_shr);
#pragma unsafe arrays
void ds_rec_core(streaming chanend c_from_tile0, streaming chanend c_to_tile0)
{
int32_t history[1057];
unsigned char control_token;
memset(history, 0, sizeof(history));
set_core_high_priority_on();
while (1) {
control_token = ds_stereo(
SSRC_DS4_48K_FINAL_SHR,
ds4_48000_coefs,
history,
c_from_tile0, /* c_in: read 192kHz from tile[0] */
c_to_tile0, /* c_out: write 48kHz back to tile[0] */
4
);
switch (control_token) {
case SET_SAMPLE_FREQ:
memset(history, 0, sizeof(history));
{
unsigned dummy;
c_from_tile0 :> dummy;
}
soutct(c_to_tile0, SET_SAMPLE_FREQ);
for (size_t i = 0; i < NUM_USB_CHAN_OUT * 3; ++i) {
c_to_tile0 <: 0;
}
break;
default:
break;
}
}
}
#pragma unsafe arrays
void us_rec_core(streaming chanend c_us_in)
{
int32_t l_history[64];
int32_t r_history[64];
unsigned char control_token;
memset(l_history, 0, sizeof(l_history));
memset(r_history, 0, sizeof(r_history));
ssrc_us_share_reset();
while (1) {
/* 改动原因us_stereo.S 是持续运行的生产者,只有收到控制 token 才返回。
* 正常音频路径不要在此函数后面发送数据,否则永远执行不到。 */
control_token = us_stereo(
us4_48000_coefs,
l_history, r_history,
c_us_in,
SSRC_US4_HISTORY_OFFSET,
ssrc_us_share_get_buffer_addr(),
ssrc_us_share_get_tail_addr(),
SSRC_US_RB_WORDS - 32,
SSRC_US4_NUM_PHASE,
SSRC_US4_PHASE_SIZE,
SSRC_US4_FINAL_SHR
);
switch (control_token) {
case SET_SAMPLE_FREQ:
memset(l_history, 0, sizeof(l_history));
memset(r_history, 0, sizeof(r_history));
ssrc_us_share_reset();
{
unsigned dummy;
c_us_in :> dummy;
}
break;
default:
break;
}
}
}
void us_rec_output_core(chanend c_us_out)
{
while (1) {
/* 改动原因C 函数封装 ring buffer避免 XC 并行共享对象规则报错和 C/XC 指针 ABI 差异。 */
c_us_out <: ssrc_us_share_pop_word_blocking();
}
}
#endif

View File

@@ -0,0 +1,43 @@
#include "ssrc_us_share_buf.h"
/* 改动原因:该 buffer 只在 tile[1] 内被 us_rec_core/us_rec_output_core 使用。
* us_stereo.S 通过 tail 地址写入;输出任务通过 head 读取并用普通 chan 发回 tile[0]。 */
static int32_t ssrc_us_rb[SSRC_US_RB_WORDS];
static int32_t ssrc_us_head;
/* 改动原因us_stereo.S 通过指针写 ssrc_us_tail编译器无法感知须加 volatile
* 否则 ssrc_us_share_pop_word_blocking 的 while 循环永远读缓存旧值,导致死锁 */
volatile int32_t ssrc_us_tail;
void ssrc_us_share_reset(void)
{
ssrc_us_head = 0;
ssrc_us_tail = 0;
}
uint32_t ssrc_us_share_get_buffer_addr(void)
{
return (uint32_t)ssrc_us_rb;
}
uint32_t ssrc_us_share_get_tail_addr(void)
{
return (uint32_t)&ssrc_us_tail;
}
int32_t ssrc_us_share_pop_word_blocking(void)
{
int32_t sample;
while (ssrc_us_head == ssrc_us_tail) {
/* 改动原因:输出任务等待 us_stereo.S 生产数据;只阻塞发送任务,不阻塞采样率转换任务。 */
asm volatile("nop");
}
sample = ssrc_us_rb[ssrc_us_head];
ssrc_us_head++;
if (ssrc_us_head >= (SSRC_US_RB_WORDS - 32)) {
/* 改动原因us_stereo.S 使用的 ring size 为 NUM_USB_CHAN_OUT*32*5不包含尾部padding。 */
ssrc_us_head = 0;
}
return sample;
}

View File

@@ -0,0 +1,15 @@
#ifndef _SSRC_US_SHARE_BUF_H_
#define _SSRC_US_SHARE_BUF_H_
#include <stdint.h>
/* 改动原因us_stereo.S 持续写 ring bufferXC 并行任务不能直接共享全局数组,
* 因此用 C 函数封装 ring buffer作为 tile[1] 内 us_rec_core → us_rec_output_core 的边界。 */
#define SSRC_US_RB_WORDS (2 * 32 * 5 + 32)
void ssrc_us_share_reset(void);
uint32_t ssrc_us_share_get_buffer_addr(void);
uint32_t ssrc_us_share_get_tail_addr(void);
int32_t ssrc_us_share_pop_word_blocking(void);
#endif

View File

@@ -0,0 +1,182 @@
#define FUNCTION_NAME us_stereo
/*
void us_stereo(
int32_t * coefs,
int32_t * l_history,
int32_t * r_history,
streaming chanend c_in,
int32_t history_offset, +1
int32_t * ring_buffer, +2
int32_t * tail, +3
int32_t ring_buffer_size, +4
int32_t num_phase, +5 (number of polyphase filter)
int32_t phase_size, +6 (in vpu mac size (8word))
int32_t final_shr); +7
*/
#define NSTACKWORDS 32
.cc_top FUNCTION_NAME.function
.type FUNCTION_NAME,@function
.issue_mode dual
.align 4
#define BYTES_PER_WORD 4
#define CHANNELS 2
#define WORDS_PER_VECTOR 8
#define BYTES_PER_VECTOR (WORDS_PER_VECTOR*BYTES_PER_WORD)
#define ZERO 0x0
#define ONE 0x40000000
filter_l_1010:
.word ZERO, ZERO, ZERO, ZERO, ONE, ZERO, ONE, ZERO
filter_l_0101:
.word ZERO, ZERO, ZERO, ZERO, ZERO, ONE, ZERO, ONE
filter_r_1010:
.word ONE, ZERO, ONE, ZERO, ZERO, ZERO, ZERO, ZERO
filter_r_0101:
.word ZERO, ONE, ZERO, ONE, ZERO, ZERO, ZERO, ZERO
zeros:
.word 0, 0, 0, 0, 0, 0, 0, 0
.align 16
.globl FUNCTION_NAME
.globl FUNCTION_NAME.nstackwords
.set FUNCTION_NAME.nstackwords, NSTACKWORDS
FUNCTION_NAME:
{ dualentsp NSTACKWORDS ; nop }
stw r4, sp[NSTACKWORDS-1]
stw r5, sp[NSTACKWORDS-2]
stw r6, sp[NSTACKWORDS-3]
stw r7, sp[NSTACKWORDS-4]
stw r8, sp[NSTACKWORDS-5]
stw r9, sp[NSTACKWORDS-6]
stw r10, sp[NSTACKWORDS-7] // sp[25]
// store coefs to stack[0]
stw r0, sp[24]
// store l,r history to stack[1,2]
std r2, r1, sp[0] // sp[1] sp[0]
// store the final_shr for the VLSAT to stack[2-9]
ldw r0, sp[NSTACKWORDS+7]
std r0, r0, sp[1] // sp[2] sp[3]
std r0, r0, sp[2] // sp[4] sp[5]
std r0, r0, sp[3] // sp[6] sp[7]
std r0, r0, sp[4] // sp[8] sp[9]
// store start of ring buffer and tail to stack[10,11]
ldw r0, sp[NSTACKWORDS+2]
ldw r1, sp[NSTACKWORDS+3]
std r0, r1, sp[5] // sp[11] sp[10]
// store sample history offset to stack[12]
ldw r0, sp[NSTACKWORDS+1]
stw r0, sp[12]
// store c_in to stack[13]
stw r3, sp[13]
// store num_phase and phase size to stack[14,15]
ldw r0, sp[NSTACKWORDS+5]
ldw r1, sp[NSTACKWORDS+6]
stw r0, sp[14]
stw r1, sp[15]
// temp vstr store at stack[16-23]
// program start
ldc r9, BYTES_PER_VECTOR // r9: BYTES_PER_WORD
ldc r10, BYTES_PER_VECTOR*3 // r10: coefs rewind
ldd r7, r8, sp[5] // r7: ring_buffer ptr, r8: tail ptr
outer_loop:
ldw r4, sp[12]
ldw r3, sp[13]
{ testct r11, res[r3] ; ldw r0, sp[0] } // r0: &l_history[0]
bt r11, exit
{ in r11, res[r3] ; add r2, r0, r4 } // r2: &l_history[offset]
{ in r11, res[r3] ; stw r11, r2[0] }
{ ldw r2, sp[1] ; add r1, r0, BYTES_PER_WORD } // r2: &r_history[0], r1: &l_history[4]
{ add r4, r2, r4 ; add r3, r2, BYTES_PER_WORD } // r4: &r_history[offset], r3: &r_history[4]
{ stw r11, r4[0] ; nop }
{ ldw r4, sp[24] ; add r11, r2, 0 } // r4: &coeff[0], r11: r2
ldw r6, sp[15] // r6: phase size
{ sub r6, r6, 2 ; ldw r5, sp[14] } // burst 2, r5: num of phase
{ vclrdr ; nop }
bu mac_loop
phase_loop:
{ nop ; ldaw r11, sp[2] }
{ vlsat r11[0] ; ldaw r11, sp[16] } // turn all accumulators into 32 bits
{ vstr r11[0] ; nop } // store accumulators result into stack[16-23]
{ vldc r11[0] ; nop } // load the accumulators result into VC from stack
{ vclrdr ; ldap r11, filter_r_1010 } // clear vR vD
{ vlmaccr r11[0] ; ldap r11, filter_l_1010 } // r us t1, vD:vR -> {r_us_t1, 0, 0, 0}
{ vlmaccr r11[0] ; ldap r11, filter_r_0101 } // l us t1, vD:vR -> {l_us_t1, r_us_t1, 0, 0}
{ vlmaccr r11[0] ; ldap r11, filter_l_0101 } // r us t0, vD:vR -> {r_us_t0, l_us_t1, r_us_t1, 0}
{ vlmaccr r11[0] ; ldap r11, zeros } // l us t0, vD:vR -> {l_us_t0, r_us_t0, l_us_t1, r_us_t1}, r11: all zeros for vlsat
{ vlsat r11[0] ; ldc r11, BYTES_PER_WORD*4 } // sat(vD:vR), r11: BYTES_PER_WORD*4 = 4 sample size
{ vstr r7[0] ; add r7, r7, r11 } // save result to ring buffer, update ring buffer ptr
{ ldw r11, r8[0] ; nop } // r11: tail value
{ ldw r6, sp[NSTACKWORDS+4] ; add r11, r11, 4 } // r6: ring_buffer size, r11: tail + 4
{ stw r11, r8[0] ; eq r11, r11, r6 } // update tail ptr, r11: check if tail at ring buffer end
{ bf r11, prepare_mac_loop ; nop } // if tail not at buffer end, prepare mac loop
{ ldw r7, sp[11] ; ldc r11, 0 } // r7: ring buffer start, r11: 0
{ stw r11, r8[0] ; nop } // update tail ptr to 0
prepare_mac_loop:
{ ldw r6, sp[15] ; sub r5, r5, 2 } // r6: phase size, r5: r5-2 processed two polyphase filter
{ bf r5, outer_loop ; sub r6, r6, 2 } // burst 2
ldd r1, r0, sp[0] // r0: &l_history[0], r2: &r_history[0]
{ vclrdr ; nop }
bu mac_loop_no_move
mac_loop:
// swap r11 for channel
{ add r2, r11, 0 ; add r11, r0, 0 } // r11: r0
// left channel
{ vldc r1[0] ; add r1, r1, r9 }
{ vstc r11[0] ; add r11, r11, r9 }
{ vlmaccr r4[0] ; add r4, r4, r9 }
{ vlmaccr r4[0] ; add r4, r4, r9 }
{ vldc r1[0] ; add r1, r1, r9 }
{ vstc r11[0] ; add r11, r11, r9 }
{ vlmaccr r4[0] ; add r4, r4, r9 }
{ vlmaccr r4[0] ; sub r4, r4, r10 } // rewind
// swap r11 for channel
{ add r0, r11, 0 ; add r11, r2, 0 }
// right channel
{ vldc r3[0] ; add r3, r3, r9 }
{ vstc r11[0] ; add r11, r11, r9 }
{ vlmaccr r4[0] ; add r4, r4, r9 }
{ vlmaccr r4[0] ; add r4, r4, r9 }
{ vldc r3[0] ; add r3, r3, r9 }
{ vstc r11[0] ; add r11, r11, r9 }
{ vlmaccr r4[0] ; add r4, r4, r9 }
{ vlmaccr r4[0] ; add r4, r4, r9 }
{ bt r6, mac_loop ; sub r6, r6, 2 } // vD:vR -> {right_f1, right_f0, left_f1, left_f0}
bu phase_loop
mac_loop_no_move:
// left channel
{ vldc r0[0] ; add r0, r0, r9 }
{ vlmaccr r4[0] ; add r4, r4, r9 }
{ vlmaccr r4[0] ; add r4, r4, r9 }
{ vldc r0[0] ; add r0, r0, r9 }
{ vlmaccr r4[0] ; add r4, r4, r9 }
{ vlmaccr r4[0] ; sub r4, r4, r10 } // rewind
// right channel
{ vldc r1[0] ; add r1, r1, r9 }
{ vlmaccr r4[0] ; add r4, r4, r9 }
{ vlmaccr r4[0] ; add r4, r4, r9 }
{ vldc r1[0] ; add r1, r1, r9 }
{ vlmaccr r4[0] ; add r4, r4, r9 }
{ vlmaccr r4[0] ; add r4, r4, r9 }
{ bt r6, mac_loop_no_move ; sub r6, r6, 2 }
bu phase_loop
exit:
{inct r0, res[r3]; nop}
ldw r4, sp[NSTACKWORDS-1]
ldw r5, sp[NSTACKWORDS-2]
ldw r6, sp[NSTACKWORDS-3]
ldw r7, sp[NSTACKWORDS-4]
ldw r8, sp[NSTACKWORDS-5]
ldw r9, sp[NSTACKWORDS-6]
ldw r10, sp[NSTACKWORDS-7]
retsp NSTACKWORDS
.cc_bottom FUNCTION_NAME.function

View File

@@ -8,8 +8,8 @@
### 1.2 支持的指令列表
| 指令码 | 命令名称 | 功能 | 方向 | 描述 |
|--------|----------|------|------|------|
| 0x82 | SET_MIC_VOLUME | 设置麦克风增益级别 | 主机→设备 | 设置麦克风PGA增益0=静音, 1-37=0dB~36dB, 1dB/步 |
| 0x83 | GET_MIC_VOLUME | 获取麦克风增益级别 | 主机→设备 | 读取当前麦克风PGA增益级别0=静音, 1-37=0dB~36dB |
| 0x82 | SET_MIC_VOLUME | 设置麦克风增益级别 | 主机→设备 | 设置麦克风增益0=静音, 1-48=0~24dB, 2级=1dB |
| 0x83 | GET_MIC_VOLUME | 获取麦克风增益级别 | 主机→设备 | 读取当前麦克风增益级别0=静音, 1-48=0~24dB, 2级=1dB |
| 0x84 | FACTORY_RESET | 恢复出厂默认设置 | 主机→设备 | 删除Flash中所有已保存参数设备重启后自动恢复出厂默认值 |
| 0x85 | SET_AI_NOISE_STRENGTH | 设置AI降噪强度 | 主机→设备 | 设置AI降噪强度0=关闭2-100偶数=强度级别步进2100对应最强-200dB |
| 0x86 | GET_AI_NOISE_STRENGTH | 获取AI降噪强度 | 主机→设备 | 读取当前AI降噪强度强度变化含按键切换、开机初始值时设备主动上报 |
@@ -24,8 +24,8 @@
| 0x90 | RESET_EQ_PARAMS | 复位EQ参数 | 主机→设备 | 删除Flash中的EQ参数并恢复头文件预设参数 |
| 0x91 | GET_EQ_MODE_COUNT | 获取EQ模式总数 | 主机→设备 | 返回预定义加用户模式的总数(不包含禁用模式) |
| 0x92 | SET_AND_SAVE_EQ_MODE | 设置并保存EQ模式 | 主机→设备 | 设置当前EQ模式(0-9)并保存到Flash开机时自动恢复 |
| 0x93 | SET_VOLUME | 设置监听音量级别 | 主机→设备 | 设置设备监听音量级别0=静音, 1-29=-28dB~0dB, 1dB/步 |
| 0x94 | GET_VOLUME | 获取监听音量级别 | 主机→设备 | 读取设备当前监听音量级别0=静音, 1-29=-28dB~0dB, 1dB/步 |
| 0x93 | SET_VOLUME | 设置监听音量级别 | 主机→设备 | 设置设备监听音量级别0=静音, 1-48按SY102dac对应表映射到-66dB~0dB |
| 0x94 | GET_VOLUME | 获取监听音量级别 | 主机→设备 | 读取设备当前监听音量级别0=静音, 1-48按SY102dac对应表映射 |
| 0x9D | SET_EQ_ENABLE | 设置EQ使能开关 | 主机→设备 | 设置EQ使能开关ON/OFF禁用时保存当前模式启用时恢复之前模式 |
| 0x9E | GET_EQ_ENABLE | 获取EQ使能开关 | 主机→设备 | 读取EQ使能开关状态ON/OFF |
| 0x9F | GET_SAMPLE_FORMAT | 获取采样率和格式 | 主机→设备 | 读取当前采样率、DSD模式和DAC采样分辨率 |
@@ -59,17 +59,18 @@
---------|------|------|------
0 | 1 | 0x77 | 同步头1
1 | 1 | 0x82 | 命令码
2 | 1 | uint8 | 增益级别 (0=静音, 1-37=0dB~36dB, 1dB/步)
2 | 1 | uint8 | 增益级别 (0=静音, 1-48=0~24dB, 2级=1dB)
3-62 | 60 | 0x00 | 保留字节
```
**参数说明**:
- **增益级别范围:** 0-37共38级)
- **增益级别范围:** 0-48共49级)
- 0静音mute
- 10dB最小有效增益
- 1约0.5dB按2级=1dB映射
- 21dB
- ...1dB/步
- 3736dB最大HID可设置增益
- ...2级=1dB
- 47约23.5dB
- 4824dB最大HID可设置增益
**返回值**:
无直接返回值。设备端增益变化会主动上报0x83格式数据包。
@@ -93,7 +94,7 @@
0 | 1 | 0x01 | Report ID
1 | 1 | 0x77 | 同步头1
2 | 1 | 0x83 | 同步头2
3 | 1 | uint8 | 当前增益级别 (0=静音, 1-37=0dB~36dB)
3 | 1 | uint8 | 当前增益级别 (0=静音, 1-48=0~24dB, 2级=1dB)
4-62 | 59 | 0x00 | 保留字节
```
@@ -515,12 +516,12 @@
---------|------|------|------
0 | 1 | 0x77 | 同步头1
1 | 1 | 0x93 | 命令码
2 | 1 | uint8 | 音量级别 (0-29: 0=静音, 1=-28dB, ..., 29=0dB)
2 | 1 | uint8 | 音量级别 (0-48: 0=静音, 1=-66dB, ..., 48=0dB按SY102dac对应表)
3-62 | 60 | 0x00 | 保留字节
```
**参数说明**:
- **音量级别范围:** 0-29共30级)
- **音量级别范围:** 0-48共49级)
- **说明:** 控制设备监听输出DAC/耳机)音量级别
- 0: 静音muteDAC完全静音
- 1: -28dB最小有效音量
@@ -550,7 +551,7 @@
0 | 1 | 0x01 | Report ID
1 | 1 | 0x77 | 同步头1
2 | 1 | 0x94 | 同步头2
3 | 1 | uint8 | 当前音量级别 (0-29: 0=静音, 1-29=-28dB~0dB, 1dB/步)
3 | 1 | uint8 | 当前音量级别 (0-48: 0=静音, 1-48按SY102dac对应表映射到-66dB~0dB)
4-62 | 59 | 0x00 | 保留字节
```
### 2.20 0x9D - SET_EQ_ENABLE (设置EQ使能开关)