diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/CMakeLists.txt b/sw_usb_audio/app_usb_aud_fosi_c1_v71/CMakeLists.txt index f6ff6a5..3e6793b 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/CMakeLists.txt +++ b/sw_usb_audio/app_usb_aud_fosi_c1_v71/CMakeLists.txt @@ -7,13 +7,24 @@ set(APP_HW_TARGET xu316_qf60.xn) include(${CMAKE_CURRENT_LIST_DIR}/../deps.cmake) #set(APP_PCA_ENABLE ON) -set(SW_USB_VERSION -DBCD_DEVICE_J=1 - -DBCD_DEVICE_M=0 - -DBCD_DEVICE_N=0) +# 改动原因:版本号单点维护;FW_VERSION 用于 factory_/update_ 输出文件名(如 phaten_module_1.0.0.bin) +set(BCD_DEVICE_J 1) +set(BCD_DEVICE_M 0) +set(BCD_DEVICE_N 0) +set(FW_VERSION "${BCD_DEVICE_J}.${BCD_DEVICE_M}.${BCD_DEVICE_N}") -set(SW_FACT_VERSION -DBCD_DEVICE_J=5 - -DBCD_DEVICE_M=5 - -DBCD_DEVICE_N=7) +set(SW_USB_VERSION -DBCD_DEVICE_J=${BCD_DEVICE_J} + -DBCD_DEVICE_M=${BCD_DEVICE_M} + -DBCD_DEVICE_N=${BCD_DEVICE_N}) + +set(FACT_BCD_DEVICE_J 5) +set(FACT_BCD_DEVICE_M 5) +set(FACT_BCD_DEVICE_N 7) +set(FW_FACT_VERSION "${FACT_BCD_DEVICE_J}.${FACT_BCD_DEVICE_M}.${FACT_BCD_DEVICE_N}") + +set(SW_FACT_VERSION -DBCD_DEVICE_J=${FACT_BCD_DEVICE_J} + -DBCD_DEVICE_M=${FACT_BCD_DEVICE_M} + -DBCD_DEVICE_N=${FACT_BCD_DEVICE_N}) set(SW_USB_AUDIO_FLAGS ${EXTRA_BUILD_FLAGS} ${SW_USB_VERSION} -O3 -report @@ -39,21 +50,42 @@ set(SW_FACT_AUDIO_FLAGS ${EXTRA_BUILD_FLAGS} ${SW_FACT_VERSION} -DXUA_QUAD_SPI_FLASH=1) +set(APP_COMPILER_FLAGS_fact ${SW_FACT_AUDIO_FLAGS} -DI2S_CHANS_DAC=2 + -DNUM_USB_CHAN_IN=0 + -DXUA_DFU_EN=1 + -DBOOT_MODE=1 + -DFACT_MODE=1 + #-fxscope + #-DXSCOPE + -DSTREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS=32 + -DOUTPUT_FORMAT_COUNT=1 + -DXUA_SPDIF_TX_EN=0 + -DMAX_FREQ=\(768000\) + -DMIN_FREQ=\(44100\) + -DDEFAULT_FREQ=\(48000\) + -DUART_DEBUG=0 + -DHID_CONTROLS=1 + -DEQ_EN=1 + -DHID_DFU_EN=1 + #-DDEBUG_MEMORY_LOG_ENABLED=0 + -DNUM_USB_CHAN_OUT=2 + -DI2S_CHANS_ADC=0) -set(APP_COMPILER_FLAGS_v71_uac2 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2 + +# 改动原因:FPS71 独立 UAC2 固件;Windows 下 g_3d_fps=2 时加载(去掉 F3_F4) +set(APP_COMPILER_FLAGS_fps71_uac2 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2 -DI2S_CHANS_ADC=2 -DMIN_FREQ=48000 -DMAX_FREQ=48000 -DUAC1_MODE=0 -DUSE_EX3D=1 - -DF3_F4_FPS_UAC2=1 -DMIXER=0 -DUAC2_MODE=1 -ldnr_50ms -llib_ex3d_all -DEQ_EN=1 - -DV71_UAC2=1 + -DFPS71_UAC2=1 #-DDNR_ENABLE=1 -DSTREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS=32 -DSTREAM_FORMAT_INPUT_1_RESOLUTION_BITS=32 @@ -72,26 +104,27 @@ set(APP_COMPILER_FLAGS_v71_uac2 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2 -DIR_SWITCHING_MODE -DHID_CONTROLS=1) -set(APP_COMPILER_FLAGS_v71_uac1 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2 +# 改动原因:BYPASS/FPS20/3A 合并 UAC1;Win 检测仅本目标(参照 fosi_c1 fps_uac1 / c1_lp) +set(APP_COMPILER_FLAGS_game_uac1 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2 -DI2S_CHANS_ADC=2 -DMIN_FREQ=48000 - -DAUDIO_CLASS=1 + #-DAUDIO_CLASS=1 -DUAC1_MODE=1 -DMAX_FREQ=48000 + -DWINDOWS_OS_DESCRIPTOR_SUPPORT -DWIN_OS_DETECTION=1 -DUSE_EX3D=1 - -DF3_F4_FPS_UAC2=1 -DMIXER=0 -DUAC2_MODE=1 -ldnr_50ms -llib_ex3d_all - -DEQ_EN=0 - -DV71_UAC1=1 - #-DDNR_ENABLE=1 - -DSTREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS=32 - -DSTREAM_FORMAT_INPUT_1_RESOLUTION_BITS=32 + -DEQ_EN=1 + -DFPS_GAME_UAC1=1 + -DSTREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS=24 + -DSTREAM_FORMAT_INPUT_1_RESOLUTION_BITS=24 -DINPUT_FORMAT_COUNT=1 -DOUTPUT_FORMAT_COUNT=1 + -DWIN_OS_DETECTION=1 -DEX3D_SF_NUM=3 -DNUM_USB_CHAN_OUT=8 -DNUM_USB_CHAN_IN=2 @@ -99,13 +132,18 @@ set(APP_COMPILER_FLAGS_v71_uac1 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2 -DMIN_VOLUME=0xE000 -DINPUT_VOLUME_CONTROL=1 -DOUTPUT_VOLUME_CONTROL=1 - #-DDEBUG_MEMORY_LOG_ENABLED=1 - -DXUA_DFU_EN=1 + -DDEBUG_MEMORY_LOG_ENABLED=1 + -DHID_CONTROLS_UAC1=1 + #-DXUA_DFU_EN=1 -DHID_DFU_EN=1 -DIR_SWITCHING_MODE -DHID_CONTROLS=1) + + + + LINK_DIRECTORIES(${CMAKE_CURRENT_LIST_DIR}/../../lib_dnr/lib_dnr ${CMAKE_CURRENT_LIST_DIR}/../../lib_ex3d/lib_ex3d/lib) set(APP_INCLUDES src src/core src/extensions ../shared/) @@ -115,48 +153,38 @@ set(XMOS_SANDBOX_DIR ${CMAKE_CURRENT_LIST_DIR}/../..) XMOS_REGISTER_APP() ###=========================================================================### -# Flash image generation -# Slot assignment (matches MODE_Fxx flag values in audiohw.xc): -# slot 1 = f3_f4_fps_uac2 (COAX_IN_FLAG = MODE_F3_F4_FPS_UAC2) -# slot 2 = f5_music_uac1 (UAC1_IN_FLAG = MODE_F5_MUSIC_UAC1) <- factory base -# slot 3 = f1_music_uac2 (OPT_IN_FLAG = MODE_F1_MUSIC_UAC2) -# slot 4 = f6_f7_fps_uac1 (USB_IN_FLAG = MODE_F6_F7_FPS_UAC1) +# Flash:两套固件 — upgrade1 fps71_uac2 (COAX);upgrade2 game_uac1 (USB,含 BYPASS/FPS20/3A) +# Windows: g_3d_fps=2 → FPS71 UAC2;其余 → game_uac1。非 Windows:四档均 game_uac1 + tile1 算法。 ###=========================================================================### set(APP_BIN_DIR ${CMAKE_CURRENT_LIST_DIR}/bin) set(APP_BASE ${PROJECT_NAME}) set(XE_FACT ${APP_BIN_DIR}/fact/${APP_BASE}_fact.xe) -set(XE_F1 ${APP_BIN_DIR}/f1_music_uac2/${APP_BASE}_f1_music_uac2.xe) -set(XE_F3F4 ${APP_BIN_DIR}/f3_f4_fps_uac2/${APP_BASE}_f3_f4_fps_uac2.xe) -set(XE_F5 ${APP_BIN_DIR}/f5_music_uac1/${APP_BASE}_f5_music_uac1.xe) -set(XE_F6F7 ${APP_BIN_DIR}/f6_f7_fps_uac1/${APP_BASE}_f6_f7_fps_uac1.xe) +set(XE_FPS71 ${APP_BIN_DIR}/fps71_uac2/${APP_BASE}_fps71_uac2.xe) +set(XE_GAME_UAC1 ${APP_BIN_DIR}/game_uac1/${APP_BASE}_game_uac1.xe) set(LOADER_OBJ ${CMAKE_CURRENT_LIST_DIR}/loader.o) set(TARGET_XN ${CMAKE_CURRENT_LIST_DIR}/src/core/synido.xn) # factory__.bin — full factory image (base + 4 upgrade slots) add_custom_target(factory_bin - COMMAND ${CMAKE_COMMAND} -E echo "xflash ${XE_FACT} --loader ${LOADER_OBJ} --upgrade 1 ${XE_F3F4} --upgrade 2 ${XE_F5} --upgrade 3 ${XE_F1} --upgrade 4 ${XE_F6F7} -o ${CMAKE_CURRENT_LIST_DIR}/factory_${APP_BASE}_${FW_VERSION}.bin" + COMMAND ${CMAKE_COMMAND} -E echo "xflash ${XE_FACT} --loader ${LOADER_OBJ} --upgrade 1 ${XE_FPS71} --upgrade 2 ${XE_GAME_UAC1} -o ${CMAKE_CURRENT_LIST_DIR}/factory_${APP_BASE}_${FW_VERSION}.bin" COMMAND xflash ${XE_FACT} --loader ${LOADER_OBJ} - --upgrade 2 ${XE_F5} - --upgrade 3 ${XE_F1} - --upgrade 1 ${XE_F3F4} - --upgrade 4 ${XE_F6F7} + --upgrade 1 ${XE_FPS71} + --upgrade 2 ${XE_GAME_UAC1} -o ${CMAKE_CURRENT_LIST_DIR}/factory_${APP_BASE}_${FW_VERSION}.bin - #DEPENDS f1_music_uac2 f3_f4_fps_uac2 f5_music_uac1 f6_f7_fps_uac1 + #DEPENDS fps71_uac2 game_uac1 COMMENT "Generating factory image: factory_${APP_BASE}_${FW_VERSION}.bin" VERBATIM ) # update__.bin — DFU upgrade package (upgrade slots only) add_custom_target(update_bin - COMMAND ${CMAKE_COMMAND} -E echo "xflash --factory-version 15.2 --target-file ${TARGET_XN} --upgrade 1 ${XE_F3F4} --upgrade 2 ${XE_F5} --upgrade 3 ${XE_F1} --upgrade 4 ${XE_F6F7} -o ${CMAKE_CURRENT_LIST_DIR}/update_${APP_BASE}_${FW_VERSION}.bin" + COMMAND ${CMAKE_COMMAND} -E echo "xflash --factory-version 15.2 --target-file ${TARGET_XN} --upgrade 1 ${XE_FPS71} --upgrade 2 ${XE_GAME_UAC1} -o ${CMAKE_CURRENT_LIST_DIR}/update_${APP_BASE}_${FW_VERSION}.bin" COMMAND xflash --factory-version 15.2 --target-file ${TARGET_XN} - --upgrade 2 ${XE_F5} - --upgrade 3 ${XE_F1} - --upgrade 1 ${XE_F3F4} - --upgrade 4 ${XE_F6F7} + --upgrade 1 ${XE_FPS71} + --upgrade 2 ${XE_GAME_UAC1} -o ${CMAKE_CURRENT_LIST_DIR}/update_${APP_BASE}_${FW_VERSION}.bin - #DEPENDS f1_music_uac2 f3_f4_fps_uac2 f5_music_uac1 f6_f7_fps_uac1 + #DEPENDS fps71_uac2 game_uac1 COMMENT "Generating update image: update_${APP_BASE}_${FW_VERSION}.bin" VERBATIM ) diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/loader.o b/sw_usb_audio/app_usb_aud_fosi_c1_v71/loader.o new file mode 100644 index 0000000..b014a4b Binary files /dev/null and b/sw_usb_audio/app_usb_aud_fosi_c1_v71/loader.o differ diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/core/xu316_qf60.xn b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/core/xu316_qf60.xn index 88bd8e0..ed79742 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/core/xu316_qf60.xn +++ b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/core/xu316_qf60.xn @@ -30,18 +30,16 @@ + - - - - - + diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/audiohw.xc b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/audiohw.xc index c71408c..14708ab 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/audiohw.xc +++ b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/audiohw.xc @@ -13,9 +13,11 @@ #include #include "debug_print.h" #include "user_uart.h" +#include "user_func.h" #include "htr3236.h" #include "tx1_rgb_brightness.h" #include "tx1_led_effects.h" +#include "tx1_ex3d_game.h" #include "eq_flash_storage.h" #include "lfs_io.h" #include "roleswitchflag.h" @@ -33,25 +35,24 @@ extern "C" { #define TIMER_PERIOD 2000000 /* 改动原因:与 jok TIMER_2_PERIOD 一致,50ms 驱动 RGB 灯效/工厂复位 LED */ #define TIMER_2_PERIOD 5000000 +/* 改动原因:与 jok buttons.h LONG_PRESS_VOL_MS / TICKS_100MS 一致(10ns tick) */ +#define TX1_LONG_PRESS_TICKS 100000000ull +#define TX1_VOL_REPEAT_TICKS 100000000ull +/* 改动原因:feature 超时 8s,按键扫描周期 TIMER_PERIOD=20ms → 8s/20ms=400 */ +#define TX1_FEATURE_TIMEOUT_MAX 400 #define DISABLE_REBOOT 1 -#define MODE_FPS_UAC2 COAX_IN_FLAG // 1 FPS -#define MODE_FPS_UAC1 USB_IN_FLAG // 2 UAC1 -#define MODE_BR_UAC2 OPT_IN_FLAG // 3 BR -#define MODE_V71_UAC2 UAC1_IN_FLAG // 4 V71 -#define MODE_V71_UAC1 BT_IN_FLAG // 5 UAC1 -#define MODE_BYPASS_UAC2 I2S_IN_FLAG // 6 BYPASS - extern unsigned g_host_os; // 1 -> Windows, 2 -> Others audio_sampling g_new_playback_format, g_playback_format; audio_type g_new_audio_type, g_audio_type = 0; unsigned g_mute_enable = 0; unsigned g_unmute_dac_state, g_unmute_time, g_format_time; -unsigned g_volume_level = 60, g_saved_volume_level = 60; +/* 改动原因:g_volume_level 为 DAC HID 等级 0~48(与 eq 0x93/0x94 一致);g_dac_vol 为 NAU88 0x0034 寄存器字节 */ +unsigned g_volume_level = 48, g_saved_volume_level = 48; unsigned g_request_volume_set = 0; -unsigned g_dac_vol = 0xB8; -unsigned g_adc_vol = 0x25; +unsigned g_dac_vol = 0xCF; +unsigned g_adc_vol = 37; unsigned g_adc_loop = 0; unsigned g_mute_switch = 0; // 改动原因:与g_adc_loop一致,记录MCU回传的静音开关状态并用于HID变化上报(k6 UART在tile0可直接设置) unsigned g_led_enable = 0; @@ -87,7 +88,12 @@ unsigned g_update_led = 0x0; #define C1_EX3D_ANGLE_CHANNELS 8 extern unsigned char g_hid_pass_data[64];; unsigned g_3d_fps = 0; -unsigned g_mic_volume_level = 37; +/* 改动原因:与 jok audio_azimuth_set_mode 同步,供 RGB 方位灯效选 FPS/3A 配色(EX3D 在 tile1 应用) */ +unsigned g_tx1_azimuth_mode = TX1_AZIMUTH_MODE_FPS; +/* 改动原因:开机 Flash 恢复 g_3d_fps 后通知 tile1 重新 apply EX3D */ +unsigned g_tx1_ex3d_resync_req = 0; +/* 改动原因:g_mic_volume_level 为 MIC HID 0~48;g_adc_vol 为 NAU88 PGA 步进 0~37(由 HID 映射) */ +unsigned g_mic_volume_level = 48; unsigned g_request_mic_volume_set = 0; unsigned g_dnr_strength = 100; unsigned g_dnr_on = 1; @@ -125,7 +131,7 @@ on tile[0]: out port p_led_tile0 = PORT_LED_D10_8_11_9; // 8D bit7-4 = D10/D8/D /* 改动原因:与 jok PCB 相同,面板从左到右为 FPS / VOL+ / VOL- / GAME / MIC, * 原理图端口位序不同。采用 lib_board_support buttons.xc #else 映射(非 #if 0 原理图直读)。 */ -#define TX1_BUTTON_MAP_PANEL_LAYOUT (1) +#define TX1_BUTTON_MAP_PANEL_LAYOUT (0) // TX1 Button timing thresholds (in 50ms ticks) #define TX1_SHORT_PRESS_TICKS 1 // 50ms minimum press @@ -169,14 +175,99 @@ timer tm; #define EQ_SYNC_DELAY (50000000) //500ms delay for EQ parameter sync +// 改动原因:c1_mode 与 tile1 mode 灯索引一致:1=灭 2=蓝 3=绿 4=橙 5=紫;合法范围 1~5,interface 原样传 c1_mode。 +#define C1_MODE_VALUE_DEFAULT 1 +#define C1_MODE_VALUE_MIN 1 +#define C1_MODE_VALUE_MAX 5 extern void device_reboot(void); +// 改动原因:灯索引与 c1_mode 同值;仅钳位非法 Flash 读数,合法值原样下发 tile1,避免误映射。 +static inline unsigned c1_mode_to_tile_mode_led_code(unsigned mode_value) +{ + if (mode_value > C1_MODE_VALUE_MAX || mode_value < C1_MODE_VALUE_MIN) + return C1_MODE_VALUE_DEFAULT; + return mode_value; +} +// 改动原因:g_hid_pass_data[] 定义已上移至与其它 HID 全局量同块,避免 extern 无实体导致链接失败。 +enum { OS_WIN = 1, OS_OTHERS = 2 }; + +#if defined(WIN_OS_DETECTION) +/* 改动原因:与 fosi_c1_lp audiohw 一致——仅 UAC1 固件内轮询 g_host_os,最多 500ms 等 MS 描述符 */ +static unsigned tx1_wait_host_os_detection(void) +{ + unsigned host_os = 0; + int i; + + for (i = 0; i < 500; i++) { + GET_SHARED_GLOBAL(host_os, g_host_os); + if (host_os == OS_WIN) { + debug_printf("Detected Windows OS (OS_WIN) host_os: %d\n", host_os); + return host_os; + } + if (host_os == OS_OTHERS) { + debug_printf("Detected non-Windows host_os: %d\n", host_os); + return host_os; + } + delay_milliseconds(1); + } + debug_printf("Host OS detect timeout host_os: %d\n", host_os); + return host_os; +} +#endif + +/** + * 改动原因:两套固件——FPS71 UAC2(仅 UAC1 上 Win 检测为 Win 且 g_3d_fps=2)与合并 UAC1。 + * @param game_mode g_3d_fps:0=BYPASS 1=FPS20 2=FPS71 3=3A + */ +void switch_mode_by_c1_mode(unsigned game_mode, unsigned force_reboot) +{ + unsigned reboot_need = 0; + unsigned want_fps71_uac2 = 0; + + if (game_mode > 3) { + game_mode = 0; + } + +#if defined(WIN_OS_DETECTION) + { + unsigned host_os; + GET_SHARED_GLOBAL(host_os, g_host_os); + if (host_os == OS_WIN && game_mode == GAME_MODE_FPS71) { + want_fps71_uac2 = 1; + } + } +#elif defined(FPS71_UAC2) + /* 改动原因:OS 检测只在 game_uac1;FPS71 固件切离 FPS71 档则回 UAC1 */ + want_fps71_uac2 = (game_mode == GAME_MODE_FPS71) ? 1u : 0u; +#else + (void)game_mode; +#endif + + if (want_fps71_uac2) { +#if !FPS71_UAC2 + SetRoleSwitchFlag(TX1_ROLE_FPS71_UAC2); + reboot_need = 1; +#endif + } else { +#if !FPS_GAME_UAC1 + SetRoleSwitchFlag(TX1_ROLE_GAME_UAC1); + reboot_need = 1; +#endif + } + + if (reboot_need || force_reboot) + { + delay_milliseconds(20); + device_reboot(); + while (1); + } +} #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) -// 改动原因:g_hid_pass_data[] 定义已上移至与其它 HID 全局量同块,避免 extern 无实体导致链接失败。 -static unsigned g_last_dac_vol = 0xFF; // 改动原因:改为检测g_dac_vol的变化,初始化为0xFF表示未初始化 +static unsigned g_last_volume_hid = 0xFF; // 改动原因:HID 0x94 上报 DAC HID 等级变化,非寄存器原始值 +static unsigned g_last_mic_volume_hid = 0xFF; // 改动原因:MIC HID 等级变化上报 0x83 static unsigned g_last_mute_switch = 0xFF; // 改动原因:检测静音开关变化并上报0xB2,0xFF=未初始化 static unsigned g_last_adc_loop = 0xFF; // 改动原因:检测监听开关(g_adc_loop)变化并上报0xB4,0xFF=未初始化 static unsigned g_last_audio_type = 0xFF; // 改动原因:上次检测到的音频类型,初始化为0xFF表示未初始化,用于LED颜色判断 @@ -386,6 +477,108 @@ void mic_volume(unsigned level, client interface i2c_master_if i2c) } } +#define TX1_DAC_HID_LEVEL_MAX 48 +#define TX1_DAC_HID_LEVEL_DEFAULT 48 +#define TX1_MIC_HID_LEVEL_MAX 48 +#define TX1_MIC_HID_LEVEL_DEFAULT 48 +#define TX1_VOL_BAR_MAX 12 + +/* 改动原因:与 phaten golden / SY102dac 表一致,DAC HID 0~48 级映射 NAU88 0x0034 寄存器值 */ +static const uint8_t tx1_dac_level_to_reg[49] = { + 0x0E, 0x4B, 0x4F, 0x53, 0x57, 0x5B, 0x5F, 0x63, 0x67, 0x6B, + 0x6F, 0x73, 0x77, 0x7B, 0x7F, 0x83, 0x87, 0x8B, 0x8F, 0x93, + 0x97, 0x9B, 0x9F, 0xA3, 0xA7, 0xA9, 0xAB, 0xAD, 0xAF, 0xB1, + 0xB3, 0xB5, 0xB7, 0xB9, 0xBB, 0xBD, 0xBF, 0xC1, 0xC3, 0xC5, + 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF +}; + +/* 改动原因:MIC HID 0~48(0.5dB/级 UI)映射到本板 PGA 1~37(1dB/级,最大 36dB) */ +static unsigned tx1_mic_hid_to_adc_vol(unsigned hid_level) +{ + unsigned max_reg = NAU88L21_PGA_GAIN_REG_MAX_VALUE - 1; + + if (hid_level == 0) { + return 0; + } + { + unsigned codec_gain = (hid_level * max_reg + 24u) / 48u; + if (codec_gain < 1) { + codec_gain = 1; + } + if (codec_gain > max_reg) { + codec_gain = max_reg; + } + return codec_gain; + } +} + +static unsigned tx1_hid_level_to_bar(unsigned hid_level) +{ + unsigned bar = (hid_level * TX1_VOL_BAR_MAX + 24u) / TX1_DAC_HID_LEVEL_MAX; + if (bar > TX1_VOL_BAR_MAX) { + bar = TX1_VOL_BAR_MAX; + } + return bar; +} + +static unsigned tx1_bar_to_hid_level(unsigned bar) +{ + if (bar >= TX1_VOL_BAR_MAX) { + return TX1_DAC_HID_LEVEL_MAX; + } + if (bar == 0) { + return 0; + } + return (bar * TX1_DAC_HID_LEVEL_MAX) / TX1_VOL_BAR_MAX; +} + +/* 改动原因:统一把 DAC HID 等级写入 g_volume_level/g_dac_vol,定时器请求分支写 0x0034 并 Flash */ +static void tx1_apply_dac_hid_level(unsigned hid_level) +{ + unsigned reg; + + if (hid_level > TX1_DAC_HID_LEVEL_MAX) { + hid_level = TX1_DAC_HID_LEVEL_MAX; + } + reg = (hid_level == 0) ? 0u : (unsigned)tx1_dac_level_to_reg[hid_level]; + SET_SHARED_GLOBAL(g_volume_level, hid_level); + SET_SHARED_GLOBAL(g_dac_vol, reg); + SET_SHARED_GLOBAL(g_request_volume_set, 1); +} + +/* 改动原因:统一把 MIC HID 等级写入 g_mic_volume_level/g_adc_vol,定时器请求分支 mic_volume 写 ADC 并 Flash */ +static void tx1_apply_mic_hid_level(unsigned hid_level) +{ + unsigned adc_vol; + + if (hid_level > TX1_MIC_HID_LEVEL_MAX) { + hid_level = TX1_MIC_HID_LEVEL_MAX; + } + adc_vol = tx1_mic_hid_to_adc_vol(hid_level); + SET_SHARED_GLOBAL(g_mic_volume_level, hid_level); + SET_SHARED_GLOBAL(g_adc_vol, adc_vol); + SET_SHARED_GLOBAL(g_request_mic_volume_set, 1); +} + +/* 改动原因:FPS 切换 feature 时,把当前硬件音量同步到 0~12 格 RGB 条 */ +static void tx1_sync_feature_volume_from_hw(tx1_feature_mode_t mode, unsigned &feature_volume) +{ + unsigned hid; + + switch (mode) { + case FEATURE_MODE_SYSTEM_VOLUME: + GET_SHARED_GLOBAL(hid, g_volume_level); + feature_volume = tx1_hid_level_to_bar(hid); + break; + case FEATURE_MODE_MIC_LEVEL: + GET_SHARED_GLOBAL(hid, g_mic_volume_level); + feature_volume = tx1_hid_level_to_bar(hid); + break; + default: + break; + } +} + /* 改动原因:bringup 失败时灯效任务不刷屏 I2C */ static unsigned g_htr3236_ready = 0; @@ -532,10 +725,9 @@ static void tx1_rgb_volume_bar_refresh(htr3236_t *dev, client interface i2c_mast switch (mode) { case FEATURE_MODE_SYSTEM_VOLUME: { - unsigned vol_pct; - GET_SHARED_GLOBAL(vol_pct, g_volume_level); - bar_level = (vol_pct * 12u) / 100u; - if (bar_level > 12) bar_level = 12; + unsigned vol_hid; + GET_SHARED_GLOBAL(vol_hid, g_volume_level); + bar_level = tx1_hid_level_to_bar(vol_hid); r = TX1_RGB_SCALE8(TX1_RGB_COLOR_YELLOW_R); g = TX1_RGB_SCALE8(TX1_RGB_COLOR_YELLOW_G); b = TX1_RGB_SCALE8(TX1_RGB_COLOR_YELLOW_B); @@ -576,9 +768,128 @@ static void tx1_rgb_volume_bar_refresh(htr3236_t *dev, client interface i2c_mast void save_value(unsigned char * unsafe path, unsigned char value); unsigned char load_value(unsigned char * unsafe path); +#define C1_MODE_INFO_PATH "c1_mode" /* 改动原因:MIC 静音与 golden/phaten 一致——g_mute_switch 驱动定时器里 effective_adc_vol=0, * 并立即写 NAU88 ADC 寄存器;old_adc_vol 与定时器分支保持同步避免重复 I2C。 */ +/** + * 改动原因:与 jok on_game_short_press 一致——更新 g_3d_fps、g_tx1_azimuth_mode, + * 供 tile1 ex3d_task 轮询下发 EX3D;persist=1 时写入 LFS(GAME 键/需记忆时)。 + */ +static void tx1_sync_game_mode_state(unsigned mode, unsigned persist) +{ + unsigned azimuth = TX1_AZIMUTH_MODE_FPS; + + if (mode > 3) { + mode = 0; + } + switch (mode) { + case GAME_MODE_3A: + azimuth = TX1_AZIMUTH_MODE_3A; + break; + case GAME_MODE_FPS20: + case GAME_MODE_FPS71: + default: + azimuth = TX1_AZIMUTH_MODE_FPS; + break; + } + SET_SHARED_GLOBAL(g_3d_fps, mode); + SET_SHARED_GLOBAL(g_tx1_azimuth_mode, azimuth); + SET_SHARED_GLOBAL(g_tx1_ex3d_resync_req, 1); + /* 改动原因:切换 GAME 模式时清方位灯效衰减缓存,与 jok audio_azimuth_set_mode 一致 */ + tx1_azimuth_clear_all_decay(); + if (persist) { + tx1_save_game_mode((unsigned char)mode); +#if defined(WIN_OS_DETECTION) + /* 改动原因:UAC1 固件内已检测过 OS;Win 才在 FPS71↔UAC1 间换固件 */ + switch_mode_by_c1_mode(mode, 0); +#elif defined(FPS71_UAC2) + /* 改动原因:FPS71 固件无 Win 检测,离开 FPS71 必回 game_uac1 */ + if (mode != GAME_MODE_FPS71) { + switch_mode_by_c1_mode(mode, 0); + } +#endif + } +} + +/** + * 改动原因:对齐 jok on_vol_plus_short_press——feature_mode==NONE 时不调节、不刷新音量条; + * SYSTEM_VOLUME 按 12 格步进 DAC HID(0~48) 并写寄存器+Flash;MIC_LEVEL 同理写 ADC。 + * 返回 1 表示需要 gpio_leds_dirty。 + */ +static unsigned tx1_vol_plus_step(tx1_feature_mode_t mode, unsigned &feature_volume) +{ + switch (mode) { + case FEATURE_MODE_NONE: + return 0; + case FEATURE_MODE_SYSTEM_VOLUME: { + unsigned hid; + unsigned bar; + GET_SHARED_GLOBAL(hid, g_volume_level); + bar = tx1_hid_level_to_bar(hid); + if (bar >= TX1_VOL_BAR_MAX) { + return 0; + } + bar++; + feature_volume = bar; + tx1_apply_dac_hid_level(tx1_bar_to_hid_level(bar)); + return 1; + } + case FEATURE_MODE_GUNSHOT_LEVEL: + case FEATURE_MODE_FOOTSTEPS_LEVEL: + if (feature_volume < TX1_VOL_BAR_MAX) { + feature_volume++; + } + return 1; + case FEATURE_MODE_MIC_LEVEL: + if (feature_volume < TX1_VOL_BAR_MAX) { + feature_volume++; + tx1_apply_mic_hid_level(tx1_bar_to_hid_level(feature_volume)); + } + return 1; + default: + return 0; + } +} + +/** + * 改动原因:对齐 jok on_vol_minus_short_press,逻辑同 tx1_vol_plus_step 方向相反。 + */ +static unsigned tx1_vol_minus_step(tx1_feature_mode_t mode, unsigned &feature_volume) +{ + switch (mode) { + case FEATURE_MODE_NONE: + return 0; + case FEATURE_MODE_SYSTEM_VOLUME: { + unsigned hid; + unsigned bar; + GET_SHARED_GLOBAL(hid, g_volume_level); + bar = tx1_hid_level_to_bar(hid); + if (bar == 0) { + return 0; + } + bar--; + feature_volume = bar; + tx1_apply_dac_hid_level(tx1_bar_to_hid_level(bar)); + return 1; + } + case FEATURE_MODE_GUNSHOT_LEVEL: + case FEATURE_MODE_FOOTSTEPS_LEVEL: + if (feature_volume > 0) { + feature_volume--; + } + return 1; + case FEATURE_MODE_MIC_LEVEL: + if (feature_volume > 0) { + feature_volume--; + tx1_apply_mic_hid_level(tx1_bar_to_hid_level(feature_volume)); + } + return 1; + default: + return 0; + } +} + static void tx1_apply_mic_mute_hw(unsigned mic_muted, unsigned &old_adc_vol, client interface i2c_master_if i2c) { @@ -656,7 +967,6 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli // TX1 LED state unsigned led_tile0_shadow = 0xF0; // bits 7-4 all off (active low) unsigned feature_timeout_ticks = 0; - #define FEATURE_TIMEOUT_MAX 160 // 8s / 50ms = 160 ticks unsigned host_os = 0; tmr :> time; /* Input time */ @@ -707,11 +1017,68 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli unsigned gpio_leds_dirty = 1; // refresh LEDs on first tick unsigned led_pattern_step = TX1_EFFECT_RACE; // 改动原因:BYPASS 下 RGB 装饰灯效,VOL++/VOL- 循环 + unsigned c1_mode = load_value(C1_MODE_INFO_PATH); + #if HID_DFU_EN firmware_upgrade_init(); #endif + if (c1_mode > C1_MODE_VALUE_MAX || c1_mode < C1_MODE_VALUE_MIN) + { + c1_mode = C1_MODE_VALUE_DEFAULT; + save_value(C1_MODE_INFO_PATH, c1_mode); + } + /* 改动原因:开机从 LFS 恢复 GAME 模式(须在 Win 检测后 switch_mode,检测前需已知 g_3d_fps) */ + { + unsigned char saved_gm = tx1_load_game_mode(); + game_mode = (tx1_game_mode_t)saved_gm; + tx1_sync_game_mode_state((unsigned)game_mode, 0); + gpio_leds_dirty = 1; + debug_printf("TX1: Loaded game_mode from flash: %u\n", (unsigned)game_mode); + } + +#if defined(WIN_OS_DETECTION) + /* 改动原因:与 fosi_c1_lp 相同——仅 UAC1 固件、定时器已启动后延时轮询,再按 OS+模式切固件 */ + host_os = tx1_wait_host_os_detection(); + { + unsigned boot_game_mode; + GET_SHARED_GLOBAL(boot_game_mode, g_3d_fps); + debug_printf("WIN_OS_DETECTION host_os=%d g_3d_fps=%d\n", host_os, boot_game_mode); + if (host_os == OS_WIN) { + switch_mode_by_c1_mode(boot_game_mode, 1); + } else { + switch_mode_by_c1_mode(boot_game_mode, 0); + } + } +#elif defined(FPS71_UAC2) + /* 改动原因:FPS71 固件不做 Win 检测;由 game_uac1 检测后 RoleSwitch 跳入 */ + debug_printf("FPS71_UAC2 boot g_3d_fps=%u\n", (unsigned)game_mode); +#else + debug_printf("game_uac1 no WIN_OS_DETECTION build\n"); +#endif + + /* 改动原因:开机恢复 DAC/MIC 音量(放在 OS 检测/切固件之后,与 c1_lp 一致避免阻塞枚举过久) */ + { + unsigned char saved_dac = tx1_load_dac_volume(); + unsigned char saved_mic = tx1_load_mic_volume(); + + if (saved_dac == 255) { + saved_dac = (unsigned char)TX1_DAC_HID_LEVEL_DEFAULT; + tx1_save_dac_volume(saved_dac); + } + if (saved_mic == 255) { + saved_mic = (unsigned char)TX1_MIC_HID_LEVEL_DEFAULT; + tx1_save_mic_volume(saved_mic); + } + tx1_apply_dac_hid_level((unsigned)saved_dac); + tx1_apply_mic_hid_level((unsigned)saved_mic); + feature_volume = tx1_hid_level_to_bar((unsigned)saved_mic); + debug_printf("TX1: Loaded dac_hid=%u mic_hid=%u\n", (unsigned)saved_dac, (unsigned)saved_mic); + } + + /* 改动原因:开机确保 tile1 按 Flash 恢复的 g_3d_fps 应用 EX3D */ + SET_SHARED_GLOBAL(g_tx1_ex3d_resync_req, 1); while(1) { select @@ -810,6 +1177,54 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli } } } + /* 改动原因:HID 0x93/0x82 置位后在此应用 DAC/MIC 等级、写寄存器并 Flash(面板步进已在 step 内保存) */ + { + unsigned req_vol; + GET_SHARED_GLOBAL(req_vol, g_request_volume_set); + if (req_vol) { + unsigned hid_lvl; + unsigned reg; + SET_SHARED_GLOBAL(g_request_volume_set, 0); + GET_SHARED_GLOBAL(hid_lvl, g_volume_level); + if (hid_lvl <= TX1_DAC_HID_LEVEL_MAX) { + reg = (hid_lvl == 0) ? 0u : (unsigned)tx1_dac_level_to_reg[hid_lvl]; + SET_SHARED_GLOBAL(g_dac_vol, reg); + if (hid_lvl == 0) { + unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, i2c); } + } else { + /* 改动原因:必须用 SY102 查表值直写 0x0034,不能用 dac_volume 线性公式 */ + unsafe { + NAU88C22_REGWRITE(0x0034, + ((reg & 0xff) << 8) | (reg & 0xff), i2c); + } + } + old_dac_vol = reg; + tx1_save_dac_volume((unsigned char)hid_lvl); + debug_printf("HID/panel SET_VOLUME: dac_hid=%u reg=0x%x\n", hid_lvl, reg); + } + } + } + { + unsigned req_mic; + GET_SHARED_GLOBAL(req_mic, g_request_mic_volume_set); + if (req_mic) { + unsigned hid_mic; + unsigned adc; + unsigned mute_sw; + SET_SHARED_GLOBAL(g_request_mic_volume_set, 0); + GET_SHARED_GLOBAL(hid_mic, g_mic_volume_level); + GET_SHARED_GLOBAL(mute_sw, g_mute_switch); + adc = tx1_mic_hid_to_adc_vol(hid_mic); + SET_SHARED_GLOBAL(g_adc_vol, adc); + if (mute_sw == 0) { + mic_volume(adc, i2c); + old_adc_vol = adc; + } + tx1_save_mic_volume((unsigned char)hid_mic); + debug_printf("HID/panel SET_MIC_VOLUME: mic_hid=%u adc=%u\n", hid_mic, adc); + } + } + GET_SHARED_GLOBAL(dac_vol, g_dac_vol); GET_SHARED_GLOBAL(adc_vol, g_adc_vol); unsigned mute_switch; @@ -880,45 +1295,60 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli } } - // 改动原因:检测g_dac_vol的变化,如果变化则通过HID上报 - // 参考hid_ret_process和UserReadHIDLog方式,使用指针访问全局数组 + // 改动原因:检测 g_volume_level(DAC HID 0~48) 变化并通过 HID 0x94 上报 { - // 改动原因:检测g_dac_vol的变化,而不是g_volume_level - unsigned current_dac_vol; - GET_SHARED_GLOBAL(current_dac_vol, g_dac_vol); + unsigned current_vol_hid; + GET_SHARED_GLOBAL(current_vol_hid, g_volume_level); - // 如果g_dac_vol发生变化,构建0x94 GET_VOLUME响应数据包并上报 - if (g_last_dac_vol != current_dac_vol && g_last_dac_vol != 0xFF) + if (g_last_volume_hid != current_vol_hid && g_last_volume_hid != 0xFF) { unsafe { unsigned char * unsafe reportPtr = g_hid_pass_data; - // 构建0x94 GET_VOLUME响应数据包格式(参考eq_hid_protocol.md) - // 字节位置 | 长度 | 内容 | 描述 - // 0 | 1 | 0x77 | 同步头1 - // 1 | 1 | 0x94 | 同步头2 - // 2 | 1 | uint8 | 当前音量级别 (0-255) - // 3-62 | 60 | 0x00 | 保留字节 - reportPtr[0] = 0x77; // 同步头1 - reportPtr[1] = 0x94; // 同步头2(GET_VOLUME命令) - reportPtr[2] = (unsigned char)current_dac_vol; // 当前音量级别(0-255) + reportPtr[0] = 0x77; + reportPtr[1] = 0x94; + reportPtr[2] = (unsigned char)current_vol_hid; - // 其余字节填充为0 for (int i = 3; i < 63; i++) { reportPtr[i] = 0x00; } - // 通知HID系统有数据变化 hidSetChangePending(0x1); debug_printf("DAC volume changed: %d -> %d, HID report prepared\n", - g_last_dac_vol, current_dac_vol); + g_last_volume_hid, current_vol_hid); } } - g_last_dac_vol = current_dac_vol; + g_last_volume_hid = current_vol_hid; + } + + /* 改动原因:MIC HID 等级变化时主动上报 0x83,与 eq GET_MIC_VOLUME 一致 */ + { + unsigned current_mic_hid; + GET_SHARED_GLOBAL(current_mic_hid, g_mic_volume_level); + + if (g_last_mic_volume_hid != current_mic_hid && g_last_mic_volume_hid != 0xFF) + { + unsafe + { + unsigned char * unsafe reportPtr = g_hid_pass_data; + + reportPtr[0] = 0x77; + reportPtr[1] = 0x83; + reportPtr[2] = (unsigned char)current_mic_hid; + for (int i = 3; i < 63; i++) { + reportPtr[i] = 0x00; + } + hidSetChangePending(0x1); + } + debug_printf("MIC volume changed: %d -> %d, HID 0x83 report prepared\n", + g_last_mic_volume_hid, current_mic_hid); + } + g_last_mic_volume_hid = current_mic_hid; + } // 改动原因:检测静音开关状态变化,如果变化则通过HID上报0xB2(格式参考eq_hid_protocol.md),与g_adc_loop一致直接读g_mute_switch { @@ -1213,9 +1643,18 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli g_last_game_mode = current_game_mode; - } #endif + /* 改动原因:HID 0xA4 在 eq.c 已写 g_3d_fps,同步本地 game_mode 以刷新 GPIO 灯 */ + { + unsigned shared_gm; + GET_SHARED_GLOBAL(shared_gm, g_3d_fps); + if ((unsigned)game_mode != shared_gm) { + game_mode = (tx1_game_mode_t)shared_gm; + gpio_leds_dirty = 1; + } + } + // ========== TX1 BUTTON SCANNING ========== { unsigned btn1, btn2; @@ -1335,6 +1774,7 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli // Short press: cycle feature mode feature_mode = (feature_mode + 1) % 5; feature_timeout_ticks = 0; + tx1_sync_feature_volume_from_hw(feature_mode, feature_volume); gpio_leds_dirty = 1; debug_printf("TX1: FPS short press - feature_mode=%d\n", feature_mode); } @@ -1349,11 +1789,11 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli game_long_fired = 0; } else { if (!game_long_fired && (now - game_press_time) < 1000000000ull) { - // Short press: cycle game mode + /* 改动原因:与 jok on_game_short_press 一致;写 Flash 并同步 tile1 EX3D */ game_mode = (game_mode + 1) % 4; gpio_leds_dirty = 1; - SET_SHARED_GLOBAL(g_3d_fps, game_mode); - debug_printf("TX1: GAME short press - game_mode=%d\n", game_mode); + tx1_sync_game_mode_state((unsigned)game_mode, 1); + debug_printf("TX1: GAME short press - game_mode=%d saved\n", game_mode); } } prev_game = game; @@ -1386,74 +1826,71 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli debug_printf("TX1: MIC long press - dnr_enabled=%d\n", dnr_enabled); } - // VOL+ continuous adjustment + /* 改动原因:VOL+ 对齐 jok buttons.xc——松开且<1s为短按;≥1s后每100ms连发(同 on_vol_plus_long_press) */ if (vol_plus != prev_vol_plus) { if (vol_plus == 0) { vol_plus_press_time = now; vol_plus_long_fired = 0; + } else { + if (!vol_plus_long_fired + && (now - vol_plus_press_time) < TX1_LONG_PRESS_TICKS) { + if (tx1_vol_plus_step(feature_mode, feature_volume)) { + gpio_leds_dirty = 1; + debug_printf("TX1: VOL+ short press feature_mode=%d\n", + feature_mode); + } + } } prev_vol_plus = vol_plus; - } - if (vol_plus == 0 && !vol_plus_long_fired && (now - vol_plus_press_time) >= 1000000000ull) { + } else if (vol_plus == 0 && !vol_plus_long_fired + && (now - vol_plus_press_time) >= TX1_LONG_PRESS_TICKS) { vol_plus_long_fired = 1; } if (vol_plus == 0 && vol_plus_long_fired) { - // Adjust volume every 100ms static unsigned last_vol_plus_trigger = 0; - if ((now - last_vol_plus_trigger) >= 100000000ull) { + if ((now - last_vol_plus_trigger) >= TX1_VOL_REPEAT_TICKS) { last_vol_plus_trigger = now; - if (feature_mode == FEATURE_MODE_NONE || feature_mode == FEATURE_MODE_SYSTEM_VOLUME) { - // System volume up - unsigned vol; - GET_SHARED_GLOBAL(vol, g_volume_level); - if (vol < 100) { - vol++; - SET_SHARED_GLOBAL(g_volume_level, vol); - SET_SHARED_GLOBAL(g_request_volume_set, 1); - } - } else { - // Feature volume up - if (feature_volume < 12) feature_volume++; + if (tx1_vol_plus_step(feature_mode, feature_volume)) { + gpio_leds_dirty = 1; } - gpio_leds_dirty = 1; } } - // VOL- continuous adjustment + /* 改动原因:VOL- 对齐 jok,结构同 VOL+ */ if (vol_minus != prev_vol_minus) { if (vol_minus == 0) { vol_minus_press_time = now; vol_minus_long_fired = 0; + } else { + if (!vol_minus_long_fired + && (now - vol_minus_press_time) < TX1_LONG_PRESS_TICKS) { + if (tx1_vol_minus_step(feature_mode, feature_volume)) { + gpio_leds_dirty = 1; + debug_printf("TX1: VOL- short press feature_mode=%d\n", + feature_mode); + } + } } prev_vol_minus = vol_minus; - } - if (vol_minus == 0 && !vol_minus_long_fired && (now - vol_minus_press_time) >= 1000000000ull) { + } else if (vol_minus == 0 && !vol_minus_long_fired + && (now - vol_minus_press_time) >= TX1_LONG_PRESS_TICKS) { vol_minus_long_fired = 1; } if (vol_minus == 0 && vol_minus_long_fired) { static unsigned last_vol_minus_trigger = 0; - if ((now - last_vol_minus_trigger) >= 100000000ull) { + if ((now - last_vol_minus_trigger) >= TX1_VOL_REPEAT_TICKS) { last_vol_minus_trigger = now; - if (feature_mode == FEATURE_MODE_NONE || feature_mode == FEATURE_MODE_SYSTEM_VOLUME) { - unsigned vol; - GET_SHARED_GLOBAL(vol, g_volume_level); - if (vol > 0) { - vol--; - SET_SHARED_GLOBAL(g_volume_level, vol); - SET_SHARED_GLOBAL(g_request_volume_set, 1); - } - } else { - if (feature_volume > 0) feature_volume--; + if (tx1_vol_minus_step(feature_mode, feature_volume)) { + gpio_leds_dirty = 1; } - gpio_leds_dirty = 1; } } } - // Feature mode timeout (8s) + /* 改动原因:与 jok TIMER_3 8s 一致,扫描周期 20ms × TX1_FEATURE_TIMEOUT_MAX(400) */ if (feature_mode != FEATURE_MODE_NONE) { feature_timeout_ticks++; - if (feature_timeout_ticks >= FEATURE_TIMEOUT_MAX) { + if (feature_timeout_ticks >= TX1_FEATURE_TIMEOUT_MAX) { feature_mode = FEATURE_MODE_NONE; feature_timeout_ticks = 0; gpio_leds_dirty = 1; @@ -1518,8 +1955,9 @@ void AudioHwRemote2(streaming chanend c, client interface i2c_master_if i2c, cli led_if.led_on(TX1_GPIO_LED_D2); } - /* 改动原因:HTR3236 RGB D1-D12 音量条;工厂复位灯效占用 RGB 时不刷条 */ - if (g_htr3236_ready && !tx1_factory_reset_rgb_active()) { + /* 改动原因:仅 feature 模式刷 RGB 音量条;非 BYPASS 时由 tx1_azimuth_effect_loop 占满 RGB(同 jok) */ + if (g_htr3236_ready && !tx1_factory_reset_rgb_active() + && feature_mode != FEATURE_MODE_NONE) { tx1_rgb_volume_bar_refresh(&htr3236_dev, i2c, feature_mode, feature_volume); } } diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/audiohw.xc.bak b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/audiohw.xc.bak deleted file mode 100644 index bd5802d..0000000 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/audiohw.xc.bak +++ /dev/null @@ -1,2534 +0,0 @@ -#if UART_DEBUG || DEBUG_MEMORY_LOG_ENABLED -#define DEBUG_PRINT_ENABLE 1 -#else -#define DEBUG_PRINT_ENABLE 0 -#endif -#define DISABLE_REBOOT 1 - -#include -#include -#include -#include "xassert.h" -#include "i2c.h" -#include "xua.h" -#include -#include "xc_ptr.h" -#include "user_uart.h" -#include "debug_print.h" -#include "roleswitchflag.h" -#include "xua_hid_report.h" -#include "lfs_io.h" - -#if defined (CODEC_AIC3204) -#include "eq_flash_storage.h" -#include "codec_ti3204.h" -#else -#error "No codec selected" -#endif - -extern "C" { - #include "sw_pll.h" -} - -#include "xc_ptr.h" -unsigned g_ch0_level = 0; -unsigned g_ch1_level = 0; - -#define NAU88C25 0 - -#if NAU88C25 -#include "nau88c25.h" -#else -#include "nau88c21.h" -#endif - -#if NAU88C25 -#define NAU88_I2C_DEVICE_ADDR 0x15 -#else -#define NAU88_I2C_DEVICE_ADDR 0x1B -#endif - -#include "htr3236.h" -#include "led_control.h" -#include "xmath/scalar/f32.h" - -#include "dnr_dsp_buf.h" - -#include "xua_hid_report.h" - -#if (XUA_PCM_FORMAT == XUA_PCM_FORMAT_TDM) && (XUA_I2S_N_BITS != 32) -#warning ADC only supports TDM operation at 32 bits -#endif - -#ifndef I2S_LOOPBACK -#define I2S_LOOPBACK (0) -#endif - - -#if UAC1 -unsigned g_uac_mode = 1; // 2 for UAC2.0, 1 for UAC1.0 -#else -unsigned g_uac_mode = 2; // 2 for UAC2.0, 1 for UAC1.0 -#endif - -unsafe client interface i2c_master_if i_i2c_client; -audio_sampling g_new_playback_format, g_playback_format; -audio_type g_new_audio_type, g_audio_type = 0; -unsigned g_mute_enable = 0; -unsigned g_mute_state = 0; -unsigned g_mute_state_old = 1; -unsigned g_unmute_dac_state, g_unmute_time, g_format_time; -unsigned g_volume_level = 29, g_saved_volume_level = 29; -unsigned g_request_volume_set = 0; -unsigned g_init_saved_settings = 0; -unsigned g_host_volume = 0x0; -unsigned g_last_volume_level = 0xFF; // 上次已上报的音量级别,0xFF表示初始化未完成 -unsigned g_mic_volume_level = 37; // 麦克风PGA增益级别(0=mute, 1-37=0dB~36dB,HID可见范围) -unsigned g_request_mic_volume_set = 0; -unsigned g_last_mic_volume_level = 0xFF; // 上次已上报的麦克风增益级别,0xFF表示初始化未完成 -unsigned g_dnr_strength = 100; // AI降噪强度HID值(1-100=档位,步进1;100→-200dB最强;关断由g_dnr_on控制,此处不再用0表示强度) -// 改动原因:用户要求与强度分离的开关量;关时仍保留g_dnr_strength供0x86读取与再次开启时恢复 -unsigned g_dnr_on = 1; // AI降噪总开关(0=关仅停算法,1=开且用g_dnr_strength档位) -unsigned g_last_dnr_strength = 0xFF; // 上次已上报的降噪强度,0xFF表示首次未上报(触发开机上报) -unsigned g_last_game_mode = 0xFF; // 上次已上报的音效模式,0xFF表示首次未上报(触发开机上报) -unsigned g_request_dnr_strength_set = 0; // HID 0x85 SET_AI_NOISE_STRENGTH待处理标志 -unsigned g_monitor_switch = 0; // 耳返开关(0=关闭,1=开启),默认关闭 -unsigned g_request_monitor_switch_set = 0; // HID 0x87 SET_MONITOR_SWITCH待处理标志 -unsigned g_dac_m_gain = 0; -unsigned g_unmute_delay_time = 0; -unsigned g_format_delay_time = 0; -unsigned g_mclk_select = 0; -// 改动原因:添加LED开关全局变量,控制LED是否显示(0=关闭,1=开启) -unsigned g_led_enable = 1; // LED开关,默认开启 -// HID 0xB0 CMD_EXPAND_GAIN到达时由eq.c设置,button_task读取后更新footstep LED -// -1 (0xFFFFFFFF) 表示无待处理请求 -unsigned g_hid_expand_gain_request = (unsigned)-1; -// HID 0xB0 CMD_LMT_THRESHOLD到达时由eq.c设置,button_task读取后保存到flash -// 存储值为-threshold (0~35);-1 (0xFFFFFFFF) 表示无待处理请求 -unsigned g_hid_lmt_threshold_request = (unsigned)-1; -// HID 0xB0 CMD_ANGLE到达时由eq.c设置,button_task读取后保存到flash -// channel=0xFFFFFFFF 表示批量更新所有通道 -#define EX3D_ANGLE_CHANNELS 8 - -unsigned g_hid_angle_values[EX3D_ANGLE_CHANNELS] = {0}; -unsigned g_hid_angle_values_old[EX3D_ANGLE_CHANNELS] = { 315, 45, 0, 0, 225, 135, 270, 90 }; - -// HID 0x84 FACTORY_RESET命令到达时由eq.c设置,button_task轮询后执行重启 -unsigned g_request_factory_reset = 0; -uint32_t get_reference_time(); -unsigned g_disable_i2c = 0; -unsigned g_dac_mode = 10; -unsigned g_new_dac_mode = 0; -unsigned g_samfreq = 48000; -unsigned g_dsd_mode = 0; - -void save_value(unsigned char * unsafe path, unsigned char value); -unsigned char load_value(unsigned char * unsafe path); -void save_value32(unsigned char * unsafe path, unsigned value); -unsigned load_value32(unsigned char * unsafe path); - -// mic detect events: mute_handler (tile[1]) → button_task (tile[0]) -#define MIC_DET_MUTE 1 // mic插入或全拔出,立即mute mic -#define MIC_DET_UNMUTE 2 // 插入1s后恢复mic音量 -#define MIC_DET_DAC_MUTE 3 // mic插入时mute DAC防pop -#define MIC_DET_DAC_UNMUTE 4 // 1s后恢复DAC音量 - -unsafe chanend uc_audiohw; // tile[1] end: AudioHwConfig → button_task (tile[0]) -#if HID_DFU_EN -unsafe streaming chanend uc_dfu; // tile[1] send end: hid_button_task → button_task (tile[0]) -#endif - -static void ex3d_angle_load_defaults(unsigned angles[EX3D_ANGLE_CHANNELS]) -{ - angles[0] = 315; - angles[1] = 45; - angles[2] = 0; - angles[3] = 0; - angles[4] = 225; - angles[5] = 135; - angles[6] = 270; - angles[7] = 90; -} - -static void ex3d_angle_make_path(unsigned channel, unsigned char path[6]) -{ - path[0] = 'x'; - path[1] = '3'; - path[2] = 'd'; - path[3] = 'a'; - path[4] = (unsigned char)('1' + channel); - path[5] = 0; -} - -static void ex3d_angle_save_channel(unsigned channel, unsigned angle) -{ - unsigned char path[6]; - debug_printf("ex3d_angle_save_channel: %d, %d\n", channel, angle); - // 改动原因:角度值改为单key一次写入32位,减少4次拆分写入的flash调用,提升效率并简化流程。 - ex3d_angle_make_path(channel, path); - save_value32(path, angle); -} - -static unsigned ex3d_angle_load_channel(unsigned channel, unsigned default_angle) -{ - unsigned char path[6]; - ex3d_angle_make_path(channel, path); - unsigned angle = load_value32(path); - - if (angle == 0xFFFFFFFF) { - // 改动原因:按用户要求去掉legacy迁移与归一化,未初始化时直接使用并保存默认值,流程最简。 - ex3d_angle_save_channel(channel, default_angle); - return default_angle; - } - - // debug_printf("ex3d_angle_load_channel: %d, %d\n", channel, angle); - // 改动原因:按用户要求去掉normalize,读取后直接返回原始32位角度值。 - return angle; -} -// 改动原因:添加增益模式和滤波器模式的请求变量,用于HID命令设置模式 -unsigned g_request_game_mode = -1; - -#if EQ_EN -extern unsigned g_request_eq_mode, g_new_eq_mode; -#endif - -// tile 1, 3d_on_off -#define LED_ON 0 -#define LED_OFF 1 -#define S3D_ON LED_ON -#define S3D_OFF LED_OFF - -unsigned g_led_color = LED_OFF; -unsigned g_led_blink_count = 0; -unsigned g_led_blink_is_white = 0; - -#define LED_OFF 0x7F // 修改:清除最高位,只保留低7位 -#define LED_RED 0b01011111 // 修改:清除最高位,只保留低7位 -#define LED_GREEN 0b01101111 // 修改:清除最高位,只保留低7am -#define LED_BLUE 0b00111111 // 修改:清除最高位,只保留低7位 -#define LED_YELLOW (LED_RED & LED_GREEN) -#define LED_CYAN (LED_GREEN & LED_BLUE) -#define LED_PURPLE (LED_RED & LED_BLUE) -#define LED_WHITE (LED_RED & LED_GREEN & LED_BLUE) -enum { OS_WIN = 1, OS_OTHERS = 2 }; -// 改动原因:定义模式切换标志值,用于在SPATIAL_GAME、STEREO_8K、STEREO_2K、UAC1之间循环切换 -#define MODE_F3_F4_FPS_UAC2 COAX_IN_FLAG //1 SPATIAL_GAME模式标志 -#define MODE_F5_MUSIC_UAC1 USB_IN_FLAG // 2 F5 MUSIC -#define MODE_F1_MUSIC_UAC2 OPT_IN_FLAG // 3 F1 MUSIC -#define MODE_F6_F7_FPS_UAC1 UAC1_IN_FLAG // 4 STEREO_2K模式标志 - -/* All on tile[0] */ -port p_scl = PORT_I2C_SCL; -port p_sda = PORT_I2C_SDA; - -//out port p_htr3235_sdb = PORT_HTR3236_SDB; /* 连接到HTR3236的SDB引脚,用于控制其电源状态 */ - -out port p_ctl_mute = PORT_CTL_MUTE; -port p_ctl_det = PORT_CTL_DET; - - -/* Board setup for XU316 MC Audio (1v1) */ -void board_setup() -{ - -} - -// tile 0 -// called on tile 0 - start -#define NAU88L21_PGA_GAIN_REG_MIN_USED_VALUE 0x0 // 0x1=1, 0dB (0x0, -1dB which is not used in this design) -#define NAU88L21_PGA_GAIN_REG_MAX_VALUE 0x25+1 // 0x25=37, 36dB. +1 is for extra 1.5dB digital gain -#define NAU88L21_PGA_GAIN_REG_DEFAULT_VALUE (NAU88L21_PGA_GAIN_REG_MAX_VALUE) - -// DAC 监听音量控制范围: 共 30 级 (0~29) -// 0 = mute (全灭, reg 0x0034=0x0000), 1~29 = -28dB ~ 0dB,1dB/步 -#define DAC_LEVEL_MIN 0 // mute,0 LEDs -#define DAC_LEVEL_MAX 29 // 0dB,15 LEDs -#define DAC_LEVEL_DEFAULT DAC_LEVEL_MAX - -static inline void NAU88C22_REGREAD(unsigned reg, unsigned &val, client interface i2c_master_if i2c) -{ - i2c_regop_res_t result; - val = i2c.read_reg16(NAU88_I2C_DEVICE_ADDR, reg, result); -} - -static inline i2c_regop_res_t NAU88C22_REGWRITE(unsigned reg, unsigned val, client interface i2c_master_if i2c) -{ - i2c_regop_res_t result = i2c.write_reg16(NAU88_I2C_DEVICE_ADDR, reg, val); - - if(result != I2C_REGOP_SUCCESS) - { - debug_printf("I2C write failed: reg="); - printhex(reg); - debug_printf(", val="); - printhex(val); - debug_printf("\n"); - } - else - { - //debug_printf("I2C write success: reg="); - //printhex(reg); - //debug_printf(", val="); - //printhex(val); - //debug_printf("\n"); - //debug_printf("."); - } - - return result; -} - -void dac_volume(signed level) -{ - // 1dB/步: level 范围 -28 ~ 0,对应寄存器 0xcf-28=0xb3 ~ 0xcf - unsigned tmp = 0xcf + level; - unsafe {NAU88C22_REGWRITE(0x0034, (tmp<<8|tmp), (client interface i2c_master_if)i_i2c_client);} -} - -void mic_volume(unsigned level) -{ - if (level == 0) - { - // mute: 关闭PGA和输出放大器 - unsafe {NAU88C22_REGWRITE(0x007E, 0, (client interface i2c_master_if)i_i2c_client);} - unsafe {NAU88C22_REGWRITE(0x0035, 0, (client interface i2c_master_if)i_i2c_client);} - } - else if(level == NAU88L21_PGA_GAIN_REG_MAX_VALUE) - { - // 内部最大值 (reg=38, +1.5dB数字增益,仅firmware使用) - // PGA设到最大(37=0x25),数字增益额外+1.5dB - unsafe {NAU88C22_REGWRITE(0x007E, (NAU88L21_PGA_GAIN_REG_MAX_VALUE-1) << 8, (client interface i2c_master_if)i_i2c_client);} - unsafe {NAU88C22_REGWRITE(0x0035, (0xd2d2), (client interface i2c_master_if)i_i2c_client);} - } - else - { - // 1-37: 0dB ~ 36dB,1dB/步 - debug_printf("mic_volume write reg=%d\n", level); - unsafe {NAU88C22_REGWRITE(0x007E, (level << 8), (client interface i2c_master_if)i_i2c_client);} - unsafe {NAU88C22_REGWRITE(0x0035, (0xcfcf), (client interface i2c_master_if)i_i2c_client);} - } -} - -void codec_init(void) -{ - /* - * Setup CODEC - */ - uint16_t addr = 0, val; - for (int i = 0; i < sizeof(nau88c22_registers) / sizeof(nau88c22_registers[0]); i++) { - addr = nau88c22_registers[i][1]; - val = (nau88c22_registers[i][2] << 8) | nau88c22_registers[i][3]; - unsafe {NAU88C22_REGWRITE(addr, val, (client interface i2c_master_if)i_i2c_client);} - } - - // ADCL PGA default setting - if(NAU88L21_PGA_GAIN_REG_DEFAULT_VALUE == NAU88L21_PGA_GAIN_REG_MAX_VALUE) - unsafe {NAU88C22_REGWRITE(0x007E, (NAU88L21_PGA_GAIN_REG_MAX_VALUE-1) << 8, (client interface i2c_master_if)i_i2c_client);} - else - unsafe {NAU88C22_REGWRITE(0x007E, NAU88L21_PGA_GAIN_REG_DEFAULT_VALUE << 8, (client interface i2c_master_if)i_i2c_client);} - - //debug_printfln("Codec init finished"); -} - -in port p_mic_gain_encoder1 = PORT_MIC_GAIN_ENCODER1; // 4F2 -in port p_mic_gain_encoder2 = PORT_MIC_GAIN_ENCODER2; // 4E2 - -in port p_hp_gain_encoder = PORT_HP_GAIN_ENCODER; // 8D4, 8D5 - -in port p_button_music_mode = PORT_BUTTON_MUSIC_MODE; // 1A -in port p_button_game_mode = PORT_BUTTON_GAME_MODE; // 1L -in port p_button_ai71_onoff = PORT_BUTTON_AI71_ONOFF; // 1M - -// -// -// -// -// -// -// -// -// - -#define KEY_POLLING_INTERVAL 10000000L // 100ms polling interval -#define TIMER_PERIOD (100000) -#define FACTORY_RESET_HOLD_TICKS 3000 // 3000 × 1ms = 3秒 -#define FACTORY_RESET_BLINK_TICKS 400 // 每相400ms -#define MUTE_BLINK_HALF_PERIOD 500 // mute LED blink half period 250ms -#define BTN_COMBO_DELAY_TICKS 40 // 单键去抖/组合检测窗口(50ms) - -unsigned g_windows_detect_done = 0; - -#define MUTE_ON 1 -#define MUTE_OFF 0 - -extern unsigned g_host_os; // 1 -> Windows, 2 -> Others -extern unsigned g_mute_on_off_t0; -extern unsigned g_uac_vol; -#define DNR_STRENGTH_off 10 -extern void dnr_set_mode(unsigned char mode); -extern void dnr_set_strength_level(unsigned char strength); - -extern void device_reboot(void); - - -enum {IR_OFF=0, IR_GAME=1, IR_MUSIC=2, IR_MOVIE=3, IR_7_1_GAME=4, IR_7_1_MUSIC=5, IR_7_1_MOVIE=6}; - -#ifndef HID_MAX_DATA_BYTES -#define HID_MAX_DATA_BYTES ( 64 ) -#endif -extern unsigned hidSendData[]; - -#if HID_DFU_EN -#include "dfu_upgrade.h" -/* 将HID收到的63字节固件升级START命令打包为16个unsigned word, - * 通过uc_dfu streaming channel发送到button_task (tile[0])执行。 - * 从eq.c的process_send_params中对0xA7命令调用此函数。 */ -void dfu_chan_forward(unsigned char data[], unsigned len) -{ - unsafe - { - for (int i = 0; i < 16; i++) { - unsigned word = 0; - for (int j = 0; j < 4; j++) { - int idx = i * 4 + j; - if (idx < 63) { - word |= ((unsigned)data[idx]) << (j * 8); - } - } - uc_dfu <: word; - } - } -} -#endif - -void button_task(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, chanend c_audiohw_rx -#if HID_DFU_EN - , streaming chanend c_dfu_rx -#endif - , chanend c_mic_det - ) -{ - //hwtimer_t timer = hwtimer_alloc(); - unsigned time = 0; - timer tmr; - - static int uac_vol=0, last_uac_vol=0; -#if EQ_EN - - static unsigned eq_sync_counter = 0; // EQ参数存储计数器(每100ms递增,5次后保存) -#endif - // port_t p_ctrl_keys = XS1_PORT_8C; - - uint32_t port_ctrl_keys = 0, curr_ctrl_keys = 0, last_ctrl_keys = 0, keys_changed = 0; - uint32_t port_ctrl_keys2 = 0, curr_ctrl_keys2 = 0, last_ctrl_keys2 = 0, keys_changed2 = 0; - - int debounce_cnt = 0; - static unsigned isMute = 0; - uint8_t tmp = 0; - - // port_t p_button_music_mode = PORT_BUTTON_MUSIC_MODE; - // port_t p_button_game_mode = PORT_BUTTON_GAME_MODE; - // port_t p_button_ai71_onoff = PORT_BUTTON_AI71_ONOFF; - - //port_enable(p_button_music_mode); - - // 出厂默认:麦克风21dB (reg=22), 监听-14dB (level=15) - int codec_adc_pga_gain_reg_value = 22; // 21dB - - int dac_level = 15; // -14dB (DAC_LEVEL_MAX - 14 = 29 - 14 = 15) - - // mic endcoder 变量 - uint8_t prev_encode_input1 = 0; - uint8_t rotation_active = 0; - uint8_t sample_count = 0; - uint8_t last_valid_direction = 0; - uint8_t fast_rotation_mode = 0; // 快速旋转模式 - uint8_t consecutive_same_dir = 0; // 连续相同方向计数 - - // hp endcoder 变量 - uint8_t hp_prev_encode_input1 = 0; - uint8_t hp_rotation_active = 0; - uint8_t hp_sample_count = 0; - uint8_t hp_last_valid_direction = 0; - uint8_t hp_fast_rotation_mode = 0; // 快速旋转模式 - uint8_t hp_consecutive_same_dir = 0; // 连续相同方向计数 - - - - // active_mode: 0=off, 1=music (LED_MUSIC, no algorithm), - // 2=game (LED_GAME_MODE, IR_GAME), 3=AI7.1 (LED_AI7_1, IR_7_1_GAME) - unsigned active_mode = 0; - // 脚步增强3档状态: 0=关(0dB), 1=中亮/6dB, 2=高亮/12dB;出厂默认开启(12dB) - unsigned flag_footsteps_enhancement = 2; - // 出厂默认:AI降噪开启 - unsigned flag_aidenoise_onoff = 1; - unsigned dnr_strength_saved = 100; // AI降噪重新开启时恢复的强度(0x85可更新) - unsigned last_footstep_expand = 0xFF; // 上次已上报的脚步增强增益值,0xFF表示初始化未完成 - - // Buttons state - unsigned push_button_music_mode_state_old = 1; // Active low - unsigned push_button_ai71_onoff_state_old = 1; // Active low - unsigned push_button_game_mode_state_old = 1; // Active low - unsigned push_button_footsteps_enhancement_state_old = 0; // Active low - unsigned push_button_aidenoise_onoff_state_old = 1; // Active low - unsigned char saved_footstep = 0; - - - - unsigned flag_mic_mute = 0; - unsigned flag_hp_mute = 0; - unsigned mic_det_muted = 0; // mic检测导致的mute(不影响LED和g_mic_volume_level) - unsigned dac_det_muted = 0; // mic插入时临时mute DAC防pop(不影响LED) - - unsigned push_button_mic_mute_state_old = 1; // Active low - unsigned push_button_hp_mute_state_old = 1; // Active low - - // 出厂恢复长按状态机:音乐+游戏同时长按3秒 - unsigned factory_reset_hold_count = 0; // 两键同时按住计数(×1ms) - unsigned factory_reset_blink_state = 0; // 0=空闲,1-6=闪烁相位 - unsigned factory_reset_blink_tick = 0; // 当前相位内计数 - unsigned mic_mute_blink_tick = 0; - unsigned hp_mute_blink_tick = 0; - // 组合键去抖:单键动作延迟 BTN_COMBO_DELAY_TICKS 后触发,期间若另一键也按下则切换为组合模式 - unsigned btn_music_hold_ticks = 0; // music键连续按住计数 - unsigned btn_game_hold_ticks = 0; // game键连续按住计数 - unsigned btn_combo_active = 0; // 1=处于组合键模式(单键动作已抑制) - unsigned fr_inhibit = 0; // 1=出厂恢复重启后抑制状态,必须松键后才允许重新触发 - - int current_mic_led_pos = 0; - - htr3236_t htr3236_dev; - - // LED控制上下文 - led_control_t led_ctx; - - - // saved_mode / active_mode: 0=off, 1=music, 2=game (IR_GAME), 3=AI7.1 (IR_7_1_GAME) - unsigned /* char */ saved_mode; - unsigned char saved_uac1_mode = 0; - unsigned char path[] = "game_mode"; - unsigned char mic_vol_path[] = "mic_vol"; - unsigned char dac_vol_path[] = "dac_vol"; - unsigned char mic_mute_path[] = "mic_mute"; - unsigned char hp_mute_path[] = "hp_mute"; - unsigned char monitor_sw_path[] = "monitor_sw"; - unsigned char dnr_strength_path[] = "dnr_strength"; - // 改动原因:断电记忆AI降噪开关与强度分离存储(旧固件仅用dnr_strength=0表示关,启动时迁移) - unsigned char dnr_on_path[] = "dnr_on"; - unsigned host_os = OS_OTHERS; -#if DNR_ENABLE - unsigned dnr_init_flag = 0; - while (dnr_init_flag == 0) - { - GET_SHARED_GLOBAL(dnr_init_flag, g_dnr_init_flag); - asm("nop"); - } -#endif -#if USE_EX3D == 1 - unsigned ex3d_key_verified = 0; - while (ex3d_key_verified == 0) - { - GET_SHARED_GLOBAL(ex3d_key_verified, g_ex3d_key_verified); - asm("nop"); - } -#endif - - delay_milliseconds(10); - saved_mode = load_value(path); - debug_printf("Loaded game_mode from flash: %d\n", saved_mode); - -#if USE_EX3D == 1 - // 加载脚步增强状态(保存值为expand_gain: 0/6/12) - { - unsigned char footstep_path[] = "footstep"; - saved_footstep = load_value(footstep_path); - debug_printf("Loaded footstep gain from flash: %d\n", saved_footstep); - if (saved_footstep == 0) { - flag_footsteps_enhancement = 0; - } else if (saved_footstep <= 6) { - flag_footsteps_enhancement = 1; - } else if (saved_footstep <= 20) { - flag_footsteps_enhancement = 2; - } else { - // 未初始化(255)或异常值:出厂默认脚步增强开启(12dB),写入flash - saved_footstep = 12; - flag_footsteps_enhancement = 2; - save_value(footstep_path, (unsigned char)12); - debug_printf("Saved footstep gain to flash: %d\n", saved_footstep); - } - debug_printf("Loaded footstep gain from flash: %d, state=%d\n", saved_footstep, flag_footsteps_enhancement); - } - - // 加载EX3D角度,未初始化时写入默认值 - { - unsigned ex3d_angles[EX3D_ANGLE_CHANNELS]; - ex3d_angle_load_defaults(ex3d_angles); - for (int i = 0; i < EX3D_ANGLE_CHANNELS; ++i) { - g_hid_angle_values[i] = ex3d_angle_load_channel(i, ex3d_angles[i]); - // 改动原因: - // - g_hid_angle_values_old 用于后续“变更检测后再写flash”; - // - 开机从flash加载角度后,旧值必须与当前值对齐,否则首次保存请求会把未变化通道也误判为变化。 - g_hid_angle_values_old[i] = g_hid_angle_values[i]; - } - } -#endif - -#if defined(UAC1_MODE) - for(int i = 0; i < 500; i++) - { - GET_SHARED_GLOBAL(host_os, g_host_os); - if (host_os == OS_WIN) { - break; - } - delay_milliseconds(1); - } - - if (host_os == OS_WIN) { - 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; - SetRoleSwitchFlag(flag); -#ifndef DISABLE_REBOOT - device_reboot(); - while (1); -#endif - } - else - { -#if F5_MUSIC_UAC1 - if (saved_mode >= 2) { - SetRoleSwitchFlag(MODE_F6_F7_FPS_UAC1); -#ifndef DISABLE_REBOOT - device_reboot(); - while (1); -#endif - } -#elif F6_F7_FPS_UAC1 - if (saved_mode <= 1) { - SetRoleSwitchFlag(MODE_F5_MUSIC_UAC1); -#ifndef DISABLE_REBOOT - device_reboot(); - while (1); -#endif - } -#endif - } -#endif - - -#if defined(UAC1_MODE) - if (saved_mode == 255) { -#if defined(F5_MUSIC_UAC1) - saved_mode = 1; // f5: default music mode -#elif defined(F6_F7_FPS_UAC1) - saved_mode = 2; // f6/f7: default game mode -#else - saved_mode = 1; // default off -#endif - save_value(path, saved_mode); - debug_printf("Saved game_mode to flash: %d\n", saved_mode); - } -#else - if (saved_mode == 255) { - // 出厂默认:AI7.1开启(mode=3) - saved_mode = 3; - save_value(path, saved_mode); - debug_printf("Saved game_mode to flash: %d\n", saved_mode); - } -#endif - - - active_mode = (saved_mode <= 3) ? saved_mode : 0; - { - SET_SHARED_GLOBAL(g_game_mode, active_mode); - debug_printf("active_mode=%d\n", active_mode); - } - - - - // 初始化硬件 - htr3236_init(&htr3236_dev, HTR3236_ADDR_GND); - htr3236_hw_enable(&htr3236_dev); - //p_htr3235_sdb <: 1; - - unsafe - { - while(htr3236_software_wake(&htr3236_dev, (client interface i2c_master_if)i_i2c_client) != 0) { - // 错误处理 - debug_printf("HTR3236 LED driver wake failed\n"); - //return; - } - } - debug_printf("HTR3236 LED driver wake success 9\n"); - - // 设置PWM频率为22kHz (避免可闻噪声) - //htr3236_set_frequency(i2c, HTR3236_FREQ_22KHZ); - unsafe - { - while(htr3236_set_frequency(&htr3236_dev, (client interface i2c_master_if)i_i2c_client, HTR3236_FREQ_22KHZ) != 0) - { - debug_printf("HTR3236 set frequency failed\n"); - } - } - debug_printf("HTR3236 set frequency success 9\n"); - - // 初始化LED控制 - unsafe{led_control_init(&led_ctx, &htr3236_dev, (client interface i2c_master_if)i_i2c_client);} - - // led_on(&led_ctx, led_l_physical_map[0]); - // delay_milliseconds(100); - // led_update_all(&led_ctx); - - // led_on(&led_ctx, led_l_physical_map[1]); - // delay_milliseconds(100); - // led_update_all(&led_ctx); - - // led_on(&led_ctx, led_l_physical_map[2]); - // delay_milliseconds(100); - // led_update_all(&led_ctx); - - //led_waterfall(&led_ctx, 50); - - - // 从 Flash 恢复 mic/dac 音量 - { - unsigned char saved_mic = load_value(mic_vol_path); - if(saved_mic >= NAU88L21_PGA_GAIN_REG_MIN_USED_VALUE && saved_mic <= NAU88L21_PGA_GAIN_REG_MAX_VALUE) - codec_adc_pga_gain_reg_value = saved_mic; - else - save_value(mic_vol_path, (unsigned char)codec_adc_pga_gain_reg_value); // 出厂默认22(21dB) - - unsigned char saved_dac = load_value(dac_vol_path); - if(saved_dac <= DAC_LEVEL_MAX) - dac_level = saved_dac; - else - save_value(dac_vol_path, (unsigned char)dac_level); // 出厂默认15(-14dB) - - // 从Flash恢复耳返开关(默认关闭) - unsigned char saved_monitor_sw = load_value(monitor_sw_path); - if(saved_monitor_sw == 1) - g_monitor_switch = 1; - else if(saved_monitor_sw == 255) { - // 未初始化:出厂默认关闭 - g_monitor_switch = 0; - save_value(monitor_sw_path, (unsigned char)0); - } else { - g_monitor_switch = 0; - } - debug_printf("Loaded monitor_switch from flash: %d\n", g_monitor_switch); - - { - unsigned char saved_dnr = load_value(dnr_strength_path); - unsigned char saved_on = load_value(dnr_on_path); - // 改动原因:强度文件只存2–100偶数档位;开关存dnr_on;兼容旧数据saved_dnr==0表示关且未单独存开关 - if (saved_dnr == 255) { - g_dnr_strength = 100; - dnr_strength_saved = 100; - g_dnr_on = 1; - flag_aidenoise_onoff = 1; - save_value(dnr_strength_path, (unsigned char)100); - if (saved_on == 255) - save_value(dnr_on_path, (unsigned char)1); - } else if (saved_dnr == 0) { - g_dnr_strength = 100; - dnr_strength_saved = 100; - g_dnr_on = 0; - flag_aidenoise_onoff = 0; - save_value(dnr_strength_path, (unsigned char)100); - save_value(dnr_on_path, (unsigned char)0); - } else if (saved_dnr <= 100) { - g_dnr_strength = saved_dnr; - dnr_strength_saved = saved_dnr; - if (saved_on == 0) { - g_dnr_on = 0; - flag_aidenoise_onoff = 0; - } else { - g_dnr_on = 1; - flag_aidenoise_onoff = 1; - if (saved_on == 255) - save_value(dnr_on_path, (unsigned char)1); - } - } else { - g_dnr_strength = 100; - dnr_strength_saved = 100; - g_dnr_on = 1; - flag_aidenoise_onoff = 1; - save_value(dnr_strength_path, (unsigned char)100); - save_value(dnr_on_path, (unsigned char)1); - } - debug_printf("Loaded dnr from flash: strength=%d saved=%d on=%d key_onoff=%d\n", - g_dnr_strength, dnr_strength_saved, g_dnr_on, flag_aidenoise_onoff); - } - - // 从Flash恢复mic_mute状态(默认关闭=未静音) - unsigned char saved_mic_mute = load_value(mic_mute_path); - if(saved_mic_mute == 1) - flag_mic_mute = 1; - else { - flag_mic_mute = 0; - if(saved_mic_mute == 255) - save_value(mic_mute_path, (unsigned char)0); - } - debug_printf("Loaded mic_mute from flash: %d\n", flag_mic_mute); - - // 从Flash恢复hp_mute状态(默认关闭=未静音) - unsigned char saved_hp_mute = load_value(hp_mute_path); - if(saved_hp_mute == 1) - flag_hp_mute = 1; - else { - flag_hp_mute = 0; - if(saved_hp_mute == 255) - save_value(hp_mute_path, (unsigned char)0); - } - debug_printf("Loaded hp_mute from flash: %d\n", flag_hp_mute); - } - - codec_init(); - // 同步全局音量变量与从Flash恢复的dac_level / codec_adc_pga_gain_reg_value - g_volume_level = dac_level; - // 麦克风HID范围上限37 (register=38的+1.5dB仅firmware内部使用) - g_mic_volume_level = (codec_adc_pga_gain_reg_value <= 37) ? codec_adc_pga_gain_reg_value : 37; - - // ADCL PGA default setting(mic_volume内部已根据g_monitor_switch决定是否启用耳返通路) - // 若mic_mute已从flash恢复为1,则此处先以正常gain调用,再用mute覆盖 - mic_volume(codec_adc_pga_gain_reg_value); - { - int mic_led_count = flag_mic_mute ? 15 : mic_gain_to_led[codec_adc_pga_gain_reg_value]; - for(int i = 0; i < 15; i++) - { - if (i < mic_led_count) - led_on(&led_ctx, led_l_physical_map[i]); - else - led_off(&led_ctx, led_l_physical_map[i]); - } - } - // 应用从flash恢复的mic_mute状态 - if(flag_mic_mute) { - mic_volume(0); - g_mic_volume_level = 0; - mic_mute_blink_tick = 1; - } - - // 硬件耳返通路已禁用,改为数字监听(在tile1 UserBufferManagement中实现) - // 初始化同步在上方已通过 cc_mic_level <: 0xFE 完成 - - // DAC 默认音量(mute 时写 0x0000) - if(dac_level == DAC_LEVEL_MIN) - unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); } - else - dac_volume(dac_level - DAC_LEVEL_MAX); - { - int dac_led_count = flag_hp_mute ? 15 : dac_gain_to_led[dac_level]; - for(int i = 0; i < 15; i++) - { - if (i < dac_led_count) - led_on(&led_ctx, led_d_physical_map[i]); - else - led_off(&led_ctx, led_d_physical_map[i]); - } - } - // 应用从flash恢复的hp_mute状态 - if(flag_hp_mute) { - unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); } - g_volume_level = 0; - hp_mute_blink_tick = 1; - } - // Initialize mode button LEDs: at most one may be lit at a time - led_off(&led_ctx, LED_MUSIC); - led_off(&led_ctx, LED_GAME_MODE); - led_off(&led_ctx, LED_AI7_1); - switch (active_mode) { - case 1: led_on(&led_ctx, LED_MUSIC); break; - case 2: led_on(&led_ctx, LED_GAME_MODE); break; - case 3: led_on(&led_ctx, LED_AI7_1); break; - default: break; - } - led_update_all(&led_ctx); - - - unsigned hidData0; - delay_milliseconds(200); - - debug_printf("button task start\n"); - - - { - cc_mic_level <: 0xFC; - cc_mic_level <: active_mode; - debug_printf("Sent sound_effect_mode %d to hid_button_task\n", active_mode); - } - -#if USE_EX3D == 1 - // 发送初始脚步增强expand_gain到tile1 - { - cc_mic_level <: 0xFD; - cc_mic_level <: (unsigned) saved_footstep; - debug_printf("set init expand_gain %d to hid_button_task\n", saved_footstep); - } - - // 加载枪声阈值并同步到tile1 - // 存储格式: -threshold (0~35, 0=threshold=0dB), 255=未初始化 - { - unsigned char lmt_thresh_path[] = "lmt_thresh"; - unsigned char raw = load_value(lmt_thresh_path); - int init_threshold; - if (raw == 255) { - // 未初始化,使用默认值-15 - init_threshold = -15; - save_value(lmt_thresh_path, (unsigned char)15); - } else if (raw <= 36) { - // raw=0~35 全部有效: 0=threshold=0dB(不限幅), 35=threshold=-35dB(最大限幅) - init_threshold = -(int)(raw - 1); - } else { - init_threshold = -15; - } - cc_mic_level <: 0xFA; - cc_mic_level <: (unsigned)init_threshold; - debug_printf("Loaded lmt_threshold=%d from flash (raw=%d), sent to tile1\n", init_threshold, raw); - } - - // 同步EX3D角度到tile1 - { - cc_mic_level <: 0xF9; - for (int i = 0; i < EX3D_ANGLE_CHANNELS; ++i) { - cc_mic_level <: g_hid_angle_values[i]; - debug_printf("angle[%d] = %d\n", i, g_hid_angle_values[i]); - } - } - - // 恢复脚步增强LED初始状态 - if (flag_footsteps_enhancement == 1) { - led_on(&led_ctx, LED_FOOTSTEP_MODE); - led_update_all(&led_ctx); - } else if (flag_footsteps_enhancement == 2) { - led_set_brightness(&led_ctx, LED_FOOTSTEP_MODE, 128); - led_update_all(&led_ctx); - } -#endif - - // 初始化数字监听开关同步到tile1 - cc_mic_level <: 0xFE; - cc_mic_level <: (unsigned)g_monitor_switch; - debug_printf("Init monitor sync: sw=%d\n", g_monitor_switch); - - // 出厂默认:AI降噪由g_dnr_on决定,关时强度变量仍保留供再次开启 -#if DNR_ENABLE == 1 - if (g_dnr_on) { - led_on(&led_ctx, LED_ANC); - led_update_all(&led_ctx); - dnr_set_mode(1); - dnr_set_strength_level((unsigned char)g_dnr_strength); - } else { - led_off(&led_ctx, LED_ANC); - led_update_all(&led_ctx); - dnr_set_mode(1); - dnr_set_strength_level(DNR_STRENGTH_off); - } -#endif - - // port_enable(p_ctrl_keys); - port_ctrl_keys = 0;//port_in(p_ctrl_keys); - if ((port_ctrl_keys & KEY_MUTE) == 0) { - // mute switch off (unmuted) - debug_printf("unmuted\n"); - isMute = 0; - SET_SHARED_GLOBAL(g_mute_on_off_t0, MUTE_OFF); // 初始化tile0静音状态 - } else { - // mute switch on (muted) - debug_printf("muted\n"); - isMute = 1; - SET_SHARED_GLOBAL(g_mute_on_off_t0, MUTE_ON); // 初始化tile0静音状态 - } - - last_ctrl_keys = ((port_ctrl_keys) & KEY_BITS); - last_ctrl_keys ^= KEY_MUTE; - - - // 启动时若两键同时按住,设置抑制标志,必须松开后才允许触发出厂恢复 - { - unsigned music_init, game_init; - p_button_music_mode :> music_init; - p_button_game_mode :> game_init; - if (music_init == 0 && game_init == 0) { - fr_inhibit = 1; - btn_combo_active = 1; - debug_printf("Boot: both keys held, FR inhibited until release\n"); - } - } - - //hwtimer_set_trigger_time(timer, hwtimer_get_time(timer) + KEY_POLLING_INTERVAL); - tmr :> time; /* Input the time */ - time += TIMER_PERIOD; /* Increment the time */ - - g_windows_detect_done = 1; - while (1) { - select - { - case c_hidSendData :> hidData0: - { - if (hidData0 == 0xffffffff) { - debug_printf("receive end data\n"); - - // 注意:UAC1模式下不会收到此命令(hid_button_task不发送) - // 读取当前g_game_mode值 - unsigned current_mode;// = chan_in_word(c_hidSendData); - c_hidSendData :> current_mode; - - - // 循环切换模式:0(STEREO_2K) -> 1(SPATIAL_GAME) -> 2(SPATIAL_MOVIE) -> 3(无音效) -> 0 - unsigned new_mode; - unsigned mode_flag; - debug_printf("current_mode: %d\n", current_mode); - if (current_mode == 0) { - // 当前是STEREO_2K,切换到STEREO_2K - new_mode = 1; -#if IR_SWITCHING_MODE - mode_flag = IR_GAME; -#else - // mode_flag = MODE_STEREO_2K; -#endif - debug_printf("Switching from STEREO_2K (0) to STEREO_2K (1)\n"); - } else if (current_mode == 1) { - // 当前是STEREO_2K,切换到SPATIAL_GAME - new_mode = 2; -#if IR_SWITCHING_MODE - mode_flag = IR_7_1_GAME; -#else - // mode_flag = MODE_SPATIAL_GAME; -#endif - debug_printf("Switching from STEREO_2K (1) to SPATIAL_GAME (2)\n"); - } else if (current_mode == 2) { - // 当前是SPATIAL_GAME,切换到SPATIAL_MOVIE - new_mode = 3; -#if IR_SWITCHING_MODE - mode_flag = IR_7_1_MOVIE; -#else - // mode_flag = MODE_SPATIAL_MOVIE; // SPATIAL_MOVIE模式使用SPATIAL_MOVIE固件 -#endif - debug_printf("Switching from SPATIAL_GAME (2) to SPATIAL_MOVIE (3)\n"); - } // 更新g_game_mode - else if(current_mode == 3) { - new_mode = 0; -#if IR_SWITCHING_MODE - mode_flag = IR_OFF; -#else - // mode_flag = MODE_STEREO_2K; -#endif - debug_printf("Switching from SPATIAL_MOVIE (3) to STEREO_2K (0)\n"); - } - - - unsigned char path[] = "game_mode"; - save_value(path, (unsigned char)new_mode); - debug_printf("Saved game_mode %d to flash\n", new_mode); - delay_milliseconds(20); - - - // 只有在需要切换固件时才reboot,同一固件内的模式切换(如0<->1)只更新模式和算法状态 -#if !UAC1_MODE - -#if IR_SWITCHING_MODE - debug_printf("Same firmware mode (0x%04X), updating mode and algorithm state without reboot\n", mode_flag); - SET_SHARED_GLOBAL(g_game_mode, new_mode); - //chan_out_byte(cc_mic_level, 0xFC); // 音频模式传输命令 - //chan_out_byte(cc_mic_level, new_mode); // 音频模式值 - cc_mic_level <: 0xFC; - cc_mic_level <: new_mode; - debug_printf("Sent audio_mode %d to hid_button_task via cc_mic_level channel\n", new_mode); -#else - if (new_mode != 1) { - - debug_printf("Set role switch flag: 0x%04X, switching firmware, rebooting...\n", mode_flag); - SetRoleSwitchFlag(mode_flag); - delay_milliseconds(20); -#ifndef DISABLE_REBOOT - device_reboot(); - while (1); -#endif - } else { - - debug_printf("Same firmware mode (0x%04X), updating mode and algorithm state without reboot\n", mode_flag); - SET_SHARED_GLOBAL(g_game_mode, new_mode); - - // chan_out_byte(cc_mic_level, 0xFC); // 音频模式传输命令 - // chan_out_byte(cc_mic_level, new_mode); // 音频模式值 - cc_mic_level <: 0xFC; - cc_mic_level <: new_mode; - debug_printf("Sent audio_mode %d to hid_button_task via cc_mic_level channel\n", new_mode); - } -#endif -#endif - break; - } - -#if HID_DFU_EN - if (!g_in_fw_upgrade) -#endif - { -#if (HID_CONTROLS == 1) - unsigned *reportData = hidSendData; - reportData[0] = hidData0; - for (int i=1; i<(HID_MAX_DATA_BYTES/4); i++) { - c_hidSendData :> reportData[i]; - } - hidSetChangePending(1); -#endif - } - break; - } - - case c_audiohw_rx :> unsigned new_samfreq: - { - // 采样率变化通知,来自AudioHwConfig (tile[1]),通过uc_audiohw专用通道传递 - unsigned new_dsd_mode; - c_audiohw_rx :> new_dsd_mode; - debug_printf("SampRate->tile0: %uHz dsd=%u\n", new_samfreq, new_dsd_mode); - - unsafe { -#if !UAC1_MODE - switch (new_samfreq) { - case 192000: - case 176400: - NAU88C22_REGWRITE(0x0003, 0x00D0, (client interface i2c_master_if)i_i2c_client); - NAU88C22_REGWRITE(0x002B, 0x4000, (client interface i2c_master_if)i_i2c_client); - - NAU88C22_REGWRITE(0x002C, 0x0082, (client interface i2c_master_if)i_i2c_client); - break; - case 96000: - case 88200: - NAU88C22_REGWRITE(0x0003, 0x0092, (client interface i2c_master_if)i_i2c_client); - NAU88C22_REGWRITE(0x002B, 0x4001, (client interface i2c_master_if)i_i2c_client); - NAU88C22_REGWRITE(0x002C, 0x0082, (client interface i2c_master_if)i_i2c_client); - break; - case 44100: - case 48000: - default: - NAU88C22_REGWRITE(0x0003, 0x0053, (client interface i2c_master_if)i_i2c_client); - NAU88C22_REGWRITE(0x002B, 0x4002, (client interface i2c_master_if)i_i2c_client); - NAU88C22_REGWRITE(0x002C, 0x0082, (client interface i2c_master_if)i_i2c_client); - break; - } -#endif -#if 0 - unsigned val; - - NAU88C22_REGREAD(0x0003, val, (client interface i2c_master_if)i_i2c_client); - debug_printf("NAU88C22_REGREAD(0x0003): 0x%08x\n", val); - NAU88C22_REGREAD(0x002B, val, (client interface i2c_master_if)i_i2c_client); - debug_printf("NAU88C22_REGREAD(0x002B): 0x%08x\n", val); - NAU88C22_REGREAD(0x002C, val, (client interface i2c_master_if)i_i2c_client); - debug_printf("NAU88C22_REGREAD(0x002C): 0x%08x\n", val); -#endif - } - c_audiohw_rx <: 0xff; - -#if HID_CONTROLS > 0 -#if HID_DFU_EN - if (!g_in_fw_upgrade) -#endif - { - unsafe { - unsigned char * unsafe ptr = (unsigned char * unsafe)hidSendData; - ptr[0] = 1; - ptr[1] = 0x77; - ptr[2] = 0x9F; - ptr[3] = (unsigned char)(new_samfreq & 0xFF); - ptr[4] = (unsigned char)((new_samfreq >> 8) & 0xFF); - ptr[5] = (unsigned char)((new_samfreq >> 16) & 0xFF); - ptr[6] = (unsigned char)((new_samfreq >> 24) & 0xFF); - ptr[7] = (unsigned char)new_dsd_mode; - for (int i = 8; i < HID_MAX_DATA_BYTES; i++) - ptr[i] = 0x00; - } - hidSetChangePending(0x1); - } -#endif - break; - } - -#if HID_DFU_EN - case c_dfu_rx :> unsigned dfu_first_word: - { - // 接收来自tile[1] hid_button_task转发的固件升级START命令(16个word) - unsigned dfu_words[16]; - dfu_words[0] = dfu_first_word; - for (int i = 1; i < 16; i++) - c_dfu_rx :> dfu_words[i]; - unsigned char cmd_buf[63]; - for (int i = 0; i < 63; i++) - cmd_buf[i] = (dfu_words[i / 4] >> ((i % 4) * 8)) & 0xFF; - if (cmd_buf[1] == FIRMWARE_UPGRADE_START) - handle_firmware_upgrade_start(cmd_buf, 63); - break; - } -#endif - - case c_mic_det :> unsigned mic_det_cmd: - { - if (mic_det_cmd == MIC_DET_MUTE) { - mic_det_muted = 1; - // 仅mute硬件,不改变g_mic_volume_level和LED - mic_volume(0); - debug_printf("mic_det: mute (det)\n"); - } else if (mic_det_cmd == MIC_DET_UNMUTE) { - mic_det_muted = 0; - // 恢复音量,但如果用户手动mute了则不恢复 - if (!flag_mic_mute) { - mic_volume(codec_adc_pga_gain_reg_value); - debug_printf("mic_det: unmute -> pga=%d\n", codec_adc_pga_gain_reg_value); - } - } else if (mic_det_cmd == MIC_DET_DAC_MUTE) { - dac_det_muted = 1; - // mute DAC硬件,不改变dac_level/g_volume_level和LED - unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); } - debug_printf("mic_det: dac mute\n"); - } else if (mic_det_cmd == MIC_DET_DAC_UNMUTE) { - dac_det_muted = 0; - // 恢复DAC音量,但如果用户手动hp_mute或dac_level==0则不恢复 - if (!flag_hp_mute && dac_level > DAC_LEVEL_MIN) { - dac_volume(dac_level - DAC_LEVEL_MAX); - debug_printf("mic_det: dac unmute -> level=%d\n", dac_level); - } - } - break; - } - - case tmr when timerafter(time) :> void : - { - //hwtimer_change_trigger_time(timer, hwtimer_get_time(timer) + KEY_POLLING_INTERVAL); - time += TIMER_PERIOD; - - - //hidData0 = 0; - -// port_t p_button_music_mode = PORT_BUTTON_MUSIC_MODE; -// port_t p_button_game_mode = PORT_BUTTON_GAME_MODE; -// port_t p_button_ai71_onoff = PORT_BUTTON_AI71_ONOFF; - -//p_button_music_mode :> button_music_mode; // 1A - - unsigned mic_encoder1, mic_encoder2, hp_encoder; - unsigned button_mic_mute, button_hp_mute; - unsigned button_music_mode, button_ai71_onoff, button_game_mode, button_footsteps_enhancement, button_aidenoise_onoff; - unsigned mode_change = 0; - - //button_music_mode = port_in(p_button_music_mode); - p_button_music_mode :> button_music_mode; // 1A - p_button_game_mode :> button_game_mode; // 1L - p_button_ai71_onoff :> button_ai71_onoff; // 1M - - p_mic_gain_encoder1 :> mic_encoder1; // 4F2 - p_mic_gain_encoder2 :> mic_encoder2; // 4E2 - - button_mic_mute = ((mic_encoder1 & 0b1000) != 0); // 4F3 - //button_hp_mute = ((hp_encoder & 0b01000000) != 0); // 8D6 - - button_footsteps_enhancement = ((mic_encoder1 & 0b0010) != 0); // 4F1 - button_aidenoise_onoff = ((mic_encoder2 & 0b1000) != 0); // 4E3 - - // --- Mode button handling --- - // active_mode: 0=off, 1=music, 2=game (IR_GAME), 3=AI7.1 (IR_7_1_GAME) - // - // Boot chain: power-on → F5 → OS detect → route to F1/F3/F4/F5/F6/F7 - // - // Music-only firmware (F1, F5): USE_EX3D not set - // Music btn: toggle LED locally (no reboot) - // Game/AI7.1 btn: save mode + reboot (F5 will route to FPS firmware) - // - // FPS firmware (F3/F4, F6/F7): USE_EX3D set - // Music btn: save mode=1 + reboot (F5 will route to music firmware) - // Game/AI7.1 btn: switch IR algorithm locally (no reboot) - - unsigned mode_btn_change = 0; - unsigned need_reboot = 0; - - // --- Music + Game 按键:组合检测 + 去抖 --- - // 两键同时按住3秒 → 出厂恢复;单键需持续 BTN_COMBO_DELAY_TICKS 后生效 - // (50ms 窗口内若另一键也按下则进入组合模式,单键动作取消) - { - int music_is_down = (button_music_mode == 0); - int game_is_down = (button_game_mode == 0); - int factory_combo_is_down = ( music_is_down && game_is_down); - - // 更新各键连续按住计数(断开则清零,用于去抖和窗口判断) - if (music_is_down && !factory_combo_is_down) - { - if (btn_music_hold_ticks < 0xFFFFu) btn_music_hold_ticks++; - debug_printf("btn_music_hold_ticks=%d\n", btn_music_hold_ticks); - } - else - { - btn_music_hold_ticks = 0; - } - if (game_is_down && !factory_combo_is_down) - { - if (btn_game_hold_ticks < 0xFFFFu) - { - btn_game_hold_ticks++; - } - debug_printf("btn_game_hold_ticks=%d\n", btn_game_hold_ticks); - } - else - { - btn_game_hold_ticks = 0; - } - - // 场景1:两键同时按住(参照 fosi_ds1 else-if 结构) - if (factory_combo_is_down) { - btn_combo_active = 1; // 粘性锁定 - // fr_inhibit=1 时(出厂恢复重启后):不计时,必须松键后重新按下才触发 - if (factory_reset_blink_state == 0 && !fr_inhibit) { - factory_reset_hold_count++; - if (factory_reset_hold_count >= FACTORY_RESET_HOLD_TICKS) { - factory_reset_hold_count = 0; - factory_reset_blink_state = 1; - factory_reset_blink_tick = 0; - // 清除所有Flash设置并重启 - debug_printf("Factory reset: clearing flash " - "and rebooting\n"); - unsafe { - lfs_format_all(); - } - - led_on(&led_ctx, LED_MUSIC); - led_on(&led_ctx, LED_ANC); - led_on(&led_ctx, LED_FOOTSTEP_MODE); - led_on(&led_ctx, LED_AI7_1); - led_on(&led_ctx, LED_GAME_MODE); - led_update_all(&led_ctx); - debug_printf("Factory reset: 3s hold detected, starting blink\n"); - } - } - } - // 场景2:仅 Music 按住 - else if (music_is_down) { - factory_reset_hold_count = 0; - if (!btn_combo_active) { - if (btn_music_hold_ticks == BTN_COMBO_DELAY_TICKS) { - debug_printf("Music button pressed for %d ticks\n", BTN_COMBO_DELAY_TICKS); -#if (F3_F4_FPS_UAC2 == 1) - active_mode = 1; - need_reboot = 1; - SetRoleSwitchFlag(MODE_F1_MUSIC_UAC2); -#elif (F6_F7_FPS_UAC1 == 1) - // UAC1 FPS firmware: music needs F5, reboot if not already music - if (active_mode != 1) { - active_mode = 1; - need_reboot = 1; - SetRoleSwitchFlag(MODE_F5_MUSIC_UAC1); - } -#elif (F5_MUSIC_UAC1 == 1) - // UAC1 Music firmware: already on music FW, toggle locally - if (active_mode != 1) { - active_mode = 1; - mode_btn_change = 1; - } -#else - if (active_mode != 1) { - active_mode = 1; - mode_btn_change = 1; - } -#endif - } - } - } - // 场景3:仅 Game 按住 - else if (game_is_down) { - factory_reset_hold_count = 0; - if (!btn_combo_active) { - if (btn_game_hold_ticks == BTN_COMBO_DELAY_TICKS) { - debug_printf("Game button pressed for %d ticks\n", BTN_COMBO_DELAY_TICKS); -#if F1_MUSIC_UAC2 == 1 - active_mode = 2; - need_reboot = 1; - SetRoleSwitchFlag(MODE_F3_F4_FPS_UAC2); -#elif (F5_MUSIC_UAC1 == 1) - // UAC1 Music firmware: game needs F6/F7, reboot if not already game - if (active_mode != 2) { - active_mode = 2; - need_reboot = 1; - SetRoleSwitchFlag(MODE_F6_F7_FPS_UAC1); - } -#elif (F6_F7_FPS_UAC1 == 1) - // UAC1 FPS firmware: already on FPS FW, switch locally (IR_OFF) - if (active_mode != 2) { - active_mode = 2; - mode_btn_change = 1; - } -#else - if (active_mode != 2) { - active_mode = 2; - mode_btn_change = 1; - } -#endif - } - } - } - // 场景4:两键全松开 → 解除组合锁定及抑制标志 - else { - factory_reset_hold_count = 0; - btn_combo_active = 0; - fr_inhibit = 0; // 松键后允许下次同时按下重新触发出厂恢复 - } - } - - if (button_ai71_onoff == 0) { - if (push_button_ai71_onoff_state_old == 1) { -#if (F1_MUSIC_UAC2 == 1) - // Music-only firmware: AI7.1 needs FPS firmware - active_mode = 3; - need_reboot = 1; - SetRoleSwitchFlag(MODE_F3_F4_FPS_UAC2); -#elif (F5_MUSIC_UAC1 == 1) - // UAC1 Music firmware: AI71 needs F6/F7 FPS, reboot if not already AI71 - if (active_mode != 3) { - active_mode = 3; - need_reboot = 1; - SetRoleSwitchFlag(MODE_F6_F7_FPS_UAC1); - } -#elif (F6_F7_FPS_UAC1 == 1) - // UAC1 FPS firmware: already on FPS FW, switch locally (IR_GAME) - if (active_mode != 3) { - active_mode = 3; - mode_btn_change = 1; - } -#else - // FPS firmware: switch algorithm locally (activate if not already) - if (active_mode != 3) { - active_mode = 3; - mode_btn_change = 1; - } -#endif - } - } - push_button_ai71_onoff_state_old = button_ai71_onoff; - - // 处理HID SET_SOUND_EFFECT_MODE (0xA4) 请求,等同于按键效果 - if (!mode_btn_change && !need_reboot) { - unsigned hid_req_mode; - GET_SHARED_GLOBAL(hid_req_mode, g_request_game_mode); - if (hid_req_mode != (unsigned)-1) { - SET_SHARED_GLOBAL(g_request_game_mode, (unsigned)-1); - unsigned target = (hid_req_mode <= 3) ? hid_req_mode : 0; -#if (F3_F4_FPS_UAC2 == 1) - if (target == 1) { - active_mode = target; - need_reboot = 1; - SetRoleSwitchFlag(MODE_F1_MUSIC_UAC2); - } else { - active_mode = target; - mode_btn_change = 1; - } -#elif (F1_MUSIC_UAC2 == 1) - if (target >= 2) { - active_mode = target; - need_reboot = 1; - SetRoleSwitchFlag(MODE_F3_F4_FPS_UAC2); - } else { - active_mode = target; - mode_btn_change = 1; - } -#elif (F5_MUSIC_UAC1 == 1) - // UAC1 Music FW: mode 1 local, mode 2/3 need F6/F7 reboot - if (target >= 2) { - active_mode = target; - need_reboot = 1; - SetRoleSwitchFlag(MODE_F6_F7_FPS_UAC1); - } else if (target != active_mode) { - active_mode = target; - mode_btn_change = 1; - } -#elif (F6_F7_FPS_UAC1 == 1) - // UAC1 FPS FW: mode 2/3 local, mode 1 needs F5 reboot - if (target <= 1) { - active_mode = target; - need_reboot = 1; - SetRoleSwitchFlag(MODE_F5_MUSIC_UAC1); - } else if (target != active_mode) { - active_mode = target; - mode_btn_change = 1; - } -#else - active_mode = target; - mode_btn_change = 1; -#endif - } - } - - if (mode_btn_change || need_reboot) { - // Always persist mode to flash so boot chain restores it - { - unsigned char save_path[] = "game_mode"; - save_value(save_path, (unsigned char)active_mode); - } - - if (need_reboot) { - // Reboot: F5 will re-detect OS and route to correct firmware - debug_printf("Mode %d requires firmware switch, rebooting\n", active_mode); - delay_milliseconds(200); -#ifndef DISABLE_REBOOT - device_reboot(); - while (1); -#endif - } - - // Local update path (no reboot): update LEDs and DSP algorithm - led_off(&led_ctx, LED_MUSIC); - led_off(&led_ctx, LED_GAME_MODE); - led_off(&led_ctx, LED_AI7_1); - switch (active_mode) { - case 1: led_on(&led_ctx, LED_MUSIC); break; - case 2: led_on(&led_ctx, LED_GAME_MODE); break; - case 3: led_on(&led_ctx, LED_AI7_1); break; - default: break; - } - led_update_all(&led_ctx); - - // Always update g_game_mode so 0xA5 reads correctly - SET_SHARED_GLOBAL(g_game_mode, active_mode); -#if USE_EX3D == 1 - { - // sound_effect_mode: 0=无音效, 1=音乐, 2=游戏, 3=AI7.1 - cc_mic_level <: 0xFC; - cc_mic_level <: active_mode; - debug_printf("Mode changed: active_mode=%d\n", active_mode); - } -#endif - } - - // 出厂恢复闪烁状态机:5个按键LED闪3次后清除Flash并重启 - if (factory_reset_blink_state > 0) { - factory_reset_blink_tick++; - if (factory_reset_blink_tick >= FACTORY_RESET_BLINK_TICKS) { - factory_reset_blink_tick = 0; - factory_reset_blink_state++; - if (factory_reset_blink_state > 6) { -#if 1 - // 3次闪烁完成:恢复原始LED显示 - factory_reset_blink_state = 0; - led_off(&led_ctx, LED_MUSIC); - led_off(&led_ctx, LED_ANC); - led_off(&led_ctx, LED_FOOTSTEP_MODE); - led_off(&led_ctx, LED_AI7_1); - led_off(&led_ctx, LED_GAME_MODE); - switch (active_mode) { - case 1: led_on(&led_ctx, LED_MUSIC); break; - case 2: led_on(&led_ctx, LED_GAME_MODE); break; - case 3: led_on(&led_ctx, LED_AI7_1); break; - default: break; - } - if (flag_footsteps_enhancement == 1) led_on(&led_ctx, LED_FOOTSTEP_MODE); - else if (flag_footsteps_enhancement == 2) led_set_brightness(&led_ctx, LED_FOOTSTEP_MODE, 128); - if (flag_aidenoise_onoff) led_on(&led_ctx, LED_ANC); - led_update_all(&led_ctx); - // 等待松键,防止重启后再次触发出厂恢复循环 - { - unsigned mw, gw; - do { - delay_milliseconds(10); - p_button_music_mode :> mw; - p_button_game_mode :> gw; - } while (mw == 0 || gw == 0); - delay_milliseconds(100); - } -#endif - // 出厂恢复默认AI7.1模式(mode=3),需要F3/F4固件 - SetRoleSwitchFlag(MODE_F3_F4_FPS_UAC2); - delay_milliseconds(20); -#ifndef DISABLE_REBOOT - device_reboot(); - while (1); -#endif - } else if (factory_reset_blink_state % 2 == 0) { - // 偶数相:全灭 - led_off(&led_ctx, LED_MUSIC); - led_off(&led_ctx, LED_ANC); - led_off(&led_ctx, LED_FOOTSTEP_MODE); - led_off(&led_ctx, LED_AI7_1); - led_off(&led_ctx, LED_GAME_MODE); - led_update_all(&led_ctx); - delay_milliseconds(200); - } else { - // 奇数相:全亮 - led_on(&led_ctx, LED_MUSIC); - led_on(&led_ctx, LED_ANC); - led_on(&led_ctx, LED_FOOTSTEP_MODE); - led_on(&led_ctx, LED_AI7_1); - led_on(&led_ctx, LED_GAME_MODE); - led_update_all(&led_ctx); - delay_milliseconds(200); - } - } - } - -#if USE_EX3D == 1 - mode_change = 0; - if(button_footsteps_enhancement == 0) - { - if(push_button_footsteps_enhancement_state_old == 1) - { - // 3档循环: 0(关/0dB) → 1(中亮/6dB) → 2(高亮/12dB) → 0 - flag_footsteps_enhancement = (flag_footsteps_enhancement + 1) % 3; - mode_change = 1; - debug_printf("Footstep mode changed: %d -> %d\n", flag_footsteps_enhancement, flag_footsteps_enhancement + 1); - } - } - push_button_footsteps_enhancement_state_old = button_footsteps_enhancement; - if(mode_change) - { - if(flag_footsteps_enhancement == 0) - { - saved_footstep = 0; - led_off(&led_ctx, LED_FOOTSTEP_MODE); - } - else if(flag_footsteps_enhancement == 1) - { - saved_footstep = 6; - led_on(&led_ctx, LED_FOOTSTEP_MODE); - } - else - { - saved_footstep = 12; - led_set_brightness(&led_ctx, LED_FOOTSTEP_MODE, 128); - } - led_update_all(&led_ctx); - // 发送expand_gain到tile1执行 - cc_mic_level <: 0xFD; - cc_mic_level <: (unsigned)saved_footstep; - // 掉电保存 - unsigned char footstep_path[] = "footstep"; - save_value(footstep_path, (unsigned char)saved_footstep); - debug_printf("Footstep state=%d, expand_gain=%d\n", flag_footsteps_enhancement, saved_footstep); - } - - // HID 0xB0 CMD_EXPAND_GAIN请求:同步footstep LED状态 - { - unsigned hid_gain_req; - GET_SHARED_GLOBAL(hid_gain_req, g_hid_expand_gain_request); - if (hid_gain_req != (unsigned)-1) { - SET_SHARED_GLOBAL(g_hid_expand_gain_request, (unsigned)-1); - // 将增益值映射到footstep档位 - unsigned new_state; - if (hid_gain_req == 0) { - new_state = 0; - } else if (hid_gain_req <= 6) { - new_state = 1; - } else { - new_state = 2; - } - if (new_state != (unsigned)flag_footsteps_enhancement) { - flag_footsteps_enhancement = (int)new_state; - if (flag_footsteps_enhancement == 0) { - led_off(&led_ctx, LED_FOOTSTEP_MODE); - } else if (flag_footsteps_enhancement == 1) { - led_on(&led_ctx, LED_FOOTSTEP_MODE); - } else { - led_set_brightness(&led_ctx, LED_FOOTSTEP_MODE, 128); - } - led_update_all(&led_ctx); - } - - unsigned char fp[] = "footstep"; - save_value(fp, (unsigned char)hid_gain_req); - saved_footstep = hid_gain_req; - debug_printf("HID set footstep gain=%d, state=%d\n", hid_gain_req, flag_footsteps_enhancement); - } - } - - // HID 0xB0 CMD_LMT_THRESHOLD请求:保存阈值到flash - // eq.c以(-threshold+1)编码存入shared global,范围1~36;此处解码后存flash (0~35) - { - unsigned hid_thresh_req; - GET_SHARED_GLOBAL(hid_thresh_req, g_hid_lmt_threshold_request); - if (hid_thresh_req != (unsigned)-1) { - SET_SHARED_GLOBAL(g_hid_lmt_threshold_request, (unsigned)-1); - if (hid_thresh_req >= 1 && hid_thresh_req <= 36) { - unsigned char lmt_thresh_path[] = "lmt_thresh"; - unsigned char flash_raw = (unsigned char)(hid_thresh_req - 1); - save_value(lmt_thresh_path, flash_raw); - debug_printf("HID set lmt_threshold=-%d, saved to flash\n", (int)(hid_thresh_req - 1)); - } - } - } - - // HID 0xB0 CMD_ANGLE请求:保存角度到flash - { - for (int i = 0; i < EX3D_ANGLE_CHANNELS; ++i) - { - // 改动原因:按用户要求去掉normalize,直接比较并保存原始角度值,减少计算分支。 - unsigned angle = g_hid_angle_values[i]; - if (angle != g_hid_angle_values_old[i]) - { - ex3d_angle_save_channel(i, angle); - g_hid_angle_values_old[i] = angle; - } - } - } -#endif - - mode_change = 0; - if(button_aidenoise_onoff == 0) - { - if(push_button_aidenoise_onoff_state_old == 1) - { - flag_aidenoise_onoff ^= 1; - mode_change = 1; - } - } - push_button_aidenoise_onoff_state_old = button_aidenoise_onoff; -#if DNR_ENABLE == 1 - if(mode_change) { - if(flag_aidenoise_onoff) - { - // 改动原因:开时应用当前保存的档位g_dnr_strength,不把强度全局量写成0 - unsigned gs_on; - GET_SHARED_GLOBAL(gs_on, g_dnr_strength); - led_on(&led_ctx, LED_ANC); - dnr_set_strength_level((unsigned char)gs_on); - SET_SHARED_GLOBAL(g_dnr_on, 1); - dnr_strength_saved = gs_on; - } - else - { - // 改动原因:关时只清开关与算法档位,保留g_dnr_strength供HID 0x86与再次开启 - led_off(&led_ctx, LED_ANC); - dnr_set_strength_level(DNR_STRENGTH_off); - SET_SHARED_GLOBAL(g_dnr_on, 0); - } - save_value(dnr_on_path, (unsigned char)flag_aidenoise_onoff); - { - unsigned gs_sv; - GET_SHARED_GLOBAL(gs_sv, g_dnr_strength); - save_value(dnr_strength_path, (unsigned char)gs_sv); - } - g_dnr_on = flag_aidenoise_onoff; - led_update_all(&led_ctx); - } -#endif - - // 检查HID 0x84 FACTORY_RESET请求 - { - unsigned factory_reset_req; - GET_SHARED_GLOBAL(factory_reset_req, g_request_factory_reset); - if (factory_reset_req) { - SET_SHARED_GLOBAL(g_request_factory_reset, 0); - debug_printf("Factory reset: rebooting...\n"); - unsafe { - lfs_format_all(); - } - delay_milliseconds(500); -#ifndef DISABLE_REBOOT - device_reboot(); - while (1); -#endif - } - } - - mode_change = 0; - if(button_mic_mute == 0) - { - if(push_button_mic_mute_state_old == 1) - { - flag_mic_mute ^= 1; - mode_change = 1; - } - } - push_button_mic_mute_state_old = button_mic_mute; - if(mode_change) - { - save_value(mic_mute_path, (unsigned char)flag_mic_mute); - debug_printf("mic_mute changed: %d, saved to flash\n", flag_mic_mute); - } - if(mode_change) - if(flag_mic_mute) - { - mic_volume(0); - g_mic_volume_level = 0; - for(int i = 0; i < 15; i++) - led_on(&led_ctx, led_l_physical_map[i]); - mic_mute_blink_tick = 1; - } - else - { - if (!mic_det_muted) - mic_volume(codec_adc_pga_gain_reg_value); - g_mic_volume_level = (codec_adc_pga_gain_reg_value <= 37) ? codec_adc_pga_gain_reg_value : 37; - mic_mute_blink_tick = 0; - for(int i = 0; i < 15; i++) - led_off(&led_ctx, led_l_physical_map[i]); - current_mic_led_pos = mic_gain_to_led[codec_adc_pga_gain_reg_value] - 1; - for(int i = 0; i <= current_mic_led_pos; i++) - { - if ((i < 15) && (i >= 0)) - led_on(&led_ctx, led_l_physical_map[i]); - } - } - uint8_t rotating = (mic_encoder2 & 0b0100) == 0; // 4E2 - uint8_t encode_input1 = ((mic_encoder1 & 0b0100) != 0); // 4F2 - - if(rotating) { - if(!rotation_active) { - // 旋转开始 - prev_encode_input1 = encode_input1; - sample_count = 1; - rotation_active = 1; - - // 根据上次方向预判 - if(fast_rotation_mode) { - // 快速模式只需要2次采样 - sample_count = 2; - } - } else { - sample_count++; - - // 动态调整采样次数:快速模式用2次,普通模式用3次 - uint8_t required_samples = fast_rotation_mode ? 2 : 3; - - if(sample_count >= required_samples) { - if(encode_input1 != prev_encode_input1) { - uint8_t current_dir = encode_input1 ? 1 : 2; - - // 执行音量调节 - if(current_dir == 1) { // 顺时针 - if((codec_adc_pga_gain_reg_value < NAU88L21_PGA_GAIN_REG_MAX_VALUE) && (flag_mic_mute == 0)) { - uint8_t old_led_count = mic_gain_to_led[codec_adc_pga_gain_reg_value]; - - ++codec_adc_pga_gain_reg_value; - - if (!mic_det_muted) - mic_volume(codec_adc_pga_gain_reg_value); - g_mic_volume_level = (codec_adc_pga_gain_reg_value <= 37) ? codec_adc_pga_gain_reg_value : 37; - debug_printf("volume up %d\n", codec_adc_pga_gain_reg_value); - save_value(mic_vol_path, codec_adc_pga_gain_reg_value); - uint8_t new_led_count = mic_gain_to_led[codec_adc_pga_gain_reg_value]; - - // 如果LED数增加,点亮新增的那个LED - if(new_led_count > old_led_count) { - // 新点亮的LED索引 = new_led_count - 1 - led_on(&led_ctx, led_l_physical_map[new_led_count - 1]); - led_update_all(&led_ctx); - } - } - } else { // 逆时针 - if((codec_adc_pga_gain_reg_value > 0) && (flag_mic_mute == 0)) { - uint8_t old_led_count = mic_gain_to_led[codec_adc_pga_gain_reg_value]; - - --codec_adc_pga_gain_reg_value; - - if (!mic_det_muted) { - if (codec_adc_pga_gain_reg_value == 0) - mic_volume(0); - else - mic_volume(codec_adc_pga_gain_reg_value); - } - g_mic_volume_level = (codec_adc_pga_gain_reg_value <= 37) ? codec_adc_pga_gain_reg_value : 37; - debug_printf("volume down %d\n", codec_adc_pga_gain_reg_value); - save_value(mic_vol_path, codec_adc_pga_gain_reg_value); - - uint8_t new_led_count = mic_gain_to_led[codec_adc_pga_gain_reg_value]; - - // 如果LED数减少,关闭减少的那个LED - if(new_led_count < old_led_count) { - // 关闭的LED索引 = old_led_count - 1 - led_off(&led_ctx, led_l_physical_map[old_led_count - 1]); - led_update_all(&led_ctx); - } - } - } - - // 检测是否快速旋转 - if(current_dir == last_valid_direction) { - consecutive_same_dir++; - if(consecutive_same_dir >= 3) { - fast_rotation_mode = 1; // 进入快速模式 - } - } else { - consecutive_same_dir = 0; - fast_rotation_mode = 0; // 方向变化,退出快速模式 - } - - last_valid_direction = current_dir; - rotation_active = 0; - sample_count = 0; - } - } - } - } else { - rotation_active = 0; - sample_count = 0; - // 停止旋转一段时间后退出快速模式 - static uint16_t idle_count = 0; - idle_count++; - if(idle_count > 50) { // 50ms无旋转 - fast_rotation_mode = 0; - consecutive_same_dir = 0; - idle_count = 0; - } - } - -#if 1 - // HP Encoder - p_hp_gain_encoder :> hp_encoder; // 8D4, 8D5 - - uint8_t hp_rotating = ((hp_encoder & 0b00100000) == 0); // 8D5 - uint8_t hp_encode_input1 = ((hp_encoder & 0b00010000) != 0); // 8D4 - - if(hp_rotating) { - if(!hp_rotation_active) { - // 旋转开始 - hp_prev_encode_input1 = hp_encode_input1; - hp_sample_count = 1; - hp_rotation_active = 1; - - // 根据上次方向预判 - if(hp_fast_rotation_mode) { - // 快速模式只需要2次采样 - hp_sample_count = 2; - } - } else { - hp_sample_count++; - - // 动态调整采样次数:快速模式用2次,普通模式用3次 - uint8_t hp_required_samples = hp_fast_rotation_mode ? 2 : 3; - - if(hp_sample_count >= hp_required_samples) { - if(hp_encode_input1 != hp_prev_encode_input1) { - uint8_t hp_current_dir = hp_encode_input1 ? 1 : 2; - - // 执行音量调节 - if(hp_current_dir == 1) { // 顺时针 - if(dac_level < DAC_LEVEL_MAX && flag_hp_mute == 0) { - uint8_t old_led_count = dac_gain_to_led[dac_level]; - - // 增加音量 - ++dac_level; - g_volume_level = dac_level; - if (!dac_det_muted) - dac_volume(dac_level - DAC_LEVEL_MAX); - save_value(dac_vol_path, dac_level); - - uint8_t new_led_count = dac_gain_to_led[dac_level]; - - // 如果LED数增加,点亮新增的那个LED - if(new_led_count > old_led_count) { - // 新点亮的LED索引 = new_led_count - 1 - led_on(&led_ctx, led_d_physical_map[new_led_count - 1]); - led_update_all(&led_ctx); - } - } - } else { // 逆时针 - if(dac_level > DAC_LEVEL_MIN && flag_hp_mute == 0) { - uint8_t old_led_count = dac_gain_to_led[dac_level]; - - // 减小音量 - --dac_level; - g_volume_level = dac_level; - if (!dac_det_muted) { - if(dac_level == DAC_LEVEL_MIN) - unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); } - else - dac_volume(dac_level - DAC_LEVEL_MAX); - } - save_value(dac_vol_path, dac_level); - - uint8_t new_led_count = dac_gain_to_led[dac_level]; - - // 如果LED数减少,关闭减少的那个LED - if(new_led_count < old_led_count) { - // 关闭的LED索引 = old_led_count - 1 - led_off(&led_ctx, led_d_physical_map[old_led_count - 1]); - led_update_all(&led_ctx); - } - } - } - - // 检测是否快速旋转 - if(hp_current_dir == hp_last_valid_direction) { - hp_consecutive_same_dir++; - if(hp_consecutive_same_dir >= 3) { - hp_fast_rotation_mode = 1; // 进入快速模式 - } - } else { - hp_consecutive_same_dir = 0; - hp_fast_rotation_mode = 0; // 方向变化,退出快速模式 - } - - hp_last_valid_direction = hp_current_dir; - hp_rotation_active = 0; - hp_sample_count = 0; - } - } - } - } else { - hp_rotation_active = 0; - hp_sample_count = 0; - // 停止旋转一段时间后退出快速模式 - static uint16_t hp_idle_count = 0; - hp_idle_count++; - if(hp_idle_count > 50) { // 50ms无旋转 - hp_fast_rotation_mode = 0; - hp_consecutive_same_dir = 0; - hp_idle_count = 0; - } - } - - button_hp_mute = ((hp_encoder & 0b01000000) != 0); // 8D6 - - mode_change = 0; - if(button_hp_mute == 0) - { - if(push_button_hp_mute_state_old == 1) - { - flag_hp_mute ^= 1; - mode_change = 1; - } - } - push_button_hp_mute_state_old = button_hp_mute; - if(mode_change) - { - save_value(hp_mute_path, (unsigned char)flag_hp_mute); - debug_printf("hp_mute changed: %d, saved to flash\n", flag_hp_mute); - } - if(mode_change) - if(flag_hp_mute) - { - unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); } - g_volume_level = 0; - for(int i = 0; i < 15; i++) - led_on(&led_ctx, led_d_physical_map[i]); - hp_mute_blink_tick = 1; - } - else - { - if (!dac_det_muted) { - if(dac_level == DAC_LEVEL_MIN) - unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); } - else - dac_volume(dac_level - DAC_LEVEL_MAX); - } - g_volume_level = dac_level; - hp_mute_blink_tick = 0; - for(int i = 0; i < 15; i++) - led_off(&led_ctx, led_d_physical_map[i]); - current_mic_led_pos = dac_gain_to_led[dac_level] - 1; - for(int i = 0; i <= current_mic_led_pos; i++) - { - if ((i < 15) && (i >= 0)) - led_on(&led_ctx, led_d_physical_map[i]); - } - } - - // mute blink: 250ms on / 250ms off - if(mic_mute_blink_tick > 0) - { - mic_mute_blink_tick++; - if(mic_mute_blink_tick >= MUTE_BLINK_HALF_PERIOD * 2) - mic_mute_blink_tick = 1; - if(mic_mute_blink_tick == 1) - for(int i = 0; i < 15; i++) led_on(&led_ctx, led_l_physical_map[i]); - else if(mic_mute_blink_tick == MUTE_BLINK_HALF_PERIOD + 1) - for(int i = 0; i < 15; i++) led_off(&led_ctx, led_l_physical_map[i]); - } - if(hp_mute_blink_tick > 0) - { - hp_mute_blink_tick++; - if(hp_mute_blink_tick >= MUTE_BLINK_HALF_PERIOD * 2) - hp_mute_blink_tick = 1; - if(hp_mute_blink_tick == 1) - for(int i = 0; i < 15; i++) led_on(&led_ctx, led_d_physical_map[i]); - else if(hp_mute_blink_tick == MUTE_BLINK_HALF_PERIOD + 1) - for(int i = 0; i < 15; i++) led_off(&led_ctx, led_d_physical_map[i]); - } - led_update_all(&led_ctx); -#endif - - GET_SHARED_GLOBAL(uac_vol, g_uac_vol); - if (uac_vol != last_uac_vol) { - unsigned conv_vol = (0xffffffff - uac_vol + 1) >> 8; - //debug_printf("vol: - %d\n", conv_vol); - //chan_out_word(c_uac_vol, conv_vol); - c_uac_vol <: conv_vol; - last_uac_vol = uac_vol; - } - - // 处理HID SET_VOLUME (0x93) 请求:应用新音量到DAC和LED - if (g_request_volume_set) { - g_request_volume_set = 0; - unsigned new_level = g_volume_level; - if (new_level <= DAC_LEVEL_MAX) { - uint8_t new_led_count; - dac_level = new_level; - if (!dac_det_muted) { - if (dac_level == DAC_LEVEL_MIN) - unsafe { NAU88C22_REGWRITE(0x0034, 0x0000, (client interface i2c_master_if)i_i2c_client); } - else - dac_volume(dac_level - DAC_LEVEL_MAX); - } - save_value(dac_vol_path, (unsigned char)dac_level); - // 更新DAC音量指示LED - new_led_count = dac_gain_to_led[dac_level]; - for (int i = 0; i < 15; i++) { - if (i < new_led_count) - led_on(&led_ctx, led_d_physical_map[i]); - else - led_off(&led_ctx, led_d_physical_map[i]); - } - led_update_all(&led_ctx); - debug_printf("HID SET_VOLUME: dac_level=%d\n", dac_level); - } - } - - // 处理HID SET_MIC_VOLUME (0x82) 请求:应用新麦克风增益到硬件和LED - if (g_request_mic_volume_set) { - g_request_mic_volume_set = 0; - unsigned new_mic_level = g_mic_volume_level; - if (new_mic_level <= 37) { // 0=mute, 1-37=0dB~36dB - uint8_t new_led_count; - if (new_mic_level == 0) { - // mute: 静音硬件,codec_adc_pga_gain_reg_value设为0(与编码器静音一致) - mic_volume(0); - codec_adc_pga_gain_reg_value = 0; - new_led_count = 0; - } else { - codec_adc_pga_gain_reg_value = new_mic_level; - if (!mic_det_muted) - mic_volume(codec_adc_pga_gain_reg_value); - new_led_count = mic_gain_to_led[codec_adc_pga_gain_reg_value]; - } - save_value(mic_vol_path, (unsigned char)codec_adc_pga_gain_reg_value); - // 更新麦克风增益指示LED(L系列) - for (int i = 0; i < 15; i++) { - if (i < new_led_count) - led_on(&led_ctx, led_l_physical_map[i]); - else - led_off(&led_ctx, led_l_physical_map[i]); - } - led_update_all(&led_ctx); - debug_printf("HID SET_MIC_VOLUME: level=%d pga=%d\n", new_mic_level, codec_adc_pga_gain_reg_value); - } - } - - // 处理HID SET_MONITOR_SWITCH (0x87) 请求:设置耳返开关 - if (g_request_monitor_switch_set) { - g_request_monitor_switch_set = 0; - unsigned new_mon = g_monitor_switch; - // 同步数字监听开关到tile1 - cc_mic_level <: 0xFE; - cc_mic_level <: (unsigned)new_mon; - debug_printf("HID monitor sync: sw=%d\n", new_mon); - save_value(monitor_sw_path, (unsigned char)new_mon); - debug_printf("HID SET_MONITOR_SWITCH: %d\n", new_mon); - } - - // 处理HID SET_AI_NOISE_STRENGTH (0x85) 请求 - // 改动原因:0x85的0仅关开关与灯并停算法,g_dnr_strength由eq.c保持原档位;非0更新强度并打开 - { - unsigned dnr_req; - GET_SHARED_GLOBAL(dnr_req, g_request_dnr_strength_set); - if (dnr_req) { - SET_SHARED_GLOBAL(g_request_dnr_strength_set, 0); - unsigned new_strength; - unsigned dnr_on_sw; - GET_SHARED_GLOBAL(new_strength, g_dnr_strength); - GET_SHARED_GLOBAL(dnr_on_sw, g_dnr_on); -#if DNR_ENABLE == 1 - if (dnr_on_sw) { - dnr_set_strength_level((unsigned char)new_strength); - flag_aidenoise_onoff = 1; - dnr_strength_saved = new_strength; - led_on(&led_ctx, LED_ANC); - } else { - dnr_set_strength_level(DNR_STRENGTH_off); - flag_aidenoise_onoff = 0; - led_off(&led_ctx, LED_ANC); - } -#endif - save_value(dnr_on_path, (unsigned char)dnr_on_sw); - save_value(dnr_strength_path, (unsigned char)new_strength); - g_dnr_on = dnr_on_sw; - led_update_all(&led_ctx); - debug_printf("HID SET_AI_NOISE_STRENGTH: strength=%d on=%d flash saved\n", - new_strength, dnr_on_sw); - } - } - -#if HID_CONTROLS == 1 - // HID监听音量变化主动上报(编码器旋转或HID命令导致的音量变化) - { - unsigned current_volume_level = g_volume_level; -#if HID_DFU_EN - if (!g_in_fw_upgrade) -#endif - if (g_last_volume_level != current_volume_level && g_last_volume_level != 0xFF) { - unsafe { - unsigned char * unsafe ptr = (unsigned char * unsafe)hidSendData; - ptr[0] = 1; - ptr[1] = 0x77; - ptr[2] = 0x94; - ptr[3] = (unsigned char)current_volume_level; - for (int i = 4; i < HID_MAX_DATA_BYTES; i++) - ptr[i] = 0x00; - } - hidSetChangePending(0x1); - debug_printf("Volume changed: %d -> %d, HID report sent\n", - g_last_volume_level, current_volume_level); - } - g_last_volume_level = current_volume_level; - } - - // HID麦克风增益变化主动上报 - { - unsigned current_mic_level = g_mic_volume_level; -#if HID_DFU_EN - if (!g_in_fw_upgrade) -#endif - if (g_last_mic_volume_level != current_mic_level && g_last_mic_volume_level != 0xFF) { - unsafe { - unsigned char * unsafe ptr = (unsigned char * unsafe)hidSendData; - ptr[0] = 1; - ptr[1] = 0x77; - ptr[2] = 0x83; - ptr[3] = (unsigned char)current_mic_level; - for (int i = 4; i < HID_MAX_DATA_BYTES; i++) - ptr[i] = 0x00; - } - hidSetChangePending(0x1); - debug_printf("Mic volume changed: %d -> %d, HID report sent\n", - g_last_mic_volume_level, current_mic_level); - } - g_last_mic_volume_level = current_mic_level; - } - - // HID AI降噪强度变化主动上报(含首次开机上报:g_last_dnr_strength初始为0xFF) - // 改动原因:按键关闭AI降噪时,协议要求上报0;开启时上报当前g_dnr_strength -#if DNR_ENABLE == 1 - { - unsigned current_dnr_strength; - unsigned current_dnr_on; - GET_SHARED_GLOBAL(current_dnr_on, g_dnr_on); - GET_SHARED_GLOBAL(current_dnr_strength, g_dnr_strength); - if (!current_dnr_on) { - current_dnr_strength = 0; - } -#if HID_DFU_EN - if (!g_in_fw_upgrade) -#endif - if (g_last_dnr_strength != current_dnr_strength) { - unsafe { - unsigned char * unsafe ptr = (unsigned char * unsafe)hidSendData; - ptr[0] = 1; - ptr[1] = 0x77; - ptr[2] = 0x86; - ptr[3] = (unsigned char)current_dnr_strength; - for (int i = 4; i < HID_MAX_DATA_BYTES; i++) - ptr[i] = 0x00; - } - hidSetChangePending(0x1); - debug_printf("DNR strength changed: %d -> %d, HID report sent\n", - g_last_dnr_strength, current_dnr_strength); - } - g_last_dnr_strength = current_dnr_strength; - } -#endif - - // HID音效模式变化主动上报(按键切换或0xA4命令导致的模式变化,含首次开机上报) - { - unsigned current_game_mode; - GET_SHARED_GLOBAL(current_game_mode, g_game_mode); -#if HID_DFU_EN - if (!g_in_fw_upgrade) -#endif - if (g_last_game_mode != current_game_mode) { - unsafe { - unsigned char * unsafe ptr = (unsigned char * unsafe)hidSendData; - ptr[0] = 1; - ptr[1] = 0x77; - ptr[2] = 0xA5; - ptr[3] = (unsigned char)current_game_mode; - for (int i = 4; i < HID_MAX_DATA_BYTES; i++) - ptr[i] = 0x00; - } - hidSetChangePending(0x1); - debug_printf("Game mode changed: %d -> %d, HID report sent\n", - g_last_game_mode, current_game_mode); - } - g_last_game_mode = current_game_mode; - } - -#if USE_EX3D == 1 - // HID脚步增强状态变化主动上报(按键切换或HID 0xB0命令导致的变化,含首次开机上报) - { -#if HID_DFU_EN - if (!g_in_fw_upgrade) -#endif - if (last_footstep_expand != saved_footstep ) { - unsafe { - unsigned char * unsafe ptr = (unsigned char * unsafe)hidSendData; - ptr[0] = 1; - ptr[1] = 0x77; - ptr[2] = 0xB1; - // EX3D GET CMD_EXPAND_GAIN = 0x193 (little-endian) - ptr[3] = 0x93; ptr[4] = 0x01; ptr[5] = 0x00; ptr[6] = 0x00; - // 返回值: expand_gain (uint32, little-endian) - ptr[7] = (unsigned char)saved_footstep; - ptr[8] = 0x00; ptr[9] = 0x00; ptr[10] = 0x00; - for (int i = 11; i < HID_MAX_DATA_BYTES; i++) ptr[i] = 0x00; - } - hidSetChangePending(0x1); - debug_printf("Footstep expand_gain changed: %d -> %d, HID 0xB1 report sent\n", - last_footstep_expand, saved_footstep); - } - last_footstep_expand = saved_footstep; - } -#endif -#endif - -#if EQ_EN - - { - unsigned request_eq_mode, new_eq_mode; - unsigned force_request_mode_change; - GET_SHARED_GLOBAL(request_eq_mode, g_request_eq_mode); - GET_SHARED_GLOBAL(new_eq_mode, g_new_eq_mode); - GET_SHARED_GLOBAL(force_request_mode_change, g_force_request_eq_mode_change); - if (new_eq_mode != request_eq_mode) - { - // debug_printf("new eq mode != request eq mode\n"); - SET_SHARED_GLOBAL(g_new_eq_mode, request_eq_mode); - } - - if (force_request_mode_change == 1) - { - debug_printf("force request mode change\n"); - SET_SHARED_GLOBAL(g_force_eq_mode_change, 1); - SET_SHARED_GLOBAL(g_force_request_eq_mode_change, 0); - } - } - - - eq_sync_counter++; - if (eq_sync_counter >= 5) { // 5 * 100ms = 500ms - eq_sync_counter = 0; - - // 使用单参数存储系统保存脏参数(独立保存EQ参数) - if (eq_save_dirty_params() == 0) { - //debug_printf("Single EQ parameters synced to Flash successfully\n"); - } else { - //debug_printf("Failed to sync single EQ parameters to Flash\n"); - } - - // 独立保存脏的增益 - if (eq_save_dirty_gain() == 0) { - // debug_printf("Gain synced to Flash successfully\n"); - } else { - //debug_printf("Failed to sync gain to Flash\n"); - } - - // 独立保存脏的模式名称 - if (eq_save_dirty_names() == 0) { - // debug_printf("Mode names synced to Flash successfully\n"); - } else { - //debug_printf("Failed to sync mode names to Flash\n"); - } - } -#endif - -#if UAC1_MODE == 1 - GET_SHARED_GLOBAL(host_os, g_host_os); - if (host_os == OS_WIN) { - unsigned flag = (saved_mode <= 1) ? MODE_F1_MUSIC_UAC2 : MODE_F3_F4_FPS_UAC2; - SetRoleSwitchFlag(flag); -#ifndef DISABLE_REBOOT - device_reboot(); - while (1); -#endif - } -#endif - break; - } - } - } -} - -void AudioHwRemote(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, chanend c_audiohw_rx -#if HID_DFU_EN - , streaming chanend c_dfu_rx -#endif - , chanend c_mic_det - ) -{ - i2c_master_if i2c[1]; - board_setup(); - par { - i2c_master(i2c, 1, p_scl, p_sda, 300); - { - unsafe {i_i2c_client = i2c[0];} - button_task(c_hidSendData, cc_mic_level, c_uac_vol, c_audiohw_rx -#if HID_DFU_EN - , c_dfu_rx -#endif - , c_mic_det - ); - } - } -} - - -/* Configures the external audio hardware at startup */ -void AudioHwInit() -{ - // p_ctl_mute <: 0; - int result=0; - - sw_pll_fixed_clock(MCLK_48); - - - - // Wait for power supply to come up. - delay_milliseconds(200); -} - -/* Configures the external audio hardware for the required sample frequency */ -void AudioHwConfig(unsigned samFreq, unsigned mClk, unsigned dsdMode, unsigned sampRes_DAC, unsigned sampRes_ADC) -{ -#if UAC1_MODE == 1 - static unsigned count = 1; -#else - static unsigned count = 0; -#endif - // p_ctl_mute <: 0; - g_samfreq = samFreq; - delay_milliseconds(2); - { - sw_pll_fixed_clock(mClk); - } - // 通知tile0 (button_task) 采样率已变化,用于配置NAU88C22寄存器 - unsafe {uc_audiohw <: samFreq; } - unsafe {uc_audiohw <: dsdMode; } - - if (count++ > 0) - { - // p_ctl_mute <: 1; - } - else - { - debug_printf("don't unmute at boot\n"); - } - - unsafe {uc_audiohw :> dsdMode; } -} - - -void mute_handler(chanend c_mic_det) -{ - // 开机mute sequence - p_ctl_mute <: 0; -#if UAC1_MODE == 1 - delay_milliseconds(3000); -#else - delay_milliseconds(1000); -#endif - p_ctl_mute <: 0xf; - - // mic detect: bit1=mic1 (插入=高, 拔出=低), bit2=mic2 (插入=低, 拔出=高) - c_mic_det <: (unsigned)MIC_DET_MUTE; - unsigned det_val; - p_ctl_det :> det_val; - unsigned mic1_in = (det_val >> 1) & 1; // bit1: 1=inserted - unsigned mic2_in = ((det_val >> 2) & 1) ^ 1; // bit2: 0=inserted, invert - unsigned phone_in = ((det_val >> 3) & 1) ^ 1; // bit3: 0=inserted, invert - unsigned any_mic_in = mic1_in || mic2_in; - unsigned prev_mic1_in = mic1_in; - unsigned prev_mic2_in = mic2_in; - unsigned prev_any_mic_in = any_mic_in; - unsigned prev_phone_in = phone_in; - - // 如果开机时全拔出,发送mute - - if (((det_val & 0b1110) == 0b1110) || ((det_val & 0b1110) == 0b1010) || ((det_val & 0b1110) == 0b0010)) { - // 有mic插入,恢复mic音量状态 - c_mic_det <: (unsigned)MIC_DET_UNMUTE; - debug_printf("mic stable -> unmute\n"); - } - - timer tmr; - unsigned time; - tmr :> time; - #define MIC_DET_POLL_MS 10 - time += MIC_DET_POLL_MS * 100000; // 10ms in 100MHz ticks - - while (1) { - select { - case tmr when timerafter(time) :> void: - { - time += MIC_DET_POLL_MS * 100000; - - p_ctl_det :> det_val; - mic1_in = (det_val >> 1) & 1; - mic2_in = ((det_val >> 2) & 1) ^ 1; - phone_in = ((det_val >> 3) & 1) ^ 1; - any_mic_in = mic1_in || mic2_in; - - // 检测单个mic插拔事件 - unsigned mic1_changed = (mic1_in != prev_mic1_in); - unsigned mic2_changed = (mic2_in != prev_mic2_in); - unsigned any_changed = mic1_changed || mic2_changed; - unsigned phone_changed = (phone_in != prev_phone_in); - - if (any_changed || phone_changed) { - // 状态变化:立即mute mic和DAC防止pop音 - p_ctl_mute <: 0; - c_mic_det <: (unsigned)MIC_DET_MUTE; - // c_mic_det <: (unsigned)MIC_DET_DAC_MUTE; - - // 配置ADC - //c_mic_det <: (unsigned)MIC_DET_REINIT_CODEC; - p_ctl_det <: 0; - delay_milliseconds(100); - - //debug_printf("mic det change: mic1=%d mic2=%d -> mute all & reconfig\n", mic1_in, mic2_in); - p_ctl_det :> det_val; - - // 等1s让插拔稳定 - delay_milliseconds(900); - p_ctl_mute <: 0xf; - - // 重新读取稳定状态 - p_ctl_det :> det_val; - mic1_in = (det_val >> 1) & 1; - mic2_in = ((det_val >> 2) & 1) ^ 1; - phone_in = ((det_val >> 3) & 1) ^ 1; - any_mic_in = mic1_in || mic2_in; - - // 恢复DAC状态 - c_mic_det <: (unsigned)MIC_DET_DAC_UNMUTE; - -#if 0 - if ((any_mic_in && !phone_in) || (phone_in && mic2_in)) { - // 有mic插入,恢复mic音量状态 - c_mic_det <: (unsigned)MIC_DET_UNMUTE; - debug_printf("mic stable -> unmute\n"); - } - // 全拔出则保持mic mute - - delay_milliseconds(200); - -#endif - - if (((det_val & 0b1110) == 0b1110) || ((det_val & 0b1110) == 0b1010) || ((det_val & 0b1110) == 0b0010)) { - // 有mic插入,恢复mic音量状态 - c_mic_det <: (unsigned)MIC_DET_UNMUTE; - debug_printf("mic stable -> unmute\n"); - } - // 全拔出则保持mic mute - - prev_mic1_in = mic1_in; - prev_mic2_in = mic2_in; - prev_any_mic_in = any_mic_in; - prev_phone_in = phone_in; - // 重新同步timer - tmr :> time; - time += MIC_DET_POLL_MS * 100000; - } - break; - } - } - } -} diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/br_wrapper.c b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/br_wrapper.c index 3bc07be..6967209 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/br_wrapper.c +++ b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/br_wrapper.c @@ -1,77 +1,10 @@ // Copyright 2024 XMOS LIMITED. -#define DEBUG_PRINT_ENABLE 0 -#include "debug_print.h" -// This Software is subject to the terms of the XMOS Public Licence: Version 1. -#include -#include -#include -#include -#include -#include -#include -#include "xc_ptr.h" +// 改动原因:EQ/DNR 已迁至 tile0 的 UserBufferManagementInit/UserBufferManagement 与 dsp_core0, +// 不再使用 c_eq_data channel 与 dsp_main;保留本文件避免构建脚本因缺源文件失败。 +// 原 buffer_exchange / dsp_main 实现已删除,逻辑见 dsp.c。 #include "xua_conf.h" -#include "share_buffer.h" - -extern uint32_t init_eq_data(unsigned sample_freq); - -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); +#if 0 +/* 历史实现(channel 桥接 tile1 UBM -> tile0 dsp_main),仅供对照,不再编译 */ #endif -} - - -void dsp_main (chanend_t c_data) { - int play_input[NUM_USB_CHAN_OUT]; - int play_output[I2S_CHANS_DAC]; - int mic_input[I2S_CHANS_ADC]; - int mic_output[I2S_CHANS_ADC]; - int count = 0; - unsigned ch[1] = {2}; -#if F1_MUSIC_UAC2 == 1 - unsigned current_sample_freq = 0; -#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; - } - - 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]; -#endif - } -} diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/dsp.c b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/dsp.c index 8326503..347048f 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/dsp.c +++ b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/dsp.c @@ -24,6 +24,8 @@ #include "roleswitchflag.h" #include "debug_print.h" #include "swlock.h" +#include "tx1_ex3d_game.h" +#include "user_func.h" // Global flash lock defined in lfs_services.c — protects all flash hardware access extern swlock_t flash_lock; @@ -33,8 +35,15 @@ extern unsigned char load_value(unsigned char *path); #if EQ_EN #include "eq_flash_storage.h" +#include "eq.h" +#include "share_buffer.h" extern unsigned g_request_eq_mode, g_new_eq_mode; extern unsigned g_force_request_eq_mode_change, g_force_eq_mode_change; +extern uint32_t init_eq_data(unsigned sample_freq); +#endif + +#if DNR_ENABLE == 1 +extern void dnr_exchange_buffer(int32_t *data); #endif extern void device_reboot(void); @@ -57,8 +66,12 @@ static volatile int32_t g_boot_footstep_expand_gain_value = 12; 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}; -chanend_t uc_ex3d_to_ubm, uc_eq_data; +chanend_t uc_ex3d_to_ubm; static unsigned ubm_sample_freq = 0; +#if EQ_EN == 1 +/* 改动原因:EQ 与 dsp_core0 同在 tile0,采样率变化在 UserBufferManagementInit 中直接 init,不再经 channel/dsp_main */ +static unsigned ubm_last_eq_init_freq = 0; +#endif #if (STEREO_8K == 1) || (STEREO_2K == 1) #define UBM_TO_EX3D_CHANS (2) @@ -75,6 +88,95 @@ unsigned g_mic_level_t1; #if defined(IR_SWITCHING_MODE) enum {IR_OFF=0, IR_GAME=1, IR_MUSIC=2, IR_MOVIE=3, IR_7_1_GAME=4, IR_7_1_MUSIC=5, IR_7_1_MOVIE=6}; unsigned g_3d_on_off_t1 = IR_OFF; // Default 3D off + +#if USE_EX3D == 1 +/* 改动原因:记录上次已下发 EX3D 的 g_3d_fps,避免 ex3d_task 每帧重复 set_sf */ +static unsigned g_tx1_last_ex3d_game_applied = 0xFFFFFFFFu; + +extern unsigned g_3d_fps; +extern unsigned g_request_game_mode; +extern unsigned g_tx1_azimuth_mode; +extern unsigned g_tx1_ex3d_resync_req; + +/** + * 改动原因:将 TX1 GAME 模式(0=BYPASS,1=FPS20,2=FPS71,3=3A) 映射为 g_3d_on_off_t1 并调用 + * audio_ex3d_set_sf/onoff,等价于 jok 物理键切换声场 + audio_azimuth_set_mode 的音频侧行为。 + * 须在 tile1 且 g_ex3d_init_done 后调用 audio_ex3d_*。 + */ +static void tx1_apply_ex3d_for_game_mode(unsigned game_mode) +{ + unsigned ir_mode; + unsigned azimuth_mode; + + switch (game_mode) { + case 1: /* GAME_MODE_FPS20 — jok audio_azimuth_set_mode(MODE_FPS) + 立体声游戏声场 */ + ir_mode = IR_GAME; + azimuth_mode = TX1_AZIMUTH_MODE_FPS; + break; + case 2: /* GAME_MODE_FPS71 — MODE_FPS + 7.1 游戏声场 sf=1 */ + ir_mode = IR_7_1_GAME; + azimuth_mode = TX1_AZIMUTH_MODE_FPS; + break; + case 3: /* GAME_MODE_3A — IR_MOVIE(非 IR_7_1_MOVIE) */ + ir_mode = IR_MOVIE; + azimuth_mode = TX1_AZIMUTH_MODE_3A; + break; + default: /* GAME_MODE_BYPASS */ + ir_mode = IR_OFF; + azimuth_mode = TX1_AZIMUTH_MODE_FPS; + break; + } + + SET_SHARED_GLOBAL(g_3d_on_off_t1, ir_mode); + SET_SHARED_GLOBAL(g_tx1_azimuth_mode, azimuth_mode); + + if (!g_ex3d_init_done) { + debug_printf("TX1 ex3d: defer game_mode=%u (init pending)\n", game_mode); + return; + } + + if (ir_mode == IR_OFF) { + audio_ex3d_set_onoff(0); + debug_printf("TX1 ex3d: BYPASS off\n"); + } else if (ir_mode == IR_GAME) { + audio_ex3d_set_sf(0); + audio_ex3d_set_onoff(1); + debug_printf("TX1 ex3d: FPS20 sf=0 on\n"); + } else if (ir_mode == IR_7_1_GAME) { + audio_ex3d_set_sf(1); + audio_ex3d_set_onoff(1); + debug_printf("TX1 ex3d: FPS71 sf=1 on\n"); + } else if (ir_mode == IR_MOVIE) { + audio_ex3d_set_sf(2); + audio_ex3d_set_onoff(1); + debug_printf("TX1 ex3d: 3A IR_MOVIE sf=2 on\n"); + } +} + +/** + * 改动原因:hid_button_task 已注释,原 event_polling 不再监视 g_3d_on_off_t1; + * 在 ex3d_task 主循环入口轮询 g_3d_fps / HID g_request_game_mode 并下发 EX3D。 + */ +static void tx1_poll_ex3d_game_mode(void) +{ + unsigned gm; + unsigned resync; + + GET_SHARED_GLOBAL(resync, g_tx1_ex3d_resync_req); + if (resync) { + SET_SHARED_GLOBAL(g_tx1_ex3d_resync_req, 0); + g_tx1_last_ex3d_game_applied = 0xFFFFFFFFu; + } + + GET_SHARED_GLOBAL(gm, g_3d_fps); + if (gm != g_tx1_last_ex3d_game_applied) { + tx1_apply_ex3d_for_game_mode(gm); + g_tx1_last_ex3d_game_applied = gm; + } + +} +#endif /* USE_EX3D == 1 */ + #else enum {A3D_OFF=0, A3D_VON=1, A3D_ON=2}; unsigned g_3d_on_off_t1 = A3D_OFF; // Default 3D off @@ -106,7 +208,7 @@ static void ex3d_apply_boot_angles(void) } #endif -// On UserBufferManagement Tile (1) +// UserBufferManagement 运行在 AUDIO_IO_TILE(当前为 tile0) static unsigned frame_index = 0; //static unsigned dnr_frame_idx = 0; static int32_t ubm_egress[UBM_TO_EX3D_CHANS][DSP_BLOCK_LENGTH]; //leaving ubm @@ -123,9 +225,6 @@ extern unsigned g_dnr_init_flag; void SetEx3dToUbmChan (chanend_t c) { uc_ex3d_to_ubm = c; } -void SetEqDataChan (chanend_t c) { - uc_eq_data = c; -} void key_receiver(chanend_t c) { debug_printf("===> key_receiver\n"); @@ -164,6 +263,17 @@ void key_sender(chanend_t c) void UserBufferManagementInit(unsigned sampFreq) { ubm_sample_freq = sampFreq; +#if EQ_EN == 1 + /* 改动原因:去掉 dsp_main/c_eq_data 后,采样率变化在 UBM 侧直接重初始化 EQ 系数并清空 ring buffer */ + if (sampFreq != 0 && sampFreq != ubm_last_eq_init_freq && sampFreq <= 192000) { + ubm_last_eq_init_freq = sampFreq; + init_eq_data(sampFreq); + clear_ring_buffer(0); + clear_ring_buffer(1); + clear_ring_buffer(2); + clear_ring_buffer(3); + } +#endif #if 0// USE_EX3D == 1 memset(ubm_ingress, 0, sizeof(ubm_ingress)); memset(ubm_egress, 0, sizeof(ubm_egress)); @@ -196,7 +306,6 @@ void UserBufferManagementInit(unsigned sampFreq) } float fLevel[NUM_USB_CHAN_OUT] = {0,}; enum {UBM_A3D_OFF=0, UBM_A3D_VON=1, UBM_A3D_ON=2}; -extern void buffer_exchange(chanend_t c_data, unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[], unsigned sample_freq); extern unsigned int is_eq_disabled(void); extern unsigned int g_eq_enable; @@ -297,10 +406,25 @@ void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudi chan_in_buf_word(uc_ex3d_to_ubm, (uint32_t *)ubm_ingress, EX3D_TO_UBM_CHANS * DSP_BLOCK_LENGTH); }; #endif -#if EQ_EN == 1 && USE_EX3D == 0 - buffer_exchange(uc_eq_data, sampsFromUsbToAudio, sampsFromAudioToUsb, ubm_sample_freq); -#elif DNR_ENABLE == 1 - buffer_exchange(uc_eq_data, sampsFromUsbToAudio, sampsFromAudioToUsb, ubm_sample_freq); +#if EQ_EN == 1 + /* 改动原因:EQ 与 dsp_core0 均在 tile0,经共享 ring buffer 交换样本,无需 c_eq_data/dsp_main */ + if (!is_eq_disabled()) { + write_to_ring_buffer(0, (int)sampsFromUsbToAudio[0]); + write_to_ring_buffer(1, (int)sampsFromUsbToAudio[1]); + sampsFromUsbToAudio[0] = (unsigned)read_from_ring_buffer(2); + sampsFromUsbToAudio[1] = (unsigned)read_from_ring_buffer(3); + } +#endif +#if DNR_ENABLE == 1 + /* 改动原因:DNR 输入缓冲与 dnr_dsp_proc_task 同在 tile0,在 UBM 中直接调用 dnr_exchange_buffer */ + { + int32_t mic_samples[2]; + mic_samples[0] = (int32_t)sampsFromAudioToUsb[0]; + mic_samples[1] = (int32_t)sampsFromAudioToUsb[1]; + dnr_exchange_buffer(mic_samples); + sampsFromAudioToUsb[0] = (unsigned)mic_samples[0]; + sampsFromAudioToUsb[1] = (unsigned)mic_samples[1]; + } #endif GET_SHARED_GLOBAL(is_monitor, g_monitor_switch_t1); if (is_monitor) { @@ -946,31 +1070,33 @@ void hid_button_task(chanend_t cc_mic_level, chanend_t c_hidRcvData, chanend_t c if (current_mode_local > 3) current_mode_local = 0; debug_printf("hid_button_task received audio_mode: %d\n", current_mode_local); #if USE_EX3D == 1 - if ((current_mode_local == 0) || (current_mode_local == 1)) { - // 无音效模式:关闭EX3D和EQ算法 - audio_ex3d_set_onoff(0); - is_3d_on = IR_OFF; - debug_printf("Mode 0: EX3D+EQ OFF\n"); - } else if (current_mode_local == 2) { - // 音乐模式:EX3D关闭,EQ开启 -#if (MODE_F3_F4_FPS_UAC2 == 1) - audio_ex3d_set_onoff(1); - is_3d_on = IR_GAME; -#endif -#if (MODE_F6_F7_FPS_UAC1 == 1) - audio_ex3d_set_onoff(0); - is_3d_on = IR_OFF; -#endif - } else if (current_mode_local == 3) { -#if (MODE_F3_F4_FPS_UAC2 == 1) - audio_ex3d_set_onoff(1); - is_3d_on = IR_7_1_GAME; -#endif -#if (MODE_F6_F7_FPS_UAC1 == 1) - audio_ex3d_set_onoff(1); - is_3d_on = IR_GAME; -#endif + /* 改动原因:与 g_3d_fps 四档一致,去掉 F3/F6 条件编译;UAC1 合并固件由本路径或 ex3d_task 轮询设置算法 */ + switch (current_mode_local) { + case 1: + audio_ex3d_set_sf(0); + audio_ex3d_set_onoff(1); + is_3d_on = IR_GAME; + debug_printf("hid 0xFC: FPS20 IR_GAME\n"); + break; + case 2: + audio_ex3d_set_sf(1); + audio_ex3d_set_onoff(1); + is_3d_on = IR_7_1_GAME; + debug_printf("hid 0xFC: FPS71 IR_7_1_GAME\n"); + break; + case 3: + audio_ex3d_set_sf(2); + audio_ex3d_set_onoff(1); + is_3d_on = IR_MOVIE; + debug_printf("hid 0xFC: 3A IR_MOVIE\n"); + break; + default: + audio_ex3d_set_onoff(0); + is_3d_on = IR_OFF; + debug_printf("hid 0xFC: BYPASS IR_OFF\n"); + break; } + SET_SHARED_GLOBAL(g_3d_on_off_t1, is_3d_on); #endif } else if (tmp == 0xFD) { @@ -1129,11 +1255,16 @@ void hid_button_task(chanend_t cc_mic_level, chanend_t c_hidRcvData, chanend_t c audio_ex3d_set_onoff(1); current_mode_local = 2; debug_printf("3d Game on (sf=1)\n"); + } else if (is_3d_on == IR_MOVIE) { + audio_ex3d_set_sf(2); + audio_ex3d_set_onoff(1); + current_mode_local = 3; + debug_printf("3d IR_MOVIE on (sf=2)\n"); } else if (is_3d_on == IR_7_1_MOVIE) { audio_ex3d_set_sf(2); audio_ex3d_set_onoff(1); current_mode_local = 3; - debug_printf("3d Movie on (sf=2)\n"); + debug_printf("3d 7.1 Movie on (sf=2)\n"); } else { audio_ex3d_set_onoff(is_3d_on != IR_OFF); } @@ -1200,9 +1331,21 @@ void ex3d_task(chanend_t c_ex3d_to_ubm){ g_ex3d_init_done = 1; debug_printf("ex3d_task init: expand_gain=%d\n", Ex3dExpandGain); + /* 改动原因:init 完成后按当前 g_3d_fps 应用一次 EX3D(默认 BYPASS) */ +#if USE_EX3D == 1 + { + unsigned init_gm; + GET_SHARED_GLOBAL(init_gm, g_3d_fps); + tx1_apply_ex3d_for_game_mode(init_gm); + g_tx1_last_ex3d_game_applied = init_gm; + } +#endif #endif while (1) { +#if USE_EX3D == 1 + tx1_poll_ex3d_game_mode(); +#endif OnProcessing(c_ex3d_to_ubm, uc_dsp_to_ex3d); } } diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/dsp.c.bak b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/dsp.c.bak deleted file mode 100644 index 161d2d6..0000000 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/dsp.c.bak +++ /dev/null @@ -1,1474 +0,0 @@ -#define DEBUG_PRINT_ENABLE 0 - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "dsp_user_impl.h" -#include "DSBuild.h" -#include "filter.h" - -#include "xua_conf.h" -#include -#include "audio_ex3d_control.h" -#include "c_dsp.h" -#include -#include "xua_hid_report.h" -#include "xc_ptr.h" -#include "dnr_dsp_buf.h" -#include "roleswitchflag.h" -#include "debug_print.h" -#include "swlock.h" - -// Global flash lock defined in lfs_services.c — protects all flash hardware access -extern swlock_t flash_lock; -// 改动原因:添加user_func.h头文件,用于调用save_value和load_value函数保存/加载模式到/从flash -extern void save_value(unsigned char *path, unsigned char value); -extern unsigned char load_value(unsigned char *path); -#if EQ_EN - -#include "eq_flash_storage.h" -extern unsigned g_request_eq_mode, g_new_eq_mode; -extern unsigned g_force_request_eq_mode_change, g_force_eq_mode_change; -#endif - -extern void device_reboot(void); -unsigned g_ex3d_key_verified = 0; -int32_t sys_vol = 0; -unsigned g_mic_vol_cmd_pending = 0; -// 0xFA boot sync收到后置1;ex3d_task用此标志决定是否保留boot sync的阈值 -static volatile int g_boot_lmt_threshold_loaded = 0; -static volatile int g_boot_footstep_expand_gain_loaded = 0; -static volatile int g_boot_angle_loaded = 0; -// 改动原因:修复“主机已通过CMD_ANGLE写入,但随后启动阶段0xF9(来自flash旧值)又覆盖回默认角度”的竞态。 -// 该标志在收到任意CMD_ANGLE写入后置1;若置1,则忽略后续0xF9覆盖,确保“最后一次主机写入”为准。 -static volatile int g_runtime_angle_written = 0; -// 改动原因:修复0xF9角度同步与ex3d_task初始化的竞态。 -// 当0xF9在ex3d_task初始化完成后才到达时,旧逻辑只缓存不应用,导致GET CMD_ANGLE仍返回默认值。 -// 通过该标志判断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_lmt_threshold_value = -5; -static volatile uint32_t g_boot_angle_values[8] = {315, 45, 0, 0, 225, 135, 270, 90}; - -chanend_t uc_ex3d_to_ubm, uc_eq_data; -static unsigned ubm_sample_freq = 0; - -#if (STEREO_8K == 1) || (STEREO_2K == 1) -#define UBM_TO_EX3D_CHANS (2) -#define EX3D_TO_UBM_CHANS (2) -#else -#define UBM_TO_EX3D_CHANS (NUM_USB_CHAN_OUT) -#define EX3D_TO_UBM_CHANS (2) -#endif - -// tile 1, mic level -unsigned g_mic_level_t1; - - -#if defined(IR_SWITCHING_MODE) -enum {IR_OFF=0, IR_GAME=1, IR_MUSIC=2, IR_MOVIE=3, IR_7_1_GAME=4, IR_7_1_MUSIC=5, IR_7_1_MOVIE=6}; -unsigned g_3d_on_off_t1 = IR_OFF; // Default 3D off -#else -enum {A3D_OFF=0, A3D_VON=1, A3D_ON=2}; -unsigned g_3d_on_off_t1 = A3D_OFF; // Default 3D off -#endif -#define DNR_ON 1 -#define DNR_OFF 0 -#define MUTE_ON 1 -#define MUTE_OFF 0 -unsigned g_mute_on_off_t1 = MUTE_ON; - -// 数字监听 tile1 共享变量(由 tile0 通过 cc_mic_level 通道同步) -unsigned g_monitor_switch_t1 = 0; // 耳返开关 tile1 副本(0=关闭,1=开启) - -unsigned g_mute_on_off_t0 = MUTE_OFF; - -unsigned g_game_mode = 0; - -#if USE_EX3D == 1 -static void ex3d_apply_boot_angles(void) -{ - int apply_count = (NUM_USB_CHAN_OUT < 8) ? NUM_USB_CHAN_OUT : 8; - for (int i = 0; i < apply_count; ++i) { - uint32_t angle = g_boot_angle_values[i]; - EX3D_VAngle[i] = (angle >> 16) & 0xFFFF; - EX3D_HAngle[i] = angle & 0xFFFF; - EX3DAudio_SetAngle(i + 1, EX3D_VAngle[i], EX3D_HAngle[i], (i == (apply_count - 1))); - debug_printf("ex3d_apply_boot_angles: %d, %d\n", EX3D_VAngle[i], EX3D_HAngle[i]); - } -} -#endif - -// On UserBufferManagement Tile (1) -static unsigned frame_index = 0; -//static unsigned dnr_frame_idx = 0; -static int32_t ubm_egress[UBM_TO_EX3D_CHANS][DSP_BLOCK_LENGTH]; //leaving ubm -static int32_t ubm_ingress[EX3D_TO_UBM_CHANS][DSP_BLOCK_LENGTH]; //entering ubm -#if AIZIP_DNR == 1 -static int32_t ubm_micIn[DSP_CH_NUM][DNR_DSP_FRAME_SIZE]; //leaving ubm -static int32_t ubm_micOut[DSP_CH_NUM][DNR_DSP_FRAME_SIZE]; //entering ubm -#endif -chanend_t uc_dsp_to_dnr_t1; -//chanend_t uc_dsp_to_dnr_t0; -chanend_t uc_key_to_ubm_t0; -volatile EXTERN DS_BOOL m_hThread; -extern unsigned g_dnr_init_flag; -void SetEqDataChan (chanend_t c) { - uc_eq_data = c; -} -void key_receiver(chanend_t c) -{ - debug_printf("===> key_receiver\n"); -#if DNR_ENABLE - unsigned dnr_init_flag = 0; - while (dnr_init_flag == 0) { - GET_SHARED_GLOBAL(dnr_init_flag, g_dnr_init_flag); - asm("nop"); - } - -#endif - // tile0 - // load the license key - // This function must be called before audio_ex3d_activate_key. - swlock_acquire(&flash_lock); - audio_ex3d_load_key(c); - swlock_release(&flash_lock); - SET_SHARED_GLOBAL(g_ex3d_key_verified, 1); -} - -void key_sender(chanend_t c) -{ - debug_printf("===> key_sender\n"); - - // tile1 - // activate the license key - // if the keys match, the function returns 0. - int ret = audio_ex3d_activate_key(c); - if (ret == NO_ERR) { - debug_printf("License keys match.\n"); - } else { - debug_printf("License keys do not match. Error code: %d\n", ret); - } -} - -void UserBufferManagementInit(unsigned sampFreq) -{ - ubm_sample_freq = sampFreq; -#if USE_EX3D == 1 - memset(ubm_ingress, 0, sizeof(ubm_ingress)); - memset(ubm_egress, 0, sizeof(ubm_egress)); - frame_index = 0; - - assert(uc_ex3d_to_ubm); - while( !m_hThread ){} - debug_printf("[UserBufferManagementInit] samfreq:%d\n\r", sampFreq); - int ret = audio_ex3d_change_parameter(NUM_USB_CHAN_OUT, NUM_USB_CHAN_OUT * FRAME_SIZE * sizeof(AUDIO_T), sampFreq, sizeof(AUDIO_T)); - if(ret != NO_ERR) { - debug_printf("audio_ex3d_change_parameter() error:%d\n\r", ret); - } else { - debug_printf("audio_ex3d_change_parameter() success\n\r"); - } - // 改动原因:修复“上电后GET CMD_ANGLE仍返回315”的问题。 - // audio_ex3d_change_parameter 内部会把 EX3D_VAngle/EX3D_HAngle 重置为库默认值(315,45,...), - // 若 0xF9 已同步了 flash 中的角度(或主机期间已通过 CMD_ANGLE 改过),必须在此重新应用, - // 否则采样率切换/流启动时刚建立的角度会被静默覆盖,导致 GET 依旧读到默认值315。 - if (g_boot_angle_loaded || g_runtime_angle_written) { - ex3d_apply_boot_angles(); - debug_printf("UserBufferManagementInit: reapplied ex3d angles after change_parameter\n"); - } - // ② 预热:推一个零帧穿过 ex3d,触发所有 worker 加载 + 首次同步 - chan_out_buf_word(uc_ex3d_to_ubm, (const uint32_t *)ubm_egress, - UBM_TO_EX3D_CHANS * DSP_BLOCK_LENGTH); - chan_in_buf_word (uc_ex3d_to_ubm, (uint32_t *)ubm_ingress, - EX3D_TO_UBM_CHANS * DSP_BLOCK_LENGTH); - memset(ubm_ingress, 0, sizeof(ubm_ingress)); // 清掉哑帧输出 -#endif -} -float fLevel[NUM_USB_CHAN_OUT] = {0,}; -enum {UBM_A3D_OFF=0, UBM_A3D_VON=1, UBM_A3D_ON=2}; -extern void buffer_exchange(chanend_t c_data, unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[], unsigned sample_freq); -extern unsigned int is_eq_disabled(void); -extern unsigned int g_eq_enable; - -void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[]) -{ - uint32_t is_3d; - unsigned is_monitor; - -#if USE_EX3D == 1 -#if defined(SPATIAL_DRAMA) || defined(SPATIAL_GAME) || defined(SPATIAL_MOVIE) || defined(SPATIAL_MUSIC) - // 6ch version - unsigned tmp[8]={0,0,0,0,0,0,0,0}, downmix[8]={0,0,0,0,0,0,0,0}; -#endif - - GET_SHARED_GLOBAL(is_3d, g_3d_on_off_t1); -#if (HID_CONTROLS > 0) - AUDIO_T absVal, maxVal; -#endif - //Frame the samples going from the usb to the DAC into frames of 8 - for(int ch=0;ch 0) - maxVal = 0; - absVal = ubm_egress[ch][frame_index]; - if(absVal < 0) absVal = -absVal; - if(maxVal < absVal) maxVal = absVal; -#if defined(AUDIO_T_16) - fLevel[ch] = (float)maxVal / 32768; -#else - fLevel[ch] = (float)maxVal / 2147483648; -#endif -#endif - } - -#if defined(SPATIAL_DRAMA) || defined(SPATIAL_GAME) || defined(SPATIAL_MOVIE) || defined(SPATIAL_MUSIC) || defined(IR_SWITCHING_MODE) - // 6ch version - // C and LFE -3dB mixed to L and R. - // L = L + C*-3dB + LFE*-3dB - // R = R + C*-3dB + LFE*-3dB - - int32_t input_L = (int32_t)sampsFromUsbToAudio[0]; - int32_t input_R = (int32_t)sampsFromUsbToAudio[1]; - int32_t input_C = (int32_t)sampsFromUsbToAudio[2]; - int32_t input_LFE = (int32_t)sampsFromUsbToAudio[3]; - - // -3dB Gain = 10^(-3/20) ~= 0.707946 - // Using 0.70710678 (1/sqrt(2)) approximation for -3dB - // Q31 factor: 0.70710678 * 2^31 = 1518500250 - const int32_t gain_minus_3db = 1518500250; - - int32_t C_weighted = (int32_t)(((int64_t)input_C * gain_minus_3db) >> 31); - int32_t LFE_weighted = (int32_t)(((int64_t)input_LFE * gain_minus_3db) >> 31); - - int64_t sum_L = (int64_t)input_L + C_weighted + LFE_weighted; - int64_t sum_R = (int64_t)input_R + C_weighted + LFE_weighted; - - // Saturation logic - if (sum_L > 2147483647) sum_L = 2147483647; - else if (sum_L < -2147483648) sum_L = -2147483648; - - if (sum_R > 2147483647) sum_R = 2147483647; - else if (sum_R < -2147483648) sum_R = -2147483648; - - // only for Stereo game, Stereo music and Stereo movie mode - if ((is_3d > IR_OFF) && (is_3d < IR_7_1_GAME)) { - // stereo mode - ubm_egress[0][frame_index] = 0; - ubm_egress[1][frame_index] = 0; - ubm_egress[2][frame_index] = 0; - ubm_egress[3][frame_index] = 0; - ubm_egress[4][frame_index] = 0; - ubm_egress[5][frame_index] = 0; - ubm_egress[6][frame_index] = (int32_t)sum_L; //SL - ubm_egress[7][frame_index] = (int32_t)sum_R; //SR - } else { - ubm_egress[0][frame_index] = (int32_t)sum_L; - ubm_egress[1][frame_index] = (int32_t)sum_R; - } - - // Zero out C (2) and LFE (3) since they are mixed into L/R - ubm_egress[2][frame_index] = 0; - ubm_egress[3][frame_index] = 0; -#endif - - for(int ch=0;ch> 16) % 181; - EX3D_HAngle[ChNum] = (angle & 0xffff) % 360; - EX3DAudio_SetAngle(ChNum+1, EX3D_VAngle[ChNum], EX3D_HAngle[ChNum], true); - // 改动原因:记录“运行期角度已被主机改写”,并同步缓存,防止后续0xF9旧值覆盖。 - g_boot_angle_values[ChNum] = ((uint32_t)EX3D_VAngle[ChNum] << 16) | (uint32_t)EX3D_HAngle[ChNum]; - g_boot_angle_loaded = 1; - g_runtime_angle_written = 1; - debug_printf("[%s] Set angle ch%d-%d,%d\n",__FUNCTION__, ChNum+1, EX3D_VAngle[ChNum], EX3D_HAngle[ChNum]); - } else { - uint8_t bApply = false; - debug_printf("[%s] Set angle(V,H):",__FUNCTION__); - ChNum = NUM_USB_CHAN_OUT; - for(int i=0; i> 16) % 181; - EX3D_HAngle[i] = (angle & 0xffff) % 360; - if(i == (ChNum - 1)) bApply = true; - EX3DAudio_SetAngle(i+1, EX3D_VAngle[i], EX3D_HAngle[i], bApply); - // 改动原因:批量写入时同样更新本地启动角度缓存,避免0xF9旧值回灌。 - g_boot_angle_values[i] = ((uint32_t)EX3D_VAngle[i] << 16) | (uint32_t)EX3D_HAngle[i]; - debug_printf(" ch%d-%d,%d,", i+1, EX3D_VAngle[i], EX3D_HAngle[i]); - } - // 改动原因:批量写入成功后置位,后续0xF9不再覆盖主机刚写的角度。 - g_boot_angle_loaded = 1; - g_runtime_angle_written = 1; - debug_printf("\n"); - } - debug_printf("Set CMD_ANGLE : %u\r\n", pRcvBuf[1]); - } else { - debug_printf("Get CMD_ANGLE : %u\r\n", pRcvBuf[1]); - - uint32_t ChNum = pRcvBuf[1]; - if (ChNum < NUM_USB_CHAN_OUT) { - angle = EX3D_VAngle[ChNum] << 16; - angle |= EX3D_HAngle[ChNum]; - pSendBuf[idx] = angle; - debug_printf("Get CMD_ANGLE : %u, %d, %d\n", ChNum, EX3D_VAngle[ChNum], EX3D_HAngle[ChNum]); - } else { - ChNum = NUM_USB_CHAN_OUT; - for (int i = 0; i < ChNum; i++) { - angle = EX3D_VAngle[i] << 16; - angle |= EX3D_HAngle[i]; - debug_printf("%08x, ", angle); - pSendBuf[idx++] = angle; - } - } - debug_printf("\r\n"); - } - break; - - case CMD_MUTE: - if (CMD_SET(CMD_MUTE) == command_code) { - uint32_t ChNum = pRcvBuf[1]; - if (ChNum < NUM_USB_CHAN_OUT) { - EX3D_Mute[ChNum] = pRcvBuf[2]; - EX3DAudio_SetMute(ChNum+1, EX3D_Mute[ChNum]); - debug_printf("[%s] Set mute ch%d-%d,%d\n",__FUNCTION__, ChNum+1, EX3D_Mute[ChNum]); - } else { - ChNum = NUM_USB_CHAN_OUT; - debug_printf("[%s] Set mute:",__FUNCTION__); - for(int i=0; i IR_GAME/IR_7_1_GAME/IR_7_1_MOVIE - const char * sfIdxName = ""; - switch (sfIdx) { - case 0: sfIdxName = "STEREO GAME"; break; - case 1: sfIdxName = "SPATIAL GAME"; break; - case 2: sfIdxName = "SPATIAL MOVIE"; break; - default: break; - } -// if (cur_mode == IR_GAME) { -// sfIdxName = spatial_game; -// } else { -// if (cur_mode == IR_MUSIC) { -// sfIdxName = spatial_music; -// } else { -// sfIdxName = spatial_movie; -// } -// } -#else - const char * sfIdxName = "EXTREME"; -#endif - int32_t NameLen = strlen(sfIdxName); - pSendBuf[idx++] = NameLen; - memcpy(&pSendBuf[idx], sfIdxName, NameLen); - //debug_printf("%s\r\n", sfDispName[sfIdx]); - } else - pSendBuf[idx] = 0xFFFFFFFF; - } - break; - - case CMD_SOUND_FIELD: - if (CMD_SET(CMD_SOUND_FIELD) == command_code) { - int32_t sfIdx = pRcvBuf[1]; - debug_printf("Set CMD_SOUND_FIELD : "); - // 改动原因: - // - host UI 现在只暴露3个“带算法声场”(GAME/MUSIC/MOVIE 三选一)。 - // - 算法开关通过 CMD_ONOFF/其它接口单独控制;CMD_SOUND_FIELD 不能隐式把算法打开/关闭。 - // 因此:CMD_SOUND_FIELD 只接受 0~2(对应 GAME/MUSIC/MOVIE),并且在算法OFF(IR_OFF)时只缓存选择、不改共享变量。 - if (sfIdx >= 0 && sfIdx < 3) { - unsigned cur_mode; - GET_SHARED_GLOBAL(cur_mode, g_3d_on_off_t1); - - last_sf_idx_0_2 = (unsigned)sfIdx; - - if (cur_mode == IR_OFF) { - // 改动原因:算法已关闭时不写 g_3d_on_off_t1,避免 event_polling 误判“主机改变声场”而自动打开算法 - debug_printf("algorithm OFF, cache sound field idx=%d only (no implicit on/off)\n", sfIdx); - } else { - // 改动原因:算法已开启时才更新声场;因EX3D_SF_NUM=3不再区分6个族 - unsigned new_mode; - if (sfIdx == 1) new_mode = IR_7_1_GAME; - else if (sfIdx == 2) new_mode = IR_7_1_MOVIE; - else new_mode = IR_GAME; - SET_SHARED_GLOBAL(g_3d_on_off_t1, new_mode); - debug_printf("set sound field idx=%d -> g_3d_on_off_t1=%d (no implicit on/off)\n", sfIdx, new_mode); - } - } else { - // 改动原因:EX3D_SF_NUM=3后只支持0~2,超过范围返回错误 - pSendBuf[idx] = 0xFFFFFFFF; - } - } else { // Get - // 改动原因:返回当前声场索引(0~2: GAME/MUSIC/MOVIE);若算法OFF则返回缓存值,避免依赖 g_3d_on_off_t1=IR_OFF - unsigned cur_mode; - GET_SHARED_GLOBAL(cur_mode, g_3d_on_off_t1); - if (cur_mode == IR_OFF) { - pSendBuf[idx] = last_sf_idx_0_2; - } else if (cur_mode == IR_7_1_MOVIE) { - pSendBuf[idx] = 2; - } else if (cur_mode == IR_7_1_GAME) { - pSendBuf[idx] = 1; - } else { - pSendBuf[idx] = 0; - } - } - break; - - case CMD_LEVEL: - { -#if 1 //TODO LISTS - uint32_t ChNum = pRcvBuf[1]; - uint32_t *pLevel = (uint32_t *)fLevel; - - if(ChNum > NUM_USB_CHAN_OUT) ChNum = NUM_USB_CHAN_OUT; - - // debug_printf("Get CMD_LEVEL : %d, %d\r\n", ChNum, NUM_USB_CHAN_OUT); - for (int i = 0; i < ChNum; i++) { - pSendBuf[idx++] = pLevel[i]; - // debug_printf("%08x, ", pLevel[i] ); - } - // debug_printf("\r\n"); -#endif - } - break; - - case CMD_ON_GAIN: - if (CMD_SET(CMD_ON_GAIN) == command_code) { - int32_t idBGain; - memcpy(&idBGain, &pRcvBuf[1], 4); - debug_printf("Set CMD_ON_GAIN : %d\r\n", idBGain); - if((-100 <= idBGain) && (idBGain <= 0)) { - Ex3dOnGain = idBGain; - EX3DAudio_SetOnGain(Ex3dOnGain); - } else { - pSendBuf[idx] = 0xFFFFFFFF; - } - } else { // Get - debug_printf("Get CMD_ON_GAIN : %d\r\n", Ex3dOnGain); - memcpy(&pSendBuf[idx], &Ex3dOnGain, 4); - } - break; - - case CMD_OFF_GAIN: - if (CMD_SET(CMD_OFF_GAIN) == command_code) { - int32_t idBGain; - memcpy(&idBGain, &pRcvBuf[1], 4); - debug_printf("Set CMD_OFF_GAIN : %d\r\n", idBGain); - if((-100 <= idBGain) && (idBGain <= 0)) { - Ex3dOffGain = idBGain; - EX3DAudio_SetOffGain(Ex3dOffGain); - } else { - pSendBuf[idx] = 0xFFFFFFFF; - } - } else { // Get - debug_printf("Get CMD_OFF_GAIN : %d\r\n", Ex3dOffGain); - memcpy(&pSendBuf[idx], &Ex3dOffGain, 4); - } - break; - - case CMD_LFE: - if (CMD_SET(CMD_LFE) == command_code) { - int32_t idBGain; - memcpy(&idBGain, &pRcvBuf[1], 4); - debug_printf("Set CMD_LFE : %d\r\n", idBGain); - if((-100 <= idBGain) && (idBGain <= 0)) { - Ex3dLfeGain = idBGain; - EX3DAudio_SetLFE(true, Ex3dLfeGain); - } else { - pSendBuf[idx] = 0xFFFFFFFF; - } - } else { // Get - debug_printf("Get CMD_LFE : %d\r\n", Ex3dLfeGain); - memcpy(&pSendBuf[idx], &Ex3dLfeGain, 4); - } - break; - - case CMD_LMT_THRESHOLD: - if (CMD_SET(CMD_LMT_THRESHOLD) == command_code) { - int32_t threshold; - memcpy(&threshold, &pRcvBuf[1], 4); - debug_printf("Set CMD_LMT_THRESHOLD : %d\r\n", threshold); - if((-35 <= threshold) && (threshold <= 0)) { - Ex3dLimiterThreshold = threshold; - } else { - pSendBuf[idx] = 0xFFFFFFFF; - } - - threshold = Ex3dLimiterThreshold + (sys_vol + Ex3dOnGain + Ex3dExpandGain); - if (threshold > 0) threshold = 0; - if (threshold < -35) threshold = -35; - EX3DAudio_SetLimiterThreshold(threshold); - - } else { // Get - debug_printf("Get CMD_LMT_THRESHOLD : %d\r\n", Ex3dLimiterThreshold); - memcpy(&pSendBuf[idx], &Ex3dLimiterThreshold, 4); - } - break; - - case CMD_LMT_ATTACKK_TIME: - if (CMD_SET(CMD_LMT_ATTACKK_TIME) == command_code) { - unsigned AttackTime; - memcpy(&AttackTime, &pRcvBuf[1], 4); - debug_printf("Set CMD_LMT_ATTACKK_TIME : %d\r\n", AttackTime); - if(AttackTime <= 10) { - Ex3dLimiterAttackTime = AttackTime; - EX3DAudio_SetLimiterAttackTime(Ex3dLimiterAttackTime); - } else { - pSendBuf[idx] = 0xFFFFFFFF; - } - } else { // Get - debug_printf("Get CMD_LMT_ATTACKK_TIME : %d\r\n", Ex3dLimiterAttackTime); - memcpy(&pSendBuf[idx], &Ex3dLimiterAttackTime, 4); - } - break; - - case CMD_LMT_RELEASE_TIME: - if (CMD_SET(CMD_LMT_RELEASE_TIME) == command_code) { - unsigned ReleaseTime; - memcpy(&ReleaseTime, &pRcvBuf[1], 4); - debug_printf("Set CMD_LMT_RELEASE_TIME : %d\r\n", ReleaseTime); - if(ReleaseTime <= 100) { - Ex3dLimiterReleaseTime = ReleaseTime; - EX3DAudio_SetLimiterReleaseTime(Ex3dLimiterReleaseTime); - } else { - pSendBuf[idx] = 0xFFFFFFFF; - } - } else { // Get - debug_printf("Get CMD_LMT_RELEASE_TIME : %d\r\n", Ex3dLimiterReleaseTime); - memcpy(&pSendBuf[idx], &Ex3dLimiterReleaseTime, 4); - } - break; - - // dhlee++ - - case CMD_EXPAND_GAIN: - if (CMD_SET(CMD_EXPAND_GAIN) == command_code) { - int32_t idBGain; - memcpy(&idBGain, &pRcvBuf[1], 4); - debug_printf("Set CMD_EXPAND_GAIN : %d\r\n", idBGain); - if((0 <= idBGain) && (idBGain <= 20)) { - Ex3dExpandGain = idBGain; - EX3DAudio_SetExpandGain(Ex3dExpandGain); - } else { - pSendBuf[idx] = 0xFFFFFFFF; - } - } else { // Get - debug_printf("Get CMD_EXPAND_GAIN : %d\r\n", Ex3dExpandGain); - memcpy(&pSendBuf[idx], &Ex3dExpandGain, 4); - } - break; - - case CMD_REDUCE_GAIN: - if (CMD_SET(CMD_REDUCE_GAIN) == command_code) { - int32_t idBGain; - memcpy(&idBGain, &pRcvBuf[1], 4); - debug_printf("Set CMD_REDUCE_GAIN : %d\r\n", idBGain); - if((-20 <= idBGain) && (idBGain <= 0)) { - Ex3dReduceGain = idBGain; - EX3DAudio_SetReduceGain(Ex3dReduceGain); - } else { - pSendBuf[idx] = 0xFFFFFFFF; - } - } else { // Get - debug_printf("Get CMD_REDUCE_GAIN : %d\r\n", Ex3dReduceGain); - memcpy(&pSendBuf[idx], &Ex3dReduceGain, 4); - } - break; - - - default: - break; -#endif - } -} - -void LevelMeter(AUDIO_T AudioData[NUM_USB_CHAN_OUT][FRAME_SIZE]) -{ - unsigned ch; - AUDIO_T absVal, maxVal; - #if defined(DETECT_CHANNEL) - AUDIO_T DetectAudioData; - unsigned MaskAudioData = 0; - unsigned Mask = 0x01; - static unsigned Mode = 0; - #endif - - for(ch=0; ch 3) current_mode_local = 0; - debug_printf("hid_button_task received audio_mode: %d\n", current_mode_local); -#if USE_EX3D == 1 - if ((current_mode_local == 0) || (current_mode_local == 1)) { - // 无音效模式:关闭EX3D和EQ算法 - audio_ex3d_set_onoff(0); - is_3d_on = IR_OFF; - debug_printf("Mode 0: EX3D+EQ OFF\n"); - } else if (current_mode_local == 2) { - // 音乐模式:EX3D关闭,EQ开启 -#if (MODE_F3_F4_FPS_UAC2 == 1) - audio_ex3d_set_onoff(1); - is_3d_on = IR_7_1_GAME; -#endif -#if (MODE_F6_F7_FPS_UAC1 == 1) - audio_ex3d_set_onoff(0); - is_3d_on = IR_OFF; -#endif - } else if (current_mode_local == 3) { -#if (MODE_F3_F4_FPS_UAC2 == 1) - audio_ex3d_set_onoff(1); - is_3d_on = IR_7_1_MOVIE; -#endif -#if (MODE_F6_F7_FPS_UAC1 == 1) - audio_ex3d_set_onoff(1); - is_3d_on = IR_MOVIE; -#endif - } -#endif - - } else if (tmp == 0xFD) { - // 脚步增强按键发来的 expand gain 命令 - // 必须先读取payload,无论是否启用EX3D - int32_t gain = (int32_t)chan_in_word(cc_mic_level); -#if USE_EX3D == 1 - if ((0 <= gain) && (gain <= 20)) { - Ex3dExpandGain = gain; - EX3DAudio_SetExpandGain(Ex3dExpandGain); - g_boot_footstep_expand_gain_value = gain; - g_boot_footstep_expand_gain_loaded = 1; - debug_printf("Button set CMD_EXPAND_GAIN: %d\n", gain); - } -#endif - } else if (tmp == 0xFA) { - // 开机同步枪声阈值:从tile0 flash加载的Ex3dLimiterThreshold - // 必须先读取payload,无论是否启用EX3D - int32_t threshold = (int32_t)chan_in_word(cc_mic_level); -#if USE_EX3D == 1 - if ((-35 <= threshold) && (threshold <= 0)) { - Ex3dLimiterThreshold = threshold; - g_boot_lmt_threshold_loaded = 1; - g_boot_lmt_threshold_value = threshold; - EX3DAudio_SetLimiterThreshold(threshold); - // audio_ex3d_init尚未运行(T≈200ms),ex3d_task将在T=500ms后用正确的OnGain重新应用 - debug_printf("Boot sync lmt_threshold=%d stored, will apply after ex3d init\n", threshold); - } -#endif - } else if (tmp == 0xFE) { - // 数字监听开关同步命令:来自 tile0(所有模式都需要处理) - unsigned mon_sw = chan_in_word(cc_mic_level); - SET_SHARED_GLOBAL(g_monitor_switch_t1, mon_sw); - debug_printf("Monitor sync: sw=%d\n", mon_sw); - } else if (tmp == 0xF9) { - uint32_t incoming_angles[8]; - for (int i = 0; i < 8; ++i) { - incoming_angles[i] = chan_in_word(cc_mic_level); - } - -#if USE_EX3D == 1 - if (g_runtime_angle_written) { - // 改动原因:主机运行期已写入角度时,0xF9可能携带启动早期flash旧值;此处只消费通道数据但不覆盖当前角度。 - debug_printf("Boot sync ex3d angles ignored (runtime angle already written)\n"); - } else { - for (int i = 0; i < 8; ++i) { - g_boot_angle_values[i] = incoming_angles[i]; - } - g_boot_angle_loaded = 1; - // 改动原因:若EX3D已初始化完成,0xF9角度同步需要立刻生效, - // 否则仅缓存会导致HID GET仍读到初始化时的默认角度。 - if (g_ex3d_init_done) { - ex3d_apply_boot_angles(); - debug_printf("Boot sync ex3d angles applied immediately (post-init)\n"); - } - debug_printf("Boot sync ex3d angles loaded\n"); - } -#endif - } - } - continue; - - event_hid: - { - unsigned length = chan_in_byte(c_hidRcvData); - for(int i=0; i= 3 && RcvData[1] == 0x77 && - (RcvData[2] == 0xB0 || RcvData[2] == 0xB1)) { - // 丢弃,由event_ex3d_hid处理 - } else { - hid_receive_task_in_c(RcvData, SendData); - for(int i=0; i<(HID_MAX_DATA_BYTES / 4); i++) { - chan_out_word(c_hidSendData, SendData[i]); - } - } -#endif - } - } - continue; - event_ex3d_hid: - { -#if (HID_CONTROLS == 1) - // 收到process_send_params发来的0xB0/0xB1 EX3D命令 - // 协议: cmd(1 byte) + ex3d_cmd_code(1 word) + params_len(1 byte) + params(N bytes) - uint8_t hid_cmd = chan_in_byte(c_ex3d_hid_cmd); - uint32_t ex3d_cmd_code = chan_in_word(c_ex3d_hid_cmd); - uint8_t params_len = chan_in_byte(c_ex3d_hid_cmd); - - // 构建EX3D原生格式缓冲区: [0x01, 0, 0, 0, cmd_code[4], params...] - unsigned char ex3d_rcv[64]; - memset(ex3d_rcv, 0, 64); - ex3d_rcv[0] = 0x01; - ex3d_rcv[4] = (uint8_t)(ex3d_cmd_code & 0xFF); - ex3d_rcv[5] = (uint8_t)((ex3d_cmd_code >> 8) & 0xFF); - ex3d_rcv[6] = (uint8_t)((ex3d_cmd_code >> 16) & 0xFF); - ex3d_rcv[7] = (uint8_t)((ex3d_cmd_code >> 24) & 0xFF); - for (int i = 0; i < params_len && i < 56; i++) { - ex3d_rcv[8 + i] = chan_in_byte(c_ex3d_hid_cmd); - } - - // 在tile1执行EX3D命令 - hid_receive_task_in_c(ex3d_rcv, SendData); - - // 将结果回传给process_send_params(16个word) - for (int i = 0; i < (HID_MAX_DATA_BYTES / 4); i++) { - chan_out_word(c_ex3d_hid_cmd, SendData[i]); - } -#endif - } - continue; - - event_uac_vol: - { - sys_vol = chan_in_word(c_uac_vol); -#if USE_EX3D == 1 - sys_vol = sys_vol * (-1); - int32_t threshold = Ex3dLimiterThreshold + (sys_vol + Ex3dOnGain + Ex3dExpandGain); - if (threshold > 0) threshold = 0; - if (threshold < -35) threshold = -35; - EX3DAudio_SetLimiterThreshold(threshold); - debug_printf("Set CMD_LMT_THRESHOLD : %d\r\n", threshold); - debug_printf("sys_vol:%d\n", sys_vol); -#endif - } - continue; - - event_polling: - { - hwtimer_set_trigger_time(timer, hwtimer_get_time(timer) + KEY_POLLING_INTERVAL); - -#if USE_EX3D == 1 - // 检查 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; - - // Select SF and set on/off together - if (is_3d_on == IR_OFF) { - audio_ex3d_set_onoff(0); - current_mode_local = 0; - debug_printf("3d off\n"); - } else if (is_3d_on == IR_GAME) { - audio_ex3d_set_sf(0); - audio_ex3d_set_onoff(1); - current_mode_local = 1; - debug_printf("Stereo Game on (sf=0)\n"); - } else if (is_3d_on == IR_7_1_GAME) { - audio_ex3d_set_sf(1); - audio_ex3d_set_onoff(1); - current_mode_local = 2; - debug_printf("3d Game on (sf=1)\n"); - } else if (is_3d_on == IR_7_1_MOVIE) { - audio_ex3d_set_sf(2); - audio_ex3d_set_onoff(1); - current_mode_local = 3; - debug_printf("3d Movie on (sf=2)\n"); - } else { - audio_ex3d_set_onoff(is_3d_on != IR_OFF); - } - SET_SHARED_GLOBAL(g_3d_on_off_t1, is_3d_on); - } -#endif - } - continue; - } - } - // port_disable(p_keys); - // port_disable(p_leds); - // port_disable(p_leds2); - hwtimer_free(timer); -} - - -chanend_t uc_dsp_to_ex3d[DSP_WORKER_COUNT]; - -extern int OnProcessing(); -void ex3d_task(){ - channel_t c = chan_alloc(); - chanend_t c_ex3d_to_ubm = c.end_a; - uc_ex3d_to_ubm = c.end_b; - - // set_core_high_priority_on(); - delay_milliseconds(500); - int ret = audio_ex3d_init(NUM_USB_CHAN_OUT, NUM_USB_CHAN_OUT * FRAME_SIZE * sizeof(AUDIO_T), 48000, sizeof(AUDIO_T)); - if(ret != 0) { - debug_printf("audio_ex3d_init() error:%d\n\r", ret); - } - -#if !UAC1_MODE - Ex3dOffGain = -5; - Ex3dOnGain = -5; - Ex3dLfeGain = -5; - // 若boot sync (0xFA) 已到达,保留flash加载的阈值;否则使用默认值-15 - if (!g_boot_lmt_threshold_loaded) { - Ex3dLimiterThreshold = -15; - } - - // audio_ex3d_init内部会将Ex3dExpandGain重置为库默认值(6),这里始终用保存值恢复 - Ex3dExpandGain = g_boot_footstep_expand_gain_loaded ? g_boot_footstep_expand_gain_value : 12; - Ex3dLimiterThreshold = g_boot_lmt_threshold_loaded ? g_boot_lmt_threshold_value : -15; - - EX3DAudio_SetOnGain(Ex3dOnGain); - EX3DAudio_SetOffGain(Ex3dOffGain); - // audio_ex3d_init完成后用正确的增益链重新计算并应用阈值 - { - int32_t init_effective = Ex3dLimiterThreshold + (sys_vol + Ex3dOnGain + Ex3dExpandGain); - if (init_effective > 0) init_effective = 0; - if (init_effective < -35) init_effective = -35; - EX3DAudio_SetLimiterThreshold(init_effective); - debug_printf("ex3d_task init: lmt_threshold=%d effective=%d expand=%d\n", - Ex3dLimiterThreshold, init_effective, Ex3dExpandGain); - } - // 0xFD boot sync在init前调用了EX3DAudio_SetExpandGain,init后重新应用 - EX3DAudio_SetExpandGain(Ex3dExpandGain); - - ex3d_apply_boot_angles(); - debug_printf("===ex3d_apply_boot_angles after init\n"); - - g_ex3d_init_done = 1; - debug_printf("ex3d_task init: expand_gain=%d\n", Ex3dExpandGain); - -#endif - - while (1) { - OnProcessing(c_ex3d_to_ubm, uc_dsp_to_ex3d); - } -} - -#ifdef USE_EX3D == 1 -#if defined(SPATIAL_DRAMA) -#define TD_DATA_BUFFER_ELEMENTS SPATIAL_71_DRAMA_v090h225_left_DATA_BUFFER_ELEMENTS -#elif defined(SPATIAL_GAME) -#define TD_DATA_BUFFER_ELEMENTS SPATIAL_71_GAME_v090h225_left_DATA_BUFFER_ELEMENTS -#elif defined(SPATIAL_MOVIE) -#define TD_DATA_BUFFER_ELEMENTS SPATIAL_71_MOVIE_v090h225_left_DATA_BUFFER_ELEMENTS -#elif defined(SPATIAL_MUSIC) -#define TD_DATA_BUFFER_ELEMENTS SPATIAL_71_MUSIC_v090h225_left_DATA_BUFFER_ELEMENTS -#elif defined(STEREO_2K) -#define TD_DATA_BUFFER_ELEMENTS SPATIAL_STEREO_2K_v090h090_left_DATA_BUFFER_ELEMENTS -#elif defined(STEREO_8K) -#define TD_DATA_BUFFER_ELEMENTS SPATIAL_STEREO_8K_v090h090_left_DATA_BUFFER_ELEMENTS -#elif defined(IR_SWITCHING_MODE) -#define TD_DATA_BUFFER_ELEMENTS SPATIAL_71_GAME_v090h225_left_DATA_BUFFER_ELEMENTS -#else -#error you need to define SPATIAL_DRAMA or STEREO_8K.... -#endif - -#if defined (IR_SWITCHING_MODE) -int dsp_worker(chanend_t c_dsp_to_ex3d, - td_block_fir_filter_t * filters[DSP_WORKER_FILTER_PER_DATA_CH*DSP_WORKER_DATA_CH_COUNT*4]){ -#else -int dsp_worker(chanend_t c_dsp_to_ex3d, - td_block_fir_filter_t * filters[DSP_WORKER_FILTER_PER_DATA_CH*DSP_WORKER_DATA_CH_COUNT]){ -#endif - int32_t sample_buffer[DSP_WORKER_DATA_CH_COUNT][TD_DATA_BUFFER_ELEMENTS]; - td_block_fir_data_t fir_data[DSP_WORKER_DATA_CH_COUNT]; -#if defined (IR_SWITCHING_MODE) - static uint32_t ir_mode; - GET_SHARED_GLOBAL(ir_mode, g_3d_on_off_t1); -#endif - - for(int i=0;i 3) { - ir_mode -= 4; - } else { - ir_mode -= 1; - } - } - for(int ch=0;ch // 添加数学函数支持 extern void device_reboot(void); +/* 改动原因:HID 0xA4 在 Windows 下切换 g_3d_fps 后调用,声明见 audiohw.xc */ +extern void switch_mode_by_c1_mode(unsigned game_mode, unsigned force_reboot); #if HID_DFU_EN #include "dfu_upgrade.h" @@ -35,6 +37,7 @@ unsigned g_log_switch = 0; #include "biquad_standalone.h" #include "eq_flash_storage.h" #include "user_func.h" +#include "tx1_ex3d_game.h" #if (USE_EX3D == 1) && (HID_CONTROLS == 1) #include #endif @@ -766,15 +769,35 @@ unsigned char process_send_params(uint8_t data[], uint16_t len) { // 处理设置音效模式命令 (0xA4) - SET_SOUND_EFFECT_MODE // 0=无音效(EQ/EX3D全关), 1=音乐模式, 2=游戏模式, 3=AI7.1模式 if (data[1] == 0xA4) { - uint8_t game_mode = data[2]; + uint8_t hid_mode = data[2]; + unsigned mapped; + unsigned azimuth; // 参数验证:0-3 - if (game_mode > 3) { + if (hid_mode > 3) { return false; } - extern unsigned g_request_game_mode; - SET_SHARED_GLOBAL(g_request_game_mode, game_mode); + /* 改动原因:与面板 GAME 键一致——写 g_3d_fps/LFS,tile1 ex3d_task 轮询 apply EX3D */ + switch (hid_mode) { + case 2: mapped = 1; break; /* 游戏 -> FPS20 */ + case 3: mapped = 2; break; /* AI7.1 -> FPS71 */ + default: mapped = 0; break; + } + azimuth = TX1_AZIMUTH_MODE_FPS; /* HID 无 3A 档,与 jok 默认 MODE_FPS 一致 */ + { + extern unsigned g_3d_fps; + extern unsigned g_tx1_azimuth_mode; + extern unsigned g_tx1_ex3d_resync_req; + SET_SHARED_GLOBAL(g_3d_fps, mapped); + SET_SHARED_GLOBAL(g_tx1_azimuth_mode, azimuth); + SET_SHARED_GLOBAL(g_tx1_ex3d_resync_req, 1); + } + tx1_save_game_mode((unsigned char)mapped); + SET_SHARED_GLOBAL(g_request_game_mode, (unsigned)-1); + /* 改动原因:HID 0xA4 后 switch_mode 内判断 OS——仅 Win+FPS71 切 UAC2,非 Win 只改 tile1 算法 */ + switch_mode_by_c1_mode(mapped, 0); + SET_SHARED_GLOBAL(g_tx1_ex3d_resync_req, 1); return true; } diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/host_os_detect.c b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/host_os_detect.c index a6f10d7..b0a1c9a 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/host_os_detect.c +++ b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/host_os_detect.c @@ -30,13 +30,13 @@ int VendorRequests(XUD_ep ep0_out, XUD_ep ep0_in, REFERENCE_PARAM(USB_SetupPacke XUD_Result_t result = XUD_RES_ERR; unsigned char request_data[EP0_MAX_REQUEST_SIZE]; - unsigned len; + unsigned len = 0; int a = 0; unsigned k = 5; //SET_SHARED_GLOBAL(g_host_os, k); switch ((sp->bmRequestType.Direction << 7) | (sp->bmRequestType.Type << 5) | (sp->bmRequestType.Recipient)) { case USB_BMREQ_H2D_VENDOR_DEV: - result = XUD_GetBuffer(ep0_out, request_data, len); + result = XUD_GetBuffer(ep0_out, request_data, &len); if (result == XUD_RES_OKAY) { if (a/*control_process_usb_set_request(sp.wIndex, sp.wValue, sp.wLength, request_data, i_control) == CONTROL_SUCCESS*/) { /* zero length data to indicate success diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/main.xc b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/main.xc index 941e45c..43a9bf2 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/main.xc +++ b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/main.xc @@ -425,8 +425,6 @@ void usb_audio_io(chanend ?c_aud_in, //extern unsafe client interface i2c_master_if i_i2c_client_t0; extern void dsp_core0(void); extern void board_setup(); -extern void dsp_main (chanend c_data); -extern void SetEqDataChan (chanend c); extern void SetEx3dHidChan (chanend c); extern int dsp_worker_tile(chanend c_dsp_to_ex3d, int worker_id); @@ -555,7 +553,6 @@ int main() #endif chan c_key; chan c_hidSendData; chan c_hidRcvData; - chan c_eq_data; chan c_uac_vol; chan c_ex3d_hid_cmd; chan c_ex3d_to_ubm; @@ -596,7 +593,6 @@ int main() /* 改动原因:参数顺序与类型对齐 audiohw.xc 的 AudioHwRemote,修复链接阶段符号类型不一致。 */ { unsafe { - SetEqDataChan(c_eq_data); SetEx3dToUbmChan(c_ex3d_to_ubm); } #if USE_EX3D == 1 @@ -630,7 +626,6 @@ int main() #endif } } - on tile[0] : { dsp_main(c_eq_data); } #if DNR_ENABLE == 1 on tile[0] : { dnr_dsp_proc_task(); } diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/main.xc.bak b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/main.xc.bak deleted file mode 100644 index 50cf2a5..0000000 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/main.xc.bak +++ /dev/null @@ -1,836 +0,0 @@ -// Copyright 2012-2024 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. - -#include "xua.h" /* Device specific defines */ -#ifdef EXCLUDE_USB_AUDIO_MAIN - -/** - * @file main.xc - * @brief Top level for XMOS USB 2.0 Audio 2.0 Reference Designs. - * @author Ross Owen, XMOS Semiconductor Ltd - */ -#include -#include -#include -#include -#include -#ifdef XSCOPE -#include -#endif - -#if XUA_USB_EN -#include "xud_device.h" /* XMOS USB Device Layer defines and functions */ -#include "xua_endpoint0.h" -#endif - -#include "uac_hwresources.h" - -#ifdef IAP -#include "i2c_shared.h" -#include "iap.h" -#endif - -#if (XUA_SPDIF_RX_EN || XUA_SPDIF_TX_EN) -#include "spdif.h" /* From lib_spdif */ -#endif - -#if (XUA_ADAT_RX_EN) -#include "adat_rx.h" -#endif - -#if (XUA_NUM_PDM_MICS > 0) -#include "xua_pdm_mic.h" -#endif - -#if (XUA_DFU_EN == 1) -[[distributable]] -void DFUHandler(server interface i_dfu i, chanend ?c_user_cmd); -#endif - -/* Audio I/O - Port declarations */ -#if I2S_WIRES_DAC > 0 -on tile[AUDIO_IO_TILE] : buffered out port:32 p_i2s_dac[I2S_WIRES_DAC] = - {PORT_I2S_DAC0, -#endif -#if I2S_WIRES_DAC > 1 - PORT_I2S_DAC1, -#endif -#if I2S_WIRES_DAC > 2 - PORT_I2S_DAC2, -#endif -#if I2S_WIRES_DAC > 3 - PORT_I2S_DAC3, -#endif -#if I2S_WIRES_DAC > 4 - PORT_I2S_DAC4, -#endif -#if I2S_WIRES_DAC > 5 - PORT_I2S_DAC5, -#endif -#if I2S_WIRES_DAC > 6 - PORT_I2S_DAC6, -#endif -#if I2S_WIRES_DAC > 7 -#error I2S_WIRES_DAC value is too large! -#endif -#if I2S_WIRES_DAC > 0 - }; -#else - #define p_i2s_dac null -#endif - -#if I2S_WIRES_ADC > 0 -on tile[AUDIO_IO_TILE] : buffered in port:32 p_i2s_adc[I2S_WIRES_ADC] = - {PORT_I2S_ADC0, -#endif -#if I2S_WIRES_ADC > 1 - PORT_I2S_ADC1, -#endif -#if I2S_WIRES_ADC > 2 - PORT_I2S_ADC2, -#endif -#if I2S_WIRES_ADC > 3 - PORT_I2S_ADC3, -#endif -#if I2S_WIRES_ADC > 4 - PORT_I2S_ADC4, -#endif -#if I2S_WIRES_ADC > 5 - PORT_I2S_ADC5, -#endif -#if I2S_WIRES_ADC > 6 - PORT_I2S_ADC6, -#endif -#if I2S_WIRES_ADC > 7 -#error I2S_WIRES_ADC value is too large! -#endif -#if I2S_WIRES_ADC > 0 - }; -#else - #define p_i2s_adc null -#endif - - -#if CODEC_MASTER -on tile[AUDIO_IO_TILE] : buffered in port:32 p_lrclk = PORT_I2S_LRCLK; -on tile[AUDIO_IO_TILE] : buffered in port:32 p_bclk = PORT_I2S_BCLK; -#else -on tile[AUDIO_IO_TILE] : buffered out port:32 p_lrclk = PORT_I2S_LRCLK; -on tile[AUDIO_IO_TILE] : buffered out port:32 p_bclk = PORT_I2S_BCLK; -#endif - -#if (!CODEC_MASTER) || XUA_SPDIF_TX_EN || XUA_ADAT_TX_EN || ((AUDIO_IO_TILE == XUD_TILE) && XUA_USB_EN) -/* Audio master clock input */ -on tile[AUDIO_IO_TILE] : in port p_mclk_in = PORT_MCLK_IN; -#else -#define p_mclk_in null -#endif - -#if (AUDIO_IO_TILE != XUD_TILE) && XUA_USB_EN -/* If audio I/O and USB running on different tiles we need a separate port for - * the master clock input (to use for USB async feedback calculation) */ -on tile[XUD_TILE] : in port p_mclk_in_usb = PORT_MCLK_IN_USB; -#endif - -#if XUA_USB_EN -on tile[XUD_TILE] : in port p_for_mclk_count = PORT_MCLK_COUNT; -#endif - -#if (XUA_SPDIF_TX_EN) -on tile[SPDIF_TX_TILE] : buffered out port:32 p_spdif_tx = PORT_SPDIF_OUT; -#endif - -#if (XUA_ADAT_TX_EN) -on stdcore[AUDIO_IO_TILE] : buffered out port:32 p_adat_tx = PORT_ADAT_OUT; -#endif - -#if (XUA_ADAT_RX_EN) -on stdcore[XUD_TILE] : buffered in port:32 p_adat_rx = PORT_ADAT_IN; -#endif - -#if (XUA_SPDIF_RX_EN) -on tile[XUD_TILE] : in port p_spdif_rx = PORT_SPDIF_IN; -#endif - -#if (XUA_SPDIF_RX_EN) || (XUA_ADAT_RX_EN) || (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) -/* Reference to external clock multiplier */ -on tile[PLL_REF_TILE] : out port p_pll_ref = PORT_PLL_REF; -#ifdef __XS3A__ -on tile[AUDIO_IO_TILE] : port p_for_mclk_count_audio = PORT_MCLK_COUNT_2; -#else /* __XS3A__ */ -#define p_for_mclk_count_audio null -#endif /* __XS3A__ */ -#endif - -#ifdef MIDI -on tile[MIDI_TILE] : port p_midi_tx = PORT_MIDI_OUT; - -#if(MIDI_RX_PORT_WIDTH == 4) -on tile[MIDI_TILE] : buffered in port:4 p_midi_rx = PORT_MIDI_IN; -#elif(MIDI_RX_PORT_WIDTH == 1) -on tile[MIDI_TILE] : buffered in port:1 p_midi_rx = PORT_MIDI_IN; -#endif -#endif - - -#ifdef MIDI -on tile[MIDI_TILE] : clock clk_midi = CLKBLK_MIDI; -#endif - -#if (XUA_SPDIF_TX_EN || XUA_ADAT_TX_EN) -on tile[SPDIF_TX_TILE] : clock clk_mst_spd = CLKBLK_SPDIF_TX; -#endif - -#if (XUA_SPDIF_RX_EN) -on tile[XUD_TILE] : clock clk_spd_rx = CLKBLK_SPDIF_RX; -#endif - -on tile[AUDIO_IO_TILE] : clock clk_audio_mclk = CLKBLK_MCLK; /* Master clock */ - -#if (AUDIO_IO_TILE != XUD_TILE) && XUA_USB_EN -/* Separate clock/port for USB feedback calculation */ -on tile[XUD_TILE] : clock clk_audio_mclk_usb = CLKBLK_MCLK; /* Master clock */ -#endif - -on tile[AUDIO_IO_TILE] : clock clk_audio_bclk = CLKBLK_I2S_BIT; /* Bit clock */ - -#ifdef IAP -/* I2C ports - in a struct for use with module_i2c_shared & module_i2c_simple/module_i2c_single_port */ -#ifdef PORT_I2C -on tile [IAP_TILE] : struct r_i2c r_i2c = {PORT_I2C}; -#else -on tile [IAP_TILE] : struct r_i2c r_i2c = {PORT_I2C_SCL, PORT_I2C_SDA}; -#endif -#endif - -#if XUA_USB_EN -/* Endpoint type tables for XUD */ -XUD_EpType epTypeTableOut[ENDPOINT_COUNT_OUT] = { XUD_EPTYPE_CTL | XUD_STATUS_ENABLE, -#if (NUM_USB_CHAN_IN > 0) - XUD_EPTYPE_ISO, /* Audio */ -#endif -#ifdef MIDI - XUD_EPTYPE_BUL, /* MIDI */ -#endif -#if HID_OUT_REQUIRED - XUD_EPTYPE_INT, -#endif -#ifdef IAP - XUD_EPTYPE_BUL, /* iAP */ -#ifdef IAP_EA_NATIVE_TRANS - XUD_EPTYPE_BUL, /* EA Native Transport */ -#endif -#endif - }; - -XUD_EpType epTypeTableIn[ENDPOINT_COUNT_IN] = { XUD_EPTYPE_CTL | XUD_STATUS_ENABLE, -#if (NUM_USB_CHAN_IN > 0) - XUD_EPTYPE_ISO, -#endif -#if (NUM_USB_CHAN_OUT > 0) && ((NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP)) - XUD_EPTYPE_ISO, /* Async feedback endpoint */ -#endif -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - XUD_EPTYPE_INT, -#endif -#ifdef MIDI - XUD_EPTYPE_BUL, -#endif -#if XUA_OR_STATIC_HID_ENABLED - XUD_EPTYPE_INT, -#endif -#ifdef IAP - XUD_EPTYPE_BUL | XUD_STATUS_ENABLE, -#ifdef IAP_INT_EP - XUD_EPTYPE_BUL | XUD_STATUS_ENABLE, -#endif -#ifdef IAP_EA_NATIVE_TRANS - XUD_EPTYPE_BUL | XUD_STATUS_ENABLE, -#endif -#endif - }; -#endif /* XUA_USB_EN */ - -void thread_speed() -{ -#ifdef FAST_MODE -#warning Building with fast mode enabled - set_thread_fast_mode_on(); -#else - set_thread_fast_mode_off(); -#endif -} - -#ifdef XSCOPE -void xscope_user_init() -{ - xscope_register(0, 0, "", 0, ""); - - xscope_config_io(XSCOPE_IO_BASIC); -} -#endif - -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE) -void SpdifTxWrapper(chanend c_spdif_tx) -{ - unsigned portId; - //configure_clock_src(clk, p_mclk); - - // TODO could share clock block here.. - // NOTE, Assuming SPDIF tile == USB tile here.. - asm("ldw %0, dp[p_mclk_in_usb]":"=r"(portId)); - asm("setclk res[%0], %1"::"r"(clk_mst_spd), "r"(portId)); - configure_out_port_no_ready(p_spdif_tx, clk_mst_spd, 0); - set_clock_fall_delay(clk_mst_spd, 7); - start_clock(clk_mst_spd); - - while(1) - { - spdif_tx(p_spdif_tx, c_spdif_tx); - } -} -#endif - -void usb_audio_io(chanend ?c_aud_in, -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE) - chanend c_spdif_tx, -#endif -#if (MIXER) - chanend c_mix_ctl, -#endif - streaming chanend ?c_spdif_rx, - streaming chanend ?c_adat_rx, - chanend ?c_clk_ctl, - chanend ?c_clk_int -#if (XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1) - , server interface i_dfu ?dfuInterface -#endif -#if (XUA_NUM_PDM_MICS > 0) - , chanend c_pdm_pcm -#endif -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - , client interface pll_ref_if i_pll_ref -#endif -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) - , chanend c_audio_rate_change -#endif -#if ((XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) && XUA_USE_SW_PLL) - , port p_for_mclk_count_aud - , chanend c_sw_pll -#endif -) -{ -#if (MIXER) - chan c_mix_out; -#endif - -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - chan c_dig_rx; - chan c_audio_rate_change; /* Notification of new mclk freq to clockgen and synch */ -#if XUA_USE_SW_PLL - /* Connect p_for_mclk_count_aud to clk_audio_mclk so we can count mclks/timestamp in digital rx*/ - unsigned x = 0; - asm("ldw %0, dp[clk_audio_mclk]":"=r"(x)); - asm("setclk res[%0], %1"::"r"(p_for_mclk_count_aud), "r"(x)); -#endif /* XUA_USE_SW_PLL */ -#endif /* (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) */ - - -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE == AUDIO_IO_TILE) - chan c_spdif_tx; - - /* Setup S/PDIF tx port - note this is done before par since sharing clock-block/port */ - spdif_tx_port_config(p_spdif_tx, clk_audio_mclk, p_mclk_in, 7); -#endif - - par - { -#if (MIXER && XUA_USB_EN) - /* Mixer cores(s) */ - { - thread_speed(); - mixer(c_aud_in, c_mix_out, c_mix_ctl); - } -#endif - -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE == AUDIO_IO_TILE) - while(1) - { - spdif_tx(p_spdif_tx, c_spdif_tx); - } -#endif - - /* Audio I/O core (pars additional S/PDIF TX Core) */ - { - thread_speed(); -#if (MIXER) -#define AUDIO_CHANNEL c_mix_out -#else -#define AUDIO_CHANNEL c_aud_in -#endif - XUA_AudioHub(AUDIO_CHANNEL, clk_audio_mclk, clk_audio_bclk, p_mclk_in, p_lrclk, p_bclk, p_i2s_dac, p_i2s_adc -#if (XUA_SPDIF_TX_EN) //&& (SPDIF_TX_TILE != AUDIO_IO_TILE) - , c_spdif_tx -#endif -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - , c_dig_rx -#endif -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - , c_audio_rate_change -#endif -#if (XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1) - , dfuInterface -#endif -#if (XUA_NUM_PDM_MICS > 0) - , c_pdm_pcm -#endif - ); - } - -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - { - /* ClockGen must currently run on same tile as AudioHub due to shared memory buffer - * However, due to the use of an interface the pll reference signal port can be on another tile - */ - thread_speed(); - clockGen( c_spdif_rx, - c_adat_rx, - i_pll_ref, - c_dig_rx, - c_clk_ctl, - c_clk_int, - c_audio_rate_change -#if XUA_USE_SW_PLL - , p_for_mclk_count_aud - , c_sw_pll -#endif - ); - } -#endif - - } // par -} - -#ifndef USER_MAIN_DECLARATIONS -#define USER_MAIN_DECLARATIONS -#endif - -#ifndef USER_MAIN_CORES -#define USER_MAIN_CORES -#endif - -//extern unsafe client interface i2c_master_if i_i2c_client; -//extern unsafe client interface i2c_master_if i_i2c_client_t0; -extern void dsp_core0(void); -extern void board_setup(); -extern void dsp_main (chanend c_data); -extern void SetEqDataChan (chanend c); -extern void SetEx3dHidChan (chanend c); - -extern int dsp_worker_tile(chanend c_dsp_to_ex3d, int worker_id); -//extern int dsp_worker_tile_1(chanend c_dsp_to_ex3d, int worker_id); -extern void ex3d_task(); -extern void hid_button_task(chanend cc_mic_level, chanend c_hid, chanend c_hidSendData, chanend c_uac_vol, chanend c_ex3d_hid_cmd); -#if HID_DFU_EN -extern void AudioHwRemote(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, chanend c_audiohw_rx, streaming chanend c_dfu_rx); -#else -extern void AudioHwRemote(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, chanend c_audiohw_rx); -#endif -extern void dnr_dsp_proc_task(void); - -extern unsafe chanend uc_dsp_to_ex3d[DSP_WORKER_COUNT]; -extern unsafe chanend uc_dsp_to_dnr_t1; -extern unsafe chanend uc_key_to_ubm_t0; -extern unsafe chanend uc_audiohw; -#if HID_DFU_EN -extern unsafe streaming chanend uc_dfu; -#endif -extern void key_sender(chanend c_key); -extern void key_receiver(chanend c_key); -extern void mute_handler(); - - -/* Main for USB Audio Applications */ -int main() -{ -#if !XUA_USB_EN - #define c_mix_out null -#else - chan c_mix_out; -#endif - -#ifdef MIDI - chan c_midi; -#endif -#ifdef IAP - chan c_iap; -#ifdef IAP_EA_NATIVE_TRANS - chan c_ea_data; -#endif -#endif - -#if (MIXER) - chan c_mix_ctl; -#endif - -#if (XUA_SPDIF_RX_EN) - streaming chan c_spdif_rx; -#else -#define c_spdif_rx null -#endif - -#if (XUA_ADAT_RX_EN) - streaming chan c_adat_rx; -#else -#define c_adat_rx null -#endif - -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE) - chan c_spdif_tx; -#endif - -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - chan c_clk_ctl; - chan c_clk_int; -#else -#define c_clk_int null -#define c_clk_ctl null -#endif - -#if (XUA_DFU_EN == 1) - interface i_dfu dfuInterface; -#else - #define dfuInterface null -#endif - -#if (XUA_NUM_PDM_MICS > 0) - chan c_pdm_pcm; -#endif - -#if (((XUA_SYNCMODE == XUA_SYNCMODE_SYNC && !XUA_USE_SW_PLL) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) ) - interface pll_ref_if i_pll_ref; -#endif - -#if ((XUA_SYNCMODE == XUA_SYNCMODE_SYNC || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) && XUA_USE_SW_PLL) - chan c_sw_pll; -#endif -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) - chan c_audio_rate_change; /* Notification of new mclk freq to ep_buffer */ -#endif - chan c_sof; - chan c_xud_out[ENDPOINT_COUNT_OUT]; /* Endpoint channels for XUD */ - chan c_xud_in[ENDPOINT_COUNT_IN]; - - /* Used to communicate controls/setting from XUA_Endpoint0() to the Audio/Buffering sub-system */ - chan c_aud_ctl; - -#if (!MIXER) -#define c_mix_ctl null -#endif - -#ifdef IAP_EA_NATIVE_TRANS - chan c_EANativeTransport_ctrl; -#else -#define c_EANativeTransport_ctrl null -#endif - -//#if (HID_CONTROLS > 0) -// chan c_hid; -//#endif - - USER_MAIN_DECLARATIONS - - chan c_dsp_to_ex3d[DSP_WORKER_COUNT]; - chan cc_mic_level; - chan c_audiohw; -#if HID_DFU_EN - streaming chan c_dfu; -#endif - chan c_key; chan c_hidSendData; - chan c_hidRcvData; - chan c_eq_data; - chan c_uac_vol; - chan c_ex3d_hid_cmd; - - par - { - USER_MAIN_CORES - on tile[1] : { - par { - unsafe { - uc_audiohw = (chanend)c_audiohw; -#if EQ_EN == 1 && USE_EX3D == 0 - SetEqDataChan(c_eq_data); -#endif - hid_button_task(cc_mic_level, c_hidRcvData, c_hidSendData, c_uac_vol, c_ex3d_hid_cmd); - } -#if USE_EX3D == 1 - par(int i = 0; i < DSP_WORKER_COUNT; i++) - dsp_worker_tile(c_dsp_to_ex3d[i], i); - - unsafe { - SetEqDataChan(c_eq_data); - delay_milliseconds(200); - key_sender(c_key); - for (int i = 0; i < DSP_WORKER_COUNT; i++) - uc_dsp_to_ex3d[i] = (chanend)c_dsp_to_ex3d[i]; - ex3d_task(); - } -#endif - - } - } - on tile[1]: mute_handler(); - - on tile[0] : { - par { - { -#if USE_EX3D == 1 - unsafe { key_receiver(c_key); } -#endif - AudioHwRemote(c_hidSendData, cc_mic_level, c_uac_vol, c_audiohw -#if HID_DFU_EN - , c_dfu -#endif - ); - } - } - } -#if EQ_EN == 1 - on tile[0] : { - { - -#if HID_DFU_EN - unsafe { - uc_dfu = (streaming chanend)c_dfu; - } -#endif - - dsp_core0(); - } - } - on tile[0] : { dsp_main(c_eq_data); } -#endif - -#if DNR_ENABLE == 1 - on tile[0] : { dnr_dsp_proc_task(); } -#endif - -#if (((XUA_SYNCMODE == XUA_SYNCMODE_SYNC && !XUA_USE_SW_PLL) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)) - on tile[PLL_REF_TILE]: PllRefPinTask(i_pll_ref, p_pll_ref); -#endif - on tile[XUD_TILE]: - par - { -#if XUA_USB_EN -#if ((XUD_TILE == 0) && (XUA_DFU_EN == 1)) - /* Check if USB is on the flash tile (tile 0) */ - /* Expect to be distrbuted into XUA_Endpoint0() */ - [[distribute]] - DFUHandler(dfuInterface, null); -#endif - - /* Core USB task, buffering, USB etc */ - { -#ifdef XUD_PRIORITY_HIGH - set_core_high_priority_on(); -#endif - /* Run UAC2.0 at high-speed, UAC1.0 at full-speed */ - unsigned usbSpeed = (AUDIO_CLASS == 2) ? XUD_SPEED_HS : XUD_SPEED_FS; - - unsigned xudPwrCfg = (XUA_POWERMODE == XUA_POWERMODE_SELF) ? XUD_PWR_SELF : XUD_PWR_BUS; - - /* USB interface core */ - XUD_Main(c_xud_out, ENDPOINT_COUNT_OUT, c_xud_in, ENDPOINT_COUNT_IN, - c_sof, epTypeTableOut, epTypeTableIn, usbSpeed, xudPwrCfg); - } - -#if (NUM_USB_CHAN_OUT > 0) || (NUM_USB_CHAN_IN > 0) || XUA_HID_ENABLED || defined(MIDI) - /* Core USB audio task, buffering, USB etc */ - { - unsigned x; - thread_speed(); - - /* Attach mclk count port to mclk clock-block (for feedback) */ - //set_port_clock(p_for_mclk_count, clk_audio_mclk); -#if(AUDIO_IO_TILE != XUD_TILE) - set_clock_src(clk_audio_mclk_usb, p_mclk_in_usb); - set_port_clock(p_for_mclk_count, clk_audio_mclk_usb); - start_clock(clk_audio_mclk_usb); -#else - /* Clock port from same clock-block as I2S */ - /* TODO remove asm() */ - asm("ldw %0, dp[clk_audio_mclk]":"=r"(x)); - asm("setclk res[%0], %1"::"r"(p_for_mclk_count), "r"(x)); -#endif - /* Endpoint & audio buffering cores - buffers all EP's other than 0 */ - XUA_Buffer( -#if (NUM_USB_CHAN_OUT > 0) - c_xud_out[ENDPOINT_NUMBER_OUT_AUDIO], /* Audio Out*/ -#endif -#if (NUM_USB_CHAN_IN > 0) - c_xud_in[ENDPOINT_NUMBER_IN_AUDIO], /* Audio In */ -#endif -#if (NUM_USB_CHAN_OUT > 0) && ((NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP)) - c_xud_in[ENDPOINT_NUMBER_IN_FEEDBACK], /* Audio FB */ -#endif -#ifdef MIDI - c_xud_out[ENDPOINT_NUMBER_OUT_MIDI], /* MIDI Out */ // 2 - c_xud_in[ENDPOINT_NUMBER_IN_MIDI], /* MIDI In */ // 4 - c_midi, -#endif -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - /* Audio Interrupt - only used for interrupts on external clock change */ - c_xud_in[ENDPOINT_NUMBER_IN_INTERRUPT], - c_clk_int, -#endif - c_sof, c_aud_ctl, p_for_mclk_count -#if (XUA_HID_ENABLED) - , c_xud_in[ENDPOINT_NUMBER_IN_HID] -#endif - , c_mix_out -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) - , c_audio_rate_change - #if (!XUA_USE_SW_PLL) - , i_pll_ref - #else - , c_sw_pll - #endif -#endif - ); - //: - } -#endif - - /* Endpoint 0 Core */ - { - thread_speed(); -#if (USE_EX3D == 1) && (HID_CONTROLS > 0) - SetEx3dHidChan(c_ex3d_hid_cmd); - XUA_Endpoint0( c_xud_out[0], c_xud_in[0], c_hidRcvData, c_aud_ctl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface VENDOR_REQUESTS_PARAMS_); -#else - XUA_Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface VENDOR_REQUESTS_PARAMS_); -#endif - } - -#endif /* XUA_USB_EN */ - } - -#if ((XUA_SYNCMODE == XUA_SYNCMODE_SYNC || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) && XUA_USE_SW_PLL) - on tile[AUDIO_IO_TILE]: sw_pll_task(c_sw_pll); -#endif - - on tile[AUDIO_IO_TILE]: - { - /* Audio I/O task, includes mixing etc */ - usb_audio_io( -#if (NUM_USB_CHAN_OUT > 0) || (NUM_USB_CHAN_IN > 0) - /* Connect audio system to XUA_Buffer(); */ - c_mix_out -#else - /* Connect to XUA_Endpoint0() */ - c_aud_ctl -#endif -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE) - , c_spdif_tx -#endif -#if (MIXER) - , c_mix_ctl -#endif - , c_spdif_rx, c_adat_rx, c_clk_ctl, c_clk_int -#if (XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1) - , dfuInterface -#endif -#if (XUA_NUM_PDM_MICS > 0) - , c_pdm_pcm -#endif -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - , i_pll_ref -#endif -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) - , c_audio_rate_change -#endif -#if ((XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) && XUA_USE_SW_PLL) - , p_for_mclk_count_audio - , c_sw_pll -#endif - ); - } - //: - -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE) - on tile[SPDIF_TX_TILE]: - { - thread_speed(); - SpdifTxWrapper(c_spdif_tx); - } -#endif - -#if defined(MIDI) && defined(IAP) && (IAP_TILE == MIDI_TILE) - /* MIDI and IAP share a core */ - on tile[IAP_TILE]: - { - thread_speed(); - usb_midi(p_midi_rx, p_midi_tx, clk_midi, c_midi, 0, c_iap, null, null, null); - } -#else -#if defined(MIDI) - /* MIDI core */ - on tile[MIDI_TILE]: - { - thread_speed(); - usb_midi(p_midi_rx, p_midi_tx, clk_midi, c_midi, 0); - } -#endif -#if defined(IAP) - on tile[IAP_TILE]: - { - thread_speed(); - iAP(c_iap, null, null, null); - } -#endif -#endif - -#if (XUA_SPDIF_RX_EN) - on tile[XUD_TILE]: - { - thread_speed(); - spdif_rx(c_spdif_rx, p_spdif_rx, clk_spd_rx, 192000); - } -#endif - -#if (XUA_ADAT_RX_EN) - on stdcore[XUD_TILE] : - { - set_thread_fast_mode_on(); - - while (1) - { - adatReceiver48000(p_adat_rx, c_adat_rx); - adatReceiver44100(p_adat_rx, c_adat_rx); - } - } -#endif - - -#if XUA_USB_EN -#if (XUD_TILE != 0) && (AUDIO_IO_TILE != 0) && (XUA_DFU_EN == 1) - /* Run flash code on its own - hope it gets combined */ - //#warning Running DFU flash code on its own - on stdcore[0]: DFUHandler(dfuInterface, null); -#endif -#endif - -#if (XUA_NUM_PDM_MICS > 0) - /* PDM Mics running on a separate to AudioHub */ - on stdcore[PDM_TILE]: - { - mic_array_task(c_mic_pcm); - } -#endif /*XUA_NUM_PDM_MICS > 0*/ - } - - return 0; -} - -#endif diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/main.xc.gemini b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/main.xc.gemini deleted file mode 100644 index d1d2184..0000000 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/main.xc.gemini +++ /dev/null @@ -1,844 +0,0 @@ -// Copyright 2012-2024 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. - -#include "xua.h" /* Device specific defines */ -#ifdef EXCLUDE_USB_AUDIO_MAIN - -/** - * @file main.xc - * @brief Top level for XMOS USB 2.0 Audio 2.0 Reference Designs. - * @author Ross Owen, XMOS Semiconductor Ltd - */ -#include -#include -#include -#include -#include -#ifdef XSCOPE -#include -#endif - -#if XUA_USB_EN -#include "xud_device.h" /* XMOS USB Device Layer defines and functions */ -#include "xua_endpoint0.h" -#endif - -#include "uac_hwresources.h" - -#ifdef IAP -#include "i2c_shared.h" -#include "iap.h" -#endif - -#if (XUA_SPDIF_RX_EN || XUA_SPDIF_TX_EN) -#include "spdif.h" /* From lib_spdif */ -#endif - -#if (XUA_ADAT_RX_EN) -#include "adat_rx.h" -#endif - -#if (XUA_NUM_PDM_MICS > 0) -#include "xua_pdm_mic.h" -#endif - -#if (XUA_DFU_EN == 1) -[[distributable]] -void DFUHandler(server interface i_dfu i, chanend ?c_user_cmd); -#endif - -/* Audio I/O - Port declarations */ -#if I2S_WIRES_DAC > 0 -on tile[AUDIO_IO_TILE] : buffered out port:32 p_i2s_dac[I2S_WIRES_DAC] = - {PORT_I2S_DAC0, -#endif -#if I2S_WIRES_DAC > 1 - PORT_I2S_DAC1, -#endif -#if I2S_WIRES_DAC > 2 - PORT_I2S_DAC2, -#endif -#if I2S_WIRES_DAC > 3 - PORT_I2S_DAC3, -#endif -#if I2S_WIRES_DAC > 4 - PORT_I2S_DAC4, -#endif -#if I2S_WIRES_DAC > 5 - PORT_I2S_DAC5, -#endif -#if I2S_WIRES_DAC > 6 - PORT_I2S_DAC6, -#endif -#if I2S_WIRES_DAC > 7 -#error I2S_WIRES_DAC value is too large! -#endif -#if I2S_WIRES_DAC > 0 - }; -#else - #define p_i2s_dac null -#endif - -#if I2S_WIRES_ADC > 0 -on tile[AUDIO_IO_TILE] : buffered in port:32 p_i2s_adc[I2S_WIRES_ADC] = - {PORT_I2S_ADC0, -#endif -#if I2S_WIRES_ADC > 1 - PORT_I2S_ADC1, -#endif -#if I2S_WIRES_ADC > 2 - PORT_I2S_ADC2, -#endif -#if I2S_WIRES_ADC > 3 - PORT_I2S_ADC3, -#endif -#if I2S_WIRES_ADC > 4 - PORT_I2S_ADC4, -#endif -#if I2S_WIRES_ADC > 5 - PORT_I2S_ADC5, -#endif -#if I2S_WIRES_ADC > 6 - PORT_I2S_ADC6, -#endif -#if I2S_WIRES_ADC > 7 -#error I2S_WIRES_ADC value is too large! -#endif -#if I2S_WIRES_ADC > 0 - }; -#else - #define p_i2s_adc null -#endif - - -#if CODEC_MASTER -on tile[AUDIO_IO_TILE] : buffered in port:32 p_lrclk = PORT_I2S_LRCLK; -on tile[AUDIO_IO_TILE] : buffered in port:32 p_bclk = PORT_I2S_BCLK; -#else -on tile[AUDIO_IO_TILE] : buffered out port:32 p_lrclk = PORT_I2S_LRCLK; -on tile[AUDIO_IO_TILE] : buffered out port:32 p_bclk = PORT_I2S_BCLK; -#endif - -#if (!CODEC_MASTER) || XUA_SPDIF_TX_EN || XUA_ADAT_TX_EN || ((AUDIO_IO_TILE == XUD_TILE) && XUA_USB_EN) -/* Audio master clock input */ -on tile[AUDIO_IO_TILE] : in port p_mclk_in = PORT_MCLK_IN; -#else -#define p_mclk_in null -#endif - -#if (AUDIO_IO_TILE != XUD_TILE) && XUA_USB_EN -/* If audio I/O and USB running on different tiles we need a separate port for - * the master clock input (to use for USB async feedback calculation) */ -on tile[XUD_TILE] : in port p_mclk_in_usb = PORT_MCLK_IN_USB; -#endif - -#if XUA_USB_EN -on tile[XUD_TILE] : in port p_for_mclk_count = PORT_MCLK_COUNT; -#endif - -#if (XUA_SPDIF_TX_EN) -on tile[SPDIF_TX_TILE] : buffered out port:32 p_spdif_tx = PORT_SPDIF_OUT; -#endif - -#if (XUA_ADAT_TX_EN) -on stdcore[AUDIO_IO_TILE] : buffered out port:32 p_adat_tx = PORT_ADAT_OUT; -#endif - -#if (XUA_ADAT_RX_EN) -on stdcore[XUD_TILE] : buffered in port:32 p_adat_rx = PORT_ADAT_IN; -#endif - -#if (XUA_SPDIF_RX_EN) -on tile[XUD_TILE] : in port p_spdif_rx = PORT_SPDIF_IN; -#endif - -#if (XUA_SPDIF_RX_EN) || (XUA_ADAT_RX_EN) || (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) -/* Reference to external clock multiplier */ -on tile[PLL_REF_TILE] : out port p_pll_ref = PORT_PLL_REF; -#ifdef __XS3A__ -on tile[AUDIO_IO_TILE] : port p_for_mclk_count_audio = PORT_MCLK_COUNT_2; -#else /* __XS3A__ */ -#define p_for_mclk_count_audio null -#endif /* __XS3A__ */ -#endif - -#ifdef MIDI -on tile[MIDI_TILE] : port p_midi_tx = PORT_MIDI_OUT; - -#if(MIDI_RX_PORT_WIDTH == 4) -on tile[MIDI_TILE] : buffered in port:4 p_midi_rx = PORT_MIDI_IN; -#elif(MIDI_RX_PORT_WIDTH == 1) -on tile[MIDI_TILE] : buffered in port:1 p_midi_rx = PORT_MIDI_IN; -#endif -#endif - - -#ifdef MIDI -on tile[MIDI_TILE] : clock clk_midi = CLKBLK_MIDI; -#endif - -#if (XUA_SPDIF_TX_EN || XUA_ADAT_TX_EN) -on tile[SPDIF_TX_TILE] : clock clk_mst_spd = CLKBLK_SPDIF_TX; -#endif - -#if (XUA_SPDIF_RX_EN) -on tile[XUD_TILE] : clock clk_spd_rx = CLKBLK_SPDIF_RX; -#endif - -on tile[AUDIO_IO_TILE] : clock clk_audio_mclk = CLKBLK_MCLK; /* Master clock */ - -#if (AUDIO_IO_TILE != XUD_TILE) && XUA_USB_EN -/* Separate clock/port for USB feedback calculation */ -on tile[XUD_TILE] : clock clk_audio_mclk_usb = CLKBLK_MCLK; /* Master clock */ -#endif - -on tile[AUDIO_IO_TILE] : clock clk_audio_bclk = CLKBLK_I2S_BIT; /* Bit clock */ - -#ifdef IAP -/* I2C ports - in a struct for use with module_i2c_shared & module_i2c_simple/module_i2c_single_port */ -#ifdef PORT_I2C -on tile [IAP_TILE] : struct r_i2c r_i2c = {PORT_I2C}; -#else -on tile [IAP_TILE] : struct r_i2c r_i2c = {PORT_I2C_SCL, PORT_I2C_SDA}; -#endif -#endif - -#if XUA_USB_EN -/* Endpoint type tables for XUD */ -XUD_EpType epTypeTableOut[ENDPOINT_COUNT_OUT] = { XUD_EPTYPE_CTL | XUD_STATUS_ENABLE, -#if (NUM_USB_CHAN_IN > 0) - XUD_EPTYPE_ISO, /* Audio */ -#endif -#ifdef MIDI - XUD_EPTYPE_BUL, /* MIDI */ -#endif -#if HID_OUT_REQUIRED - XUD_EPTYPE_INT, -#endif -#ifdef IAP - XUD_EPTYPE_BUL, /* iAP */ -#ifdef IAP_EA_NATIVE_TRANS - XUD_EPTYPE_BUL, /* EA Native Transport */ -#endif -#endif - }; - -XUD_EpType epTypeTableIn[ENDPOINT_COUNT_IN] = { XUD_EPTYPE_CTL | XUD_STATUS_ENABLE, -#if (NUM_USB_CHAN_IN > 0) - XUD_EPTYPE_ISO, -#endif -#if (NUM_USB_CHAN_OUT > 0) && ((NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP)) - XUD_EPTYPE_ISO, /* Async feedback endpoint */ -#endif -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - XUD_EPTYPE_INT, -#endif -#ifdef MIDI - XUD_EPTYPE_BUL, -#endif -#if XUA_OR_STATIC_HID_ENABLED - XUD_EPTYPE_INT, -#endif -#ifdef IAP - XUD_EPTYPE_BUL | XUD_STATUS_ENABLE, -#ifdef IAP_INT_EP - XUD_EPTYPE_BUL | XUD_STATUS_ENABLE, -#endif -#ifdef IAP_EA_NATIVE_TRANS - XUD_EPTYPE_BUL | XUD_STATUS_ENABLE, -#endif -#endif - }; -#endif /* XUA_USB_EN */ - -void thread_speed() -{ -#ifdef FAST_MODE -#warning Building with fast mode enabled - set_thread_fast_mode_on(); -#else - set_thread_fast_mode_off(); -#endif -} - -#ifdef XSCOPE -void xscope_user_init() -{ - xscope_register(0, 0, "", 0, ""); - - xscope_config_io(XSCOPE_IO_BASIC); -} -#endif - -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE) -void SpdifTxWrapper(chanend c_spdif_tx) -{ - unsigned portId; - //configure_clock_src(clk, p_mclk); - - // TODO could share clock block here.. - // NOTE, Assuming SPDIF tile == USB tile here.. - asm("ldw %0, dp[p_mclk_in_usb]":"=r"(portId)); - asm("setclk res[%0], %1"::"r"(clk_mst_spd), "r"(portId)); - configure_out_port_no_ready(p_spdif_tx, clk_mst_spd, 0); - set_clock_fall_delay(clk_mst_spd, 7); - start_clock(clk_mst_spd); - - while(1) - { - spdif_tx(p_spdif_tx, c_spdif_tx); - } -} -#endif - -void usb_audio_io(chanend ?c_aud_in, -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE) - chanend c_spdif_tx, -#endif -#if (MIXER) - chanend c_mix_ctl, -#endif - streaming chanend ?c_spdif_rx, - streaming chanend ?c_adat_rx, - chanend ?c_clk_ctl, - chanend ?c_clk_int -#if (XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1) - , server interface i_dfu ?dfuInterface -#endif -#if (XUA_NUM_PDM_MICS > 0) - , chanend c_pdm_pcm -#endif -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - , client interface pll_ref_if i_pll_ref -#endif -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) - , chanend c_audio_rate_change -#endif -#if ((XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) && XUA_USE_SW_PLL) - , port p_for_mclk_count_aud - , chanend c_sw_pll -#endif -) -{ -#if (MIXER) - chan c_mix_out; -#endif - -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - chan c_dig_rx; - chan c_audio_rate_change; /* Notification of new mclk freq to clockgen and synch */ -#if XUA_USE_SW_PLL - /* Connect p_for_mclk_count_aud to clk_audio_mclk so we can count mclks/timestamp in digital rx*/ - unsigned x = 0; - asm("ldw %0, dp[clk_audio_mclk]":"=r"(x)); - asm("setclk res[%0], %1"::"r"(p_for_mclk_count_aud), "r"(x)); -#endif /* XUA_USE_SW_PLL */ -#endif /* (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) */ - - -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE == AUDIO_IO_TILE) - chan c_spdif_tx; - - /* Setup S/PDIF tx port - note this is done before par since sharing clock-block/port */ - spdif_tx_port_config(p_spdif_tx, clk_audio_mclk, p_mclk_in, 7); -#endif - - par - { -#if (MIXER && XUA_USB_EN) - /* Mixer cores(s) */ - { - thread_speed(); - mixer(c_aud_in, c_mix_out, c_mix_ctl); - } -#endif - -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE == AUDIO_IO_TILE) - while(1) - { - spdif_tx(p_spdif_tx, c_spdif_tx); - } -#endif - - /* Audio I/O core (pars additional S/PDIF TX Core) */ - { - thread_speed(); -#if (MIXER) -#define AUDIO_CHANNEL c_mix_out -#else -#define AUDIO_CHANNEL c_aud_in -#endif - XUA_AudioHub(AUDIO_CHANNEL, clk_audio_mclk, clk_audio_bclk, p_mclk_in, p_lrclk, p_bclk, p_i2s_dac, p_i2s_adc -#if (XUA_SPDIF_TX_EN) //&& (SPDIF_TX_TILE != AUDIO_IO_TILE) - , c_spdif_tx -#endif -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - , c_dig_rx -#endif -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - , c_audio_rate_change -#endif -#if (XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1) - , dfuInterface -#endif -#if (XUA_NUM_PDM_MICS > 0) - , c_pdm_pcm -#endif - ); - } - -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - { - /* ClockGen must currently run on same tile as AudioHub due to shared memory buffer - * However, due to the use of an interface the pll reference signal port can be on another tile - */ - thread_speed(); - clockGen( c_spdif_rx, - c_adat_rx, - i_pll_ref, - c_dig_rx, - c_clk_ctl, - c_clk_int, - c_audio_rate_change -#if XUA_USE_SW_PLL - , p_for_mclk_count_aud - , c_sw_pll -#endif - ); - } -#endif - - } // par -} - -#ifndef USER_MAIN_DECLARATIONS -#define USER_MAIN_DECLARATIONS -#endif - -#ifndef USER_MAIN_CORES -#define USER_MAIN_CORES -#endif - -//extern unsafe client interface i2c_master_if i_i2c_client; -//extern unsafe client interface i2c_master_if i_i2c_client_t0; -extern void dsp_core0(void); -extern void board_setup(); -extern void dsp_main (streaming chanend c_data); -extern void SetEqDataChan (streaming chanend c); -extern void SetUbmInitChan (streaming chanend c); -extern void UserBufferForwardingTask(streaming chanend c_dsp, streaming chanend c_init); -extern void SetEx3dHidChan (chanend c); - -extern int dsp_worker_tile(chanend c_dsp_to_ex3d, int worker_id); -//extern int dsp_worker_tile_1(chanend c_dsp_to_ex3d, int worker_id); -extern void ex3d_task(); -extern void hid_button_task(chanend cc_mic_level, chanend c_hid, chanend c_hidSendData, chanend c_uac_vol, chanend c_ex3d_hid_cmd); -#if HID_DFU_EN -extern void AudioHwRemote(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, chanend c_audiohw_rx, streaming chanend c_dfu_rx, chanend c_mic_det); -#else -extern void AudioHwRemote(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, chanend c_audiohw_rx, chanend c_mic_det); -#endif -extern void dnr_dsp_proc_task(void); - -extern unsafe chanend uc_dsp_to_ex3d[DSP_WORKER_COUNT]; -extern unsafe chanend uc_dsp_to_dnr_t1; -extern unsafe chanend uc_key_to_ubm_t0; -extern unsafe chanend uc_audiohw; -#if HID_DFU_EN -extern unsafe streaming chanend uc_dfu; -#endif -extern void key_sender(chanend c_key); -extern void key_receiver(chanend c_key); -extern void mute_handler(chanend c_mic_det); - - -/* Main for USB Audio Applications */ -int main() -{ -#if !XUA_USB_EN - #define c_mix_out null -#else - chan c_mix_out; -#endif - -#ifdef MIDI - chan c_midi; -#endif -#ifdef IAP - chan c_iap; -#ifdef IAP_EA_NATIVE_TRANS - chan c_ea_data; -#endif -#endif - -#if (MIXER) - chan c_mix_ctl; -#endif - -#if (XUA_SPDIF_RX_EN) - streaming chan c_spdif_rx; -#else -#define c_spdif_rx null -#endif - -#if (XUA_ADAT_RX_EN) - streaming chan c_adat_rx; -#else -#define c_adat_rx null -#endif - -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE) - chan c_spdif_tx; -#endif - -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - chan c_clk_ctl; - chan c_clk_int; -#else -#define c_clk_int null -#define c_clk_ctl null -#endif - -#if (XUA_DFU_EN == 1) - interface i_dfu dfuInterface; -#else - #define dfuInterface null -#endif - -#if (XUA_NUM_PDM_MICS > 0) - chan c_pdm_pcm; -#endif - -#if (((XUA_SYNCMODE == XUA_SYNCMODE_SYNC && !XUA_USE_SW_PLL) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) ) - interface pll_ref_if i_pll_ref; -#endif - -#if ((XUA_SYNCMODE == XUA_SYNCMODE_SYNC || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) && XUA_USE_SW_PLL) - chan c_sw_pll; -#endif -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) - chan c_audio_rate_change; /* Notification of new mclk freq to ep_buffer */ -#endif - chan c_sof; - chan c_xud_out[ENDPOINT_COUNT_OUT]; /* Endpoint channels for XUD */ - chan c_xud_in[ENDPOINT_COUNT_IN]; - - /* Used to communicate controls/setting from XUA_Endpoint0() to the Audio/Buffering sub-system */ - chan c_aud_ctl; - -#if (!MIXER) -#define c_mix_ctl null -#endif - -#ifdef IAP_EA_NATIVE_TRANS - chan c_EANativeTransport_ctrl; -#else -#define c_EANativeTransport_ctrl null -#endif - -//#if (HID_CONTROLS > 0) -// chan c_hid; -//#endif - - USER_MAIN_DECLARATIONS - - chan c_dsp_to_ex3d[DSP_WORKER_COUNT]; - chan cc_mic_level; - chan c_audiohw; -#if HID_DFU_EN - streaming chan c_dfu; -#endif - chan c_key; chan c_hidSendData; - chan c_hidRcvData; - streaming chan c_eq_data; - streaming chan c_ubm_init; - chan c_uac_vol; - chan c_ex3d_hid_cmd; - chan c_mic_det; - - par - { - USER_MAIN_CORES - on tile[1] : { - par { - // Forwarder Task on its own core - UserBufferForwardingTask(c_eq_data, c_ubm_init); - - // HID & Control sequence on its own core - unsafe { - uc_audiohw = (chanend)c_audiohw; - SetUbmInitChan(c_ubm_init); - hid_button_task(cc_mic_level, c_hidRcvData, c_hidSendData, c_uac_vol, c_ex3d_hid_cmd); - } - -#if USE_EX3D == 1 - // Workers on their own cores - par(int i = 0; i < DSP_WORKER_COUNT; i++) - dsp_worker_tile(c_dsp_to_ex3d[i], i); - - // EX3D Task sequence on its own core - unsafe { - delay_milliseconds(200); - key_sender(c_key); - for (int i = 0; i < DSP_WORKER_COUNT; i++) - uc_dsp_to_ex3d[i] = (chanend)c_dsp_to_ex3d[i]; - ex3d_task(); - } -#endif - } - } - on tile[1]: mute_handler(c_mic_det); - - on tile[0] : { - par { - { -#if USE_EX3D == 1 - unsafe { key_receiver(c_key); } -#endif - AudioHwRemote(c_hidSendData, cc_mic_level, c_uac_vol, c_audiohw -#if HID_DFU_EN - , c_dfu -#endif - , c_mic_det - ); - } - } - } -#if EQ_EN == 1 - on tile[0] : { - { - -#if HID_DFU_EN - unsafe { - uc_dfu = (streaming chanend)c_dfu; - } -#endif - - dsp_core0(); - } - } - on tile[0] : { dsp_main(c_eq_data); } -#endif - -#if DNR_ENABLE == 1 - on tile[0] : { dnr_dsp_proc_task(); } -#endif - -#if (((XUA_SYNCMODE == XUA_SYNCMODE_SYNC && !XUA_USE_SW_PLL) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)) - on tile[PLL_REF_TILE]: PllRefPinTask(i_pll_ref, p_pll_ref); -#endif - on tile[XUD_TILE]: - par - { -#if XUA_USB_EN -#if ((XUD_TILE == 0) && (XUA_DFU_EN == 1)) - /* Check if USB is on the flash tile (tile 0) */ - /* Expect to be distrbuted into XUA_Endpoint0() */ - [[distribute]] - DFUHandler(dfuInterface, null); -#endif - - /* Core USB task, buffering, USB etc */ - { -#ifdef XUD_PRIORITY_HIGH - set_core_high_priority_on(); -#endif - /* Run UAC2.0 at high-speed, UAC1.0 at full-speed */ - unsigned usbSpeed = (AUDIO_CLASS == 2) ? XUD_SPEED_HS : XUD_SPEED_FS; - - unsigned xudPwrCfg = (XUA_POWERMODE == XUA_POWERMODE_SELF) ? XUD_PWR_SELF : XUD_PWR_BUS; - - /* USB interface core */ - XUD_Main(c_xud_out, ENDPOINT_COUNT_OUT, c_xud_in, ENDPOINT_COUNT_IN, - c_sof, epTypeTableOut, epTypeTableIn, usbSpeed, xudPwrCfg); - } - -#if (NUM_USB_CHAN_OUT > 0) || (NUM_USB_CHAN_IN > 0) || XUA_HID_ENABLED || defined(MIDI) - /* Core USB audio task, buffering, USB etc */ - { - unsigned x; - thread_speed(); - - /* Attach mclk count port to mclk clock-block (for feedback) */ - //set_port_clock(p_for_mclk_count, clk_audio_mclk); -#if(AUDIO_IO_TILE != XUD_TILE) - set_clock_src(clk_audio_mclk_usb, p_mclk_in_usb); - set_port_clock(p_for_mclk_count, clk_audio_mclk_usb); - start_clock(clk_audio_mclk_usb); -#else - /* Clock port from same clock-block as I2S */ - /* TODO remove asm() */ - asm("ldw %0, dp[clk_audio_mclk]":"=r"(x)); - asm("setclk res[%0], %1"::"r"(p_for_mclk_count), "r"(x)); -#endif - /* Endpoint & audio buffering cores - buffers all EP's other than 0 */ - XUA_Buffer( -#if (NUM_USB_CHAN_OUT > 0) - c_xud_out[ENDPOINT_NUMBER_OUT_AUDIO], /* Audio Out*/ -#endif -#if (NUM_USB_CHAN_IN > 0) - c_xud_in[ENDPOINT_NUMBER_IN_AUDIO], /* Audio In */ -#endif -#if (NUM_USB_CHAN_OUT > 0) && ((NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP)) - c_xud_in[ENDPOINT_NUMBER_IN_FEEDBACK], /* Audio FB */ -#endif -#ifdef MIDI - c_xud_out[ENDPOINT_NUMBER_OUT_MIDI], /* MIDI Out */ // 2 - c_xud_in[ENDPOINT_NUMBER_IN_MIDI], /* MIDI In */ // 4 - c_midi, -#endif -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - /* Audio Interrupt - only used for interrupts on external clock change */ - c_xud_in[ENDPOINT_NUMBER_IN_INTERRUPT], - c_clk_int, -#endif - c_sof, c_aud_ctl, p_for_mclk_count -#if (XUA_HID_ENABLED) - , c_xud_in[ENDPOINT_NUMBER_IN_HID] -#endif - , c_mix_out -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) - , c_audio_rate_change - #if (!XUA_USE_SW_PLL) - , i_pll_ref - #else - , c_sw_pll - #endif -#endif - ); - //: - } -#endif - - /* Endpoint 0 Core */ - { - thread_speed(); -#if (USE_EX3D == 1) && (HID_CONTROLS > 0) - SetEx3dHidChan(c_ex3d_hid_cmd); - XUA_Endpoint0( c_xud_out[0], c_xud_in[0], c_hidRcvData, c_aud_ctl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface VENDOR_REQUESTS_PARAMS_); -#else - XUA_Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface VENDOR_REQUESTS_PARAMS_); -#endif - } - -#endif /* XUA_USB_EN */ - } - -#if ((XUA_SYNCMODE == XUA_SYNCMODE_SYNC || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) && XUA_USE_SW_PLL) - on tile[AUDIO_IO_TILE]: sw_pll_task(c_sw_pll); -#endif - - on tile[AUDIO_IO_TILE]: - { - set_core_high_priority_on(); - /* Audio I/O task, includes mixing etc */ - usb_audio_io( -#if (NUM_USB_CHAN_OUT > 0) || (NUM_USB_CHAN_IN > 0) - /* Connect audio system to XUA_Buffer(); */ - c_mix_out -#else - /* Connect to XUA_Endpoint0() */ - c_aud_ctl -#endif -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE) - , c_spdif_tx -#endif -#if (MIXER) - , c_mix_ctl -#endif - , c_spdif_rx, c_adat_rx, c_clk_ctl, c_clk_int -#if (XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1) - , dfuInterface -#endif -#if (XUA_NUM_PDM_MICS > 0) - , c_pdm_pcm -#endif -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - , i_pll_ref -#endif -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) - , c_audio_rate_change -#endif -#if ((XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) && XUA_USE_SW_PLL) - , p_for_mclk_count_audio - , c_sw_pll -#endif - ); - } - -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE) - on tile[SPDIF_TX_TILE]: - { - thread_speed(); - SpdifTxWrapper(c_spdif_tx); - } -#endif - -#if defined(MIDI) && defined(IAP) && (IAP_TILE == MIDI_TILE) - /* MIDI and IAP share a core */ - on tile[IAP_TILE]: - { - thread_speed(); - usb_midi(p_midi_rx, p_midi_tx, clk_midi, c_midi, 0, c_iap, null, null, null); - } -#else -#if defined(MIDI) - /* MIDI core */ - on tile[MIDI_TILE]: - { - thread_speed(); - usb_midi(p_midi_rx, p_midi_tx, clk_midi, c_midi, 0); - } -#endif -#if defined(IAP) - on tile[IAP_TILE]: - { - thread_speed(); - iAP(c_iap, null, null, null); - } -#endif -#endif - -#if (XUA_SPDIF_RX_EN) - on tile[XUD_TILE]: - { - thread_speed(); - spdif_rx(c_spdif_rx, p_spdif_rx, clk_spd_rx, 192000); - } -#endif - -#if (XUA_ADAT_RX_EN) - on stdcore[XUD_TILE] : - { - set_thread_fast_mode_on(); - - while (1) - { - adatReceiver48000(p_adat_rx, c_adat_rx); - adatReceiver44100(p_adat_rx, c_adat_rx); - } - } -#endif - - -#if XUA_USB_EN -#if (XUD_TILE != 0) && (AUDIO_IO_TILE != 0) && (XUA_DFU_EN == 1) - /* Run flash code on its own - hope it gets combined */ - //#warning Running DFU flash code on its own - on stdcore[0]: DFUHandler(dfuInterface, null); -#endif -#endif - -#if (XUA_NUM_PDM_MICS > 0) - /* PDM Mics running on a separate to AudioHub */ - on stdcore[PDM_TILE]: - { - mic_array_task(c_mic_pcm); - } -#endif /*XUA_NUM_PDM_MICS > 0*/ - } - - return 0; -} - -#endif diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/main.xc.gemini1 b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/main.xc.gemini1 deleted file mode 100644 index c5d664e..0000000 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/main.xc.gemini1 +++ /dev/null @@ -1,846 +0,0 @@ -// Copyright 2012-2024 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. - -#include "xua.h" /* Device specific defines */ -#ifdef EXCLUDE_USB_AUDIO_MAIN - -/** - * @file main.xc - * @brief Top level for XMOS USB 2.0 Audio 2.0 Reference Designs. - * @author Ross Owen, XMOS Semiconductor Ltd - */ -#include -#include -#include -#include -#include -#ifdef XSCOPE -#include -#endif - -#if XUA_USB_EN -#include "xud_device.h" /* XMOS USB Device Layer defines and functions */ -#include "xua_endpoint0.h" -#endif - -#include "uac_hwresources.h" - -#ifdef IAP -#include "i2c_shared.h" -#include "iap.h" -#endif - -#if (XUA_SPDIF_RX_EN || XUA_SPDIF_TX_EN) -#include "spdif.h" /* From lib_spdif */ -#endif - -#if (XUA_ADAT_RX_EN) -#include "adat_rx.h" -#endif - -#if (XUA_NUM_PDM_MICS > 0) -#include "xua_pdm_mic.h" -#endif - -#if (XUA_DFU_EN == 1) -[[distributable]] -void DFUHandler(server interface i_dfu i, chanend ?c_user_cmd); -#endif - -/* Audio I/O - Port declarations */ -#if I2S_WIRES_DAC > 0 -on tile[AUDIO_IO_TILE] : buffered out port:32 p_i2s_dac[I2S_WIRES_DAC] = - {PORT_I2S_DAC0, -#endif -#if I2S_WIRES_DAC > 1 - PORT_I2S_DAC1, -#endif -#if I2S_WIRES_DAC > 2 - PORT_I2S_DAC2, -#endif -#if I2S_WIRES_DAC > 3 - PORT_I2S_DAC3, -#endif -#if I2S_WIRES_DAC > 4 - PORT_I2S_DAC4, -#endif -#if I2S_WIRES_DAC > 5 - PORT_I2S_DAC5, -#endif -#if I2S_WIRES_DAC > 6 - PORT_I2S_DAC6, -#endif -#if I2S_WIRES_DAC > 7 -#error I2S_WIRES_DAC value is too large! -#endif -#if I2S_WIRES_DAC > 0 - }; -#else - #define p_i2s_dac null -#endif - -#if I2S_WIRES_ADC > 0 -on tile[AUDIO_IO_TILE] : buffered in port:32 p_i2s_adc[I2S_WIRES_ADC] = - {PORT_I2S_ADC0, -#endif -#if I2S_WIRES_ADC > 1 - PORT_I2S_ADC1, -#endif -#if I2S_WIRES_ADC > 2 - PORT_I2S_ADC2, -#endif -#if I2S_WIRES_ADC > 3 - PORT_I2S_ADC3, -#endif -#if I2S_WIRES_ADC > 4 - PORT_I2S_ADC4, -#endif -#if I2S_WIRES_ADC > 5 - PORT_I2S_ADC5, -#endif -#if I2S_WIRES_ADC > 6 - PORT_I2S_ADC6, -#endif -#if I2S_WIRES_ADC > 7 -#error I2S_WIRES_ADC value is too large! -#endif -#if I2S_WIRES_ADC > 0 - }; -#else - #define p_i2s_adc null -#endif - - -#if CODEC_MASTER -on tile[AUDIO_IO_TILE] : buffered in port:32 p_lrclk = PORT_I2S_LRCLK; -on tile[AUDIO_IO_TILE] : buffered in port:32 p_bclk = PORT_I2S_BCLK; -#else -on tile[AUDIO_IO_TILE] : buffered out port:32 p_lrclk = PORT_I2S_LRCLK; -on tile[AUDIO_IO_TILE] : buffered out port:32 p_bclk = PORT_I2S_BCLK; -#endif - -#if (!CODEC_MASTER) || XUA_SPDIF_TX_EN || XUA_ADAT_TX_EN || ((AUDIO_IO_TILE == XUD_TILE) && XUA_USB_EN) -/* Audio master clock input */ -on tile[AUDIO_IO_TILE] : in port p_mclk_in = PORT_MCLK_IN; -#else -#define p_mclk_in null -#endif - -#if (AUDIO_IO_TILE != XUD_TILE) && XUA_USB_EN -/* If audio I/O and USB running on different tiles we need a separate port for - * the master clock input (to use for USB async feedback calculation) */ -on tile[XUD_TILE] : in port p_mclk_in_usb = PORT_MCLK_IN_USB; -#endif - -#if XUA_USB_EN -on tile[XUD_TILE] : in port p_for_mclk_count = PORT_MCLK_COUNT; -#endif - -#if (XUA_SPDIF_TX_EN) -on tile[SPDIF_TX_TILE] : buffered out port:32 p_spdif_tx = PORT_SPDIF_OUT; -#endif - -#if (XUA_ADAT_TX_EN) -on stdcore[AUDIO_IO_TILE] : buffered out port:32 p_adat_tx = PORT_ADAT_OUT; -#endif - -#if (XUA_ADAT_RX_EN) -on stdcore[XUD_TILE] : buffered in port:32 p_adat_rx = PORT_ADAT_IN; -#endif - -#if (XUA_SPDIF_RX_EN) -on tile[XUD_TILE] : in port p_spdif_rx = PORT_SPDIF_IN; -#endif - -#if (XUA_SPDIF_RX_EN) || (XUA_ADAT_RX_EN) || (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) -/* Reference to external clock multiplier */ -on tile[PLL_REF_TILE] : out port p_pll_ref = PORT_PLL_REF; -#ifdef __XS3A__ -on tile[AUDIO_IO_TILE] : port p_for_mclk_count_audio = PORT_MCLK_COUNT_2; -#else /* __XS3A__ */ -#define p_for_mclk_count_audio null -#endif /* __XS3A__ */ -#endif - -#ifdef MIDI -on tile[MIDI_TILE] : port p_midi_tx = PORT_MIDI_OUT; - -#if(MIDI_RX_PORT_WIDTH == 4) -on tile[MIDI_TILE] : buffered in port:4 p_midi_rx = PORT_MIDI_IN; -#elif(MIDI_RX_PORT_WIDTH == 1) -on tile[MIDI_TILE] : buffered in port:1 p_midi_rx = PORT_MIDI_IN; -#endif -#endif - - -#ifdef MIDI -on tile[MIDI_TILE] : clock clk_midi = CLKBLK_MIDI; -#endif - -#if (XUA_SPDIF_TX_EN || XUA_ADAT_TX_EN) -on tile[SPDIF_TX_TILE] : clock clk_mst_spd = CLKBLK_SPDIF_TX; -#endif - -#if (XUA_SPDIF_RX_EN) -on tile[XUD_TILE] : clock clk_spd_rx = CLKBLK_SPDIF_RX; -#endif - -on tile[AUDIO_IO_TILE] : clock clk_audio_mclk = CLKBLK_MCLK; /* Master clock */ - -#if (AUDIO_IO_TILE != XUD_TILE) && XUA_USB_EN -/* Separate clock/port for USB feedback calculation */ -on tile[XUD_TILE] : clock clk_audio_mclk_usb = CLKBLK_MCLK; /* Master clock */ -#endif - -on tile[AUDIO_IO_TILE] : clock clk_audio_bclk = CLKBLK_I2S_BIT; /* Bit clock */ - -#ifdef IAP -/* I2C ports - in a struct for use with module_i2c_shared & module_i2c_simple/module_i2c_single_port */ -#ifdef PORT_I2C -on tile [IAP_TILE] : struct r_i2c r_i2c = {PORT_I2C}; -#else -on tile [IAP_TILE] : struct r_i2c r_i2c = {PORT_I2C_SCL, PORT_I2C_SDA}; -#endif -#endif - -#if XUA_USB_EN -/* Endpoint type tables for XUD */ -XUD_EpType epTypeTableOut[ENDPOINT_COUNT_OUT] = { XUD_EPTYPE_CTL | XUD_STATUS_ENABLE, -#if (NUM_USB_CHAN_IN > 0) - XUD_EPTYPE_ISO, /* Audio */ -#endif -#ifdef MIDI - XUD_EPTYPE_BUL, /* MIDI */ -#endif -#if HID_OUT_REQUIRED - XUD_EPTYPE_INT, -#endif -#ifdef IAP - XUD_EPTYPE_BUL, /* iAP */ -#ifdef IAP_EA_NATIVE_TRANS - XUD_EPTYPE_BUL, /* EA Native Transport */ -#endif -#endif - }; - -XUD_EpType epTypeTableIn[ENDPOINT_COUNT_IN] = { XUD_EPTYPE_CTL | XUD_STATUS_ENABLE, -#if (NUM_USB_CHAN_IN > 0) - XUD_EPTYPE_ISO, -#endif -#if (NUM_USB_CHAN_OUT > 0) && ((NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP)) - XUD_EPTYPE_ISO, /* Async feedback endpoint */ -#endif -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - XUD_EPTYPE_INT, -#endif -#ifdef MIDI - XUD_EPTYPE_BUL, -#endif -#if XUA_OR_STATIC_HID_ENABLED - XUD_EPTYPE_INT, -#endif -#ifdef IAP - XUD_EPTYPE_BUL | XUD_STATUS_ENABLE, -#ifdef IAP_INT_EP - XUD_EPTYPE_BUL | XUD_STATUS_ENABLE, -#endif -#ifdef IAP_EA_NATIVE_TRANS - XUD_EPTYPE_BUL | XUD_STATUS_ENABLE, -#endif -#endif - }; -#endif /* XUA_USB_EN */ - -void thread_speed() -{ -#ifdef FAST_MODE -#warning Building with fast mode enabled - set_thread_fast_mode_on(); -#else - set_thread_fast_mode_off(); -#endif -} - -#ifdef XSCOPE -void xscope_user_init() -{ - xscope_register(0, 0, "", 0, ""); - - xscope_config_io(XSCOPE_IO_BASIC); -} -#endif - -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE) -void SpdifTxWrapper(chanend c_spdif_tx) -{ - unsigned portId; - //configure_clock_src(clk, p_mclk); - - // TODO could share clock block here.. - // NOTE, Assuming SPDIF tile == USB tile here.. - asm("ldw %0, dp[p_mclk_in_usb]":"=r"(portId)); - asm("setclk res[%0], %1"::"r"(clk_mst_spd), "r"(portId)); - configure_out_port_no_ready(p_spdif_tx, clk_mst_spd, 0); - set_clock_fall_delay(clk_mst_spd, 7); - start_clock(clk_mst_spd); - - while(1) - { - spdif_tx(p_spdif_tx, c_spdif_tx); - } -} -#endif - -void usb_audio_io(chanend ?c_aud_in, -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE) - chanend c_spdif_tx, -#endif -#if (MIXER) - chanend c_mix_ctl, -#endif - streaming chanend ?c_spdif_rx, - streaming chanend ?c_adat_rx, - chanend ?c_clk_ctl, - chanend ?c_clk_int -#if (XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1) - , server interface i_dfu ?dfuInterface -#endif -#if (XUA_NUM_PDM_MICS > 0) - , chanend c_pdm_pcm -#endif -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - , client interface pll_ref_if i_pll_ref -#endif -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) - , chanend c_audio_rate_change -#endif -#if ((XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) && XUA_USE_SW_PLL) - , port p_for_mclk_count_aud - , chanend c_sw_pll -#endif -) -{ -#if (MIXER) - chan c_mix_out; -#endif - -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - chan c_dig_rx; - chan c_audio_rate_change; /* Notification of new mclk freq to clockgen and synch */ -#if XUA_USE_SW_PLL - /* Connect p_for_mclk_count_aud to clk_audio_mclk so we can count mclks/timestamp in digital rx*/ - unsigned x = 0; - asm("ldw %0, dp[clk_audio_mclk]":"=r"(x)); - asm("setclk res[%0], %1"::"r"(p_for_mclk_count_aud), "r"(x)); -#endif /* XUA_USE_SW_PLL */ -#endif /* (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) */ - - -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE == AUDIO_IO_TILE) - chan c_spdif_tx; - - /* Setup S/PDIF tx port - note this is done before par since sharing clock-block/port */ - spdif_tx_port_config(p_spdif_tx, clk_audio_mclk, p_mclk_in, 7); -#endif - - par - { -#if (MIXER && XUA_USB_EN) - /* Mixer cores(s) */ - { - thread_speed(); - mixer(c_aud_in, c_mix_out, c_mix_ctl); - } -#endif - -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE == AUDIO_IO_TILE) - while(1) - { - spdif_tx(p_spdif_tx, c_spdif_tx); - } -#endif - - /* Audio I/O core (pars additional S/PDIF TX Core) */ - { - thread_speed(); -#if (MIXER) -#define AUDIO_CHANNEL c_mix_out -#else -#define AUDIO_CHANNEL c_aud_in -#endif - XUA_AudioHub(AUDIO_CHANNEL, clk_audio_mclk, clk_audio_bclk, p_mclk_in, p_lrclk, p_bclk, p_i2s_dac, p_i2s_adc -#if (XUA_SPDIF_TX_EN) //&& (SPDIF_TX_TILE != AUDIO_IO_TILE) - , c_spdif_tx -#endif -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - , c_dig_rx -#endif -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - , c_audio_rate_change -#endif -#if (XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1) - , dfuInterface -#endif -#if (XUA_NUM_PDM_MICS > 0) - , c_pdm_pcm -#endif - ); - } - -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - { - /* ClockGen must currently run on same tile as AudioHub due to shared memory buffer - * However, due to the use of an interface the pll reference signal port can be on another tile - */ - thread_speed(); - clockGen( c_spdif_rx, - c_adat_rx, - i_pll_ref, - c_dig_rx, - c_clk_ctl, - c_clk_int, - c_audio_rate_change -#if XUA_USE_SW_PLL - , p_for_mclk_count_aud - , c_sw_pll -#endif - ); - } -#endif - - } // par -} - -#ifndef USER_MAIN_DECLARATIONS -#define USER_MAIN_DECLARATIONS -#endif - -#ifndef USER_MAIN_CORES -#define USER_MAIN_CORES -#endif - -//extern unsafe client interface i2c_master_if i_i2c_client; -//extern unsafe client interface i2c_master_if i_i2c_client_t0; -extern void dsp_core0(void); -extern void board_setup(); -extern void dsp_main (streaming chanend c_data); -extern void UserBufferForwardingTask_XC(unsigned c_dsp, unsigned c_init); -extern void SetEx3dHidChan (chanend c); - -extern int dsp_worker_tile(chanend c_dsp_to_ex3d, int worker_id); -//extern int dsp_worker_tile_1(chanend c_dsp_to_ex3d, int worker_id); -extern void ex3d_task(); -extern void hid_button_task(chanend cc_mic_level, chanend c_hid, chanend c_hidSendData, chanend c_uac_vol, chanend c_ex3d_hid_cmd); -#if HID_DFU_EN -extern void AudioHwRemote(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, chanend c_audiohw_rx, streaming chanend c_dfu_rx, chanend c_mic_det); -#else -extern void AudioHwRemote(chanend c_hidSendData, chanend cc_mic_level, chanend c_uac_vol, chanend c_audiohw_rx, chanend c_mic_det); -#endif -extern void dnr_dsp_proc_task(void); - -extern unsafe chanend uc_dsp_to_ex3d[DSP_WORKER_COUNT]; -extern unsafe chanend uc_dsp_to_dnr_t1; -extern unsafe chanend uc_key_to_ubm_t0; -extern unsafe chanend uc_audiohw; -#if HID_DFU_EN -extern unsafe streaming chanend uc_dfu; -#endif -extern void key_sender(chanend c_key); -extern void key_receiver(chanend c_key); -extern void mute_handler(chanend c_mic_det); - - -/* Main for USB Audio Applications */ -int main() -{ -#if !XUA_USB_EN - #define c_mix_out null -#else - chan c_mix_out; -#endif - -#ifdef MIDI - chan c_midi; -#endif -#ifdef IAP - chan c_iap; -#ifdef IAP_EA_NATIVE_TRANS - chan c_ea_data; -#endif -#endif - -#if (MIXER) - chan c_mix_ctl; -#endif - -#if (XUA_SPDIF_RX_EN) - streaming chan c_spdif_rx; -#else -#define c_spdif_rx null -#endif - -#if (XUA_ADAT_RX_EN) - streaming chan c_adat_rx; -#else -#define c_adat_rx null -#endif - -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE) - chan c_spdif_tx; -#endif - -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - chan c_clk_ctl; - chan c_clk_int; -#else -#define c_clk_int null -#define c_clk_ctl null -#endif - -#if (XUA_DFU_EN == 1) - interface i_dfu dfuInterface; -#else - #define dfuInterface null -#endif - -#if (XUA_NUM_PDM_MICS > 0) - chan c_pdm_pcm; -#endif - -#if (((XUA_SYNCMODE == XUA_SYNCMODE_SYNC && !XUA_USE_SW_PLL) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) ) - interface pll_ref_if i_pll_ref; -#endif - -#if ((XUA_SYNCMODE == XUA_SYNCMODE_SYNC || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) && XUA_USE_SW_PLL) - chan c_sw_pll; -#endif -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) - chan c_audio_rate_change; /* Notification of new mclk freq to ep_buffer */ -#endif - chan c_sof; - chan c_xud_out[ENDPOINT_COUNT_OUT]; /* Endpoint channels for XUD */ - chan c_xud_in[ENDPOINT_COUNT_IN]; - - /* Used to communicate controls/setting from XUA_Endpoint0() to the Audio/Buffering sub-system */ - chan c_aud_ctl; - -#if (!MIXER) -#define c_mix_ctl null -#endif - -#ifdef IAP_EA_NATIVE_TRANS - chan c_EANativeTransport_ctrl; -#else -#define c_EANativeTransport_ctrl null -#endif - -//#if (HID_CONTROLS > 0) -// chan c_hid; -//#endif - - USER_MAIN_DECLARATIONS - - chan c_dsp_to_ex3d[DSP_WORKER_COUNT]; - chan cc_mic_level; - chan c_audiohw; -#if HID_DFU_EN - streaming chan c_dfu; -#endif - chan c_key; chan c_hidSendData; - chan c_hidRcvData; - streaming chan c_eq_data; - streaming chan c_ubm_init; - chan c_uac_vol; - chan c_ex3d_hid_cmd; - chan c_mic_det; - - par - { - USER_MAIN_CORES - on tile[1] : { - par { - // Forwarder Task on its own core - { - unsigned u_dsp, u_init; - asm("mov %0, %1" : "=r"(u_dsp) : "r"(c_eq_data)); - asm("mov %0, %1" : "=r"(u_init) : "r"(c_ubm_init)); - UserBufferForwardingTask_C(u_dsp, u_init); - } - - // HID & Control sequence on its own core - unsafe { - uc_audiohw = (chanend)c_audiohw; - hid_button_task(cc_mic_level, c_hidRcvData, c_hidSendData, c_uac_vol, c_ex3d_hid_cmd); - } - -#if USE_EX3D == 1 - // Workers on their own cores - par(int i = 0; i < DSP_WORKER_COUNT; i++) - dsp_worker_tile(c_dsp_to_ex3d[i], i); - - // EX3D Task sequence on its own core - unsafe { - delay_milliseconds(200); - key_sender(c_key); - for (int i = 0; i < DSP_WORKER_COUNT; i++) - uc_dsp_to_ex3d[i] = (chanend)c_dsp_to_ex3d[i]; - ex3d_task(); - } -#endif - } - } - on tile[1]: mute_handler(c_mic_det); - - on tile[0] : { - par { - { -#if USE_EX3D == 1 - unsafe { key_receiver(c_key); } -#endif - AudioHwRemote(c_hidSendData, cc_mic_level, c_uac_vol, c_audiohw -#if HID_DFU_EN - , c_dfu -#endif - , c_mic_det - ); - } - } - } -#if EQ_EN == 1 - on tile[0] : { - { - -#if HID_DFU_EN - unsafe { - uc_dfu = (streaming chanend)c_dfu; - } -#endif - - dsp_core0(); - } - } - on tile[0] : { dsp_main(c_eq_data); } -#endif - -#if DNR_ENABLE == 1 - on tile[0] : { dnr_dsp_proc_task(); } -#endif - -#if (((XUA_SYNCMODE == XUA_SYNCMODE_SYNC && !XUA_USE_SW_PLL) || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN)) - on tile[PLL_REF_TILE]: PllRefPinTask(i_pll_ref, p_pll_ref); -#endif - on tile[XUD_TILE]: - par - { -#if XUA_USB_EN -#if ((XUD_TILE == 0) && (XUA_DFU_EN == 1)) - /* Check if USB is on the flash tile (tile 0) */ - /* Expect to be distrbuted into XUA_Endpoint0() */ - [[distribute]] - DFUHandler(dfuInterface, null); -#endif - - /* Core USB task, buffering, USB etc */ - { -#ifdef XUD_PRIORITY_HIGH - set_core_high_priority_on(); -#endif - /* Run UAC2.0 at high-speed, UAC1.0 at full-speed */ - unsigned usbSpeed = (AUDIO_CLASS == 2) ? XUD_SPEED_HS : XUD_SPEED_FS; - - unsigned xudPwrCfg = (XUA_POWERMODE == XUA_POWERMODE_SELF) ? XUD_PWR_SELF : XUD_PWR_BUS; - - /* USB interface core */ - XUD_Main(c_xud_out, ENDPOINT_COUNT_OUT, c_xud_in, ENDPOINT_COUNT_IN, - c_sof, epTypeTableOut, epTypeTableIn, usbSpeed, xudPwrCfg); - } - -#if (NUM_USB_CHAN_OUT > 0) || (NUM_USB_CHAN_IN > 0) || XUA_HID_ENABLED || defined(MIDI) - /* Core USB audio task, buffering, USB etc */ - { - unsigned x; - thread_speed(); - - /* Attach mclk count port to mclk clock-block (for feedback) */ - //set_port_clock(p_for_mclk_count, clk_audio_mclk); -#if(AUDIO_IO_TILE != XUD_TILE) - set_clock_src(clk_audio_mclk_usb, p_mclk_in_usb); - set_port_clock(p_for_mclk_count, clk_audio_mclk_usb); - start_clock(clk_audio_mclk_usb); -#else - /* Clock port from same clock-block as I2S */ - /* TODO remove asm() */ - asm("ldw %0, dp[clk_audio_mclk]":"=r"(x)); - asm("setclk res[%0], %1"::"r"(p_for_mclk_count), "r"(x)); -#endif - /* Endpoint & audio buffering cores - buffers all EP's other than 0 */ - XUA_Buffer( -#if (NUM_USB_CHAN_OUT > 0) - c_xud_out[ENDPOINT_NUMBER_OUT_AUDIO], /* Audio Out*/ -#endif -#if (NUM_USB_CHAN_IN > 0) - c_xud_in[ENDPOINT_NUMBER_IN_AUDIO], /* Audio In */ -#endif -#if (NUM_USB_CHAN_OUT > 0) && ((NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP)) - c_xud_in[ENDPOINT_NUMBER_IN_FEEDBACK], /* Audio FB */ -#endif -#ifdef MIDI - c_xud_out[ENDPOINT_NUMBER_OUT_MIDI], /* MIDI Out */ // 2 - c_xud_in[ENDPOINT_NUMBER_IN_MIDI], /* MIDI In */ // 4 - c_midi, -#endif -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - /* Audio Interrupt - only used for interrupts on external clock change */ - c_xud_in[ENDPOINT_NUMBER_IN_INTERRUPT], - c_clk_int, -#endif - c_sof, c_aud_ctl, p_for_mclk_count -#if (XUA_HID_ENABLED) - , c_xud_in[ENDPOINT_NUMBER_IN_HID] -#endif - , c_mix_out -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) - , c_audio_rate_change - #if (!XUA_USE_SW_PLL) - , i_pll_ref - #else - , c_sw_pll - #endif -#endif - ); - //: - } -#endif - - /* Endpoint 0 Core */ - { - thread_speed(); -#if (USE_EX3D == 1) && (HID_CONTROLS > 0) - SetEx3dHidChan(c_ex3d_hid_cmd); - XUA_Endpoint0( c_xud_out[0], c_xud_in[0], c_hidRcvData, c_aud_ctl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface VENDOR_REQUESTS_PARAMS_); -#else - XUA_Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface VENDOR_REQUESTS_PARAMS_); -#endif - } - -#endif /* XUA_USB_EN */ - } - -#if ((XUA_SYNCMODE == XUA_SYNCMODE_SYNC || XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) && XUA_USE_SW_PLL) - on tile[AUDIO_IO_TILE]: sw_pll_task(c_sw_pll); -#endif - - on tile[AUDIO_IO_TILE]: - { - set_core_high_priority_on(); - /* Audio I/O task, includes mixing etc */ - usb_audio_io( -#if (NUM_USB_CHAN_OUT > 0) || (NUM_USB_CHAN_IN > 0) - /* Connect audio system to XUA_Buffer(); */ - c_mix_out -#else - /* Connect to XUA_Endpoint0() */ - c_aud_ctl -#endif -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE) - , c_spdif_tx -#endif -#if (MIXER) - , c_mix_ctl -#endif - , c_spdif_rx, c_adat_rx, c_clk_ctl, c_clk_int -#if (XUD_TILE != 0) && (AUDIO_IO_TILE == 0) && (XUA_DFU_EN == 1) - , dfuInterface -#endif -#if (XUA_NUM_PDM_MICS > 0) - , c_pdm_pcm -#endif -#if (XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) - , i_pll_ref -#endif -#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) - , c_audio_rate_change -#endif -#if ((XUA_SPDIF_RX_EN || XUA_ADAT_RX_EN) && XUA_USE_SW_PLL) - , p_for_mclk_count_audio - , c_sw_pll -#endif - ); - } - -#if (XUA_SPDIF_TX_EN) && (SPDIF_TX_TILE != AUDIO_IO_TILE) - on tile[SPDIF_TX_TILE]: - { - thread_speed(); - SpdifTxWrapper(c_spdif_tx); - } -#endif - -#if defined(MIDI) && defined(IAP) && (IAP_TILE == MIDI_TILE) - /* MIDI and IAP share a core */ - on tile[IAP_TILE]: - { - thread_speed(); - usb_midi(p_midi_rx, p_midi_tx, clk_midi, c_midi, 0, c_iap, null, null, null); - } -#else -#if defined(MIDI) - /* MIDI core */ - on tile[MIDI_TILE]: - { - thread_speed(); - usb_midi(p_midi_rx, p_midi_tx, clk_midi, c_midi, 0); - } -#endif -#if defined(IAP) - on tile[IAP_TILE]: - { - thread_speed(); - iAP(c_iap, null, null, null); - } -#endif -#endif - -#if (XUA_SPDIF_RX_EN) - on tile[XUD_TILE]: - { - thread_speed(); - spdif_rx(c_spdif_rx, p_spdif_rx, clk_spd_rx, 192000); - } -#endif - -#if (XUA_ADAT_RX_EN) - on stdcore[XUD_TILE] : - { - set_thread_fast_mode_on(); - - while (1) - { - adatReceiver48000(p_adat_rx, c_adat_rx); - adatReceiver44100(p_adat_rx, c_adat_rx); - } - } -#endif - - -#if XUA_USB_EN -#if (XUD_TILE != 0) && (AUDIO_IO_TILE != 0) && (XUA_DFU_EN == 1) - /* Run flash code on its own - hope it gets combined */ - //#warning Running DFU flash code on its own - on stdcore[0]: DFUHandler(dfuInterface, null); -#endif -#endif - -#if (XUA_NUM_PDM_MICS > 0) - /* PDM Mics running on a separate to AudioHub */ - on stdcore[PDM_TILE]: - { - mic_array_task(c_mic_pcm); - } -#endif /*XUA_NUM_PDM_MICS > 0*/ - } - - return 0; -} - -#endif diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_ex3d_game.h b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_ex3d_game.h new file mode 100644 index 0000000..fc6529e --- /dev/null +++ b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_ex3d_game.h @@ -0,0 +1,32 @@ +/** + * @file tx1_ex3d_game.h + * @brief TX1 面板 GAME 模式与 EX3D / 方位 RGB 灯效的共享定义 + * + * 改动原因:jok ui_app on_game_short_press 会调用 audio_azimuth_set_mode(MODE_FPS/3A), + * 同时需切换 EX3D 声场;c1 的 audiohw 在 tile0,EX3D API 在 tile1,通过 g_3d_fps 与 + * g_tx1_azimuth_mode 跨 tile 同步,由 dsp.c ex3d_task 轮询并调用 audio_ex3d_set_sf/onoff。 + */ + +#ifndef TX1_EX3D_GAME_H +#define TX1_EX3D_GAME_H + +#include "roleswitchflag.h" + +/* + * 改动原因:仅两套固件——FPS71 UAC2 + 合并 UAC1(BYPASS/FPS20/3A 由 g_3d_fps 在 tile1 选算法)。 + * Windows 且 g_3d_fps=2 时加载 upgrade1;否则加载 upgrade2。 + */ +#define TX1_ROLE_FPS71_UAC2 COAX_IN_FLAG /* upgrade 1 -DFPS71_UAC2=1 */ +#define TX1_ROLE_GAME_UAC1 USB_IN_FLAG /* upgrade 2 -DFPS_GAME_UAC1=1 */ + +/* 与 jok ui_app.h azimuth_mode_t 一致,供 RGB 方位灯效选择 FPS/3A 配色 */ +#define TX1_AZIMUTH_MODE_FPS 0 +#define TX1_AZIMUTH_MODE_3A 1 + +/* tile0 audiohw / tile1 ex3d_task 共享;默认 FPS(与 jok board 初始化 MODE_FPS 一致) */ +extern unsigned g_tx1_azimuth_mode; + +/* 改动原因:tile0 从 Flash 恢复 g_3d_fps 后置 1,tile1 ex3d_task 强制重新 apply(防 init 早于 load) */ +extern unsigned g_tx1_ex3d_resync_req; + +#endif /* TX1_EX3D_GAME_H */ diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_led_effects.h b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_led_effects.h index 4ab02f5..92d73e8 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_led_effects.h +++ b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_led_effects.h @@ -51,4 +51,10 @@ void tx1_led_effects_periodic(htr3236_t *dev, client interface i2c_master_if i2c unsigned feature_mode, unsigned led_pattern_step); +#define TX1_AZIMUTH_MAX 7 +extern uint8_t g_tx1_audio_voltage[TX1_AZIMUTH_MAX]; + +void tx1_azimuth_clear_all_decay(void); +void tx1_azimuth_update_all_voltages(const uint8_t voltages[TX1_AZIMUTH_MAX]); + #endif /* TX1_LED_EFFECTS_H */ diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_led_effects.xc b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_led_effects.xc index 43bb709..b766fff 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_led_effects.xc +++ b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_led_effects.xc @@ -4,6 +4,8 @@ */ #include "tx1_led_effects.h" #include "tx1_rgb_brightness.h" +#include "tx1_ex3d_game.h" +#include "xc_ptr.h" #include #define TX1_RGB_LED_MAX 12 @@ -357,6 +359,158 @@ static void tx1_effect_gradient(htr3236_t *dev, client interface i2c_master_if i gradient_pos = (gradient_pos + 2) % 256; } +/*========================================================================= + * 音频方位 RGB 灯效(移植 jok led_effects.xc audio_azimuth_*) + * 改动原因:jok 在 game_mode!=BYPASS 时跑 audio_azimuth_effect_loop;BYPASS 时跑跑马灯等装饰灯效 + *------------------------------------------------------------------------*/ +#define TX1_AZIMUTH_MAX 7 + +/* 与 jok ui_app.h FPS / 3A 配色一致,经 TX1_RGB_SCALE8 对齐全局亮度 10 */ +#define TX1_FPS_COLOR_R TX1_RGB_SCALE8(34) +#define TX1_FPS_COLOR_G TX1_RGB_SCALE8(197) +#define TX1_FPS_COLOR_B TX1_RGB_SCALE8(94) +#define TX1_MODE3A_COLOR_R TX1_RGB_SCALE8(139) +#define TX1_MODE3A_COLOR_G TX1_RGB_SCALE8(91) +#define TX1_MODE3A_COLOR_B TX1_RGB_SCALE8(246) + +/* jok channel_led_map: FL D12, FC D1, FR D2, SL D10, SR D4, RL D9, RR D5 */ +static const uint8_t tx1_azimuth_led_index[TX1_AZIMUTH_MAX] = { + 12, 1, 2, 10, 4, 9, 5 +}; + +uint8_t g_tx1_audio_voltage[TX1_AZIMUTH_MAX] = {0}; +static uint8_t tx1_azimuth_brightness[TX1_AZIMUTH_MAX] = {0}; +static unsigned tx1_azimuth_fx_step = 0; + +/* 改动原因:与 jok CURRENT_TEST TEST_SCAN_CCW 一致,无实时电平输入时演示方位灯效 */ +#define TX1_AZIMUTH_SCAN_HOLD 4 + +static int tx1_cw_hold_count = 0; +static int tx1_cw_current_index = 0; + +static const int tx1_scan_ccw_order[TX1_AZIMUTH_MAX] = { + 0, 3, 5, 6, 4, 2, 1 /* FL→SL→RL→RR→SR→FR→FC,同 jok counterclockwise_order */ +}; + +static uint8_t tx1_fmax_u8(uint8_t a, uint8_t b) { return (a > b) ? a : b; } + +void tx1_azimuth_clear_all_decay(void) +{ + int ch; + for (ch = 0; ch < TX1_AZIMUTH_MAX; ch++) { + tx1_azimuth_brightness[ch] = 0; + } +} + +void tx1_azimuth_update_all_voltages(const uint8_t voltages[TX1_AZIMUTH_MAX]) +{ + int i; + for (i = 0; i < TX1_AZIMUTH_MAX; i++) { + g_tx1_audio_voltage[i] = voltages[i]; + } +} + +/* 改动原因:jok test_scan_counterclockwise,每 50ms 步进驱动 g_tx1_audio_voltage */ +static void tx1_azimuth_test_scan_ccw(void) +{ + uint8_t voltages[TX1_AZIMUTH_MAX] = {0}; + + if (tx1_cw_hold_count >= TX1_AZIMUTH_SCAN_HOLD) { + tx1_cw_hold_count = 0; + tx1_cw_current_index = (tx1_cw_current_index + 1) % TX1_AZIMUTH_MAX; + } + voltages[tx1_scan_ccw_order[tx1_cw_current_index]] = 255; + tx1_cw_hold_count++; + tx1_azimuth_clear_all_decay(); + tx1_azimuth_update_all_voltages(voltages); +} + +static void tx1_azimuth_update_fps(htr3236_t *dev, client interface i2c_master_if i2c) +{ + uint8_t new_brightness[TX1_AZIMUTH_MAX] = {0}; + int ch; + + tx1_fx_all_off(dev, i2c); + for (ch = 0; ch < TX1_AZIMUTH_MAX; ch++) { + uint8_t voltage = g_tx1_audio_voltage[ch]; + + if (voltage > 0) { + uint8_t target = voltage; + new_brightness[ch] = target; + tx1_azimuth_brightness[ch] = target; + } else { + if (tx1_azimuth_brightness[ch] > 0) { + uint8_t decay = tx1_fmax_u8(1, tx1_azimuth_brightness[ch] / 12); + if (tx1_azimuth_brightness[ch] <= decay) { + tx1_azimuth_brightness[ch] = 0; + } else { + tx1_azimuth_brightness[ch] -= decay; + } + new_brightness[ch] = tx1_azimuth_brightness[ch]; + } + } + if (new_brightness[ch] > 0) { + uint8_t r = (TX1_FPS_COLOR_R * new_brightness[ch]) / 255; + uint8_t g = (TX1_FPS_COLOR_G * new_brightness[ch]) / 255; + uint8_t b = (TX1_FPS_COLOR_B * new_brightness[ch]) / 255; + tx1_fx_pwm_led(dev, i2c, tx1_azimuth_led_index[ch], r, g, b); + } + } + tx1_fx_update(dev, i2c); +} + +static void tx1_azimuth_update_3a(htr3236_t *dev, client interface i2c_master_if i2c) +{ + int ch; + + tx1_fx_all_off(dev, i2c); + for (ch = 0; ch < TX1_AZIMUTH_MAX; ch++) { + uint8_t voltage = g_tx1_audio_voltage[ch]; + + if (voltage > 0) { + if (voltage > tx1_azimuth_brightness[ch]) { + tx1_azimuth_brightness[ch] = voltage; + } + } else { + if (tx1_azimuth_brightness[ch] > 0) { + uint8_t decay = tx1_azimuth_brightness[ch] / 6; + if (decay < 2) decay = 2; + if (tx1_azimuth_brightness[ch] <= decay) { + tx1_azimuth_brightness[ch] = 0; + } else { + tx1_azimuth_brightness[ch] -= decay; + } + } + } + if (tx1_azimuth_brightness[ch] > 0) { + uint8_t brightness = tx1_azimuth_brightness[ch]; + if (brightness < 30 && voltage > 0) brightness = 30; + uint8_t r = (TX1_MODE3A_COLOR_R * brightness) / 255; + uint8_t g = (TX1_MODE3A_COLOR_G * brightness) / 255; + uint8_t b = (TX1_MODE3A_COLOR_B * brightness) / 255; + tx1_fx_pwm_led(dev, i2c, tx1_azimuth_led_index[ch], r, g, b); + } + } + tx1_fx_update(dev, i2c); +} + +static void tx1_azimuth_effect_loop(htr3236_t *dev, client interface i2c_master_if i2c) +{ + unsigned azimuth_mode; + static unsigned last_azimuth_mode = 0xFFFFFFFFu; + + GET_SHARED_GLOBAL(azimuth_mode, g_tx1_azimuth_mode); + if (azimuth_mode != last_azimuth_mode) { + tx1_azimuth_clear_all_decay(); + last_azimuth_mode = azimuth_mode; + } + if (azimuth_mode == TX1_AZIMUTH_MODE_3A) { + tx1_azimuth_update_3a(dev, i2c); + } else { + tx1_azimuth_update_fps(dev, i2c); + } +} + /* game_mode / feature_mode 数值与 audiohw tx1_*_t 枚举一致:BYPASS=0, FEATURE_NONE=0 */ void tx1_led_effects_periodic(htr3236_t *dev, client interface i2c_master_if i2c, unsigned game_mode, @@ -372,8 +526,12 @@ void tx1_led_effects_periodic(htr3236_t *dev, client interface i2c_master_if i2c return; } - /* 非 BYPASS 时暂不跑方位灯效(ex3d 后续可接);熄灭 RGB 装饰 */ + tx1_azimuth_fx_step++; + + /* 改动原因:与 jok led_effects_period_update_task 一致——非 BYPASS 方位灯效,BYPASS 装饰灯效 */ if (game_mode != 0) { + tx1_azimuth_test_scan_ccw(); + tx1_azimuth_effect_loop(dev, i2c); return; } diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_rgb_brightness.h b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_rgb_brightness.h new file mode 100644 index 0000000..f482342 --- /dev/null +++ b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/tx1_rgb_brightness.h @@ -0,0 +1,39 @@ +/** + * @file tx1_rgb_brightness.h + * @brief 与 jok rgb_led_control.c 中 rgb_led_set_global_brightness(10) 一致的全局亮度 + */ +#ifndef TX1_RGB_BRIGHTNESS_H +#define TX1_RGB_BRIGHTNESS_H + +/* 改动原因:jok xk_audio_316_mc_ab_board 初始化后 rgb_led_set_global_brightness(10) */ +#define TX1_RGB_BRIGHTNESS 10 + +/* 改动原因:等同 jok adj = color * g_brightness / 255 */ +#define TX1_RGB_SCALE8(c) ((uint8_t)(((unsigned)(c) * TX1_RGB_BRIGHTNESS) / 255)) + +/* 改动原因:与 jok g_rgb_colors[] 一致,供音量条/灯效使用 */ +#define TX1_RGB_COLOR_YELLOW_R 255 +#define TX1_RGB_COLOR_YELLOW_G 255 +#define TX1_RGB_COLOR_YELLOW_B 0 + +#define TX1_RGB_COLOR_PURPLE_R 128 +#define TX1_RGB_COLOR_PURPLE_G 0 +#define TX1_RGB_COLOR_PURPLE_B 128 + +#define TX1_RGB_COLOR_ORANGE_R 255 +#define TX1_RGB_COLOR_ORANGE_G 165 +#define TX1_RGB_COLOR_ORANGE_B 0 + +#define TX1_RGB_COLOR_BLUE_R 0 +#define TX1_RGB_COLOR_BLUE_G 0 +#define TX1_RGB_COLOR_BLUE_B 255 + +#define TX1_RGB_COLOR_GREEN_R 0 +#define TX1_RGB_COLOR_GREEN_G 255 +#define TX1_RGB_COLOR_GREEN_B 0 + +#define TX1_RGB_COLOR_RED_R 255 +#define TX1_RGB_COLOR_RED_G 0 +#define TX1_RGB_COLOR_RED_B 0 + +#endif /* TX1_RGB_BRIGHTNESS_H */ diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_buffer.xc.bak b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_buffer.xc.bak deleted file mode 100644 index 077b7f1..0000000 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_buffer.xc.bak +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2021-2024 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. -#define DEBUG_PRINT_ENABLE 1 -#include -#include -#include -#include -#include -#include "xc_ptr.h" -#include "share_buffer.h" -#include "debug_print.h" - -unsafe streaming chanend uc_eq_data; -unsigned g_current_sample_freq = 0; -extern void UserBufferManagement_ex3d(unsigned sampsFromUsbToAudio[]); -extern void UserBufferManagementInit_ex3d(unsigned sampFreq); -extern uint32_t init_eq_data(unsigned sample_freq); -extern unsigned g_monitor_switch_t1; - -unsigned dnr_exchange_buffer(unsigned data); - -void SetEqDataChan (streaming chanend c) { -unsafe { - uc_eq_data = c; - } -} - -void dsp_main (streaming chanend c_data) { - int play_input[NUM_USB_CHAN_OUT]; - int play_output[I2S_CHANS_DAC]; - unsigned mic_input[I2S_CHANS_ADC]; - int mic_output[I2S_CHANS_ADC]; - unsigned sample_freq_old = 0; - - play_output[0] = 0; - play_output[1] = 0; - while (1) { - // 用 stestct 区分控制令牌(采样率变更)和数据令牌(音频样本) - if (stestct(c_data)) { - // 控制令牌:采样率变更,执行初始化 - sinct(c_data); - unsigned sample_freq; - c_data :> sample_freq; - if ( sample_freq != sample_freq_old) - { - 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; - sample_freq_old = sample_freq; - } - // 回送控制令牌作为确认 - soutct(c_data, 0x06); - } else { - // 数据令牌:正常音频处理路径 - c_data :> play_input[0]; - c_data :> play_input[1]; - - c_data <: play_output[0]; - c_data <: play_output[1]; - -#if DNR_ENABLE == 1 - c_data :> mic_input[1]; - c_data <: mic_output[1]; -#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 - unsafe { - mic_output[1] = dnr_exchange_buffer(mic_input[1]); - } -#endif - } - } -} - - -#pragma unsafe arrays -void UserBufferManagementInit(unsigned sampFreq) -{ - SET_SHARED_GLOBAL(g_current_sample_freq, sampFreq); - UserBufferManagementInit_ex3d(sampFreq); -unsafe { - // 发送控制令牌 + 采样率给 dsp_main,触发初始化 - soutct((streaming chanend)uc_eq_data, 0x06); - uc_eq_data <: sampFreq; - // 等待 dsp_main 确认:排空残留数据令牌,等控制令牌回来 - int trashbin; - for (;;) { - if (stestct((streaming chanend)uc_eq_data)) { - sinct((streaming chanend)uc_eq_data); - break; - } else { - uc_eq_data :> trashbin; - } - } -} -} -// out port freq_port = PORT_X1D26_27_32_33; -#pragma unsafe arrays -void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[]) -{ - unsigned is_monitor; - UserBufferManagement_ex3d(sampsFromUsbToAudio); -unsafe { - // 数据路径:只传输音频样本,不传采样率(采样率变更由 UserBufferManagementInit 通过控制令牌处理) - uc_eq_data <: sampsFromUsbToAudio[0]; - uc_eq_data <: sampsFromUsbToAudio[1]; - uc_eq_data :> sampsFromUsbToAudio[0]; - uc_eq_data :> sampsFromUsbToAudio[1]; -#if DNR_ENABLE == 1 - uc_eq_data <: sampsFromAudioToUsb[1]; - uc_eq_data :> sampsFromAudioToUsb[1]; - sampsFromAudioToUsb[0] = sampsFromAudioToUsb[1]; -#endif - } - GET_SHARED_GLOBAL(is_monitor, g_monitor_switch_t1); - if (is_monitor) { - sampsFromUsbToAudio[0] += (sampsFromAudioToUsb[0]); - sampsFromUsbToAudio[1] += (sampsFromAudioToUsb[1]); - } -} - diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_buffer.xc.gemini b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_buffer.xc.gemini deleted file mode 100644 index bb681a7..0000000 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_buffer.xc.gemini +++ /dev/null @@ -1,207 +0,0 @@ -// Copyright 2021-2024 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. -#define DEBUG_PRINT_ENABLE 1 -#include -#include -#include -#include -#include -#include "xc_ptr.h" -#include "share_buffer.h" -#include "debug_print.h" -#include "ubm_memory.h" - -unsafe streaming chanend uc_eq_data; -unsafe streaming chanend uc_ubm_init; -unsigned g_current_sample_freq = 0; -extern void UserBufferManagement_ex3d(unsigned sampsFromUsbToAudio[]); -extern void UserBufferManagementInit_ex3d(unsigned sampFreq); -extern uint32_t init_eq_data(unsigned sample_freq); -extern unsigned g_monitor_switch_t1; - -unsigned dnr_exchange_buffer(unsigned data); - -void SetEqDataChan (streaming chanend c) { -unsafe { - uc_eq_data = c; - } -} - -void SetUbmInitChan (streaming chanend c) { -unsafe { - uc_ubm_init = c; - } -} - -void UserBufferForwardingTask(streaming chanend c_dsp, streaming chanend c_init) { - unsigned sample_freq = 0; - unsafe { - ubm_shared_t * unsafe p = (ubm_shared_t * unsafe)get_ubm_shared_ptr(); - while(1) { - select { - // 1. Handle Init Request via Channel - case c_init :> sample_freq: - soutct(c_dsp, 0x06); - c_dsp <: sample_freq; - // wait for ack from dsp_main (Tile 0) - int trashbin; - for (;;) { - if (stestct(c_dsp)) { - sinct(c_dsp); - break; - } else { - c_dsp :> trashbin; - } - } - c_init <: 1; // Send ack back - break; - - // 2. Forward samples to dsp_main on Tile 0 - default: - if (p->head != p->tail) { - unsigned t = p->tail; - unsigned p_in[2]; -#if DNR_ENABLE == 1 - unsigned dnr_in; -#endif - unsigned p_out[2]; -#if DNR_ENABLE == 1 - unsigned dnr_out; -#endif - - p_in[0] = p->usb_to_dsp[0][t]; - p_in[1] = p->usb_to_dsp[1][t]; -#if DNR_ENABLE == 1 - dnr_in = p->dnr_to_dsp[t]; -#endif - p->tail = (t + 1) & 3; - - // Talk to dsp_main (Tile 0) - c_dsp <: p_in[0]; - c_dsp <: p_in[1]; - c_dsp :> p_out[0]; - c_dsp :> p_out[1]; -#if DNR_ENABLE == 1 - c_dsp <: dnr_in; - c_dsp :> dnr_out; -#endif - - // Put processed sample back - unsigned fh = p->f_head; - p->usb_from_dsp[0][fh] = p_out[0]; - p->usb_from_dsp[1][fh] = p_out[1]; -#if DNR_ENABLE == 1 - p->dnr_from_dsp[fh] = dnr_out; -#endif - p->f_head = (fh + 1) & 3; - } - break; - } - } - } -} - -void dsp_main (streaming chanend c_data) { - int play_input[NUM_USB_CHAN_OUT]; - int play_output[I2S_CHANS_DAC]; - unsigned sample_freq_old = 0; -#if DNR_ENABLE == 1 - static int mic_output_dnr = 0; // 必须为 static 以保持采样间状态并回传上一结果 -#endif - - play_output[0] = 0; - play_output[1] = 0; - while (1) { - if (stestct(c_data)) { - sinct(c_data); - unsigned sample_freq; - c_data :> sample_freq; - if ( sample_freq != sample_freq_old) - { - 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; - sample_freq_old = sample_freq; - } - soutct(c_data, 0x06); - } else { - c_data :> play_input[0]; - c_data :> play_input[1]; - - c_data <: play_output[0]; - c_data <: play_output[1]; - -#if DNR_ENABLE == 1 - unsigned mic_input_dnr; - c_data :> mic_input_dnr; - c_data <: mic_output_dnr; // 发送上一次的处理结果,避免阻塞 - - // 在 Tile 0 上执行 DNR 处理(与 dnr_dsp_proc_task 共享内存) - // 注意:即便 DNR level 为 0,也必须调用 dnr_exchange_buffer 以维持缓冲区轮转和数据直通 - unsafe { - mic_output_dnr = (int)dnr_exchange_buffer(mic_input_dnr); - } -#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); - } - } -} - - -#pragma unsafe arrays -void UserBufferManagementInit(unsigned sampFreq) -{ - SET_SHARED_GLOBAL(g_current_sample_freq, sampFreq); - UserBufferManagementInit_ex3d(sampFreq); - -unsafe { - uc_ubm_init <: sampFreq; - int ack; - uc_ubm_init :> ack; -} -} - -// out port freq_port = PORT_X1D26_27_32_33; -#pragma unsafe arrays -void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[]) -{ - unsigned is_monitor; - UserBufferManagement_ex3d(sampsFromUsbToAudio); - -unsafe { - ubm_shared_t * unsafe p = (ubm_shared_t * unsafe)get_ubm_shared_ptr(); - // 1. Push new samples into ring buffer - unsigned h = p->head; - p->usb_to_dsp[0][h] = sampsFromUsbToAudio[0]; - p->usb_to_dsp[1][h] = sampsFromUsbToAudio[1]; -#if DNR_ENABLE == 1 - p->dnr_to_dsp[h] = sampsFromAudioToUsb[1]; -#endif - p->head = (h + 1) & 3; - - // 2. Pull processed samples from ring buffer - if (p->f_head != p->f_tail) { - unsigned ft = p->f_tail; - sampsFromUsbToAudio[0] = p->usb_from_dsp[0][ft]; - sampsFromUsbToAudio[1] = p->usb_from_dsp[1][ft]; -#if DNR_ENABLE == 1 - sampsFromAudioToUsb[1] = p->dnr_from_dsp[ft]; - sampsFromAudioToUsb[0] = sampsFromAudioToUsb[1]; // 拷贝处理后的单声道到双声道 -#endif - p->f_tail = (ft + 1) & 3; - } -} - - GET_SHARED_GLOBAL(is_monitor, g_monitor_switch_t1); - if (is_monitor) { - sampsFromUsbToAudio[0] += (sampsFromAudioToUsb[0]); - sampsFromUsbToAudio[1] += (sampsFromAudioToUsb[1]); - } -} diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_buffer.xc.gemini1 b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_buffer.xc.gemini1 deleted file mode 100644 index c85424b..0000000 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_buffer.xc.gemini1 +++ /dev/null @@ -1,200 +0,0 @@ -// Copyright 2021-2024 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. -#define DEBUG_PRINT_ENABLE 1 -#include -#include -#include -#include -#include -#include "xc_ptr.h" -#include "share_buffer.h" -#include "debug_print.h" -#include "ubm_memory.h" - -unsigned g_current_sample_freq = 0; -extern void UserBufferManagement_ex3d(unsigned sampsFromUsbToAudio[]); -extern void UserBufferManagementInit_ex3d(unsigned sampFreq); -extern uint32_t init_eq_data(unsigned sample_freq); -extern unsigned g_monitor_switch_t1; - -unsigned dnr_exchange_buffer(unsigned data); - -// 保持定义以兼容 main.xc -void SetEqDataChan (chanend c) {} -void SetUbmInitChan (chanend c) {} - -// XC 中实现转发任务。使用 unsigned 参数避开 XC 编译器的并行资源分析 Bug。 -void UserBufferForwardingTask_XC(unsigned c_dsp_val, unsigned c_init_val) { - unsigned sample_freq = 0; - // 设置 Init 通道供回调使用 - set_ubm_init_chan_c(c_init_val); - - unsafe { - ubm_shared_t * unsafe p = (ubm_shared_t * unsafe)get_ubm_shared_ptr(); - while(1) { - // 1. 处理初始化请求 - int is_ct; - asm("testct %0, res[%1]" : "=r"(is_ct) : "r"(c_init_val)); - if (is_ct) { - asm("in %0, res[%1]" : "=r"(sample_freq) : "r"(c_init_val)); - asm("outct res[%0], %1" :: "r"(c_dsp_val), "r"(0x06)); - asm("out res[%0], %1" :: "r"(c_dsp_val), "r"(sample_freq)); - - // 等待确认 - while (1) { - int dsp_ct; - asm("testct %0, res[%1]" : "=r"(dsp_ct) : "r"(c_dsp_val)); - if (dsp_ct) { - unsigned tmp; - asm("inct %0, res[%1]" : "=r"(tmp) : "r"(c_dsp_val)); - break; - } else { - unsigned trash; - asm("in %0, res[%1]" : "=r"(trash) : "r"(c_dsp_val)); - } - } - asm("out res[%0], %1" :: "r"(c_init_val), "r"(1)); - } - - // 2. 处理音频转发 - if (p->head != p->tail) { - unsigned t = p->tail; - unsigned p_in[NUM_USB_CHAN_OUT]; - unsigned p_out[2]; -#if DNR_ENABLE == 1 - unsigned dnr_in = p->dnr_to_dsp[t]; - unsigned dnr_out; -#endif - for(int i=0; iusb_to_dsp[i][t]; - } - p->tail = (t + 1) & 3; - - // 在此处调用算法,确保 XC 宏定义完全有效 - UserBufferManagement_ex3d(p_in); - - // 发送给 Tile 0 (EQ 处理) - asm("out res[%0], %1" :: "r"(c_dsp_val), "r"(p_in[0])); - asm("out res[%0], %1" :: "r"(c_dsp_val), "r"(p_in[1])); - asm("in %0, res[%1]" : "=r"(p_out[0]) : "r"(c_dsp_val)); - asm("in %0, res[%1]" : "=r"(p_out[1]) : "r"(c_dsp_val)); - -#if DNR_ENABLE == 1 - // 发送给 Tile 0 (DNR 处理) - asm("out res[%0], %1" :: "r"(c_dsp_val), "r"(dnr_in)); - asm("in %0, res[%1]" : "=r"(dnr_out) : "r"(c_dsp_val)); -#endif - - // 写回结果 - unsigned fh = p->f_head; - p->usb_from_dsp[0][fh] = p_out[0]; - p->usb_from_dsp[1][fh] = p_out[1]; -#if DNR_ENABLE == 1 - p->dnr_from_dsp[fh] = dnr_out; -#endif - p->f_head = (fh + 1) & 3; - } - } - } -} - -void dsp_main (streaming chanend c_data) { - int play_input[2]; - int play_output[2]; - unsigned sample_freq_old = 0; -#if DNR_ENABLE == 1 - static int mic_output_dnr = 0; -#endif - - play_output[0] = 0; - play_output[1] = 0; - while (1) { - if (stestct(c_data)) { - sinct(c_data); - unsigned sample_freq; - c_data :> sample_freq; - if ( sample_freq != sample_freq_old) - { - 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; - sample_freq_old = sample_freq; - } - soutct(c_data, 0x06); - } else { - c_data :> play_input[0]; - c_data :> play_input[1]; - - c_data <: play_output[0]; - c_data <: play_output[1]; - -#if DNR_ENABLE == 1 - unsigned mic_input_dnr; - c_data :> mic_input_dnr; - c_data <: mic_output_dnr; - - unsafe { - mic_output_dnr = (int)dnr_exchange_buffer(mic_input_dnr); - } -#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); - } - } -} - -#pragma unsafe arrays -void UserBufferManagementInit(unsigned sampFreq) -{ - SET_SHARED_GLOBAL(g_current_sample_freq, sampFreq); - UserBufferManagementInit_ex3d(sampFreq); - - unsigned val = get_ubm_init_chan_c(); - if (val != 0) { - unsafe { - asm("out res[%0], %1" :: "r"(val), "r"(sampFreq)); - unsigned ack; - asm("in %0, res[%1]" : "=r"(ack) : "r"(val)); - } - } -} - -#pragma unsafe arrays -void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[]) -{ - unsigned is_monitor; -unsafe { - ubm_shared_t * unsafe p = (ubm_shared_t * unsafe)get_ubm_shared_ptr(); - unsigned h = p->head; - for(int i=0; iusb_to_dsp[i][h] = sampsFromUsbToAudio[i]; - } -#if DNR_ENABLE == 1 - p->dnr_to_dsp[h] = sampsFromAudioToUsb[1]; -#endif - p->head = (h + 1) & 3; - - if (p->f_head != p->f_tail) { - unsigned ft = p->f_tail; - sampsFromUsbToAudio[0] = p->usb_from_dsp[0][ft]; - sampsFromUsbToAudio[1] = p->usb_from_dsp[1][ft]; -#if DNR_ENABLE == 1 - sampsFromAudioToUsb[1] = p->dnr_from_dsp[ft]; - sampsFromAudioToUsb[0] = sampsFromAudioToUsb[1]; -#endif - p->f_tail = (ft + 1) & 3; - } -} - - GET_SHARED_GLOBAL(is_monitor, g_monitor_switch_t1); - if (is_monitor) { - sampsFromUsbToAudio[0] += (sampsFromAudioToUsb[0]); - sampsFromUsbToAudio[1] += (sampsFromAudioToUsb[1]); - } -} diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_buffer.xc.new b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_buffer.xc.new deleted file mode 100644 index 9a1770e..0000000 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_buffer.xc.new +++ /dev/null @@ -1,208 +0,0 @@ -// Copyright 2021-2024 XMOS LIMITED. -// This Software is subject to the terms of the XMOS Public Licence: Version 1. -#define DEBUG_PRINT_ENABLE 1 -#include -#include -#include -#include -#include -#include "xc_ptr.h" -#include "share_buffer.h" -#include "debug_print.h" -#include "ubm_memory.h" - -unsafe streaming chanend uc_eq_data; -unsafe streaming chanend uc_ubm_init; -unsigned g_current_sample_freq = 0; -extern void UserBufferManagement_ex3d(unsigned sampsFromUsbToAudio[]); -extern void UserBufferManagementInit_ex3d(unsigned sampFreq); -extern uint32_t init_eq_data(unsigned sample_freq); -extern unsigned g_monitor_switch_t1; - -unsigned dnr_exchange_buffer(unsigned data); - -void SetEqDataChan (streaming chanend c) { -unsafe { - uc_eq_data = c; - } -} - -void SetUbmInitChan (streaming chanend c) { -unsafe { - uc_ubm_init = c; - } -} - -void UserBufferForwardingTask(streaming chanend c_dsp, streaming chanend c_init) { - unsigned sample_freq = 0; - unsafe { - ubm_shared_t * unsafe p = (ubm_shared_t * unsafe)get_ubm_shared_ptr(); - while(1) { - select { - // 1. Handle Init Request via Channel - case c_init :> sample_freq: - soutct(c_dsp, 0x06); - c_dsp <: sample_freq; - // wait for ack from dsp_main (Tile 0) - int trashbin; - for (;;) { - if (stestct(c_dsp)) { - sinct(c_dsp); - break; - } else { - c_dsp :> trashbin; - } - } - c_init <: 1; // Send ack back - break; - - // 2. Forward samples to dsp_main on Tile 0 - default: - if (p->head != p->tail) { - unsigned t = p->tail; - unsigned p_in[NUM_USB_CHAN_OUT]; -#if DNR_ENABLE == 1 - unsigned dnr_in; -#endif - unsigned p_out[2]; -#if DNR_ENABLE == 1 - unsigned dnr_out; -#endif - - for(int i=0; iusb_to_dsp[i][t]; - } -#if DNR_ENABLE == 1 - dnr_in = p->dnr_to_dsp[t]; -#endif - p->tail = (t + 1) & 3; - // 在此处调用算法,确保 XC 宏定义完全有效 - UserBufferManagement_ex3d(p_in); - // Talk to dsp_main (Tile 0) - c_dsp <: p_in[0]; - c_dsp <: p_in[1]; - c_dsp :> p_out[0]; - c_dsp :> p_out[1]; -#if DNR_ENABLE == 1 - c_dsp <: dnr_in; - c_dsp :> dnr_out; -#endif - - // Put processed sample back - unsigned fh = p->f_head; - p->usb_from_dsp[0][fh] = p_out[0]; - p->usb_from_dsp[1][fh] = p_out[1]; -#if DNR_ENABLE == 1 - p->dnr_from_dsp[fh] = dnr_out; -#endif - p->f_head = (fh + 1) & 3; - } - break; - } - } - } -} - -void dsp_main (streaming chanend c_data) { - int play_input[NUM_USB_CHAN_OUT]; - int play_output[I2S_CHANS_DAC]; - unsigned sample_freq_old = 0; -#if DNR_ENABLE == 1 - static int mic_output_dnr = 0; // 必须为 static 以保持采样间状态并回传上一结果 -#endif - - play_output[0] = 0; - play_output[1] = 0; - while (1) { - if (stestct(c_data)) { - sinct(c_data); - unsigned sample_freq; - c_data :> sample_freq; - if ( sample_freq != sample_freq_old) - { - 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; - sample_freq_old = sample_freq; - } - soutct(c_data, 0x06); - } else { - c_data :> play_input[0]; - c_data :> play_input[1]; - - c_data <: play_output[0]; - c_data <: play_output[1]; - -#if DNR_ENABLE == 1 - unsigned mic_input_dnr; - c_data :> mic_input_dnr; - c_data <: mic_output_dnr; // 发送上一次的处理结果,避免阻塞 - - // 在 Tile 0 上执行 DNR 处理(与 dnr_dsp_proc_task 共享内存) - // 注意:即便 DNR level 为 0,也必须调用 dnr_exchange_buffer 以维持缓冲区轮转和数据直通 - unsafe { - mic_output_dnr = (int)dnr_exchange_buffer(mic_input_dnr); - } -#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); - } - } -} - - -#pragma unsafe arrays -void UserBufferManagementInit(unsigned sampFreq) -{ - SET_SHARED_GLOBAL(g_current_sample_freq, sampFreq); - UserBufferManagementInit_ex3d(sampFreq); - -unsafe { - uc_ubm_init <: sampFreq; - int ack; - uc_ubm_init :> ack; -} -} - -// out port freq_port = PORT_X1D26_27_32_33; -#pragma unsafe arrays -void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[]) -{ - unsigned is_monitor; -unsafe { - ubm_shared_t * unsafe p = (ubm_shared_t * unsafe)get_ubm_shared_ptr(); - // 1. Push new samples into ring buffer - unsigned h = p->head; - for(int i=0; iusb_to_dsp[i][h] = sampsFromUsbToAudio[i]; - } -#if DNR_ENABLE == 1 - p->dnr_to_dsp[h] = sampsFromAudioToUsb[1]; -#endif - p->head = (h + 1) & 3; - - // 2. Pull processed samples from ring buffer - if (p->f_head != p->f_tail) { - unsigned ft = p->f_tail; - sampsFromUsbToAudio[0] = p->usb_from_dsp[0][ft]; - sampsFromUsbToAudio[1] = p->usb_from_dsp[1][ft]; -#if DNR_ENABLE == 1 - sampsFromAudioToUsb[1] = p->dnr_from_dsp[ft]; - sampsFromAudioToUsb[0] = sampsFromAudioToUsb[1]; // 拷贝处理后的单声道到双声道 -#endif - p->f_tail = (ft + 1) & 3; - } -} - - GET_SHARED_GLOBAL(is_monitor, g_monitor_switch_t1); - if (is_monitor) { - sampsFromUsbToAudio[0] += (sampsFromAudioToUsb[0]); - sampsFromUsbToAudio[1] += (sampsFromAudioToUsb[1]); - } -} diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_func.c b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_func.c index 60eb87f..23fe9bc 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_func.c +++ b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_func.c @@ -102,6 +102,67 @@ void save_value32(unsigned char *path, unsigned value) lfs_deinit(); } +/* 改动原因:与 mic_mute 相同 LFS 键值存储,供 GAME 键/HID 0xA4 写入、开机 AudioHwRemote2 恢复 */ +static unsigned char tx1_game_mode_lfs_path[] = "tx1_game_mode"; + +void tx1_save_game_mode(unsigned char mode) +{ + if (mode > 3) { + mode = 0; + } + save_value(tx1_game_mode_lfs_path, mode); +} + +unsigned char tx1_load_game_mode(void) +{ + unsigned char v = load_value(tx1_game_mode_lfs_path); + if (v > 3) { + v = 0; + save_value(tx1_game_mode_lfs_path, v); + } + return v; +} + +/* 改动原因:面板 SYSTEM_VOLUME 调节的是 DAC 0~48 级(与 HID 0x93/0x94 一致),写入 NAU88 0x0034 前持久化 */ +static unsigned char tx1_dac_vol_lfs_path[] = "tx1_dac_vol"; + +void tx1_save_dac_volume(unsigned char level) +{ + if (level > 48) { + level = 48; + } + save_value(tx1_dac_vol_lfs_path, level); +} + +unsigned char tx1_load_dac_volume(void) +{ + unsigned char v = load_value(tx1_dac_vol_lfs_path); + if (v > 48) { + v = 48; + } + return v; +} + +/* 改动原因:面板 MIC_LEVEL 调节的是 MIC HID 0~48 级(与 HID 0x82/0x83 一致),映射后写 ADC 寄存器 */ +static unsigned char tx1_mic_vol_lfs_path[] = "tx1_mic_vol"; + +void tx1_save_mic_volume(unsigned char level) +{ + if (level > 48) { + level = 48; + } + save_value(tx1_mic_vol_lfs_path, level); +} + +unsigned char tx1_load_mic_volume(void) +{ + unsigned char v = load_value(tx1_mic_vol_lfs_path); + if (v > 48) { + v = 48; + } + return v; +} + unsigned char load_value(unsigned char *path) { unsigned char value = 255; @@ -277,7 +338,7 @@ void user_read_hidpass(unsigned char * hidPassData) for (i = 0; i < 64; i++) { hidPassData[i] = g_hid_pass_data[i]; - debug_printf("hidPassData[%d] = %02x\n", i, hidPassData[i]); + //debug_printf("hidPassData[%d] = %02x\n", i, hidPassData[i]); g_hid_pass_data[i] = 0; } } @@ -289,7 +350,7 @@ void user_set_hidpass(unsigned char *data) for (int i = 0; i < 63; i++) { g_hid_pass_data[i] = data[i]; - debug_printf("g_hid_pass_data[%d] = %02x\n", i, g_hid_pass_data[i]); + // debug_printf("g_hid_pass_data[%d] = %02x\n", i, g_hid_pass_data[i]); } hidSetChangePending(0x1); diff --git a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_func.h b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_func.h index 750e9c7..04e3a13 100644 --- a/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_func.h +++ b/sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/user_func.h @@ -59,5 +59,15 @@ void save_value32(unsigned char *path, unsigned value); unsigned load_value32(unsigned char *path); #endif +/* 改动原因:TX1 GAME 模式(0..3) 断电记忆,与 jok 面板四档一致;tile0/tile1 均可调用 */ +void tx1_save_game_mode(unsigned char mode); +unsigned char tx1_load_game_mode(void); + +/* 改动原因:SYSTEM_VOLUME 对应 DAC HID 等级(0~48)、MIC_LEVEL 对应 MIC HID 等级(0~48),断电记忆 */ +void tx1_save_dac_volume(unsigned char level); +unsigned char tx1_load_dac_volume(void); +void tx1_save_mic_volume(unsigned char level); +unsigned char tx1_load_mic_volume(void); + #endif