From ca7ee58883db02ee546ee763726ddb6caad142c2 Mon Sep 17 00:00:00 2001 From: Ed Clarke Date: Wed, 14 Nov 2018 10:04:39 +0000 Subject: [PATCH] Fix buffer level calcs (now locks over & under) --- examples/xua_lite_example/src/audio_config.xc | 11 +- examples/xua_lite_example/src/audio_hub.xc | 2 +- .../xua_lite_example/src/xua_buffer_lite.xc | 101 +++++++----------- 3 files changed, 44 insertions(+), 70 deletions(-) diff --git a/examples/xua_lite_example/src/audio_config.xc b/examples/xua_lite_example/src/audio_config.xc index d1c126e1..5a523156 100755 --- a/examples/xua_lite_example/src/audio_config.xc +++ b/examples/xua_lite_example/src/audio_config.xc @@ -74,19 +74,18 @@ on tile[0]: out port p_leds = XS1_PORT_4F; int old_nudge = 0; void pll_nudge(int nudge) { if (nudge > 0){ - set_node_pll_reg(tile[0], PLL_HIGH); - p_leds <: 0xf; + write_sswitch_reg(get_tile_id(tile[0]), XS1_SSWITCH_PLL_CTL_NUM, PLL_HIGH); + p_leds <: 0x02; //LED B } else if (nudge < 0){ - set_node_pll_reg(tile[0], PLL_LOW); - p_leds <: 0xf; + write_sswitch_reg(get_tile_id(tile[0]), XS1_SSWITCH_PLL_CTL_NUM, PLL_LOW); + p_leds <: 0x01; //LED A } else { 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; + write_sswitch_reg(get_tile_id(tile[0]), XS1_SSWITCH_PLL_CTL_NUM, PLL_NOM); } void setup_audio_gpio(out port p_gpio){ diff --git a/examples/xua_lite_example/src/audio_hub.xc b/examples/xua_lite_example/src/audio_hub.xc index f83f3e2c..863d8505 100644 --- a/examples/xua_lite_example/src/audio_hub.xc +++ b/examples/xua_lite_example/src/audio_hub.xc @@ -70,7 +70,7 @@ void AudioHub(server i2s_frame_callback_if i2s, } pll_nudge(clock_nudge); - //tmr :> t1; debug_printf("%d\n", t1 - t0); + //tmr :> t1; if (t1-t0 > 500) debug_printf("*%d\n", t1 - t0); //delay_microseconds(10); //Test backpressure tolerance break; } diff --git a/examples/xua_lite_example/src/xua_buffer_lite.xc b/examples/xua_lite_example/src/xua_buffer_lite.xc index 8b1d832d..b784691c 100644 --- a/examples/xua_lite_example/src/xua_buffer_lite.xc +++ b/examples/xua_lite_example/src/xua_buffer_lite.xc @@ -103,27 +103,25 @@ static void do_feedback_calculation(unsigned &sof_count ,long long &feedback_value ,unsigned &mod_from_last_time ,unsigned fb_clocks[1]){ - /* Assuming 48kHz from a 24.576 master clock (0.0407uS period) - * MCLK ticks per SOF = 125uS / 0.0407 = 3072 MCLK ticks per SOF. - * expected Feedback is 48000/8000 = 6 samples. so 0x60000 in 16:16 format. - * Average over 128 SOFs - 128 x 3072 = 0x60000. */ + // Assuming 48kHz from a 24.576 master clock (0.0407uS period) + // MCLK ticks per SOF = 125uS / 0.0407 = 3072 MCLK ticks per SOF. + // expected Feedback is 48000/8000 = 6 samples. so 0x60000 in 16:16 format. + // Average over 128 SOFs - 128 x 3072 = 0x60000. unsigned long long feedbackMul = 64ULL; - if(AUDIO_CLASS == 1) - feedbackMul = 8ULL; /* TODO Use 4 instead of 8 to avoid windows LSB issues? */ + if(AUDIO_CLASS == 1) feedbackMul = 8ULL; // TODO Use 4 instead of 8 to avoid windows LSB issues? - /* Number of MCLK ticks in this SOF period (E.g = 125 * 24.576 = 3072) */ + // Number of MCLK ticks in this SOF period (E.g = 125 * 24.576 = 3072) int mclk_ticks_this_sof_period = (int) ((short)(mclk_port_counter - mclk_port_counter_old)); unsigned long long full_result = mclk_ticks_this_sof_period * feedbackMul * DEFAULT_FREQ; feedback_value += full_result; - /* Store MCLK for next time around... */ + // Store MCLK for next time around... mclk_port_counter_old = mclk_port_counter; - /* Reset counts based on SOF counting. Expect 16ms (128 HS SOFs/16 FS SOFS) per feedback poll - * We always count 128 SOFs, so 16ms @ HS, 128ms @ FS */ - if(sof_count == 128) - { + // Reset counts based on SOF counting. Expect 16ms (128 HS SOFs/16 FS SOFS) per feedback poll + // We always count 128 SOFs, so 16ms @ HS, 128ms @ FS + if(sof_count == 128){ //debug_printf("fb\n"); sof_count = 0; @@ -132,36 +130,31 @@ static void do_feedback_calculation(unsigned &sof_count mod_from_last_time = feedback_value % mclk_hz; feedback_value = 0; - //Scale for working out number of samps to take from device for input - if(AUDIO_CLASS == 2) - { + if(AUDIO_CLASS == 2){ clocks <<= 3; } - else - { + else{ clocks <<= 6; } asm volatile("stw %0, dp[g_speed]"::"r"(clocks)); // g_speed = clocks //Write to feedback EP buffer - if (AUDIO_CLASS == 2) - { + if (AUDIO_CLASS == 2){ fb_clocks[0] = clocks; } - else - { + else{ fb_clocks[0] = clocks >> 2; } } } void fill_level_process(int fill_level, int &clock_nudge){ - const int trigger_high_upper = 6; - //const int trigger_high_lower = 8; + //Because we always check level after USB has produced a block, and total FIFO size is 2x max, half full is at 3/4 + const int half_full_out = ((MAX_OUT_SAMPLES_PER_SOF_PERIOD * 2) * 3) / 4; - const int trigger_low_upper = -6; - //const int trigger_low_lower = -8; + const int trigger_high_upper = half_full_out + 4; + const int trigger_low_upper = half_full_out - 4; if (fill_level >= trigger_high_upper){ clock_nudge = 1; @@ -250,7 +243,7 @@ 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 * 2; i++) c_audio_hub <: 0; + for (int i = 0; i < 2 * (NUM_USB_CHAN_OUT + (XUA_ADAPTIVE != 0 ? 1 : 0)); i++) c_audio_hub <: 0; //FIFOs from EP buffers to audio short host_to_device_fifo_storage[MAX_OUT_SAMPLES_PER_SOF_PERIOD * 2]; @@ -263,7 +256,8 @@ unsafe void XUA_Buffer_lite(chanend c_ep0_out, chanend c_ep0_in, chanend c_aud_o //XUD transaction variables passed in by reference XUD_Result_t result; unsigned length = 0; - unsigned u_tmp; //For select channel input by ref + unsigned u_tmp; //For select channel input by ref on EP0 + int s_tmp; //For select on channel from audiohub while(1){ #pragma ordered select{ @@ -301,7 +295,7 @@ unsafe void XUA_Buffer_lite(chanend c_ep0_out, chanend c_ep0_in, chanend c_aud_o 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_short(host_to_device_fifo_ptr); + int fill_level = fifo_get_fill_short(host_to_device_fifo_ptr); fill_level_process(fill_level, clock_nudge); //Mark EP as ready for next frame from host @@ -340,12 +334,12 @@ unsafe void XUA_Buffer_lite(chanend c_ep0_out, chanend c_ep0_in, chanend c_aud_o break; //Exchange samples with audiohub. Note we are using channel buffering here to act as a FIFO - case c_audio_hub :> u_tmp: + case c_audio_hub :> s_tmp: timer tmr; int t0, t1; tmr :> t0; - samples_in_short[0] = (int)u_tmp >> 16; + samples_in_short[0] = s_tmp >> 16; for (int i = 1; i < NUM_USB_CHAN_IN; i++){ - c_audio_hub :> u_tmp; - samples_in_short[i] = (int)u_tmp >> 16; + c_audio_hub :> s_tmp; + samples_in_short[i] = s_tmp >> 16; } 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"); @@ -414,7 +408,7 @@ unsafe void XUA_Buffer_lite2(server ep0_control_if i_ep0_ctl, chanend c_aud_out, //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 < 2 * (NUM_USB_CHAN_OUT + (XUA_ADAPTIVE != 0 ? 1 : 0)); i++) c_audio_hub <: 0; //FIFOs from EP buffers to audio short host_to_device_fifo_storage[MAX_OUT_SAMPLES_PER_SOF_PERIOD * 2]; @@ -424,29 +418,22 @@ unsafe void XUA_Buffer_lite2(server ep0_control_if i_ep0_ctl, chanend c_aud_out, 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; unsigned length = 0; - unsigned u_tmp; //For select channel input by ref + unsigned u_tmp; //For select channel input by ref on EP0 + int s_tmp; //For select on channel from audiohub while(1){ select{ //Handle EP0 requests case i_ep0_ctl.set_output_interface(unsigned num): output_interface_num = num; + debug_printf("output_interface_num: %d\n", num); break; case i_ep0_ctl.set_input_interface(unsigned num): input_interface_num = num; + debug_printf("input_interface_num: %d\n", num); break; case i_ep0_ctl.set_host_active(unsigned active): @@ -460,9 +447,6 @@ 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 @@ -470,13 +454,14 @@ 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; + + if (num_samples_received_from_host != 96) debug_printf("hs: %d\n", 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_short(host_to_device_fifo_ptr); + int fill_level = fifo_get_fill_short(host_to_device_fifo_ptr); fill_level_process(fill_level, clock_nudge); //Mark EP as ready for next frame from host @@ -491,7 +476,6 @@ unsafe void XUA_Buffer_lite2(server ep0_control_if i_ep0_ctl, chanend c_aud_out, 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 @@ -514,22 +498,13 @@ unsafe void XUA_Buffer_lite2(server ep0_control_if i_ep0_ctl, chanend c_aud_out, //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 :> u_tmp: + case c_audio_hub :> s_tmp: timer tmr; int t0, t1; tmr :> t0; - samples_in_short[0] = (int)u_tmp >> 16; - ac++; + samples_in_short[0] = s_tmp >> 16; for (int i = 1; i < NUM_USB_CHAN_IN; i++){ - c_audio_hub :> u_tmp; - samples_in_short[i] = (int)u_tmp >> 16; + c_audio_hub :> s_tmp; + samples_in_short[i] = s_tmp >> 16; } 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");