diff --git a/examples/xua_lite_example/src/AudioConfig.xc b/examples/xua_lite_example/src/AudioConfig.xc index fc9efad0..1bb907c5 100755 --- a/examples/xua_lite_example/src/AudioConfig.xc +++ b/examples/xua_lite_example/src/AudioConfig.xc @@ -86,7 +86,7 @@ void pll_nudge(int nudge) { p_leds <: 0x0; } set_node_pll_reg(tile[0], PLL_NOM); - if(nudge != old_nudge && nudge){debug_printf("nudge: %d\n", nudge); }old_nudge = nudge; + //if(nudge != old_nudge && nudge){debug_printf("nudge: %d\n", nudge); }old_nudge = nudge; } void AudioHwConfigure(unsigned samFreq, client i2c_master_if i_i2c) diff --git a/examples/xua_lite_example/src/app_xua_lite.xc b/examples/xua_lite_example/src/app_xua_lite.xc index 94115c54..618e7308 100644 --- a/examples/xua_lite_example/src/app_xua_lite.xc +++ b/examples/xua_lite_example/src/app_xua_lite.xc @@ -11,6 +11,8 @@ #include "i2s.h" #include "i2c.h" #include "mic_array.h" +#include "XUA_Buffer_lite.h" +#include "xua_ep0_wrapper.h" #define DEBUG_UNIT XUA_APP #define DEBUG_PRINT_ENABLE_XUA_APP 1 @@ -56,13 +58,10 @@ on tile[0]: clock pdmclk6 = XS1_CLKBLK_5; XUD_EpType epTypeTableOut[] = {XUD_EPTYPE_CTL | XUD_STATUS_ENABLE, XUD_EPTYPE_ISO}; XUD_EpType epTypeTableIn[] = {XUD_EPTYPE_CTL | XUD_STATUS_ENABLE, XUD_EPTYPE_ISO, XUD_EPTYPE_ISO}; -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_aud_host); [[distributable]] void AudioHub(server i2s_frame_callback_if i2s, streaming chanend c_audio, streaming chanend (&?c_ds_output)[1]); void setup_audio_gpio(out port p_gpio); void AudioHwConfigure(unsigned samFreq, client i2c_master_if i_i2c); -void XUA_Endpoint0_select(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, - chanend ?c_mix_ctl, chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, ?dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_); void pdm_mic(streaming chanend c_ds_output, in buffered port:32 p_pdm_mics); void mic_array_setup_ddr_xcore(clock pdmclk, clock pdmclk6, out port p_pdm_clk, buffered in port:32 p_pdm_data, int divide); @@ -90,6 +89,8 @@ int main() streaming chan c_audio; //We use the channel buffering (48B across switch each way) streaming chan c_ds_output[1]; + interface ep0_control_if i_ep0_ctl; + par { on tile[0]: { @@ -111,7 +112,7 @@ int main() par (int i = 0; i < 0; i++) burn_high_priority(); } } - on tile[1]:{ + on tile[1]:unsafe{ // Connect master-clock input clock-block to clock-block pin for asnch feedback calculation set_clock_src(clk_usb_mclk, p_mclk_in_usb); // Clock clock-block from mclk pin set_port_clock(p_for_mclk_count, clk_usb_mclk); // Clock the "count" port from the clock block @@ -132,15 +133,22 @@ int main() null, null, -1 , (AUDIO_CLASS == 1) ? XUD_SPEED_FS : XUD_SPEED_HS, XUD_PWR_BUS); - // Buffering core - handles audio and control data to/from EP's and gives/gets data to/from the audio I/O core - XUA_Buffer_lite(c_ep_out[0], - c_ep_in[0], + // // Buffering core - handles audio and control data to/from EP's and gives/gets data to/from the audio I/O core + // XUA_Buffer_lite(c_ep_out[0], + // c_ep_in[0], + // 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_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 < 4; i++) burn_normal_priority(); + par (int i = 0; i < 3; i++) burn_normal_priority(); par (int i = 0; i < 2; i++) burn_high_priority(); } }//Tile[1] par diff --git a/examples/xua_lite_example/src/xua_buffer_lite.h b/examples/xua_lite_example/src/xua_buffer_lite.h new file mode 100644 index 00000000..5ad972de --- /dev/null +++ b/examples/xua_lite_example/src/xua_buffer_lite.h @@ -0,0 +1,8 @@ +#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 1eb91963..8649d5a3 100644 --- a/examples/xua_lite_example/src/xua_buffer_lite.xc +++ b/examples/xua_lite_example/src/xua_buffer_lite.xc @@ -10,6 +10,7 @@ #include "debug_print.h" #include "xua.h" #include "fifo_impl.h" +#include "xua_ep0_wrapper.h" //Currently only single frequency supported #define NOMINAL_SR_DEVICE DEFAULT_FREQ @@ -95,7 +96,7 @@ static inline void pack_samples_to_buff(int input[], const unsigned n_samples, c } -void do_feedback_calculation(unsigned &sof_count +static void do_feedback_calculation(unsigned &sof_count ,const unsigned mclk_hz ,unsigned mclk_port_counter ,unsigned &mclk_port_counter_old @@ -189,8 +190,9 @@ void XUD_GetSetupData_Select(chanend c, XUD_ep e_out, unsigned &length, XUD_Resu extern XUD_ep ep0_out; extern XUD_ep ep0_in; - -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 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) { debug_printf("%d\n", MAX_OUT_SAMPLES_PER_SOF_PERIOD); @@ -241,113 +243,259 @@ void XUA_Buffer_lite(chanend c_ep0_out, chanend c_ep0_in, chanend c_aud_out, cha //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; + + //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){ + select{ + //Handle EP0 requests + case XUD_GetSetupData_Select(c_ep0_out, ep0_out, length, result): + timer tmr; int t0, t1; tmr :> t0; + + debug_printf("ep0, result: %d, length: %d\n", result, length); //-1 reset, 0 ok, 1 error + USB_ParseSetupPacket(sbuffer, sp); //Parse data buffer end populate SetupPacket struct + + 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); + + break; + + //SOF handling + case inuint_byref(c_sof, u_tmp): + timer tmr; int t0, t1; tmr :> t0; + unsigned mclk_port_counter = 0; + 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); + + break; + + //Receive samples from host + case XUD_GetData_Select(c_aud_out, ep_aud_out, length, result): + timer tmr; int t0, t1; tmr :> t0; + + num_samples_received_from_host = length / out_subslot_size; + + fifo_ret_t ret = fifo_block_push_short_pairs(host_to_device_fifo_ptr, (short *)buffer_aud_out, 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); + 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); + //tmr :> t1; debug_printf("o%d\n", t1 - t0); + break; + + //Send asynch explicit feedback value, but only if enabled + case !isnull(c_feedback) => XUD_SetData_Select(c_feedback, ep_feedback, result): + timer tmr; int t0, t1; tmr :> t0; + + 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); + + break; + + //Send samples to host + case XUD_SetData_Select(c_aud_in, ep_aud_in, result): + timer tmr; int t0, t1; tmr :> t0; + + 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, (short *)buffer_aud_in, num_samples_received_from_host); + if (ret != FIFO_SUCCESS) debug_printf("d2h empty\n"); + + //Populate the input buffer ready for the next read + //pack_samples_to_buff(loopback_samples, num_samples_to_send_to_host, in_subslot_size, buffer_aud_in); + //Use the number of samples we received last time so we are always balanced (assumes same in/out count) + + unsigned input_buffer_size = num_samples_to_send_to_host * in_subslot_size; + XUD_SetReady_InPtr(ep_aud_in, (unsigned)buffer_aud_in, input_buffer_size); //loopback + num_samples_to_send_to_host = 0; + //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]: + timer tmr; int t0, t1; tmr :> t0; + + for (int i = 1; i < NUM_USB_CHAN_IN; i++){ + c_audio_hub :> samples_in[i]; + } + fifo_ret_t ret = fifo_block_pop(host_to_device_fifo_ptr, samples_out, 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]; + if (XUA_ADAPTIVE) c_audio_hub <: clock_nudge; + ret = fifo_block_push(device_to_host_fifo_ptr, samples_in, 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; + } + } +} + +[[combinable]] +//Unsafe to allow us to use fifo API without local unsafe scope +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) { + + debug_printf("%d\n", MAX_OUT_SAMPLES_PER_SOF_PERIOD); + + unsigned char buffer_aud_out[OUT_AUDIO_BUFFER_SIZE_BYTES]; + unsigned char buffer_aud_in[IN_AUDIO_BUFFER_SIZE_BYTES]; + + unsigned in_subslot_size = (AUDIO_CLASS == 1) ? FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES : HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES; + unsigned out_subslot_size = (AUDIO_CLASS == 1) ? FS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES : HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES; + + //Asynch feedback calculation + unsigned sof_count = 0; + unsigned mclk_port_counter_old = 0; + long long feedback_value = 0; + unsigned mod_from_last_time = 0; + const unsigned mclk_hz = MCLK_48; + unsigned int fb_clocks[1] = {0}; + + //Adapative device clock control + int clock_nudge = 0; + + //Endpoints + XUD_ep ep_aud_out = XUD_InitEp(c_aud_out); + XUD_ep ep_aud_in = XUD_InitEp(c_aud_in); + XUD_ep ep_feedback = 0; + if (!isnull(c_feedback)) ep_feedback = XUD_InitEp(c_feedback); + + 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; + + //Enable all EPs + XUD_SetReady_OutPtr(ep_aud_out, (unsigned)buffer_aud_out); + XUD_SetReady_InPtr(ep_aud_in, (unsigned)buffer_aud_in, num_samples_to_send_to_host); + if (!isnull(c_feedback)) XUD_SetReady_InPtr(ep_feedback, (unsigned)fb_clocks, (AUDIO_CLASS == 2) ? 4 : 3); - //Unsafe to allow us to use fifo API - unsafe{ + //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; + //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; - //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){ - select{ - //Handle EP0 requests - case XUD_GetSetupData_Select(c_ep0_out, ep0_out, length, result): - timer tmr; int t0, t1; tmr :> t0; + //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){ + select{ + //Handle EP0 requests + case i_ep0_ctl.set_output_interface(unsigned num): + output_interface_num = num; + break; - debug_printf("ep0, result: %d, length: %d\n", result, length); //-1 reset, 0 ok, 1 error - USB_ParseSetupPacket(sbuffer, sp); //Parse data buffer end populate SetupPacket struct - - 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); + case i_ep0_ctl.set_input_interface(unsigned num): + input_interface_num = num; + break; - break; + case i_ep0_ctl.set_host_active(unsigned active): + break; - //SOF handling - case inuint_byref(c_sof, u_tmp): - timer tmr; int t0, t1; tmr :> t0; - unsigned mclk_port_counter = 0; - asm volatile(" getts %0, res[%1]" : "=r" (mclk_port_counter) : "r" (p_for_mclk_count)); - 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); + //SOF handling + case inuint_byref(c_sof, u_tmp): + timer tmr; int t0, t1; tmr :> t0; + unsigned mclk_port_counter = 0; + 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); - break; + break; - //Receive samples from host - case XUD_GetData_Select(c_aud_out, ep_aud_out, length, result): - timer tmr; int t0, t1; tmr :> t0; + //Receive samples from host + case XUD_GetData_Select(c_aud_out, ep_aud_out, length, result): + timer tmr; int t0, t1; tmr :> t0; - num_samples_received_from_host = length / out_subslot_size; + num_samples_received_from_host = length / out_subslot_size; + + fifo_ret_t ret = fifo_block_push_short_pairs(host_to_device_fifo_ptr, (short *)buffer_aud_out, 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); + 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); + //tmr :> t1; debug_printf("o%d\n", t1 - t0); + break; + + //Send asynch explicit feedback value, but only if enabled + case !isnull(c_feedback) => XUD_SetData_Select(c_feedback, ep_feedback, result): + timer tmr; int t0, t1; tmr :> t0; + + 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); + + break; + + //Send samples to host + case XUD_SetData_Select(c_aud_in, ep_aud_in, result): + timer tmr; int t0, t1; tmr :> t0; + + 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, (short *)buffer_aud_in, num_samples_received_from_host); + if (ret != FIFO_SUCCESS) debug_printf("d2h empty\n"); + + //Populate the input buffer ready for the next read + //pack_samples_to_buff(loopback_samples, num_samples_to_send_to_host, in_subslot_size, buffer_aud_in); + //Use the number of samples we received last time so we are always balanced (assumes same in/out count) - fifo_ret_t ret = fifo_block_push_short_pairs(host_to_device_fifo_ptr, (short *)buffer_aud_out, 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); - fill_level_process(fill_level, clock_nudge); + unsigned input_buffer_size = num_samples_to_send_to_host * in_subslot_size; + XUD_SetReady_InPtr(ep_aud_in, (unsigned)buffer_aud_in, input_buffer_size); //loopback + num_samples_to_send_to_host = 0; + //tmr :> t1; debug_printf("i%d\n", t1 - t0); - //Mark EP as ready for next frame from host - XUD_SetReady_OutPtr(ep_aud_out, (unsigned)buffer_aud_out); - //tmr :> t1; debug_printf("o%d\n", t1 - t0); - break; + break; - //Send asynch explicit feedback value, but only if enabled - case !isnull(c_feedback) => XUD_SetData_Select(c_feedback, ep_feedback, result): - timer tmr; int t0, t1; tmr :> t0; + //Exchange samples with audiohub. Note we are using channel buffering here to act as a FIFO + case c_audio_hub :> samples_in[0]: + timer tmr; int t0, t1; tmr :> t0; - 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); - - break; - - //Send samples to host - case XUD_SetData_Select(c_aud_in, ep_aud_in, result): - timer tmr; int t0, t1; tmr :> t0; - - 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, (short *)buffer_aud_in, num_samples_received_from_host); - if (ret != FIFO_SUCCESS) debug_printf("d2h empty\n"); - - //Populate the input buffer ready for the next read - //pack_samples_to_buff(loopback_samples, num_samples_to_send_to_host, in_subslot_size, buffer_aud_in); - //Use the number of samples we received last time so we are always balanced (assumes same in/out count) - - unsigned input_buffer_size = num_samples_to_send_to_host * in_subslot_size; - XUD_SetReady_InPtr(ep_aud_in, (unsigned)buffer_aud_in, input_buffer_size); //loopback - num_samples_to_send_to_host = 0; - //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]: - timer tmr; int t0, t1; tmr :> t0; - - for (int i = 1; i < NUM_USB_CHAN_IN; i++){ - c_audio_hub :> samples_in[i]; - } - fifo_ret_t ret = fifo_block_pop(host_to_device_fifo_ptr, samples_out, 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]; - if (XUA_ADAPTIVE) c_audio_hub <: clock_nudge; - ret = fifo_block_push(device_to_host_fifo_ptr, samples_in, 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; - } + for (int i = 1; i < NUM_USB_CHAN_IN; i++){ + c_audio_hub :> samples_in[i]; + } + fifo_ret_t ret = fifo_block_pop(host_to_device_fifo_ptr, samples_out, 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]; + if (XUA_ADAPTIVE) c_audio_hub <: clock_nudge; + ret = fifo_block_push(device_to_host_fifo_ptr, samples_in, 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; } } } \ No newline at end of file diff --git a/lib_xua/src/core/endpoint0/xua_ep0_wrapper.h b/lib_xua/src/core/endpoint0/xua_ep0_wrapper.h new file mode 100644 index 00000000..8015b95e --- /dev/null +++ b/lib_xua/src/core/endpoint0/xua_ep0_wrapper.h @@ -0,0 +1,27 @@ +#ifndef _EP0_WRAPPER_ +#define _EP0_WRAPPER_ + +#include +#include +#include +#include "xua.h" + +typedef interface ep0_control_if{ + void set_output_interface(unsigned num); + void set_input_interface(unsigned num); + void set_host_active(unsigned num); +}ep0_control_if; + +extern "C"{ +void XUA_Endpoint0_lite_init(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, + chanend ?c_mix_ctl, chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, ?dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_); +void XUA_Endpoint0_lite_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, + chanend ?c_mix_ctl, chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, ?dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_, unsigned *input_interface_num, unsigned *output_interface_num); +} +#pragma select handler +void XUD_GetSetupData_Select(chanend c, XUD_ep e_out, unsigned &length, XUD_Result_t &result); + +[[combinable]] +void XUA_Endpoint0_select(chanend c_ep0_out, chanend c_ep0_in, client ep0_control_if i_ep0_ctl, CLIENT_INTERFACE(i_dfu, ?dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_); + +#endif \ No newline at end of file diff --git a/lib_xua/src/core/endpoint0/xua_ep0_wrapper.xc b/lib_xua/src/core/endpoint0/xua_ep0_wrapper.xc index 3846c1c6..14a5148b 100644 --- a/lib_xua/src/core/endpoint0/xua_ep0_wrapper.xc +++ b/lib_xua/src/core/endpoint0/xua_ep0_wrapper.xc @@ -2,56 +2,46 @@ #include #include #include "xua.h" +#include "xua_ep0_wrapper.h" #define DEBUG_UNIT EP0_WRAPPER #define DEBUG_PRINT_ENABLE_EP0_WRAPPER 0 #include "debug_print.h" -extern "C"{ -void XUA_Endpoint0_lite_init(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, - chanend ?c_mix_ctl, chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, ?dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_); -void XUA_Endpoint0_lite_loop(XUD_Result_t result, USB_SetupPacket_t sp, chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, - chanend ?c_mix_ctl, chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, ?dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_, unsigned *input_interface_num, unsigned *output_interface_num); -} -#pragma select handler -void XUD_GetSetupData_Select(chanend c, XUD_ep e_out, unsigned &length, XUD_Result_t &result); - extern XUD_ep ep0_out; extern XUD_ep ep0_in; - -void XUA_Endpoint0_select(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, - chanend ?c_mix_ctl, chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_) +[[combinable]] +void XUA_Endpoint0_select(chanend c_ep0_out, chanend c_ep0_in, client ep0_control_if i_ep0_ctl, CLIENT_INTERFACE(i_dfu, ?dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_) { - USB_SetupPacket_t sp; - XUA_Endpoint0_lite_init(c_ep0_out, c_ep0_in, c_audioControl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface); - unsigned char sbuffer[120]; - XUD_SetReady_Out(ep0_out, sbuffer); + USB_SetupPacket_t sp; + XUA_Endpoint0_lite_init(c_ep0_out, c_ep0_in, null, null, null, null, dfuInterface); + unsigned char sbuffer[120]; + XUD_SetReady_Out(ep0_out, sbuffer); - unsigned input_interface_num = 0; - unsigned output_interface_num = 0; + unsigned input_interface_num = 0; + unsigned output_interface_num = 0; + XUD_Result_t result = XUD_RES_ERR; + unsigned length = 0; - while(1){ + while(1){ + select{ + case XUD_GetSetupData_Select(c_ep0_out, ep0_out, length, result): + if (result == XUD_RES_OKAY) + { + /* Parse data buffer end populate SetupPacket struct */ + USB_ParseSetupPacket(sbuffer, sp); + } + debug_printf("ep0, result: %d, length: %d\n", result, length); //-1 reset, 0 ok, 1 error - XUD_Result_t result = XUD_RES_ERR; - unsigned length = 0; - - select{ - case XUD_GetSetupData_Select(c_ep0_out, ep0_out, length, result): - break; - } - - if (result == XUD_RES_OKAY) - { - /* Parse data buffer end populate SetupPacket struct */ - USB_ParseSetupPacket(sbuffer, sp); - } - debug_printf("ep0, result: %d, length: %d\n", result, length); //-1 reset, 0 ok, 1 error - - XUA_Endpoint0_lite_loop(result, sp, c_ep0_out, c_ep0_in, c_audioControl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface, &input_interface_num, &output_interface_num); - XUD_SetReady_Out(ep0_out, sbuffer); + XUA_Endpoint0_lite_loop(result, sp, c_ep0_out, c_ep0_in, null, null, null, null, dfuInterface, &input_interface_num, &output_interface_num); + i_ep0_ctl.set_output_interface(output_interface_num); + i_ep0_ctl.set_input_interface(input_interface_num); + XUD_SetReady_Out(ep0_out, sbuffer); + break; } + } } \ No newline at end of file