forked from PAWPAW-Mirror/lib_xua
combinable ep0 task
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
8
examples/xua_lite_example/src/xua_buffer_lite.h
Normal file
8
examples/xua_lite_example/src/xua_buffer_lite.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#include <xs1.h>
|
||||
#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);
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
27
lib_xua/src/core/endpoint0/xua_ep0_wrapper.h
Normal file
27
lib_xua/src/core/endpoint0/xua_ep0_wrapper.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef _EP0_WRAPPER_
|
||||
#define _EP0_WRAPPER_
|
||||
|
||||
#include <xs1.h>
|
||||
#include <safestring.h>
|
||||
#include <stddef.h>
|
||||
#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
|
||||
@@ -2,56 +2,46 @@
|
||||
#include <safestring.h>
|
||||
#include <stddef.h>
|
||||
#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;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user