diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 5c8ce1b7..0dcbab5f 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -13,6 +13,9 @@ UNRELEASED * FIXED: ADAT Tx called too frequently * CHANGED: ADAT Tx presents different channel count interfaces based on sample rate + * CHANGED: aud_to_host buffer size and the condition to come out of underflow + in decoupler to fix buffer underflow seen in ADAT tests + * FIXED: Initialise SMUX based on DEFAULT_FREQ in clockgen 4.0.0 ----- diff --git a/lib_xua/api/xua_conf_default.h b/lib_xua/api/xua_conf_default.h index 76da2106..f7e6b5aa 100644 --- a/lib_xua/api/xua_conf_default.h +++ b/lib_xua/api/xua_conf_default.h @@ -1318,7 +1318,7 @@ #endif #if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) - #if (XUA_SPDIF_RX_EN|| ADAT_RX) + #if (XUA_SPDIF_RX_EN|| XUA_ADAT_RX_EN) #error "Digital input streams not supported in Sync mode" #endif #endif diff --git a/lib_xua/src/core/buffer/decouple/decouple.xc b/lib_xua/src/core/buffer/decouple/decouple.xc index cadebd21..b5405fa2 100644 --- a/lib_xua/src/core/buffer/decouple/decouple.xc +++ b/lib_xua/src/core/buffer/decouple/decouple.xc @@ -1,4 +1,4 @@ -// Copyright 2011-2023 XMOS LIMITED. +// Copyright 2011-2024 XMOS LIMITED. // This Software is subject to the terms of the XMOS Public Licence: Version 1. #include "xua.h" @@ -42,8 +42,13 @@ #define MAX_DEVICE_AUD_PACKET_SIZE_OUT (MAX(MAX_DEVICE_AUD_PACKET_SIZE_OUT_FS, MAX_DEVICE_AUD_PACKET_SIZE_OUT_HS)) /*** BUFFER SIZES ***/ - -#define BUFFER_PACKET_COUNT (4) /* How many packets too allow for in buffer - minimum is 4 */ +/* How many packets too allow for in buffer - minimum is 5. +2 for having in the aud_to_host buffer when it comes out of underflow, space available for 2 more for to accomodate cases when +2 pkts from audio hub get written into the aud_to_host buffer within 1 SOF period, and space for 1 extra packet to ensure that +when the 4th packet gets written to the buffer, there's space to accomodate the next packet, otherwise handle_audio_request() will +drop packets after writing the 4th packet in the buffer +*/ +#define BUFFER_PACKET_COUNT (5) #define BUFF_SIZE_OUT_HS MAX_DEVICE_AUD_PACKET_SIZE_OUT_HS * BUFFER_PACKET_COUNT #define BUFF_SIZE_OUT_FS MAX_DEVICE_AUD_PACKET_SIZE_OUT_FS * BUFFER_PACKET_COUNT @@ -1054,7 +1059,21 @@ void XUA_Buffer_Decouple(chanend c_mix_out assert(fillLevel <= BUFF_SIZE_IN); /* Check if we have come out of underflow */ - if (fillLevel >= IN_BUFFER_PREFILL) + unsigned sampFreq; + GET_SHARED_GLOBAL(sampFreq, g_freqChange_sampFreq); + int min, mid, max; + GetADCCounts(sampFreq, min, mid, max); + const int min_pkt_size = ((min * g_curSubSlot_In * g_numUsbChan_In + 3) & ~0x3) + 4; + + /* + Come out of underflow if there are exactly 2 packets in the buffer. + This ensures that handle_audio_request() does not drop packets when writing packets into the aud_to_host buffer + when aud_to_host buffer is not in underflow. + For example, coming out of underflow with 3 packets in the buffer would mean handle_audio_request() + drops packets if 2 pkts are received from audio hub in 1 SOF period. Coming out of underflow with 4 + packets would mean handle_audio_request would drop packets after writing 1 packet to the aud_to_host buffer. + */ + if ((fillLevel >= (min_pkt_size*2)) && (fillLevel < (min_pkt_size*3))) { int aud_to_host_rdptr; GET_SHARED_GLOBAL(aud_to_host_rdptr, g_aud_to_host_rdptr); diff --git a/lib_xua/src/core/clocking/clockgen.xc b/lib_xua/src/core/clocking/clockgen.xc index c75f56e4..ac172b8f 100644 --- a/lib_xua/src/core/clocking/clockgen.xc +++ b/lib_xua/src/core/clocking/clockgen.xc @@ -235,7 +235,23 @@ void clockGen ( streaming chanend ?c_spdif_rx, unsigned tmp; /* Start in no-SMUX (8-channel) mode */ - int smux = 0; + int smux; + // Initialise smux based based on the DEFAULT_FREQ + if(DEFAULT_FREQ < 88200) + { + /* No SMUX */ + smux = 0; + } + else if(DEFAULT_FREQ < 176400) + { + /* SMUX */ + smux = 1; + } + else + { + /* SMUX II */ + smux = 2; + } #ifdef LEVEL_METER_LEDS timer t_level; diff --git a/tests/test_i2s_loopback/xk_216_mc/audiohw.xc b/tests/test_i2s_loopback/xk_216_mc/audiohw.xc index ed1d5f7e..f98604ac 100644 --- a/tests/test_i2s_loopback/xk_216_mc/audiohw.xc +++ b/tests/test_i2s_loopback/xk_216_mc/audiohw.xc @@ -1,4 +1,4 @@ -// Copyright 2016-2022 XMOS LIMITED. +// Copyright 2016-2024 XMOS LIMITED. // This Software is subject to the terms of the XMOS Public Licence: Version 1. #ifdef HARDWARE @@ -19,7 +19,7 @@ /* CS2100 lists typical lock time as 100 * input period */ #define AUDIO_PLL_LOCK_DELAY (40000000) -#if defined(SPDIF_RX) || defined(ADAT_RX) +#if defined(XUA_SPDIF_RX_EN) || defined(XUA_ADAT_RX_EN) #define USE_FRACTIONAL_N 1 #endif @@ -32,7 +32,7 @@ port p_i2c = on tile[0]:PORT_I2C; #ifdef USE_FRACTIONAL_N -#if !(defined(SPDIF_RX) || defined(ADAT_RX)) +#if !(defined(XUA_SPDIF_RX_EN) || defined(XUA_ADAT_RX_EN)) /* Choose a frequency the xcore can easily generate internally */ #define PLL_SYNC_FREQ 1000000 #else @@ -95,7 +95,7 @@ void PllMult(unsigned output, unsigned ref, client interface i2c_master_if i2c) } #endif -#if !(defined(SPDIF_RX) || defined(ADAT_RX)) && defined(USE_FRACTIONAL_N) +#if !(defined(XUA_SPDIF_RX_EN) || defined(XUA_ADAT_RX_EN)) && defined(USE_FRACTIONAL_N) on tile[AUDIO_IO_TILE] : out port p_pll_clk = PORT_PLL_REF; on tile[AUDIO_IO_TILE] : clock clk_pll_sync = XS1_CLKBLK_5; #endif @@ -111,7 +111,7 @@ void wait_us(int microseconds) void AudioHwInit(chanend ?c_codec) { -#if !(defined(SPDIF_RX) || defined(ADAT_RX)) && defined(USE_FRACTIONAL_N) +#if !(defined(XUA_SPDIF_RX_EN) || defined(XUA_ADAT_RX_EN)) && defined(USE_FRACTIONAL_N) /* Output a fixed sync clock to the pll */ configure_clock_rate(clk_pll_sync, 100, 100/(PLL_SYNC_FREQ/1000000)); configure_port_clock_output(p_pll_clk, clk_pll_sync);