rename app_usb_aud_fosi_c1_v71
This commit is contained in:
163
sw_usb_audio/app_usb_aud_fosi_c1_v71/CMakeLists.txt
Normal file
163
sw_usb_audio/app_usb_aud_fosi_c1_v71/CMakeLists.txt
Normal file
@@ -0,0 +1,163 @@
|
||||
cmake_minimum_required(VERSION 3.21)
|
||||
include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/mode_cal.cmake)
|
||||
project(phaten_module)
|
||||
|
||||
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)
|
||||
|
||||
set(SW_FACT_VERSION -DBCD_DEVICE_J=5
|
||||
-DBCD_DEVICE_M=5
|
||||
-DBCD_DEVICE_N=7)
|
||||
|
||||
set(SW_USB_AUDIO_FLAGS ${EXTRA_BUILD_FLAGS} ${SW_USB_VERSION} -O3
|
||||
-report
|
||||
-lquadflash
|
||||
-g
|
||||
-lotp3
|
||||
-DUART_TX_VALUE=0x4
|
||||
-DUSB_TILE=tile[0]
|
||||
-DADAT_TX_USE_SHARED_BUFF=1
|
||||
-DXUA_QUAD_SPI_FLASH=1)
|
||||
|
||||
|
||||
|
||||
set(SW_FACT_AUDIO_FLAGS ${EXTRA_BUILD_FLAGS} ${SW_FACT_VERSION}
|
||||
-O3
|
||||
-report
|
||||
-lquadflash
|
||||
-g
|
||||
-lotp3
|
||||
-DUART_TX_VALUE=0x4
|
||||
-DUSB_TILE=tile[0]
|
||||
-DADAT_TX_USE_SHARED_BUFF=1
|
||||
-DXUA_QUAD_SPI_FLASH=1)
|
||||
|
||||
|
||||
|
||||
LINK_DIRECTORIES(${CMAKE_CURRENT_LIST_DIR}/../../lib_dnr/lib_dnr)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
set(APP_COMPILER_FLAGS_v71_uac2 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2
|
||||
-DI2S_CHANS_ADC=2
|
||||
-DMIN_FREQ=48000
|
||||
-DMAX_FREQ=48000
|
||||
-DUSE_EX3D=1
|
||||
-DF3_F4_FPS_UAC2=1
|
||||
-DMIXER=0
|
||||
-DUAC2_MODE=1
|
||||
-ldnr_50ms
|
||||
-llib_ex3d_all
|
||||
-DEQ_EN=1
|
||||
-DDNR_ENABLE=1
|
||||
-DSTREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS=16
|
||||
-DSTREAM_FORMAT_INPUT_1_RESOLUTION_BITS=16
|
||||
-DINPUT_FORMAT_COUNT=1
|
||||
-DOUTPUT_FORMAT_COUNT=1
|
||||
-DEX3D_SF_NUM=3
|
||||
-DNUM_USB_CHAN_OUT=8
|
||||
-DNUM_USB_CHAN_IN=2
|
||||
-DNUM_EX3D_CHAN_OUT=2
|
||||
-DMIN_VOLUME=0xE000
|
||||
-DINPUT_VOLUME_CONTROL=1
|
||||
-DOUTPUT_VOLUME_CONTROL=1
|
||||
#-DDEBUG_MEMORY_LOG_ENABLED=1
|
||||
-DXUA_DFU_EN=1
|
||||
-DHID_DFU_EN=1
|
||||
-DIR_SWITCHING_MODE
|
||||
-DHID_CONTROLS=1)
|
||||
|
||||
set(APP_COMPILER_FLAGS_v71_uac1 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2
|
||||
-DI2S_CHANS_ADC=2
|
||||
-DMIN_FREQ=48000
|
||||
-DAUDIO_CLASS=1
|
||||
-DMAX_FREQ=48000
|
||||
-DUSE_EX3D=1
|
||||
-DF3_F4_FPS_UAC2=1
|
||||
-DMIXER=0
|
||||
-DUAC2_MODE=1
|
||||
-ldnr_50ms
|
||||
-llib_ex3d_all
|
||||
-DEQ_EN=1
|
||||
-DDNR_ENABLE=1
|
||||
-DSTREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS=32
|
||||
-DSTREAM_FORMAT_INPUT_1_RESOLUTION_BITS=32
|
||||
-DINPUT_FORMAT_COUNT=1
|
||||
-DOUTPUT_FORMAT_COUNT=1
|
||||
-DEX3D_SF_NUM=3
|
||||
-DNUM_USB_CHAN_OUT=8
|
||||
-DNUM_USB_CHAN_IN=2
|
||||
-DNUM_EX3D_CHAN_OUT=2
|
||||
-DMIN_VOLUME=0xE000
|
||||
-DINPUT_VOLUME_CONTROL=1
|
||||
-DOUTPUT_VOLUME_CONTROL=1
|
||||
#-DDEBUG_MEMORY_LOG_ENABLED=1
|
||||
-DXUA_DFU_EN=1
|
||||
-DHID_DFU_EN=1
|
||||
-DIR_SWITCHING_MODE
|
||||
-DHID_CONTROLS=1)
|
||||
|
||||
|
||||
set(APP_INCLUDES src src/core src/extensions ../../lib_dnr/lib_dnr)
|
||||
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)
|
||||
###=========================================================================###
|
||||
|
||||
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(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 xflash ${XE_FACT} --loader ${LOADER_OBJ}
|
||||
--upgrade 2 ${XE_F5}
|
||||
--upgrade 3 ${XE_F1}
|
||||
--upgrade 1 ${XE_F3F4}
|
||||
--upgrade 4 ${XE_F6F7}
|
||||
-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
|
||||
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 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}
|
||||
-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
|
||||
COMMENT "Generating update image: update_${APP_BASE}_${FW_VERSION}.bin"
|
||||
VERBATIM
|
||||
)
|
||||
83
sw_usb_audio/app_usb_aud_fosi_c1_v71/src/core/xu316_qf60.xn
Normal file
83
sw_usb_audio/app_usb_aud_fosi_c1_v71/src/core/xu316_qf60.xn
Normal file
@@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Network xmlns="http://www.xmos.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.xmos.com http://www.xmos.com" ManuallySpecifiedRouting="true">
|
||||
<Type>Board</Type>
|
||||
<Name>XS3 MC Audio</Name>
|
||||
<Declarations>
|
||||
<Declaration>tileref tile[2]</Declaration>
|
||||
<Declaration>tileref usb_tile</Declaration>
|
||||
</Declarations>
|
||||
<Packages>
|
||||
<Package id="0" Type="XS3-UnA-1024-QF60A">
|
||||
<Nodes>
|
||||
<Node Id="0" InPackageId="0" Type="XS3-L16A-1024" Oscillator="24MHz" SystemFrequency="600MHz" referencefrequency="100MHz">
|
||||
<Boot>
|
||||
<Source Location="SPI:bootFlash"/>
|
||||
</Boot>
|
||||
<Tile Number="0" Reference="tile[0]">
|
||||
<Port Location="XS1_PORT_1B" Name="PORT_SQI_CS"/>
|
||||
<Port Location="XS1_PORT_1C" Name="PORT_SQI_SCLK"/>
|
||||
<Port Location="XS1_PORT_4B" Name="PORT_SQI_SIO"/>
|
||||
|
||||
<!-- GPIO Ports -->
|
||||
<!-- I2C -->
|
||||
<Port Location="XS1_PORT_1D" Name="PORT_I2C_SCL"/>
|
||||
<Port Location="XS1_PORT_1A" Name="PORT_I2C_SDA"/>
|
||||
|
||||
<!-- Audio Ports -->
|
||||
<Port Location="XS1_PORT_1P" Name="PORT_MCLK_IN"/>
|
||||
<Port Location="XS1_PORT_1L" Name="PORT_I2S_BCLK"/>
|
||||
<Port Location="XS1_PORT_1M" Name="PORT_I2S_LRCLK"/>
|
||||
<Port Location="XS1_PORT_1O" Name="PORT_I2S_DAC0"/>
|
||||
<Port Location="XS1_PORT_1N" Name="PORT_I2S_ADC0"/>
|
||||
|
||||
<Port Location="XS1_PORT_16B" Name="PORT_MCLK_COUNT"/>
|
||||
<Port Location="XS1_PORT_16B" Name="PORT_MCLK_COUNT_2"/>
|
||||
|
||||
<!-- 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"/>
|
||||
</Tile>
|
||||
|
||||
<Tile Number="1" Reference="tile[1]">
|
||||
<Port Location="XS1_PORT_1A" Name="PORT_UART_RX"/>
|
||||
<Port Location="XS1_PORT_1K" Name="PORT_UART_TX"/>
|
||||
<Port Location="XS1_PORT_1F" Name="PORT_OPT_IN"/>
|
||||
|
||||
<Port Location="XS1_PORT_1D" Name="PORT_MCLK_IN_SPDIF_TX"/>
|
||||
<Port Location="XS1_PORT_1B" Name="PORT_I2S_SLRCLK"/>
|
||||
<Port Location="XS1_PORT_1C" Name="PORT_I2S_SBCLK"/>
|
||||
<Port Location="XS1_PORT_1G" Name="PORT_COAX_IN"/>
|
||||
|
||||
|
||||
</Tile>
|
||||
</Node>
|
||||
</Nodes>
|
||||
</Package>
|
||||
</Packages>
|
||||
<Nodes>
|
||||
<Node Id="2" Type="device:" RoutingId="0x8000">
|
||||
<Service Id="0" Proto="xscope_host_data(chanend c);">
|
||||
<Chanend Identifier="c" end="3"/>
|
||||
</Service>
|
||||
</Node>
|
||||
</Nodes>
|
||||
<Links>
|
||||
<Link Encoding="2wire" Delays="4,4" Flags="XSCOPE">
|
||||
<LinkEndpoint NodeId="0" Link="XL0"/>
|
||||
<LinkEndpoint NodeId="2" Chanend="1"/>
|
||||
</Link>
|
||||
</Links>
|
||||
<ExternalDevices>
|
||||
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash" Type="S25FL116K" PageSize="256" SectorSize="4096" NumPages="16384">
|
||||
<Attribute Name="PORT_SQI_CS" Value="PORT_SQI_CS"/>
|
||||
<Attribute Name="PORT_SQI_SCLK" Value="PORT_SQI_SCLK"/>
|
||||
<Attribute Name="PORT_SQI_SIO" Value="PORT_SQI_SIO"/>
|
||||
<Attribute Name="QE_REGISTER" Value="flash_qe_location_status_reg_0"/>
|
||||
<Attribute Name="QE_BIT" Value="flash_qe_bit_6"/>
|
||||
</Device>
|
||||
</ExternalDevices>
|
||||
<JTAGChain>
|
||||
<JTAGDevice NodeId="0"/>
|
||||
</JTAGChain>
|
||||
</Network>
|
||||
2534
sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/audiohw.xc.bak
Normal file
2534
sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/audiohw.xc.bak
Normal file
File diff suppressed because it is too large
Load Diff
BIN
sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/dist/eq_designer_new.exe
vendored
Normal file
BIN
sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/dist/eq_designer_new.exe
vendored
Normal file
Binary file not shown.
@@ -0,0 +1,32 @@
|
||||
// Copyright 2026 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
|
||||
#include "noise_gate_simple.h"
|
||||
|
||||
#define GATE_THRESHOLD_DB_MIN (-80)
|
||||
#define GATE_THRESHOLD_DB_MAX (0)
|
||||
|
||||
// 10^(db/20) scaled to Q1.31, 4 dB resolution. Input dB is rounded to nearest
|
||||
// 4 dB on lookup. 21 entries = 84 bytes of ROM.
|
||||
static const int32_t k_db_to_q31_step4[21] = {
|
||||
/* -80 */ 214748, 340354, 539423, 855025,
|
||||
/* -64 */ 1355287, 2147484, 3403542, 5394226,
|
||||
/* -48 */ 8550255, 13552872, 21474836, 34035417,
|
||||
/* -32 */ 53942258, 85502547, 135528724, 214748365,
|
||||
/* -16 */ 340354167, 539422577, 855025466, 1355287238,
|
||||
/* 0 */ 2147483647
|
||||
};
|
||||
|
||||
void gate_reset(simple_gate_t *g) {
|
||||
g->env = 0;
|
||||
g->gain = NOISE_GATE_Q31_ONE;
|
||||
}
|
||||
|
||||
void gate_set_threshold_db(simple_gate_t *g, int8_t db) {
|
||||
if (db > GATE_THRESHOLD_DB_MAX) db = GATE_THRESHOLD_DB_MAX;
|
||||
if (db < GATE_THRESHOLD_DB_MIN) db = GATE_THRESHOLD_DB_MIN;
|
||||
int idx = (db - GATE_THRESHOLD_DB_MIN + 2) >> 2; // round to nearest 4 dB
|
||||
if (idx < 0) idx = 0;
|
||||
if (idx > 20) idx = 20;
|
||||
g->threshold_q31 = k_db_to_q31_step4[idx];
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// Copyright 2026 XMOS LIMITED.
|
||||
// This Software is subject to the terms of the XMOS Public Licence: Version 1.
|
||||
//
|
||||
// Minimal, zero-latency Q1.31 noise gate. Coefficients are hard-coded for
|
||||
// fs = 48 kHz; the struct only carries per-instance state.
|
||||
//
|
||||
// Algorithm:
|
||||
// 1) Peak envelope tracker: single-pole EMA on |x|, separate rise/decay
|
||||
// coefficients.
|
||||
// 2) Hard-knee decision: target_gain = (env < threshold) ? 0 : 1.0.
|
||||
// 3) Gain smoothing: EMA toward target_gain; fast when opening
|
||||
// (gain rising), slow when closing (gain falling).
|
||||
// 4) Output = x * gain (Q31 * Q31 -> Q31).
|
||||
// Group delay: 0 samples.
|
||||
//
|
||||
// gate_process() lives in this header as static inline so the single call
|
||||
// site in dnr_dsp.c inlines without function-call overhead — halves the
|
||||
// tile-0 code footprint vs. an out-of-line implementation.
|
||||
|
||||
#ifndef NOISE_GATE_SIMPLE_H
|
||||
#define NOISE_GATE_SIMPLE_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define NOISE_GATE_Q31_ONE 0x7FFFFFFF
|
||||
|
||||
// Alphas = 1 - exp(-1 / (tau * fs)) in Q1.31 at fs = 48 kHz.
|
||||
#define NOISE_GATE_ENV_ATTACK_A 44291727 // 1 ms
|
||||
#define NOISE_GATE_ENV_RELEASE_A 4469637 // 10 ms
|
||||
#define NOISE_GATE_OPEN_A 22253774 // 2 ms (gain rising)
|
||||
#define NOISE_GATE_CLOSE_A 558561 // 80 ms (gain falling)
|
||||
|
||||
typedef struct {
|
||||
int32_t env; // Envelope state, Q1.31 unsigned magnitude.
|
||||
int32_t gain; // Smoothed gain, Q1.31 (0..INT32_MAX).
|
||||
int32_t threshold_q31; // Linear threshold, Q1.31 unsigned magnitude.
|
||||
} simple_gate_t;
|
||||
|
||||
// Reset envelope and gain. Leaves threshold unchanged.
|
||||
void gate_reset(simple_gate_t *g);
|
||||
|
||||
// Set threshold in integer dBFS, clamped to [-80, 0]. Quantised to 4 dB.
|
||||
void gate_set_threshold_db(simple_gate_t *g, int8_t db);
|
||||
|
||||
// Single-sample gate. Inlined at the call site.
|
||||
static inline int32_t gate_process(simple_gate_t *g, int32_t x) {
|
||||
int32_t ax;
|
||||
if (x == (int32_t)0x80000000) ax = NOISE_GATE_Q31_ONE;
|
||||
else if (x < 0) ax = -x;
|
||||
else ax = x;
|
||||
|
||||
int32_t edelta = ax - g->env;
|
||||
int32_t env_a = (edelta > 0) ? NOISE_GATE_ENV_ATTACK_A : NOISE_GATE_ENV_RELEASE_A;
|
||||
int64_t estep = (int64_t)env_a * (int64_t)edelta;
|
||||
g->env += (int32_t)(estep >> 31);
|
||||
|
||||
int32_t target = (g->env < g->threshold_q31) ? 0 : NOISE_GATE_Q31_ONE;
|
||||
|
||||
int32_t gain_a = (target > g->gain) ? NOISE_GATE_OPEN_A : NOISE_GATE_CLOSE_A;
|
||||
int32_t gdelta = target - g->gain;
|
||||
int64_t gstep = (int64_t)gain_a * (int64_t)gdelta;
|
||||
g->gain += (int32_t)(gstep >> 31);
|
||||
|
||||
int64_t y = (int64_t)x * (int64_t)g->gain;
|
||||
return (int32_t)(y >> 31);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // NOISE_GATE_SIMPLE_H
|
||||
1474
sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/dsp.c.bak
Normal file
1474
sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/dsp.c.bak
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,224 @@
|
||||
#if DEBUG_MEMORY_LOG_ENABLED
|
||||
#define DEBUG_PRINT_ENABLE 1
|
||||
#else
|
||||
#define DEBUG_PRINT_ENABLE 0
|
||||
#endif
|
||||
#include <xs1.h>
|
||||
#include <platform.h>
|
||||
#include <print.h>
|
||||
#include <string.h>
|
||||
#include "xmath/filter.h"
|
||||
#include "stdio.h"
|
||||
#include "xc_ptr.h"
|
||||
#include "eq.h"
|
||||
#include "share_buffer.h"
|
||||
#include "debug_print.h"
|
||||
#include "eq_flash_storage.h"
|
||||
|
||||
#if 0
|
||||
#define DPRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define DPRINTF(...)
|
||||
#endif
|
||||
|
||||
#define LEN_FADE_ (2024)
|
||||
|
||||
// EQ Flash存储初始化标志
|
||||
int eq_flash_initialized = 0;
|
||||
extern unsigned int is_mode_changed(void);
|
||||
extern void change_eq_mode(unsigned sample_freq);
|
||||
extern void clear_eq_status(unsigned sample_freq, unsigned ch_no);
|
||||
extern unsigned int g_request_eq_mode;
|
||||
extern unsigned int g_eq_enable; // 改动原因:添加EQ使能开关外部声明,用于初始化时检查EQ状态
|
||||
extern unsigned int g_saved_eq_mode; // 改动原因:添加保存模式外部声明,用于初始化时设置保存的模式
|
||||
extern void debug_print_eq_params(unsigned sample_freq);
|
||||
extern uint32_t get_reference_time(void);
|
||||
extern void update_eq_post_gain(void);
|
||||
extern unsigned int g_eq_sample_rate;
|
||||
extern unsigned g_windows_detect_done;
|
||||
extern unsigned g_dnr_init_flag;
|
||||
extern unsigned g_ex3d_key_verified;
|
||||
|
||||
#pragma unsafe arrays
|
||||
void dsp_core0(void)
|
||||
{
|
||||
unsigned t0,t1;
|
||||
static int audio_in_samples[2]; // idx 0: input_samples
|
||||
static int audio_out_samples[2]; // idx 0: input_samples
|
||||
static unsigned int usb_to_dsp_ratio = 1;
|
||||
static int buffer_in_active = 0;
|
||||
static int buffer_out_active = 0;
|
||||
static unsigned int sample_freq = 48000 ;
|
||||
unsigned b_fade_in = 0;
|
||||
unsigned u_in_step;
|
||||
unsigned b_fade_out = 0;
|
||||
unsigned u_out_step;
|
||||
|
||||
// EQ Flash存储初始化标志
|
||||
|
||||
delay_milliseconds(300);
|
||||
unsigned windows_detect_done, dnr_init_flag, ex3d_key_verified;
|
||||
GET_SHARED_GLOBAL(windows_detect_done, g_windows_detect_done);
|
||||
#if DNR_ENABLE
|
||||
GET_SHARED_GLOBAL(dnr_init_flag, g_dnr_init_flag);
|
||||
#endif
|
||||
#if USE_EX3D
|
||||
GET_SHARED_GLOBAL(ex3d_key_verified, g_ex3d_key_verified);
|
||||
#endif
|
||||
while ((windows_detect_done == 0)
|
||||
#if DNR_ENABLE
|
||||
|| (dnr_init_flag == 0)
|
||||
#endif
|
||||
#if USE_EX3D
|
||||
|| (ex3d_key_verified == 0)
|
||||
#endif
|
||||
) {
|
||||
asm("nop");
|
||||
GET_SHARED_GLOBAL(windows_detect_done, g_windows_detect_done);
|
||||
#if DNR_ENABLE
|
||||
GET_SHARED_GLOBAL(dnr_init_flag, g_dnr_init_flag);
|
||||
#endif
|
||||
#if USE_EX3D
|
||||
GET_SHARED_GLOBAL(ex3d_key_verified, g_ex3d_key_verified);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
#if EQ_EN
|
||||
|
||||
uint32_t time = get_reference_time(), time2;
|
||||
// EQ Flash存储初始化 - 只在第一次运行时执行
|
||||
if (eq_flash_initialized == 0) {
|
||||
// 延迟更长时间,确保QSPI Flash完全初始化
|
||||
debug_printf("Initializing EQ Flash storage system\n");
|
||||
|
||||
// 初始化EQ Flash存储系统
|
||||
if (eq_flash_init() == 0) {
|
||||
debug_printf("EQ Flash storage initialized successfully\n");
|
||||
init_mode_info();
|
||||
eq_load_gain_and_names();
|
||||
// 检查Flash中是否有EQ参数数据
|
||||
debug_printf("Loading EQ parameters from Flash using simplified storage\n");
|
||||
// 简化加载逻辑:每个模式只加载一次,会自动应用到所有采样率和通道
|
||||
int loaded_modes = 0;
|
||||
|
||||
for (int mode = EQ_USER_MODE_MIN; mode <= EQ_USER_MODE_MAX; mode++) {
|
||||
if (eq_load_all_params_and_calculate_coefficients(44100, mode) == 0) {
|
||||
loaded_modes++;
|
||||
debug_printf("Loaded mode %d parameters from Flash (applied to all sample rates and channels)\n", mode);
|
||||
}
|
||||
}
|
||||
debug_printf("Loaded %d EQ modes from Flash successfully\n", loaded_modes);
|
||||
|
||||
// 从mode info里获取gain值,并相应的赋值到eq数组的post gain
|
||||
update_eq_post_gain();
|
||||
// 从Flash加载并设置当前EQ模式和使能状态
|
||||
// 改动原因:修复EQ开关逻辑问题,确保从Flash加载模式时正确设置g_saved_eq_mode和g_eq_enable
|
||||
// eq_flash_load_current_mode()会同时加载模式并设置g_eq_enable
|
||||
int saved_mode_result = eq_flash_load_current_mode();
|
||||
|
||||
// 改动原因:确保g_eq_enable被正确加载,无论模式加载是否成功
|
||||
// eq_flash_load_current_mode()已经设置了g_eq_enable,这里读取确认
|
||||
unsigned int eq_enable = g_eq_enable;
|
||||
|
||||
if (saved_mode_result >= 0 && saved_mode_result <= 9) {
|
||||
uint8_t saved_mode = (uint8_t)saved_mode_result;
|
||||
debug_printf("Loaded current EQ mode %d and enable %d from Flash\n", saved_mode, eq_enable);
|
||||
|
||||
// 改动原因:将eq_enable独立为全局开关,所有模式共用一个开关
|
||||
// 无论EQ是否启用,都设置到Flash中保存的模式,eq_enable只控制EQ处理开关
|
||||
g_saved_eq_mode = saved_mode;
|
||||
SET_SHARED_GLOBAL(g_request_eq_mode, saved_mode);
|
||||
debug_printf("EQ initialization: Set mode to %d from Flash, EQ enable: %d (global switch, independent of mode)\n",
|
||||
saved_mode, eq_enable);
|
||||
} else {
|
||||
// Flash加载失败时,使用默认模式0,EQ默认禁用
|
||||
// 改动原因:如果模式加载失败,确保g_eq_enable也被设置为默认值0
|
||||
g_saved_eq_mode = 0;
|
||||
SET_SHARED_GLOBAL(g_request_eq_mode, 0);
|
||||
g_eq_enable = 0;
|
||||
eq_enable = 0; // 同步本地变量
|
||||
debug_printf("Failed to load EQ mode from Flash, using default mode 0, EQ disabled (enable: %d)\n", eq_enable);
|
||||
}
|
||||
|
||||
} else {
|
||||
debug_printf("Failed to initialize EQ Flash storage system, continuing without Flash storage\n");
|
||||
// 即使Flash初始化失败,也标记为已初始化,避免重复尝试
|
||||
// 系统将继续运行,只是不使用Flash存储功能
|
||||
}
|
||||
|
||||
eq_single_param_database_init();
|
||||
time2 = get_reference_time();
|
||||
debug_printf("EQ Flash storage initialized time %lu\n", time2 - time);
|
||||
eq_flash_initialized = 1;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
if(is_ring_buffer_empty(0) && is_ring_buffer_empty(1))
|
||||
{
|
||||
// delay_microseconds(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
GET_SHARED_GLOBAL(sample_freq, g_eq_sample_rate);
|
||||
if (sample_freq == 0) sample_freq = 48000;
|
||||
audio_in_samples[0] = read_from_ring_buffer(0);
|
||||
audio_in_samples[1] = read_from_ring_buffer(1);
|
||||
|
||||
if (is_mode_changed() && b_fade_out == 0 && b_fade_in == 0)
|
||||
{
|
||||
|
||||
debug_printf("mode changed ====================== \n");
|
||||
//debug_print_eq_params(sample_freq);
|
||||
b_fade_out=1;
|
||||
u_out_step=1;
|
||||
}
|
||||
|
||||
|
||||
audio_out_samples[0] = handler_eq_filter(sample_freq, 0, audio_in_samples[0]);
|
||||
audio_out_samples[1] = handler_eq_filter(sample_freq, 1, audio_in_samples[1]);
|
||||
|
||||
|
||||
if(b_fade_out)
|
||||
{
|
||||
audio_out_samples[0] /= LEN_FADE_;
|
||||
audio_out_samples[0] *= (LEN_FADE_-u_out_step) ;
|
||||
|
||||
audio_out_samples[1] /= LEN_FADE_;
|
||||
audio_out_samples[1] *= (LEN_FADE_-u_out_step) ;
|
||||
|
||||
++u_out_step;
|
||||
}
|
||||
|
||||
if(b_fade_out == 1 && u_out_step == LEN_FADE_){
|
||||
b_fade_out = 0;
|
||||
change_eq_mode(sample_freq);
|
||||
clear_eq_status(sample_freq, 0);
|
||||
clear_eq_status(sample_freq, 1);
|
||||
clear_ring_buffer(0);
|
||||
clear_ring_buffer(1);
|
||||
b_fade_in=1;
|
||||
u_in_step=1;
|
||||
}
|
||||
|
||||
|
||||
if (b_fade_in)
|
||||
{
|
||||
audio_out_samples[0] /= LEN_FADE_;
|
||||
audio_out_samples[0] *= (u_in_step) ;
|
||||
|
||||
audio_out_samples[1] /= LEN_FADE_;
|
||||
audio_out_samples[1] *= (u_in_step);
|
||||
|
||||
if(++u_in_step >= LEN_FADE_){
|
||||
b_fade_in = 0;
|
||||
}
|
||||
}
|
||||
|
||||
write_to_ring_buffer(2, audio_out_samples[0]);
|
||||
write_to_ring_buffer(3, audio_out_samples[1]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -0,0 +1,421 @@
|
||||
#if DEBUG_MEMORY_LOG_ENABLED
|
||||
#define DEBUG_PRINT_ENABLE 1
|
||||
#else
|
||||
#define DEBUG_PRINT_ENABLE 0
|
||||
#endif
|
||||
#include <xs1.h>
|
||||
#include <platform.h>
|
||||
#include <print.h>
|
||||
#include <string.h>
|
||||
#include "xmath/filter.h"
|
||||
#include "stdio.h"
|
||||
#include "xc_ptr.h"
|
||||
#include "eq.h"
|
||||
#include "share_buffer.h"
|
||||
#include "debug_print.h"
|
||||
#include "eq_flash_storage.h"
|
||||
#include "eq_channel_protocol.h"
|
||||
|
||||
#if 0
|
||||
#define DPRINTF(...) printf(__VA_ARGS__)
|
||||
#else
|
||||
#define DPRINTF(...)
|
||||
#endif
|
||||
|
||||
#define LEN_FADE_ (2024)
|
||||
|
||||
extern unsigned int is_mode_changed(void);
|
||||
extern void change_eq_mode(unsigned sample_freq);
|
||||
extern void clear_eq_status(unsigned sample_freq, unsigned ch_no);
|
||||
extern unsigned int g_request_eq_mode;
|
||||
extern unsigned int g_eq_enable;
|
||||
extern unsigned int g_saved_eq_mode;
|
||||
extern void debug_print_eq_params(unsigned sample_freq);
|
||||
extern uint32_t get_reference_time(void);
|
||||
extern void update_eq_post_gain(void);
|
||||
extern unsigned int g_eq_sample_rate;
|
||||
extern unsigned g_windows_detect_done;
|
||||
extern unsigned g_dnr_init_flag;
|
||||
extern unsigned g_ex3d_key_verified;
|
||||
extern unsigned int g_new_eq_mode;
|
||||
extern unsigned int g_force_eq_mode_change;
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* eq_flash_init_task — 运行在 tile[0]
|
||||
*
|
||||
* 负责:
|
||||
* 1) 等待系统就绪 (windows_detect / dnr / ex3d)
|
||||
* 2) 从 QSPI Flash 加载 EQ 预设参数
|
||||
* 3) 通过 c_eq_params channel 将加载的参数发送到 tile[1] 的 dsp_core0
|
||||
* 4) 完成后退出 (不占用线程)
|
||||
* ---------------------------------------------------------------- */
|
||||
void eq_flash_init_task(chanend c_eq_params)
|
||||
{
|
||||
#if EQ_EN
|
||||
delay_milliseconds(300);
|
||||
|
||||
/* ---- 等待系统就绪 ---- */
|
||||
unsigned windows_detect_done, dnr_init_flag, ex3d_key_verified;
|
||||
GET_SHARED_GLOBAL(windows_detect_done, g_windows_detect_done);
|
||||
#if DNR_ENABLE
|
||||
GET_SHARED_GLOBAL(dnr_init_flag, g_dnr_init_flag);
|
||||
#endif
|
||||
#if USE_EX3D
|
||||
GET_SHARED_GLOBAL(ex3d_key_verified, g_ex3d_key_verified);
|
||||
#endif
|
||||
while ((windows_detect_done == 0)
|
||||
#if DNR_ENABLE
|
||||
|| (dnr_init_flag == 0)
|
||||
#endif
|
||||
#if USE_EX3D
|
||||
|| (ex3d_key_verified == 0)
|
||||
#endif
|
||||
) {
|
||||
asm("nop");
|
||||
GET_SHARED_GLOBAL(windows_detect_done, g_windows_detect_done);
|
||||
#if DNR_ENABLE
|
||||
GET_SHARED_GLOBAL(dnr_init_flag, g_dnr_init_flag);
|
||||
#endif
|
||||
#if USE_EX3D
|
||||
GET_SHARED_GLOBAL(ex3d_key_verified, g_ex3d_key_verified);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint32_t time = get_reference_time(), time2;
|
||||
|
||||
/* ---- Flash 初始化 & 加载 ---- */
|
||||
debug_printf("Initializing EQ Flash storage system\n");
|
||||
|
||||
unsigned int saved_mode = 0;
|
||||
unsigned int eq_enable = 0;
|
||||
|
||||
if (eq_flash_init() == 0) {
|
||||
debug_printf("EQ Flash storage initialized successfully\n");
|
||||
init_mode_info();
|
||||
eq_load_gain_and_names();
|
||||
|
||||
debug_printf("Loading EQ parameters from Flash using simplified storage\n");
|
||||
int loaded_modes = 0;
|
||||
for (int mode = EQ_USER_MODE_MIN; mode <= EQ_USER_MODE_MAX; mode++) {
|
||||
if (eq_load_all_params_and_calculate_coefficients(44100, mode) == 0) {
|
||||
loaded_modes++;
|
||||
debug_printf("Loaded mode %d parameters from Flash\n", mode);
|
||||
}
|
||||
}
|
||||
debug_printf("Loaded %d EQ modes from Flash successfully\n", loaded_modes);
|
||||
|
||||
update_eq_post_gain();
|
||||
|
||||
int saved_mode_result = eq_flash_load_current_mode();
|
||||
eq_enable = g_eq_enable;
|
||||
|
||||
if (saved_mode_result >= 0 && saved_mode_result <= 9) {
|
||||
saved_mode = (unsigned int)saved_mode_result;
|
||||
debug_printf("Loaded current EQ mode %d and enable %d from Flash\n", saved_mode, eq_enable);
|
||||
g_saved_eq_mode = saved_mode;
|
||||
SET_SHARED_GLOBAL(g_request_eq_mode, saved_mode);
|
||||
} else {
|
||||
saved_mode = 0;
|
||||
g_saved_eq_mode = 0;
|
||||
SET_SHARED_GLOBAL(g_request_eq_mode, 0);
|
||||
g_eq_enable = 0;
|
||||
eq_enable = 0;
|
||||
}
|
||||
} else {
|
||||
debug_printf("Failed to initialize EQ Flash storage system\n");
|
||||
}
|
||||
|
||||
eq_single_param_database_init();
|
||||
time2 = get_reference_time();
|
||||
debug_printf("EQ Flash storage initialized time %lu\n", time2 - time);
|
||||
|
||||
/* ---- 通过 channel 将加载的参数发送到 tile[1] ---- */
|
||||
/* 发送每个 mode / channel 的完整 band 参数 */
|
||||
unsafe {
|
||||
extern eq_mode_data_t sEQ_data_44100HZ[NUM_EQ_MODES][NUM_EQ_CHANS];
|
||||
for (int mode = 0; mode < NUM_EQ_MODES; mode++) {
|
||||
for (int ch = 0; ch < NUM_EQ_CHANS; ch++) {
|
||||
c_eq_params <: (unsigned)EQ_CMD_FLASH_LOAD_MODE;
|
||||
c_eq_params <: (unsigned)mode;
|
||||
c_eq_params <: (unsigned)ch;
|
||||
c_eq_params <: (unsigned)sEQ_data_44100HZ[mode][ch].post_gain_db;
|
||||
for (int b = 0; b < MAX_EQ_BANDS; b++) {
|
||||
filter_params_t * unsafe bp = &sEQ_data_44100HZ[mode][ch].bands[b];
|
||||
c_eq_params <: (unsigned)bp->type;
|
||||
unsigned fc_u, q_u, bw_u, gain_u;
|
||||
memcpy(&fc_u, &bp->fc, 4);
|
||||
memcpy(&q_u, &bp->q, 4);
|
||||
memcpy(&bw_u, &bp->bw, 4);
|
||||
memcpy(&gain_u, &bp->gain, 4);
|
||||
c_eq_params <: fc_u;
|
||||
c_eq_params <: q_u;
|
||||
c_eq_params <: bw_u;
|
||||
c_eq_params <: gain_u;
|
||||
c_eq_params <: (unsigned)bp->index;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 发送初始化完成信号 + 当前模式/使能 */
|
||||
c_eq_params <: (unsigned)EQ_CMD_FLASH_INIT_COMPLETE;
|
||||
c_eq_params <: (unsigned)saved_mode;
|
||||
c_eq_params <: (unsigned)eq_enable;
|
||||
}
|
||||
|
||||
debug_printf("EQ Flash init task: all params sent to tile[1], task exiting\n");
|
||||
#endif /* EQ_EN */
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* 接收 channel 参数更新的内部处理函数 (tile[1])
|
||||
* ---------------------------------------------------------------- */
|
||||
#if EQ_EN
|
||||
static void handle_eq_channel_cmd(chanend c_eq_params, unsigned cmd, unsigned sample_freq)
|
||||
{
|
||||
extern eq_mode_data_t sEQ_data_44100HZ[NUM_EQ_MODES][NUM_EQ_CHANS];
|
||||
|
||||
switch (cmd) {
|
||||
case EQ_CMD_SET_MODE:
|
||||
{
|
||||
unsigned mode;
|
||||
c_eq_params :> mode;
|
||||
g_new_eq_mode = mode;
|
||||
debug_printf("EQ channel: SET_MODE %d\n", mode);
|
||||
break;
|
||||
}
|
||||
case EQ_CMD_SET_ENABLE:
|
||||
{
|
||||
unsigned enable;
|
||||
c_eq_params :> enable;
|
||||
g_eq_enable = enable;
|
||||
debug_printf("EQ channel: SET_ENABLE %d\n", enable);
|
||||
break;
|
||||
}
|
||||
case EQ_CMD_UPDATE_BAND:
|
||||
{
|
||||
unsigned mode, band_index, filter_type;
|
||||
unsigned fc_u, q_u, bw_u, gain_u;
|
||||
c_eq_params :> mode;
|
||||
c_eq_params :> band_index;
|
||||
c_eq_params :> filter_type;
|
||||
c_eq_params :> fc_u;
|
||||
c_eq_params :> q_u;
|
||||
c_eq_params :> bw_u;
|
||||
c_eq_params :> gain_u;
|
||||
|
||||
if (mode < NUM_EQ_MODES && band_index < MAX_EQ_BANDS) {
|
||||
float fc, q, bw, gain;
|
||||
memcpy(&fc, &fc_u, 4);
|
||||
memcpy(&q, &q_u, 4);
|
||||
memcpy(&bw, &bw_u, 4);
|
||||
memcpy(&gain, &gain_u, 4);
|
||||
|
||||
for (int ch = 0; ch < NUM_EQ_CHANS; ch++) {
|
||||
filter_params_t *bp = &sEQ_data_44100HZ[mode][ch].bands[band_index];
|
||||
bp->type = (filter_type_t)filter_type;
|
||||
bp->fc = fc;
|
||||
bp->q = q;
|
||||
bp->bw = bw;
|
||||
bp->gain = gain;
|
||||
bp->index = band_index;
|
||||
}
|
||||
/* 重算系数 */
|
||||
calculate_current_mode_coefficients(sample_freq, mode);
|
||||
debug_printf("EQ channel: UPDATE_BAND mode=%d band=%d\n", mode, band_index);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EQ_CMD_SET_GAIN:
|
||||
{
|
||||
unsigned mode;
|
||||
unsigned gain_val;
|
||||
c_eq_params :> mode;
|
||||
c_eq_params :> gain_val;
|
||||
if (mode < NUM_EQ_MODES) {
|
||||
int32_t gain_db = (int32_t)gain_val;
|
||||
sEQ_data_44100HZ[mode][0].post_gain_db = gain_db;
|
||||
sEQ_data_44100HZ[mode][1].post_gain_db = gain_db;
|
||||
debug_printf("EQ channel: SET_GAIN mode=%d gain=%d\n", mode, gain_db);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EQ_CMD_FORCE_REFRESH:
|
||||
{
|
||||
g_force_eq_mode_change = 1;
|
||||
debug_printf("EQ channel: FORCE_REFRESH\n");
|
||||
break;
|
||||
}
|
||||
case EQ_CMD_FLASH_LOAD_MODE:
|
||||
{
|
||||
unsigned mode, ch, post_gain;
|
||||
c_eq_params :> mode;
|
||||
c_eq_params :> ch;
|
||||
c_eq_params :> post_gain;
|
||||
if (mode < NUM_EQ_MODES && ch < NUM_EQ_CHANS) {
|
||||
sEQ_data_44100HZ[mode][ch].post_gain_db = (int32_t)post_gain;
|
||||
for (int b = 0; b < MAX_EQ_BANDS; b++) {
|
||||
unsigned type_u, fc_u, q_u, bw_u, gain_u, idx_u;
|
||||
c_eq_params :> type_u;
|
||||
c_eq_params :> fc_u;
|
||||
c_eq_params :> q_u;
|
||||
c_eq_params :> bw_u;
|
||||
c_eq_params :> gain_u;
|
||||
c_eq_params :> idx_u;
|
||||
filter_params_t *bp = &sEQ_data_44100HZ[mode][ch].bands[b];
|
||||
bp->type = (filter_type_t)type_u;
|
||||
memcpy(&bp->fc, &fc_u, 4);
|
||||
memcpy(&bp->q, &q_u, 4);
|
||||
memcpy(&bp->bw, &bw_u, 4);
|
||||
memcpy(&bp->gain, &gain_u, 4);
|
||||
bp->index = (uint8_t)idx_u;
|
||||
}
|
||||
} else {
|
||||
/* mode/ch 越界, 仍然要读空 channel 数据 */
|
||||
for (int b = 0; b < MAX_EQ_BANDS; b++) {
|
||||
unsigned dummy;
|
||||
c_eq_params :> dummy; c_eq_params :> dummy;
|
||||
c_eq_params :> dummy; c_eq_params :> dummy;
|
||||
c_eq_params :> dummy; c_eq_params :> dummy;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EQ_CMD_FLASH_INIT_COMPLETE:
|
||||
{
|
||||
unsigned saved_mode, eq_en;
|
||||
c_eq_params :> saved_mode;
|
||||
c_eq_params :> eq_en;
|
||||
g_saved_eq_mode = saved_mode;
|
||||
g_new_eq_mode = saved_mode;
|
||||
SET_SHARED_GLOBAL(g_request_eq_mode, saved_mode);
|
||||
g_eq_enable = eq_en;
|
||||
/* 为所有模式计算初始系数 */
|
||||
init_eq_data(48000);
|
||||
debug_printf("EQ channel: FLASH_INIT_COMPLETE mode=%d enable=%d\n", saved_mode, eq_en);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
debug_printf("EQ channel: unknown cmd 0x%x\n", cmd);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* EQ_EN */
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* dsp_core0 — 运行在 tile[1]
|
||||
*
|
||||
* EQ 滤波主循环 + 通过 channel 接收参数更新
|
||||
* ---------------------------------------------------------------- */
|
||||
#pragma unsafe arrays
|
||||
void dsp_core0(chanend c_eq_params)
|
||||
{
|
||||
unsigned t0,t1;
|
||||
static int audio_in_samples[2];
|
||||
static int audio_out_samples[2];
|
||||
static unsigned int usb_to_dsp_ratio = 1;
|
||||
static int buffer_in_active = 0;
|
||||
static int buffer_out_active = 0;
|
||||
static unsigned int sample_freq = 48000;
|
||||
unsigned b_fade_in = 0;
|
||||
unsigned u_in_step;
|
||||
unsigned b_fade_out = 0;
|
||||
unsigned u_out_step;
|
||||
|
||||
#if EQ_EN
|
||||
|
||||
/* 等待 Flash 初始化数据从 tile[0] 到达 */
|
||||
{
|
||||
unsigned flash_init_done = 0;
|
||||
while (!flash_init_done) {
|
||||
unsigned cmd;
|
||||
c_eq_params :> cmd;
|
||||
if (cmd == EQ_CMD_FLASH_INIT_COMPLETE) {
|
||||
handle_eq_channel_cmd(c_eq_params, cmd, sample_freq);
|
||||
flash_init_done = 1;
|
||||
} else {
|
||||
handle_eq_channel_cmd(c_eq_params, cmd, sample_freq);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clear_ring_buffer(0);
|
||||
clear_ring_buffer(1);
|
||||
clear_ring_buffer(2);
|
||||
clear_ring_buffer(3);
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* ---- 优先检查 channel 上的参数更新 (non-blocking) ---- */
|
||||
select {
|
||||
case c_eq_params :> unsigned cmd:
|
||||
handle_eq_channel_cmd(c_eq_params, cmd, sample_freq);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* ---- 音频处理 ---- */
|
||||
if(is_ring_buffer_empty(0) && is_ring_buffer_empty(1))
|
||||
{
|
||||
// 无数据, 继续轮询
|
||||
}
|
||||
else
|
||||
{
|
||||
GET_SHARED_GLOBAL(sample_freq, g_eq_sample_rate);
|
||||
if (sample_freq == 0) sample_freq = 48000;
|
||||
audio_in_samples[0] = read_from_ring_buffer(0);
|
||||
audio_in_samples[1] = read_from_ring_buffer(1);
|
||||
|
||||
if (is_mode_changed() && b_fade_out == 0 && b_fade_in == 0)
|
||||
{
|
||||
debug_printf("mode changed ====================== \n");
|
||||
b_fade_out=1;
|
||||
u_out_step=1;
|
||||
}
|
||||
|
||||
audio_out_samples[0] = handler_eq_filter(sample_freq, 0, audio_in_samples[0]);
|
||||
audio_out_samples[1] = handler_eq_filter(sample_freq, 1, audio_in_samples[1]);
|
||||
|
||||
if(b_fade_out)
|
||||
{
|
||||
audio_out_samples[0] /= LEN_FADE_;
|
||||
audio_out_samples[0] *= (LEN_FADE_-u_out_step) ;
|
||||
|
||||
audio_out_samples[1] /= LEN_FADE_;
|
||||
audio_out_samples[1] *= (LEN_FADE_-u_out_step) ;
|
||||
|
||||
++u_out_step;
|
||||
}
|
||||
|
||||
if(b_fade_out == 1 && u_out_step == LEN_FADE_){
|
||||
b_fade_out = 0;
|
||||
change_eq_mode(sample_freq);
|
||||
clear_eq_status(sample_freq, 0);
|
||||
clear_eq_status(sample_freq, 1);
|
||||
clear_ring_buffer(0);
|
||||
clear_ring_buffer(1);
|
||||
b_fade_in=1;
|
||||
u_in_step=1;
|
||||
}
|
||||
|
||||
if (b_fade_in)
|
||||
{
|
||||
audio_out_samples[0] /= LEN_FADE_;
|
||||
audio_out_samples[0] *= (u_in_step) ;
|
||||
|
||||
audio_out_samples[1] /= LEN_FADE_;
|
||||
audio_out_samples[1] *= (u_in_step);
|
||||
|
||||
if(++u_in_step >= LEN_FADE_){
|
||||
b_fade_in = 0;
|
||||
}
|
||||
}
|
||||
|
||||
write_to_ring_buffer(2, audio_out_samples[0]);
|
||||
write_to_ring_buffer(3, audio_out_samples[1]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
1330
sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/eq.c.bak
Normal file
1330
sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/eq.c.bak
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,67 @@
|
||||
#ifndef __EQ_CHANNEL_PROTOCOL_H__
|
||||
#define __EQ_CHANNEL_PROTOCOL_H__
|
||||
|
||||
/**
|
||||
* @file eq_channel_protocol.h
|
||||
* @brief EQ 参数跨 tile 通道通信协议
|
||||
*
|
||||
* 当 dsp_core0 运行在 tile[1] 时, process_send_params (tile[0]) 和
|
||||
* AudioHwRemote (tile[0]) 通过 chanend c_eq_params 将 EQ 参数变更
|
||||
* 发送到 tile[1] 的 dsp_core0.
|
||||
*
|
||||
* 通道数据格式: [cmd:32] [payload...]
|
||||
* - 发送端先发 cmd word, 再发各命令对应的 payload words
|
||||
* - 接收端在 dsp_core0 主循环中 non-blocking select 接收
|
||||
*/
|
||||
|
||||
/*--- 命令码定义 ---*/
|
||||
|
||||
/** 切换EQ模式 (对应 HID 0x8A / 0x92)
|
||||
* payload: [mode:32]
|
||||
*/
|
||||
#define EQ_CMD_SET_MODE 0x01
|
||||
|
||||
/** EQ使能开关 (对应 HID 0x9D)
|
||||
* payload: [enable:32] (0=OFF, 1=ON)
|
||||
*/
|
||||
#define EQ_CMD_SET_ENABLE 0x02
|
||||
|
||||
/** 更新单个 band 参数 (对应 HID 0x8D)
|
||||
* payload: [mode:32] [band_index:32] [filter_type:32]
|
||||
* [fc_bits:32] [q_bits:32] [bw_bits:32] [gain_bits:32]
|
||||
* float 值以 memcpy 方式打包到 uint32
|
||||
*/
|
||||
#define EQ_CMD_UPDATE_BAND 0x03
|
||||
|
||||
/** 设置模式增益 (对应 HID 0x8C 的增益部分)
|
||||
* payload: [mode:32] [gain_db:32] (int32_t, 0 ~ -50)
|
||||
*/
|
||||
#define EQ_CMD_SET_GAIN 0x05
|
||||
|
||||
/** 强制刷新系数 (对应 apply_eq_band_params 中的 force_mode_change)
|
||||
* payload: 无
|
||||
*/
|
||||
#define EQ_CMD_FORCE_REFRESH 0x06
|
||||
|
||||
/** Flash 初始化完成, 传输单个 mode 的完整参数
|
||||
* payload: [mode:32] [ch:32] [post_gain_db:32]
|
||||
* 每个 band (共 MAX_EQ_BANDS 个):
|
||||
* [type:32] [fc_bits:32] [q_bits:32] [bw_bits:32] [gain_bits:32] [index:32]
|
||||
* 发送完所有 mode/ch 后发 EQ_CMD_FLASH_INIT_COMPLETE
|
||||
*/
|
||||
#define EQ_CMD_FLASH_LOAD_MODE 0x10
|
||||
|
||||
/** Flash 初始化全部完成, 开始正常运行
|
||||
* payload: [saved_mode:32] [eq_enable:32]
|
||||
*/
|
||||
#define EQ_CMD_FLASH_INIT_COMPLETE 0x11
|
||||
|
||||
/*--- 辅助宏 ---*/
|
||||
|
||||
/** 将 float 打包为 uint32_t 以便通过 channel 传输 */
|
||||
#define FLOAT_TO_U32(f) ({ float _f = (f); uint32_t _u; memcpy(&_u, &_f, 4); _u; })
|
||||
|
||||
/** 将 uint32_t 解包为 float */
|
||||
#define U32_TO_FLOAT(u) ({ uint32_t _u = (u); float _f; memcpy(&_f, &_u, 4); _f; })
|
||||
|
||||
#endif /* __EQ_CHANNEL_PROTOCOL_H__ */
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,255 @@
|
||||
/**
|
||||
* @file htr3236.c
|
||||
* @brief HTR3236 36-Channel LED PWM Driver Implementation for XMOS
|
||||
* @version 1.1
|
||||
*/
|
||||
|
||||
#include "htr3236.h"
|
||||
#include <xccompat.h>
|
||||
|
||||
#include <platform.h>
|
||||
|
||||
out port p_htr3235_sdb = PORT_HTR3236_SDB; /* 连接到HTR3236的SDB引脚,用于控制其电源状态 */
|
||||
|
||||
/*=========================================================================
|
||||
Gamma 校正查找表
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
static const uint8_t gamma_table_32[32] = {
|
||||
0, 1, 2, 4, 6, 10, 13, 18,
|
||||
22, 28, 33, 39, 46, 53, 61, 69,
|
||||
78, 86, 96, 106, 116, 126, 138, 149,
|
||||
161, 173, 186, 199, 212, 226, 240, 255
|
||||
};
|
||||
|
||||
static const uint8_t gamma_table_64[64] = {
|
||||
0, 1, 2, 3, 4, 5, 6, 7,
|
||||
8, 10, 12, 14, 16, 18, 20, 22,
|
||||
24, 26, 29, 32, 35, 38, 41, 44,
|
||||
47, 50, 53, 57, 61, 65, 69, 73,
|
||||
77, 81, 85, 89, 94, 99, 104, 109,
|
||||
114, 119, 124, 129, 134, 140, 146, 152,
|
||||
158, 164, 170, 176, 182, 188, 195, 202,
|
||||
209, 216, 223, 230, 237, 244, 251, 255
|
||||
};
|
||||
|
||||
/*=========================================================================
|
||||
内部函数
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* @brief 写单字节到寄存器
|
||||
*/
|
||||
static int write_reg(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t reg, uint8_t data)
|
||||
{
|
||||
#if 0
|
||||
uint8_t buf[2] = {reg, data};
|
||||
size_t n;
|
||||
|
||||
i2c.write(dev->i2c_addr, buf, 2, n, 1);
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
return I2C_REGOP_DEVICE_NACK;
|
||||
}
|
||||
if (n < 2)
|
||||
{
|
||||
return I2C_REGOP_INCOMPLETE;
|
||||
}
|
||||
|
||||
#endif
|
||||
return I2C_REGOP_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 写多字节到寄存器 (支持自动地址递增)
|
||||
*/
|
||||
static int write_reg_bulk(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t start_reg,
|
||||
const uint8_t *data, uint8_t len)
|
||||
{
|
||||
uint8_t buf[36 + 1];
|
||||
size_t n;
|
||||
#if 0
|
||||
buf[0] = start_reg;
|
||||
|
||||
for (int i = 0; i < len; i++) {
|
||||
buf[i + 1] = data[i];
|
||||
}
|
||||
|
||||
i2c.write(dev->i2c_addr, buf, len + 1, n, 1);
|
||||
|
||||
if (n == 0)
|
||||
{
|
||||
return I2C_REGOP_DEVICE_NACK;
|
||||
}
|
||||
if (n < 2)
|
||||
{
|
||||
return I2C_REGOP_INCOMPLETE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return I2C_REGOP_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 读取寄存器值
|
||||
*/
|
||||
static int read_reg(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t reg, i2c_regop_res_t &result)
|
||||
{
|
||||
uint8_t a_reg[1] = {reg};
|
||||
uint8_t data[1] = {0};
|
||||
size_t n;
|
||||
i2c_res_t res;
|
||||
|
||||
unsafe
|
||||
{
|
||||
res = i2c.write(dev->i2c_addr, a_reg, 1, n, 0);
|
||||
|
||||
if (n != 1)
|
||||
{
|
||||
result = I2C_REGOP_DEVICE_NACK;
|
||||
i2c.send_stop_bit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
res = i2c.read(dev->i2c_addr, data, 1, 1);
|
||||
}
|
||||
|
||||
if (res == I2C_ACK)
|
||||
{
|
||||
result = I2C_REGOP_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = I2C_REGOP_DEVICE_NACK;
|
||||
}
|
||||
return data[0];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*=========================================================================
|
||||
API 函数实现
|
||||
-----------------------------------------------------------------------*/
|
||||
|
||||
void htr3236_init(htr3236_t *dev, uint8_t addr)
|
||||
{
|
||||
dev->i2c_addr = addr;
|
||||
|
||||
// 默认 SDB 拉高,使能芯片
|
||||
//htr3236_hw_enable(dev);
|
||||
}
|
||||
|
||||
void htr3236_hw_enable(htr3236_t *dev)
|
||||
{
|
||||
p_htr3235_sdb <: 1;
|
||||
}
|
||||
|
||||
void htr3236_hw_disable(htr3236_t *dev)
|
||||
{
|
||||
p_htr3235_sdb <: 0;
|
||||
}
|
||||
|
||||
int htr3236_software_wake(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c))
|
||||
{
|
||||
return write_reg(dev, i2c, HTR3236_REG_SHUTDOWN, HTR3236_NORMAL_OP);
|
||||
}
|
||||
|
||||
int htr3236_software_shutdown(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c))
|
||||
{
|
||||
return write_reg(dev, i2c, HTR3236_REG_SHUTDOWN, HTR3236_SHUTDOWN_SOFT);
|
||||
}
|
||||
|
||||
int htr3236_software_reset(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c))
|
||||
{
|
||||
return write_reg(dev, i2c, HTR3236_REG_RESET, 0x00);
|
||||
}
|
||||
|
||||
int htr3236_set_pwm(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t channel, uint8_t brightness)
|
||||
{
|
||||
if (channel < 1 || channel > 36) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t reg = HTR3236_REG_PWM_START + (channel - 1);
|
||||
return write_reg(dev, i2c, reg, brightness);
|
||||
}
|
||||
|
||||
int htr3236_set_pwm_bulk(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t start_ch,
|
||||
const uint8_t *values, uint8_t len)
|
||||
{
|
||||
if (start_ch < 1 || start_ch > 36 || len == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 检查是否会超出寄存器范围
|
||||
if (start_ch + len - 1 > 36) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t start_reg = HTR3236_REG_PWM_START + (start_ch - 1);
|
||||
return write_reg_bulk(dev, i2c, start_reg, values, len);
|
||||
}
|
||||
|
||||
int htr3236_set_led_config(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t channel,
|
||||
htr3236_current_t current, uint8_t enable)
|
||||
{
|
||||
if (channel < 1 || channel > 36) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t reg = HTR3236_REG_LED_CTRL_START + (channel - 1);
|
||||
uint8_t data = (enable ? 1 : 0) | (current << 1);
|
||||
|
||||
return write_reg(dev, i2c, reg, data);
|
||||
}
|
||||
|
||||
int htr3236_set_led_config_bulk(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t start_ch,
|
||||
const uint8_t *configs, uint8_t len)
|
||||
{
|
||||
if (start_ch < 1 || start_ch > 36 || len == 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 检查是否会超出寄存器范围
|
||||
if (start_ch + len - 1 > 36) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t start_reg = HTR3236_REG_LED_CTRL_START + (start_ch - 1);
|
||||
return write_reg_bulk(dev, i2c, start_reg, configs, len);
|
||||
}
|
||||
|
||||
int htr3236_update(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c))
|
||||
{
|
||||
// 写入任意值到更新寄存器使配置生效
|
||||
return write_reg(dev, i2c, HTR3236_REG_PWM_UPDATE, 0x00);
|
||||
}
|
||||
|
||||
int htr3236_global_enable(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), uint8_t enable)
|
||||
{
|
||||
uint8_t data = enable ? 1 : 0;
|
||||
return write_reg(dev, i2c, HTR3236_REG_GLOBAL_CTRL, data);
|
||||
}
|
||||
|
||||
int htr3236_set_frequency(htr3236_t *dev, CLIENT_INTERFACE(i2c_master_if, i2c), htr3236_freq_t freq)
|
||||
{
|
||||
uint8_t data = (freq == HTR3236_FREQ_22KHZ) ? 1 : 0;
|
||||
return write_reg(dev, i2c, HTR3236_REG_FREQ_SET, data);
|
||||
}
|
||||
|
||||
uint8_t htr3236_gamma_32(uint8_t index)
|
||||
{
|
||||
if (index >= 32) {
|
||||
index = 31;
|
||||
}
|
||||
return gamma_table_32[index];
|
||||
}
|
||||
|
||||
uint8_t htr3236_gamma_64(uint8_t index)
|
||||
{
|
||||
if (index >= 64) {
|
||||
index = 63;
|
||||
}
|
||||
return gamma_table_64[index];
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#if UART_DEBUG || DEBUG_MEMORY_LOG_ENABLED
|
||||
#define DEBUG_PRINT_ENABLE 1
|
||||
#define DEBUG_PRINT_ENABLE 0
|
||||
#else
|
||||
#define DEBUG_PRINT_ENABLE 0
|
||||
#endif
|
||||
@@ -0,0 +1,233 @@
|
||||
#include <stdlib.h>
|
||||
#include <xs1.h>
|
||||
#include <platform.h>
|
||||
#include "lfs.h"
|
||||
#include "rtos_qspi_flash.h"
|
||||
#include "swlock.h"
|
||||
#include "debug_print.h"
|
||||
// variables used by the filesystem
|
||||
lfs_t lfs;
|
||||
lfs_file_t file;
|
||||
swlock_t lfs_lock = SWLOCK_INITIAL_VALUE;
|
||||
|
||||
static rtos_qspi_flash_t qspi_flash_ctx_s;
|
||||
#define FLASH_CLKBLK XS1_CLKBLK_3
|
||||
#ifndef FS_BASE_ADDR
|
||||
#define FS_BASE_ADDR 0x1da000
|
||||
#endif
|
||||
#define SECTOR_SIZE 4096
|
||||
rtos_qspi_flash_t *qspi_flash_ctx = &qspi_flash_ctx_s;
|
||||
|
||||
__attribute__((fptrgroup(" local_block_device_read_fptr_grp")))
|
||||
int local_block_device_read(const struct lfs_config *c, lfs_block_t block,
|
||||
lfs_off_t off, void *buffer, lfs_size_t size)
|
||||
{
|
||||
unsigned address = (FS_BASE_ADDR + block * SECTOR_SIZE + off);
|
||||
qspi_flash_ctx->read(qspi_flash_ctx, buffer, address, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((fptrgroup(" local_block_device_prog_fptr_grp")))
|
||||
int local_block_device_prog(const struct lfs_config *c, lfs_block_t block,
|
||||
lfs_off_t off, const void *buffer, lfs_size_t size)
|
||||
{
|
||||
unsigned address = (FS_BASE_ADDR + block * SECTOR_SIZE + off);
|
||||
qspi_flash_ctx->write(qspi_flash_ctx, buffer, address, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((fptrgroup(" local_block_device_erase_fptr_grp")))
|
||||
int local_block_device_erase(const struct lfs_config *c, lfs_block_t block)
|
||||
{
|
||||
unsigned address = (FS_BASE_ADDR + block * SECTOR_SIZE);
|
||||
qspi_flash_ctx->erase(qspi_flash_ctx, address, SECTOR_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
__attribute__((fptrgroup(" local_block_device_sync_fptr_grp")))
|
||||
int local_block_device_sync(const struct lfs_config *c)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
// configuration of the filesystem is provided by this struct
|
||||
const struct lfs_config cfg = {
|
||||
// block device operations
|
||||
.read = local_block_device_read,
|
||||
.prog = local_block_device_prog,
|
||||
.erase = local_block_device_erase,
|
||||
.sync = local_block_device_sync,
|
||||
|
||||
// block device configuration
|
||||
.read_size = 16,
|
||||
.prog_size = 16,
|
||||
.block_size = 4096,
|
||||
.block_count = 128,
|
||||
.cache_size = 16,
|
||||
.lookahead_size = 16,
|
||||
.block_cycles = 500,
|
||||
};
|
||||
|
||||
int lfs_init(void) {
|
||||
swlock_acquire(&lfs_lock);
|
||||
rtos_qspi_flash_init(
|
||||
qspi_flash_ctx,
|
||||
FLASH_CLKBLK,
|
||||
XS1_PORT_1B,
|
||||
XS1_PORT_1C,
|
||||
XS1_PORT_4B,
|
||||
NULL);
|
||||
|
||||
|
||||
// mount the filesystem
|
||||
int err = lfs_mount(&lfs, &cfg);
|
||||
|
||||
// reformat if we can't mount the filesystem
|
||||
// this should only happen on the first boot
|
||||
if (err) {
|
||||
debug_printf("no lfs partiton is found, formating ...\n");
|
||||
lfs_format(&lfs, &cfg);
|
||||
lfs_mount(&lfs, &cfg);
|
||||
swlock_release(&lfs_lock);
|
||||
return -1;
|
||||
}
|
||||
swlock_release(&lfs_lock);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
void lfs_deinit(void) {
|
||||
swlock_acquire(&lfs_lock);
|
||||
lfs_unmount(&lfs);
|
||||
swlock_release(&lfs_lock);
|
||||
}
|
||||
|
||||
#pragma stackfunction 1300
|
||||
void lfs_read_config(unsigned char * config, unsigned char * buffer, unsigned size)
|
||||
{
|
||||
swlock_acquire(&lfs_lock);
|
||||
debug_printf("lfs_read_config: %s, size: %d\n", config, size);
|
||||
int result = lfs_file_open(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT);
|
||||
debug_printf("lfs_read_config: %s, result: %d\n", config, result);
|
||||
if (result != 0) {
|
||||
debug_printf("lfs_read_config: %s, open file failed\n", config);
|
||||
swlock_release(&lfs_lock);
|
||||
return;
|
||||
}
|
||||
debug_printf("lfs_read_config: %s, file opened\n", config);
|
||||
result = lfs_file_read(&lfs, &file, buffer, size);
|
||||
debug_printf("lfs_read_config: %s, result: %d\n", config, result);
|
||||
if (result < 0) {
|
||||
debug_printf("lfs_read_config: %s, read file failed, error: %d\n", config, result);
|
||||
// Update: Added lfs_file_close to ensure file is closed even on error.
|
||||
// Missing this caused subsequent open calls to assert/crash.
|
||||
lfs_file_close(&lfs, &file);
|
||||
swlock_release(&lfs_lock);
|
||||
return;
|
||||
}
|
||||
lfs_file_close(&lfs, &file);
|
||||
swlock_release(&lfs_lock);
|
||||
}
|
||||
|
||||
|
||||
#pragma stackfunction 1300
|
||||
void lfs_write_config(unsigned char * config, unsigned char * buffer, unsigned size)
|
||||
{
|
||||
swlock_acquire(&lfs_lock);
|
||||
debug_printf("lfs_write_config: %s, size: %d\n", config, size);
|
||||
int result = lfs_file_open(&lfs, &file, config, LFS_O_RDWR | LFS_O_CREAT);
|
||||
if (result != 0) {
|
||||
debug_printf("lfs_write_config: open file failed\n");
|
||||
swlock_release(&lfs_lock);
|
||||
return;
|
||||
}
|
||||
result = lfs_file_rewind(&lfs, &file);
|
||||
if (result != 0) {
|
||||
debug_printf("lfs_write_config: rewind file failed\n");
|
||||
// Update: Added lfs_file_close to prevent file remaining open if rewind fails.
|
||||
lfs_file_close(&lfs, &file);
|
||||
swlock_release(&lfs_lock);
|
||||
return;
|
||||
}
|
||||
lfs_file_write(&lfs, &file, buffer, size);
|
||||
lfs_file_close(&lfs, &file);
|
||||
swlock_release(&lfs_lock);
|
||||
}
|
||||
|
||||
|
||||
// 检查文件是否存在
|
||||
int lfs_file_exists(const char * file_path)
|
||||
{
|
||||
swlock_acquire(&lfs_lock);
|
||||
lfs_file_t file;
|
||||
int result = lfs_file_open(&lfs, &file, file_path, LFS_O_RDONLY);
|
||||
if (result == 0) {
|
||||
lfs_file_close(&lfs, &file);
|
||||
swlock_release(&lfs_lock);
|
||||
return 1; // 文件存在
|
||||
}
|
||||
swlock_release(&lfs_lock);
|
||||
return 0; // 文件不存在
|
||||
}
|
||||
|
||||
// EQ参数专用读写函数
|
||||
void lfs_read_eq_config(const char * file_path, unsigned char * buffer, unsigned size)
|
||||
{
|
||||
lfs_file_open(&lfs, &file, file_path, LFS_O_RDONLY);
|
||||
lfs_file_read(&lfs, &file, buffer, size);
|
||||
lfs_file_close(&lfs, &file);
|
||||
}
|
||||
|
||||
void lfs_write_eq_config(const char * file_path, unsigned char * buffer, unsigned size)
|
||||
{
|
||||
lfs_file_open(&lfs, &file, file_path, LFS_O_RDWR | LFS_O_CREAT);
|
||||
lfs_file_rewind(&lfs, &file);
|
||||
lfs_file_write(&lfs, &file, buffer, size);
|
||||
lfs_file_close(&lfs, &file);
|
||||
}
|
||||
|
||||
|
||||
// 删除文件
|
||||
int lfs_remove_file(const char * file_path)
|
||||
{
|
||||
return lfs_remove(&lfs, file_path);
|
||||
}
|
||||
|
||||
// 创建目录(通过创建临时文件然后删除)
|
||||
int lfs_create_directory(const char * dir_path)
|
||||
{
|
||||
char temp_file[256];
|
||||
snprintf(temp_file, sizeof(temp_file), "%s/.dir", dir_path);
|
||||
|
||||
lfs_file_t file;
|
||||
int result = lfs_file_open(&lfs, &file, temp_file, LFS_O_RDWR | LFS_O_CREAT);
|
||||
if (result == 0) {
|
||||
lfs_file_close(&lfs, &file);
|
||||
lfs_remove(&lfs, temp_file);
|
||||
return 0; // 成功
|
||||
}
|
||||
return -1; // 失败
|
||||
}
|
||||
|
||||
#if 0
|
||||
// read current count
|
||||
uint32_t boot_count = 0;
|
||||
lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT);
|
||||
lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count));
|
||||
|
||||
// update boot count
|
||||
boot_count += 1;
|
||||
lfs_file_rewind(&lfs, &file);
|
||||
for (int i = 0; i < 100; i++)
|
||||
lfs_file_write(&lfs, &file, &boot_count, sizeof(boot_count));
|
||||
|
||||
// remember the storage is not updated until the file is closed successfully
|
||||
lfs_file_close(&lfs, &file);
|
||||
|
||||
// release any resources we were using
|
||||
lfs_unmount(&lfs);
|
||||
|
||||
// print the boot count
|
||||
printf("boot_count: %d\n", boot_count);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1 @@
|
||||
ninja: Entering directory `build'
|
||||
836
sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/main.xc.bak
Normal file
836
sw_usb_audio/app_usb_aud_fosi_c1_v71/src/extensions/main.xc.bak
Normal file
@@ -0,0 +1,836 @@
|
||||
// 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
|
||||
@@ -0,0 +1,844 @@
|
||||
// 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
|
||||
@@ -0,0 +1,846 @@
|
||||
// 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
|
||||
@@ -0,0 +1,128 @@
|
||||
// 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]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,207 @@
|
||||
// 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]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,200 @@
|
||||
// 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]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,208 @@
|
||||
// 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]);
|
||||
}
|
||||
}
|
||||
3
sw_usb_audio/app_usb_aud_fosi_c1_v71/xscope.xscope
Normal file
3
sw_usb_audio/app_usb_aud_fosi_c1_v71/xscope.xscope
Normal file
@@ -0,0 +1,3 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<xSCOPEconfig enabled="false" initTracing="true" ioMode="none">
|
||||
</xSCOPEconfig>
|
||||
@@ -1,283 +0,0 @@
|
||||
cmake_minimum_required(VERSION 3.21)
|
||||
include($ENV{XMOS_CMAKE_PATH}/xcommon.cmake)
|
||||
project(app_usb_aud_sy102)
|
||||
|
||||
set(APP_HW_TARGET synido.xn)
|
||||
include(${CMAKE_CURRENT_LIST_DIR}/../deps.cmake)
|
||||
set(APP_PCA_ENABLE ON)
|
||||
|
||||
###=========================================================================###
|
||||
set(TARGET_HW_PHATEN_GSV2 ON)
|
||||
set(CODEC_IS_AIC3204 ON)
|
||||
|
||||
# Configure host os detection here... (Windows or Non-Windows)
|
||||
#-----------------------------------------------------------------------------#
|
||||
# Host OS detection, set HOST_OS_DETECTION to ON
|
||||
|
||||
set(HOST_OS_DETECTION ON)
|
||||
###=========================================================================###
|
||||
# Customer
|
||||
if (TARGET_HW_PHATEN_GSV2)
|
||||
message("-- Building for PHATEN_GSv2 ---")
|
||||
set(TARGET_BOARD PHATEN_GSV2)
|
||||
set(APP_HW_TARGET synido.xn)
|
||||
endif()
|
||||
|
||||
# CODEC IC
|
||||
if (CODEC_IS_AIC3204)
|
||||
message("-- DAC: AIC3204 ---")
|
||||
set(CODEC_IC CODEC_AIC3204)
|
||||
endif()
|
||||
|
||||
# Host OS detection
|
||||
if (HOST_OS_DETECTION)
|
||||
message("-- Host OS detection (Windows/Non-Windows) enabled ---")
|
||||
set(EXTRA_BUILD_FLAGS ${EXTRA_BUILD_FLAGS} -DHOST_OS_DETECTION)
|
||||
endif()
|
||||
|
||||
# Firmware version (maps to BCD_DEVICE_J.M.N in USB descriptor)
|
||||
set(FW_VER_J 1)
|
||||
set(FW_VER_M 1)
|
||||
set(FW_VER_N 15)
|
||||
set(FW_VERSION "v${FW_VER_J}.${FW_VER_M}.${FW_VER_N}")
|
||||
|
||||
set(SW_USB_AUDIO_FLAGS ${EXTRA_BUILD_FLAGS} -Os
|
||||
-report
|
||||
-L${CMAKE_CURRENT_LIST_DIR}/../../lib_ex3d/lib_ex3d/lib
|
||||
-lquadflash
|
||||
-g
|
||||
#-fxscope
|
||||
-DUSB_TILE=tile[0]
|
||||
-DXUA_QUAD_SPI_FLASH=1
|
||||
-D${TARGET_BOARD}
|
||||
-DBCD_DEVICE_J=${FW_VER_J}
|
||||
-DBCD_DEVICE_M=${FW_VER_M}
|
||||
-DBCD_DEVICE_N=${FW_VER_N}
|
||||
-D${CODEC_IC}
|
||||
-DWINDOWS_OS_DESCRIPTOR_SUPPORT)
|
||||
|
||||
set(SW_USB_FACT_FLAGS ${EXTRA_BUILD_FLAGS} -Os
|
||||
-report
|
||||
-L${CMAKE_CURRENT_LIST_DIR}/../../lib_ex3d/lib_ex3d/lib
|
||||
-lquadflash
|
||||
-g
|
||||
#-fxscope
|
||||
-DUSB_TILE=tile[0]
|
||||
-DXUA_QUAD_SPI_FLASH=1
|
||||
-D${TARGET_BOARD}
|
||||
-DBCD_DEVICE_J=5
|
||||
-DBCD_DEVICE_M=5
|
||||
-DBCD_DEVICE_N=7
|
||||
-D${CODEC_IC}
|
||||
-DWINDOWS_OS_DESCRIPTOR_SUPPORT)
|
||||
|
||||
|
||||
|
||||
LINK_DIRECTORIES(${CMAKE_CURRENT_LIST_DIR}/../../lib_dnr/lib_dnr)
|
||||
|
||||
set(APP_COMPILER_FLAGS_f5_music_uac1 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2
|
||||
-DI2S_CHANS_ADC=2
|
||||
-DAUDIO_CLASS=1
|
||||
-DMIN_FREQ=48000
|
||||
-DMAX_FREQ=48000
|
||||
-DMCLK_441=512*44100
|
||||
-DMCLK_48=512*48000
|
||||
-DUAC1_MODE=1
|
||||
-DF5_MUSIC_UAC1=1
|
||||
#-DUSE_EX3D
|
||||
-DMIXER=0
|
||||
#-ldnr_11ms
|
||||
#-DDNR_ENABLE=1
|
||||
#-llib_ex3d_all
|
||||
-DEQ_EN=1
|
||||
-DEX3D_SF_NUM=3
|
||||
-DNUM_USB_CHAN_OUT=8
|
||||
-DNUM_USB_CHAN_OUT_FS=2
|
||||
-DNUM_USB_CHAN_IN=2
|
||||
-DSTREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS=16
|
||||
-DSTREAM_FORMAT_INPUT_1_RESOLUTION_BITS=16
|
||||
-DINPUT_FORMAT_COUNT=1
|
||||
-DOUTPUT_FORMAT_COUNT=1
|
||||
#-DNUM_EX3D_CHAN_OUT=2
|
||||
-DMIN_VOLUME=0xE000
|
||||
-DINPUT_VOLUME_CONTROL=0
|
||||
-DOUTPUT_VOLUME_CONTROL=0
|
||||
#-DDEBUG_MEMORY_LOG_ENABLED=1
|
||||
-DXUA_DFU_EN=0
|
||||
-DHID_DFU_EN=1
|
||||
-DHID_CONTROLS_UAC1=1
|
||||
#-DIR_SWITCHING_MODE
|
||||
-DHID_CONTROLS=1)
|
||||
|
||||
|
||||
|
||||
set(APP_COMPILER_FLAGS_fact ${SW_USB_FACT_FLAGS} -DI2S_CHANS_DAC=2
|
||||
-DI2S_CHANS_ADC=0
|
||||
-DMIN_FREQ=48000
|
||||
-DMAX_FREQ=48000
|
||||
-DFACT=1
|
||||
#-DUSE_EX3D
|
||||
-DMIXER=0
|
||||
-DUAC2_MODE=1
|
||||
#-ldnr_50ms
|
||||
#-llib_ex3d_all
|
||||
#-DEQ_EN=1
|
||||
#-DEX3D_SF_NUM=3
|
||||
-DNUM_USB_CHAN_OUT=2
|
||||
-DNUM_USB_CHAN_IN=0
|
||||
#-DNUM_EX3D_CHAN_OUT=2
|
||||
-DMIN_VOLUME=0xE000
|
||||
-DINPUT_VOLUME_CONTROL=0
|
||||
-DOUTPUT_VOLUME_CONTROL=0
|
||||
-DDEBUG_MEMORY_LOG_ENABLED=1
|
||||
-DHID_DFU_EN=1
|
||||
-DXUA_DFU_EN=1
|
||||
#-DIR_SWITCHING_MODE
|
||||
-DHID_CONTROLS=1)
|
||||
|
||||
|
||||
|
||||
set(APP_COMPILER_FLAGS_f1_music_uac2 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2
|
||||
-DI2S_CHANS_ADC=2
|
||||
-DMIN_FREQ=44100
|
||||
-DMAX_FREQ=192000
|
||||
-DF1_MUSIC_UAC2=1
|
||||
-DSTREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS=24
|
||||
-DSTREAM_FORMAT_OUTPUT_2_RESOLUTION_BITS=24
|
||||
-DSTREAM_FORMAT_INPUT_1_RESOLUTION_BITS=24
|
||||
-DSTREAM_FORMAT_INPUT_2_RESOLUTION_BITS=24
|
||||
-DINPUT_FORMAT_COUNT=1
|
||||
-DOUTPUT_FORMAT_COUNT=1
|
||||
#-DUSE_EX3D
|
||||
-DMIXER=0
|
||||
-DUAC2_MODE=1
|
||||
#-ldnr_50ms
|
||||
#-llib_ex3d_all
|
||||
-DEQ_EN=1
|
||||
#-DEX3D_SF_NUM=3
|
||||
-DNUM_USB_CHAN_OUT=2
|
||||
-DNUM_USB_CHAN_IN=2
|
||||
#-DNUM_EX3D_CHAN_OUT=2
|
||||
-DMIN_VOLUME=0xE000
|
||||
-DINPUT_VOLUME_CONTROL=1
|
||||
-DOUTPUT_VOLUME_CONTROL=1
|
||||
#-DDEBUG_MEMORY_LOG_ENABLED=1
|
||||
-DXUA_DFU_EN=1
|
||||
-DHID_DFU_EN=1
|
||||
#-DIR_SWITCHING_MODE
|
||||
-DHID_CONTROLS=1)
|
||||
|
||||
|
||||
set(APP_COMPILER_FLAGS_f3_f4_fps_uac2 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2
|
||||
-DI2S_CHANS_ADC=2
|
||||
-DMIN_FREQ=48000
|
||||
-DMAX_FREQ=48000
|
||||
-DUSE_EX3D=1
|
||||
-DF3_F4_FPS_UAC2=1
|
||||
-DMIXER=0
|
||||
-DUAC2_MODE=1
|
||||
-ldnr_50ms
|
||||
-llib_ex3d_all
|
||||
-DEQ_EN=1
|
||||
-DDNR_ENABLE=1
|
||||
-DSTREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS=16
|
||||
-DSTREAM_FORMAT_INPUT_1_RESOLUTION_BITS=16
|
||||
-DINPUT_FORMAT_COUNT=1
|
||||
-DOUTPUT_FORMAT_COUNT=1
|
||||
-DEX3D_SF_NUM=3
|
||||
-DNUM_USB_CHAN_OUT=8
|
||||
-DNUM_USB_CHAN_IN=2
|
||||
-DNUM_EX3D_CHAN_OUT=2
|
||||
-DMIN_VOLUME=0xE000
|
||||
-DINPUT_VOLUME_CONTROL=1
|
||||
-DOUTPUT_VOLUME_CONTROL=1
|
||||
#-DDEBUG_MEMORY_LOG_ENABLED=1
|
||||
-DXUA_DFU_EN=1
|
||||
-DHID_DFU_EN=1
|
||||
-DIR_SWITCHING_MODE
|
||||
-DHID_CONTROLS=1)
|
||||
|
||||
set(APP_COMPILER_FLAGS_f6_f7_fps_uac1 ${SW_USB_AUDIO_FLAGS} -DI2S_CHANS_DAC=2
|
||||
-DI2S_CHANS_ADC=2
|
||||
-DAUDIO_CLASS=1
|
||||
-DMIN_FREQ=48000
|
||||
-DMAX_FREQ=48000
|
||||
-DMCLK_441=512*44100
|
||||
-DMCLK_48=512*48000
|
||||
-DSTREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS=16
|
||||
-DSTREAM_FORMAT_INPUT_1_RESOLUTION_BITS=16
|
||||
-DINPUT_FORMAT_COUNT=1
|
||||
-DOUTPUT_FORMAT_COUNT=1
|
||||
-DUAC1_MODE=1
|
||||
-DUSE_EX3D=1
|
||||
-DF6_F7_FPS_UAC1=1
|
||||
-DMIXER=0
|
||||
-ldnr_50ms
|
||||
-DDNR_ENABLE=1
|
||||
-llib_ex3d_all
|
||||
-DEQ_EN=1
|
||||
-DEX3D_SF_NUM=3
|
||||
-DNUM_USB_CHAN_OUT=8
|
||||
-DNUM_USB_CHAN_IN=2
|
||||
-DNUM_EX3D_CHAN_OUT=2
|
||||
-DMIN_VOLUME=0xE000
|
||||
-DINPUT_VOLUME_CONTROL=1
|
||||
-DOUTPUT_VOLUME_CONTROL=1
|
||||
#-DDEBUG_MEMORY_LOG_ENABLED=1
|
||||
-DXUA_DFU_EN=1
|
||||
-DHID_DFU_EN=1
|
||||
-DHID_CONTROLS_UAC1=1
|
||||
-DIR_SWITCHING_MODE
|
||||
-DHID_CONTROLS=1)
|
||||
|
||||
set(APP_INCLUDES src src/core src/extensions ../../lib_dnr/lib_dnr)
|
||||
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)
|
||||
###=========================================================================###
|
||||
|
||||
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(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 xflash ${XE_FACT} --loader ${LOADER_OBJ}
|
||||
--upgrade 2 ${XE_F5}
|
||||
--upgrade 3 ${XE_F1}
|
||||
--upgrade 1 ${XE_F3F4}
|
||||
--upgrade 4 ${XE_F6F7}
|
||||
-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
|
||||
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 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}
|
||||
-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
|
||||
COMMENT "Generating update image: update_${APP_BASE}_${FW_VERSION}.bin"
|
||||
VERBATIM
|
||||
)
|
||||
@@ -1,3 +0,0 @@
|
||||
xflash bin/fact/app_usb_aud_sy102_fact.xe --loader loader.o --upgrade 2 bin/f5_music_uac1/app_usb_aud_sy102_f5_music_uac1.xe --upgrade 3 bin/f1_music_uac2/app_usb_aud_sy102_f1_music_uac2.xe --upgrade 1 bin/f3_f4_fps_uac2/app_usb_aud_sy102_f3_f4_fps_uac2.xe --upgrade 4 bin/f6_f7_fps_uac1/app_usb_aud_sy102_f6_f7_fps_uac1.xe -o %1
|
||||
|
||||
rem --upgrade 4 bin/f6_f7_fps_uac1/app_usb_aud_sy102_f6_f7_fps_uac1.xe
|
||||
@@ -1 +0,0 @@
|
||||
xflash --factory-version 15.3 --target-file src/core/synido.xn --upgrade 2 bin/f5_music_uac1/app_usb_aud_sy102_f5_music_uac1.xe --upgrade 3 bin/f1_music_uac2/app_usb_aud_sy102_f1_music_uac2.xe --upgrade 1 bin/f3_f4_fps_uac2/app_usb_aud_sy102_f3_f4_fps_uac2.xe --upgrade 4 bin/f6_f7_fps_uac1/app_usb_aud_sy102_f6_f7_fps_uac1.xe -o %1
|
||||
Binary file not shown.
Binary file not shown.
@@ -1,89 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Network xmlns="http://www.xmos.com"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.xmos.com http://www.xmos.com">
|
||||
<Type>Board</Type>
|
||||
<Name>xcore.ai MC Audio Board</Name>
|
||||
|
||||
<Declarations>
|
||||
<Declaration>tileref tile[2]</Declaration>
|
||||
</Declarations>
|
||||
|
||||
<Packages>
|
||||
<Package id="0" Type="XS3-UnA-1024-TQ128">
|
||||
<Nodes>
|
||||
<Node Id="0" InPackageId="0" Type="XS3-L16A-1024" Oscillator="24MHz" SystemFrequency="600MHz" ReferenceFrequency="100MHz">
|
||||
<Boot>
|
||||
<Source Location="bootFlash"/>
|
||||
</Boot>
|
||||
<Tile Number="0" Reference="tile[0]">
|
||||
<Port Location="XS1_PORT_1B" Name="PORT_SQI_CS"/>
|
||||
<Port Location="XS1_PORT_1C" Name="PORT_SQI_SCLK"/>
|
||||
<Port Location="XS1_PORT_4B" Name="PORT_SQI_SIO"/>
|
||||
|
||||
<!-- I2C -->
|
||||
<Port Location="XS1_PORT_1P" Name="PORT_I2C_SCL"/> <!-- orig 1L, Synido 1P -->
|
||||
<Port Location="XS1_PORT_1O" Name="PORT_I2C_SDA"/> <!-- orig 1M, Synido 1O -->
|
||||
|
||||
<!-- HRT3236 -->
|
||||
<Port Location="XS1_PORT_1N" Name="PORT_HTR3236_SDB"/>
|
||||
|
||||
<!-- Mic Encoder -->
|
||||
<Port Location="XS1_PORT_4F" Name="PORT_MIC_GAIN_ENCODER1"/> <!-- 4F1: FOOTSTEPS ENHANCEMENT; 4F2: MIC_GAIN_ENCODER_INPUT_1; 4F3: MIC MUTE -->
|
||||
<Port Location="XS1_PORT_4E" Name="PORT_MIC_GAIN_ENCODER2"/> <!-- 4E2: MIC_GAIN_ENCODER_INPUT_2; 4E3: AI DENOISE ONOFF -->
|
||||
<!-- HP Encoder -->
|
||||
<Port Location="XS1_PORT_8D" Name="PORT_HP_GAIN_ENCODER"/> <!-- 8D4: HP_GAIN_ENCODER_INPUT_1; 8D5: HP_GAIN_ENCODER_INPUT_2; 8D6: HP MUTE -->
|
||||
<!-- Buttons -->
|
||||
<Port Location="XS1_PORT_1A" Name="PORT_BUTTON_MUSIC_MODE"/>
|
||||
<Port Location="XS1_PORT_1M" Name="PORT_BUTTON_GAME_MODE"/>
|
||||
<Port Location="XS1_PORT_1L" Name="PORT_BUTTON_AI71_ONOFF"/>
|
||||
|
||||
<!-- Clocking -->
|
||||
<Port Location="XS1_PORT_16B" Name="PORT_MCLK_COUNT"/>
|
||||
<Port Location="XS1_PORT_1D" Name="PORT_MCLK_IN_USB"/>
|
||||
|
||||
</Tile>
|
||||
<Tile Number="1" Reference="tile[1]">
|
||||
<!-- Audio Ports: I2S -->
|
||||
<Port Location="XS1_PORT_1D" Name="PORT_MCLK_IN"/>
|
||||
<Port Location="XS1_PORT_16B" Name="PORT_MCLK_COUNT_2"/>
|
||||
<Port Location="XS1_PORT_1B" Name="PORT_I2S_LRCLK"/>
|
||||
<Port Location="XS1_PORT_1C" Name="PORT_I2S_BCLK"/>
|
||||
<Port Location="XS1_PORT_1K" Name="PORT_I2S_DAC0"/> <!-- orig 1P, Synido 1K -->
|
||||
<Port Location="XS1_PORT_1A" Name="PORT_I2S_ADC0"/> <!-- orig 1I, Synido 1A -->
|
||||
|
||||
<Port Location="XS1_PORT_4A" Name="PORT_CTL_MUTE"/> <!-- Tile1 4D0 -->
|
||||
<Port Location="XS1_PORT_4D" Name="PORT_CTL_DET"/> <!-- Tile1 4D0 -->
|
||||
|
||||
</Tile>
|
||||
</Node>
|
||||
</Nodes>
|
||||
</Package>
|
||||
</Packages>
|
||||
<!--
|
||||
<Nodes>
|
||||
<Node Id="2" Type="device:" RoutingId="0x8000">
|
||||
<Service Id="0" Proto="xscope_host_data(chanend c);">
|
||||
<Chanend Identifier="c" end="3"/>
|
||||
</Service>
|
||||
</Node>
|
||||
</Nodes>
|
||||
<Links>
|
||||
<Link Encoding="2wire" Delays="5clk" Flags="XSCOPE">
|
||||
<LinkEndpoint NodeId="0" Link="XL0"/>
|
||||
<LinkEndpoint NodeId="2" Chanend="1"/>
|
||||
</Link>
|
||||
</Links>
|
||||
-->
|
||||
<ExternalDevices>
|
||||
<Device NodeId="0" Tile="0" Class="SQIFlash" Name="bootFlash" PageSize="256" SectorSize="4096" NumPages="16384">
|
||||
<Attribute Name="PORT_SQI_CS" Value="PORT_SQI_CS"/>
|
||||
<Attribute Name="PORT_SQI_SCLK" Value="PORT_SQI_SCLK"/>
|
||||
<Attribute Name="PORT_SQI_SIO" Value="PORT_SQI_SIO"/>
|
||||
</Device>
|
||||
</ExternalDevices>
|
||||
<JTAGChain>
|
||||
<JTAGDevice NodeId="0"/>
|
||||
</JTAGChain>
|
||||
|
||||
</Network>
|
||||
Reference in New Issue
Block a user