From e93901f0ccbc59a46d6c8d6dc74ca188ca9187f7 Mon Sep 17 00:00:00 2001 From: Ed Clarke Date: Fri, 9 Nov 2018 17:32:32 +0000 Subject: [PATCH] Update FIFO to use true shorts + add/use fast block fifo API --- examples/xua_lite_example/src/app_xua_lite.xc | 4 +- examples/xua_lite_example/src/audio_hub.xc | 2 + examples/xua_lite_example/src/fifo_impl.h | 105 +++++++++++++++- examples/xua_lite_example/src/fifo_types.h | 7 ++ .../xua_lite_example/src/xua_buffer_lite.h | 2 - .../xua_lite_example/src/xua_buffer_lite.xc | 117 +++++++++++------- 6 files changed, 182 insertions(+), 55 deletions(-) diff --git a/examples/xua_lite_example/src/app_xua_lite.xc b/examples/xua_lite_example/src/app_xua_lite.xc index 0976810d..a53982ca 100644 --- a/examples/xua_lite_example/src/app_xua_lite.xc +++ b/examples/xua_lite_example/src/app_xua_lite.xc @@ -137,13 +137,15 @@ int main() // c_ep_in[XUA_ENDPOINT_COUNT_IN - 1], // c_sof, p_for_mclk_count, c_audio); + //[[combine]] + par{ XUA_Buffer_lite2(i_ep0_ctl, c_ep_out[1], null, //c_ep_in[XUA_ENDPOINT_COUNT_IN - 2],/*feedback*/ c_ep_in[XUA_ENDPOINT_COUNT_IN - 1], c_sof, p_for_mclk_count, c_audio); XUA_Endpoint0_select(c_ep_out[0], c_ep_in[0], i_ep0_ctl, null VENDOR_REQUESTS_PARAMS_DEC_); - + } par (int i = 0; i < 3; i++) burn_normal_priority(); par (int i = 0; i < 2; i++) burn_high_priority(); } diff --git a/examples/xua_lite_example/src/audio_hub.xc b/examples/xua_lite_example/src/audio_hub.xc index 8318f254..f83f3e2c 100644 --- a/examples/xua_lite_example/src/audio_hub.xc +++ b/examples/xua_lite_example/src/audio_hub.xc @@ -57,6 +57,8 @@ void AudioHub(server i2s_frame_callback_if i2s, case i2s.restart_check() -> i2s_restart_t restart: restart = I2S_NO_RESTART; // Keep on looping timer tmr; int t0, t1; tmr :> t0; + + //Transfer samples for (int i = 0; i < NUM_USB_CHAN_OUT; i++) c_audio :> samples_out[i]; if (XUA_ADAPTIVE) c_audio :> clock_nudge; for (int i = 0; i < NUM_USB_CHAN_IN; i++) c_audio <: raw_mics[i]; diff --git a/examples/xua_lite_example/src/fifo_impl.h b/examples/xua_lite_example/src/fifo_impl.h index 181d4f18..3341f32a 100644 --- a/examples/xua_lite_example/src/fifo_impl.h +++ b/examples/xua_lite_example/src/fifo_impl.h @@ -25,6 +25,19 @@ static inline unsigned fifo_get_fill(volatile mem_fifo_t * unsafe fifo) { } } +static inline unsigned fifo_get_fill_short(volatile mem_fifo_short_t * unsafe fifo) { + unsafe{ + unsigned fifo_fill = 0; + if (fifo->write_idx >= fifo->read_idx){ + fifo_fill = fifo->write_idx - fifo->read_idx; + } + else{ + fifo_fill = (fifo->size + fifo->write_idx) - fifo->read_idx; + } + return fifo_fill; + } +} + #pragma unsafe arrays static inline fifo_ret_t fifo_block_push(volatile mem_fifo_t * unsafe fifo, int data[], unsigned n) { unsafe{ @@ -44,23 +57,58 @@ static inline fifo_ret_t fifo_block_push(volatile mem_fifo_t * unsafe fifo, int } #pragma unsafe arrays -static inline fifo_ret_t fifo_block_push_short_pairs(volatile mem_fifo_t * unsafe fifo, short data[], unsigned n) { +static inline fifo_ret_t fifo_block_push_short(volatile mem_fifo_short_t * unsafe fifo, short data[], unsigned n) { unsafe{ //check there is a block of space large enough - unsigned space_remaining = fifo->size - fifo_get_fill(fifo) - 1; + unsigned space_remaining = fifo->size - fifo_get_fill_short(fifo) - 1; if (n > space_remaining) { return FIFO_FULL; } for (int i = 0; i < n; i++){ unsigned next_idx = fifo->write_idx + 1; if (next_idx == fifo->size) next_idx = 0; //Check for wrap - fifo->data_base_ptr[fifo->write_idx] = data[i] << 16; + fifo->data_base_ptr[fifo->write_idx] = data[i]; fifo->write_idx = next_idx; } return FIFO_SUCCESS; } } +#pragma unsafe arrays +static inline fifo_ret_t fifo_block_push_short_fast(volatile mem_fifo_short_t * unsafe fifo, short data[], unsigned n) { + unsafe{ + //check there is a block of space large enough + unsigned space_remaining = fifo->size - fifo_get_fill_short(fifo) - 1; + if (n > space_remaining) { + return FIFO_FULL; + } + //We will write either one or two blocks depending on wrap + unsigned first_block_size = 0; + unsigned second_block_size = 0; + + //See if we need to wrap during block writes + unsigned space_left_at_top = fifo->size - fifo->write_idx; + //printf("space_left_at_top %d\n", space_left_at_top); + //Yes, we do need to wrap + if (n > space_left_at_top){ + first_block_size = space_left_at_top; + second_block_size = n - space_left_at_top; + memcpy(&fifo->data_base_ptr[fifo->write_idx], &data[0], first_block_size * sizeof(short)); + memcpy(&fifo->data_base_ptr[0], &data[first_block_size], second_block_size * sizeof(short)); + fifo->write_idx = second_block_size; + } + //No wrap, do all in one go + else{ + first_block_size = n; + second_block_size = 0; + memcpy(&fifo->data_base_ptr[fifo->write_idx], &data[0], first_block_size * sizeof(short)); + fifo->write_idx += first_block_size; + } + + return FIFO_SUCCESS; + } +} + #pragma unsafe arrays static inline fifo_ret_t fifo_block_pop(volatile mem_fifo_t * unsafe fifo, int data[], unsigned n) { unsafe{ @@ -78,14 +126,14 @@ static inline fifo_ret_t fifo_block_pop(volatile mem_fifo_t * unsafe fifo, int d } #pragma unsafe arrays -static inline fifo_ret_t fifo_block_pop_short_pairs(volatile mem_fifo_t * unsafe fifo, short data[], unsigned n) { +static inline fifo_ret_t fifo_block_pop_short(volatile mem_fifo_short_t * unsafe fifo, short data[], unsigned n) { unsafe{ //Check we have a block big enough to send - if (n > fifo_get_fill(fifo)){ + if (n > fifo_get_fill_short(fifo)){ return FIFO_EMPTY; } for (int i = 0; i < n; i++){ - data[i] = fifo->data_base_ptr[fifo->read_idx] >> 16; + data[i] = fifo->data_base_ptr[fifo->read_idx]; fifo->read_idx++; if (fifo->read_idx == fifo->size) fifo->read_idx = 0; //Check for wrap } @@ -93,6 +141,43 @@ static inline fifo_ret_t fifo_block_pop_short_pairs(volatile mem_fifo_t * unsafe } } +#pragma unsafe arrays +static inline fifo_ret_t fifo_block_pop_short_fast(volatile mem_fifo_short_t * unsafe fifo, short data[], unsigned n) { + unsafe{ + //Check we have a block big enough to send + if (n > fifo_get_fill_short(fifo)){ + return FIFO_EMPTY; + } + //We will read either one or two blocks depending on wrap + unsigned first_block_size = 0; + unsigned second_block_size = 0; + + //See if we need to wrap during block read + unsigned num_read_at_top = fifo->size - fifo->read_idx; + // printf("num_read_at_top %d\n", num_read_at_top); + //Yes, we do need to wrap + if (n > num_read_at_top){ + first_block_size = num_read_at_top; + second_block_size = n - num_read_at_top; + memcpy(&data[0], &fifo->data_base_ptr[fifo->read_idx], first_block_size * sizeof(short)); + memcpy( &data[first_block_size], &fifo->data_base_ptr[0], second_block_size * sizeof(short)); + fifo->read_idx = second_block_size; + // printf("wrap\n"); + } + //No wrap, do all in one go + else{ + first_block_size = n; + second_block_size = 0; + memcpy(&data[0], &fifo->data_base_ptr[fifo->read_idx], first_block_size * sizeof(short)); + fifo->read_idx += first_block_size; + // printf("no wrap\n"); + + } + + return FIFO_SUCCESS; + } +} + //Version of above that returns fill level relative to half full static inline int fifo_get_fill_relative_half(volatile mem_fifo_t * unsafe fifo){ unsafe{ @@ -102,4 +187,12 @@ static inline int fifo_get_fill_relative_half(volatile mem_fifo_t * unsafe fifo) } } +//Version of above that returns fill level relative to half full +static inline int fifo_get_fill_relative_half_short(volatile mem_fifo_short_t * unsafe fifo){ + unsafe{ + int fifo_fill = (int)fifo_get_fill_short(fifo); + fifo_fill -= (fifo->size / 2); + return fifo_fill; + } +} #endif \ No newline at end of file diff --git a/examples/xua_lite_example/src/fifo_types.h b/examples/xua_lite_example/src/fifo_types.h index 159a95ae..5bc5248a 100644 --- a/examples/xua_lite_example/src/fifo_types.h +++ b/examples/xua_lite_example/src/fifo_types.h @@ -27,4 +27,11 @@ typedef struct mem_fifo_t { unsigned read_idx; } mem_fifo_t; +typedef struct mem_fifo_short_t { + const unsigned size; //Size in SHORTs + short * const unsafe data_base_ptr; //Base of the data array - declared externally so we can have differnt sized FIFOs + unsigned write_idx; + unsigned read_idx; +} mem_fifo_short_t; + #endif \ No newline at end of file diff --git a/examples/xua_lite_example/src/xua_buffer_lite.h b/examples/xua_lite_example/src/xua_buffer_lite.h index 5ad972de..0a5a3366 100644 --- a/examples/xua_lite_example/src/xua_buffer_lite.h +++ b/examples/xua_lite_example/src/xua_buffer_lite.h @@ -1,8 +1,6 @@ #include #include "xua_ep0_wrapper.h" - -[[combinable]] unsafe void XUA_Buffer_lite(chanend c_ep0_out, chanend c_ep0_in, chanend c_aud_out, chanend ?c_feedback, chanend c_aud_in, chanend c_sof, in port p_for_mclk_count, streaming chanend c_audio_hub); [[combinable]] unsafe void XUA_Buffer_lite2(server ep0_control_if i_ep0_ctl, chanend c_aud_out, chanend ?c_feedback, chanend c_aud_in, chanend c_sof, in port p_for_mclk_count, streaming chanend c_audio_hub); \ No newline at end of file diff --git a/examples/xua_lite_example/src/xua_buffer_lite.xc b/examples/xua_lite_example/src/xua_buffer_lite.xc index 6d8cd6de..8b1d832d 100644 --- a/examples/xua_lite_example/src/xua_buffer_lite.xc +++ b/examples/xua_lite_example/src/xua_buffer_lite.xc @@ -158,10 +158,10 @@ static void do_feedback_calculation(unsigned &sof_count void fill_level_process(int fill_level, int &clock_nudge){ const int trigger_high_upper = 6; - const int trigger_high_lower = 8; + //const int trigger_high_lower = 8; const int trigger_low_upper = -6; - const int trigger_low_lower = -8; + //const int trigger_low_lower = -8; if (fill_level >= trigger_high_upper){ clock_nudge = 1; @@ -190,7 +190,6 @@ void XUD_GetSetupData_Select(chanend c, XUD_ep e_out, unsigned &length, XUD_Resu extern XUD_ep ep0_out; extern XUD_ep ep0_in; -[[combinable]] //Unsafe to allow us to use fifo API without local unsafe scope unsafe void XUA_Buffer_lite(chanend c_ep0_out, chanend c_ep0_in, chanend c_aud_out, chanend ?c_feedback, chanend c_aud_in, chanend c_sof, in port p_for_mclk_count, streaming chanend c_audio_hub) { @@ -231,8 +230,8 @@ unsafe void XUA_Buffer_lite(chanend c_ep0_out, chanend c_ep0_in, chanend c_aud_o unsigned num_samples_received_from_host = 0; unsigned num_samples_to_send_to_host = 0; - int samples_out[NUM_USB_CHAN_OUT] = {0}; - int samples_in[NUM_USB_CHAN_IN] = {0}; + short samples_in_short[NUM_USB_CHAN_IN] = {0}; + short samples_out_short[NUM_USB_CHAN_OUT] = {0}; #define c_audioControl null #define dfuInterface null @@ -251,21 +250,22 @@ unsafe void XUA_Buffer_lite(chanend c_ep0_out, chanend c_ep0_in, chanend c_aud_o //Send initial samples so audiohub is not blocked - for (int i = 0; i < NUM_USB_CHAN_OUT * 6; i++) c_audio_hub <: 0; + for (int i = 0; i < NUM_USB_CHAN_OUT * 2; i++) c_audio_hub <: 0; //FIFOs from EP buffers to audio - int host_to_device_fifo_storage[MAX_OUT_SAMPLES_PER_SOF_PERIOD * 2]; - int device_to_host_fifo_storage[MAX_IN_SAMPLES_PER_SOF_PERIOD * 2]; - mem_fifo_t host_to_device_fifo = {sizeof(host_to_device_fifo_storage)/sizeof(host_to_device_fifo_storage[0]), host_to_device_fifo_storage, 0, 0}; - mem_fifo_t device_to_host_fifo = {sizeof(device_to_host_fifo_storage)/sizeof(device_to_host_fifo_storage[0]), device_to_host_fifo_storage, 0, 0}; - volatile mem_fifo_t * unsafe host_to_device_fifo_ptr = &host_to_device_fifo; - volatile mem_fifo_t * unsafe device_to_host_fifo_ptr = &device_to_host_fifo; + short host_to_device_fifo_storage[MAX_OUT_SAMPLES_PER_SOF_PERIOD * 2]; + short device_to_host_fifo_storage[MAX_IN_SAMPLES_PER_SOF_PERIOD * 2]; + mem_fifo_short_t host_to_device_fifo = {sizeof(host_to_device_fifo_storage)/sizeof(host_to_device_fifo_storage[0]), host_to_device_fifo_storage, 0, 0}; + mem_fifo_short_t device_to_host_fifo = {sizeof(device_to_host_fifo_storage)/sizeof(device_to_host_fifo_storage[0]), device_to_host_fifo_storage, 0, 0}; + volatile mem_fifo_short_t * unsafe host_to_device_fifo_ptr = &host_to_device_fifo; + volatile mem_fifo_short_t * unsafe device_to_host_fifo_ptr = &device_to_host_fifo; //XUD transaction variables passed in by reference XUD_Result_t result; unsigned length = 0; unsigned u_tmp; //For select channel input by ref while(1){ + #pragma ordered select{ //Handle EP0 requests case XUD_GetSetupData_Select(c_ep0_out, ep0_out, length, result): @@ -276,7 +276,7 @@ unsafe void XUA_Buffer_lite(chanend c_ep0_out, chanend c_ep0_in, chanend c_aud_o XUA_Endpoint0_lite_loop(result, sp, c_ep0_out, c_ep0_in, c_audioControl, null/*mix*/, null/*clk*/, null/*EA*/, dfuInterface, &input_interface_num, &output_interface_num); XUD_SetReady_Out(ep0_out, sbuffer); - //tmr :> t1; debug_printf("c%d\n", t1 - t0); + tmr :> t1; debug_printf("c%d\n", t1 - t0); break; @@ -287,7 +287,7 @@ unsafe void XUA_Buffer_lite(chanend c_ep0_out, chanend c_ep0_in, chanend c_aud_o asm volatile(" getts %0, res[%1]" : "=r" (mclk_port_counter) : "r" (p_for_mclk_count)); if (!isnull(c_feedback)) do_feedback_calculation(sof_count, mclk_hz, mclk_port_counter, mclk_port_counter_old, feedback_value, mod_from_last_time, fb_clocks); sof_count++; - //tmr :> t1; debug_printf("s%d\n", t1 - t0); + tmr :> t1; debug_printf("s%d\n", t1 - t0); break; @@ -297,16 +297,16 @@ unsafe void XUA_Buffer_lite(chanend c_ep0_out, chanend c_ep0_in, chanend c_aud_o num_samples_received_from_host = length / out_subslot_size; - fifo_ret_t ret = fifo_block_push_short_pairs(host_to_device_fifo_ptr, buffer_aud_out.short_words, num_samples_received_from_host); + fifo_ret_t ret = fifo_block_push_short(host_to_device_fifo_ptr, buffer_aud_out.short_words, num_samples_received_from_host); if (ret != FIFO_SUCCESS) debug_printf("h2d full\n"); num_samples_to_send_to_host = num_samples_received_from_host; - int fill_level = fifo_get_fill_relative_half(host_to_device_fifo_ptr); + int fill_level = fifo_get_fill_relative_half_short(host_to_device_fifo_ptr); fill_level_process(fill_level, clock_nudge); //Mark EP as ready for next frame from host XUD_SetReady_OutPtr(ep_aud_out, (unsigned)buffer_aud_out.long_words); - //tmr :> t1; debug_printf("o%d\n", t1 - t0); + tmr :> t1; debug_printf("o%d\n", t1 - t0); break; //Send asynch explicit feedback value, but only if enabled @@ -315,7 +315,7 @@ unsafe void XUA_Buffer_lite(chanend c_ep0_out, chanend c_ep0_in, chanend c_aud_o XUD_SetReady_In(ep_feedback, (fb_clocks, unsigned char[]), (AUDIO_CLASS == 2) ? 4 : 3); //debug_printf("0x%x\n", fb_clocks[0]); - //tmr :> t1; debug_printf("f%d\n", t1 - t0); + tmr :> t1; debug_printf("f%d\n", t1 - t0); break; @@ -325,7 +325,7 @@ unsafe void XUA_Buffer_lite(chanend c_ep0_out, chanend c_ep0_in, chanend c_aud_o if (output_interface_num == 0) num_samples_to_send_to_host = (DEFAULT_FREQ / SOF_FREQ_HZ) * NUM_USB_CHAN_IN; - fifo_ret_t ret = fifo_block_pop_short_pairs(device_to_host_fifo_ptr, buffer_aud_in.short_words, num_samples_received_from_host); + fifo_ret_t ret = fifo_block_pop_short(device_to_host_fifo_ptr, buffer_aud_in.short_words, num_samples_received_from_host); if (ret != FIFO_SUCCESS) debug_printf("d2h empty\n"); //Populate the input buffer ready for the next read @@ -335,28 +335,30 @@ unsafe void XUA_Buffer_lite(chanend c_ep0_out, chanend c_ep0_in, chanend c_aud_o unsigned input_buffer_size = num_samples_to_send_to_host * in_subslot_size; XUD_SetReady_InPtr(ep_aud_in, (unsigned)buffer_aud_in.long_words, input_buffer_size); //loopback num_samples_to_send_to_host = 0; - //tmr :> t1; debug_printf("i%d\n", t1 - t0); + tmr :> t1; debug_printf("i%d\n", t1 - t0); break; //Exchange samples with audiohub. Note we are using channel buffering here to act as a FIFO - case c_audio_hub :> samples_in[0]: + case c_audio_hub :> u_tmp: timer tmr; int t0, t1; tmr :> t0; - + samples_in_short[0] = (int)u_tmp >> 16; for (int i = 1; i < NUM_USB_CHAN_IN; i++){ - c_audio_hub :> samples_in[i]; + c_audio_hub :> u_tmp; + samples_in_short[i] = (int)u_tmp >> 16; } - fifo_ret_t ret = fifo_block_pop(host_to_device_fifo_ptr, samples_out, NUM_USB_CHAN_OUT); + fifo_ret_t ret = fifo_block_pop_short(host_to_device_fifo_ptr, samples_out_short, NUM_USB_CHAN_OUT); if (ret != FIFO_SUCCESS && output_interface_num != 0) debug_printf("h2d empty\n"); - for (int i = 0; i < NUM_USB_CHAN_OUT; i++) c_audio_hub <: samples_out[i]; + for (int i = 0; i < NUM_USB_CHAN_OUT; i++) c_audio_hub <: (int)samples_out_short[i] << 16; if (XUA_ADAPTIVE) c_audio_hub <: clock_nudge; - ret = fifo_block_push(device_to_host_fifo_ptr, samples_in, NUM_USB_CHAN_IN); + ret = fifo_block_push_short(device_to_host_fifo_ptr, samples_in_short, NUM_USB_CHAN_IN); if (ret != FIFO_SUCCESS && input_interface_num != 0) debug_printf("d2h full\n"); - //tmr :> t1; debug_printf("a%d\n", t1 - t0); + tmr :> t1; debug_printf("a%d\n", t1 - t0); break; } } } +extern port p_sda; [[combinable]] //Unsafe to allow us to use fifo API without local unsafe scope @@ -399,9 +401,6 @@ unsafe void XUA_Buffer_lite2(server ep0_control_if i_ep0_ctl, chanend c_aud_out, unsigned num_samples_received_from_host = 0; unsigned num_samples_to_send_to_host = 0; - int samples_out[NUM_USB_CHAN_OUT] = {0}; - int samples_in[NUM_USB_CHAN_IN] = {0}; - unsigned input_interface_num = 0; unsigned output_interface_num = 0; @@ -410,17 +409,30 @@ unsafe void XUA_Buffer_lite2(server ep0_control_if i_ep0_ctl, chanend c_aud_out, XUD_SetReady_InPtr(ep_aud_in, (unsigned)buffer_aud_in.long_words, num_samples_to_send_to_host); if (!isnull(c_feedback)) XUD_SetReady_InPtr(ep_feedback, (unsigned)fb_clocks, (AUDIO_CLASS == 2) ? 4 : 3); + short samples_in_short[NUM_USB_CHAN_IN] = {0}; + short samples_out_short[NUM_USB_CHAN_OUT] = {0}; + //Send initial samples so audiohub is not blocked for (int i = 0; i < NUM_USB_CHAN_OUT * 6; i++) c_audio_hub <: 0; //FIFOs from EP buffers to audio - int host_to_device_fifo_storage[MAX_OUT_SAMPLES_PER_SOF_PERIOD * 2]; - int device_to_host_fifo_storage[MAX_IN_SAMPLES_PER_SOF_PERIOD * 2]; - mem_fifo_t host_to_device_fifo = {sizeof(host_to_device_fifo_storage)/sizeof(host_to_device_fifo_storage[0]), host_to_device_fifo_storage, 0, 0}; - mem_fifo_t device_to_host_fifo = {sizeof(device_to_host_fifo_storage)/sizeof(device_to_host_fifo_storage[0]), device_to_host_fifo_storage, 0, 0}; - volatile mem_fifo_t * unsafe host_to_device_fifo_ptr = &host_to_device_fifo; - volatile mem_fifo_t * unsafe device_to_host_fifo_ptr = &device_to_host_fifo; + short host_to_device_fifo_storage[MAX_OUT_SAMPLES_PER_SOF_PERIOD * 2]; + short device_to_host_fifo_storage[MAX_IN_SAMPLES_PER_SOF_PERIOD * 2]; + mem_fifo_short_t host_to_device_fifo = {sizeof(host_to_device_fifo_storage)/sizeof(host_to_device_fifo_storage[0]), host_to_device_fifo_storage, 0, 0}; + mem_fifo_short_t device_to_host_fifo = {sizeof(device_to_host_fifo_storage)/sizeof(device_to_host_fifo_storage[0]), device_to_host_fifo_storage, 0, 0}; + volatile mem_fifo_short_t * unsafe host_to_device_fifo_ptr = &host_to_device_fifo; + volatile mem_fifo_short_t * unsafe device_to_host_fifo_ptr = &device_to_host_fifo; + + //debug + const unsigned trig_period = 100000000; //1s + timer tmr; + unsigned sc = 0; + unsigned ac = 0; + unsigned hc = 0; + unsigned tmr_trig; + tmr :> tmr_trig; + tmr_trig += trig_period; //XUD transaction variables passed in by reference XUD_Result_t result; @@ -448,7 +460,9 @@ unsafe void XUA_Buffer_lite2(server ep0_control_if i_ep0_ctl, chanend c_aud_out, if (!isnull(c_feedback)) do_feedback_calculation(sof_count, mclk_hz, mclk_port_counter, mclk_port_counter_old, feedback_value, mod_from_last_time, fb_clocks); sof_count++; //tmr :> t1; debug_printf("s%d\n", t1 - t0); - + p_sda <: 1; + p_sda <: 0; + sc++; break; //Receive samples from host @@ -456,12 +470,13 @@ unsafe void XUA_Buffer_lite2(server ep0_control_if i_ep0_ctl, chanend c_aud_out, timer tmr; int t0, t1; tmr :> t0; num_samples_received_from_host = length / out_subslot_size; + hc += num_samples_received_from_host / NUM_USB_CHAN_OUT; - fifo_ret_t ret = fifo_block_push_short_pairs(host_to_device_fifo_ptr, buffer_aud_out.short_words, num_samples_received_from_host); + fifo_ret_t ret = fifo_block_push_short_fast(host_to_device_fifo_ptr, buffer_aud_out.short_words, num_samples_received_from_host); if (ret != FIFO_SUCCESS) debug_printf("h2d full\n"); num_samples_to_send_to_host = num_samples_received_from_host; - int fill_level = fifo_get_fill_relative_half(host_to_device_fifo_ptr); + int fill_level = fifo_get_fill_relative_half_short(host_to_device_fifo_ptr); fill_level_process(fill_level, clock_nudge); //Mark EP as ready for next frame from host @@ -483,9 +498,10 @@ unsafe void XUA_Buffer_lite2(server ep0_control_if i_ep0_ctl, chanend c_aud_out, case XUD_SetData_Select(c_aud_in, ep_aud_in, result): timer tmr; int t0, t1; tmr :> t0; + //If host is not streaming out, then send a fixed number of samples to host if (output_interface_num == 0) num_samples_to_send_to_host = (DEFAULT_FREQ / SOF_FREQ_HZ) * NUM_USB_CHAN_IN; - fifo_ret_t ret = fifo_block_pop_short_pairs(device_to_host_fifo_ptr, buffer_aud_in.short_words, num_samples_received_from_host); + fifo_ret_t ret = fifo_block_pop_short_fast(device_to_host_fifo_ptr, buffer_aud_in.short_words, num_samples_received_from_host); if (ret != FIFO_SUCCESS) debug_printf("d2h empty\n"); //Populate the input buffer ready for the next read @@ -496,21 +512,30 @@ unsafe void XUA_Buffer_lite2(server ep0_control_if i_ep0_ctl, chanend c_aud_out, XUD_SetReady_InPtr(ep_aud_in, (unsigned)buffer_aud_in.long_words, input_buffer_size); //loopback num_samples_to_send_to_host = 0; //tmr :> t1; debug_printf("i%d\n", t1 - t0); + break; + case tmr when timerafter(tmr_trig) :> int _: + tmr_trig += trig_period; + debug_printf("HOST: %d SAMP: %d SOF: %d\n", ac, hc, sc); + sc = 0; + ac = 0; + hc = 0; break; //Exchange samples with audiohub. Note we are using channel buffering here to act as a FIFO - case c_audio_hub :> samples_in[0]: + case c_audio_hub :> u_tmp: timer tmr; int t0, t1; tmr :> t0; - + samples_in_short[0] = (int)u_tmp >> 16; + ac++; for (int i = 1; i < NUM_USB_CHAN_IN; i++){ - c_audio_hub :> samples_in[i]; + c_audio_hub :> u_tmp; + samples_in_short[i] = (int)u_tmp >> 16; } - fifo_ret_t ret = fifo_block_pop(host_to_device_fifo_ptr, samples_out, NUM_USB_CHAN_OUT); + fifo_ret_t ret = fifo_block_pop_short(host_to_device_fifo_ptr, samples_out_short, NUM_USB_CHAN_OUT); if (ret != FIFO_SUCCESS && output_interface_num != 0) debug_printf("h2d empty\n"); - for (int i = 0; i < NUM_USB_CHAN_OUT; i++) c_audio_hub <: samples_out[i]; + for (int i = 0; i < NUM_USB_CHAN_OUT; i++) c_audio_hub <: (int)samples_out_short[i] << 16; if (XUA_ADAPTIVE) c_audio_hub <: clock_nudge; - ret = fifo_block_push(device_to_host_fifo_ptr, samples_in, NUM_USB_CHAN_IN); + ret = fifo_block_push_short(device_to_host_fifo_ptr, samples_in_short, NUM_USB_CHAN_IN); if (ret != FIFO_SUCCESS && input_interface_num != 0) debug_printf("d2h full\n"); //tmr :> t1; debug_printf("a%d\n", t1 - t0); break;