add more modes

This commit is contained in:
Steven Dan
2026-05-25 11:04:11 +08:00
parent 26e64a3421
commit fadd5e4f54
25 changed files with 1112 additions and 7525 deletions

View File

@@ -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 合并 UAC1Win 检测仅本目标(参照 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_<project>_<version>.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_<project>_<version>.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
)

Binary file not shown.

View File

@@ -30,18 +30,16 @@
<Port Location="XS1_PORT_1O" Name="PORT_I2S_DAC0"/>
<Port Location="XS1_PORT_1N" Name="PORT_I2S_ADC0"/>
<!-- 改动原因:与 jok.xn 一致,仅保留 PORT_MCLK_COUNT勿与 PORT_MCLK_COUNT_2 重复绑定 16B -->
<Port Location="XS1_PORT_16B" Name="PORT_MCLK_COUNT"/>
<Port Location="XS1_PORT_16B" Name="PORT_MCLK_COUNT_2"/>
<!-- 改动原因:与 UAC2 jok.xn tile[0] 对齐,供 audiohw.xc TX1 按键/指示灯使用 -->
<Port Location="XS1_PORT_8D" Name="PORT_LED_D10_8_11_9"/> <!-- 8D7..4 = D10/8/11/9低有效 -->
<Port Location="XS1_PORT_4F" Name="PORT_BUTTON_FPSMODE_GAMEMODE_MICMUTE"/> <!-- 4F3..1 = FPS/GAME/MIC -->
<Port Location="XS1_PORT_4E" Name="PORT_BUTTON_VOLPLUS_VOLMINUS"/> <!-- 4E3..2 = VOL+/VOL- -->
<!-- UART Ports -->
<Port Location="XS1_PORT_4D" Name="PORT_MQA_RATE"/>
<Port Location="XS1_PORT_4A" Name="PORT_MQA_AUTH_STATE"/>
<Port Location="XS1_PORT_1P" Name="PORT_PLL_REF"/>
<!-- 改动原因:删除 PORT_PLL_REF 与 PORT_MCLK_IN 同绑 XS1_PORT_1P旧 fosi_c1 xn 遗留),
* 会导致 ConfigAudioPorts 对 p_lrclk 执行 setc 时 ET_ILLEGAL_RESOURCEPLL 若需要请改到独立脚位(如 jok 316-mc 用 1A -->
</Tile>
<Tile Number="1" Reference="tile[1]">

View File

@@ -13,9 +13,11 @@
#include <stdio.h>
#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~48g_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~5interface 原样传 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_fps0=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_uac1FPS71 固件切离 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; // 改动原因检测静音开关变化并上报0xB20xFF=未初始化
static unsigned g_last_adc_loop = 0xFF; // 改动原因:检测监听开关(g_adc_loop)变化并上报0xB40xFF=未初始化
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~480.5dB/级 UI映射到本板 PGA 1~371dB/级,最大 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 轮询下发 EX3Dpersist=1 时写入 LFSGAME 键/需记忆时)。
*/
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 固件内已检测过 OSWin 才在 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) 并写寄存器+FlashMIC_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; // 同步头2GET_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);
}
}

View File

@@ -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 <print.h>
#include <stdio.h>
#include <string.h>
#include <platform.h>
#include <xs1.h>
#include <xcore/chanend.h>
#include <xcore/channel.h>
#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
}
}

View File

@@ -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);
}
}

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -8,6 +8,8 @@
#include <math.h> // 添加数学函数支持
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 <xcore/channel.h>
#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/LFStile1 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;
}

View File

@@ -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

View File

@@ -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(); }

View File

@@ -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 <syscall.h>
#include <platform.h>
#include <xs1.h>
#include <xclib.h>
#include <print.h>
#ifdef XSCOPE
#include <xscope.h>
#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

View File

@@ -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 <syscall.h>
#include <platform.h>
#include <xs1.h>
#include <xclib.h>
#include <print.h>
#ifdef XSCOPE
#include <xscope.h>
#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

View File

@@ -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 <syscall.h>
#include <platform.h>
#include <xs1.h>
#include <xclib.h>
#include <print.h>
#ifdef XSCOPE
#include <xscope.h>
#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

View File

@@ -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 在 tile0EX3D 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 + 合并 UAC1BYPASS/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 后置 1tile1 ex3d_task 强制重新 apply防 init 早于 load */
extern unsigned g_tx1_ex3d_resync_req;
#endif /* TX1_EX3D_GAME_H */

View File

@@ -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 */

View File

@@ -4,6 +4,8 @@
*/
#include "tx1_led_effects.h"
#include "tx1_rgb_brightness.h"
#include "tx1_ex3d_game.h"
#include "xc_ptr.h"
#include <string.h>
#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_loopBYPASS 时跑跑马灯等装饰灯效
*------------------------------------------------------------------------*/
#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;
}

View File

@@ -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 */

View File

@@ -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 <platform.h>
#include <print.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#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]);
}
}

View File

@@ -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 <platform.h>
#include <print.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#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]);
}
}

View File

@@ -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 <platform.h>
#include <print.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#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; i<NUM_USB_CHAN_OUT; i++) {
p_in[i] = p->usb_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; i<NUM_USB_CHAN_OUT; i++) {
p->usb_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]);
}
}

View File

@@ -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 <platform.h>
#include <print.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#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; i<NUM_USB_CHAN_OUT; i++) {
p_in[i] = p->usb_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; i<NUM_USB_CHAN_OUT; i++) {
p->usb_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]);
}
}

View File

@@ -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);

View File

@@ -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