From ff42c23a6d165a8c2f80a3fea206d0c08573a725 Mon Sep 17 00:00:00 2001 From: xross Date: Tue, 21 Jun 2022 12:11:09 +0100 Subject: [PATCH] Basic support for sync mode streaming --- lib_xua/api/xua_buffer.h | 38 ++--- lib_xua/api/xua_conf_default.h | 6 + lib_xua/src/core/buffer/ep/ep_buffer.xc | 132 ++++++++---------- lib_xua/src/core/endpoint0/xua_endpoint0.c | 3 +- .../src/core/endpoint0/xua_ep0_descriptors.h | 1 - lib_xua/src/core/main.xc | 48 +++---- 6 files changed, 99 insertions(+), 129 deletions(-) diff --git a/lib_xua/api/xua_buffer.h b/lib_xua/api/xua_buffer.h index 302e3f67..4940564a 100644 --- a/lib_xua/api/xua_buffer.h +++ b/lib_xua/api/xua_buffer.h @@ -38,20 +38,6 @@ void XUA_Buffer( chanend c_midi_to_host, chanend c_midi, #endif -#ifdef IAP - chanend c_iap_from_host, - chanend c_iap_to_host, -#ifdef IAP_INT_EP - chanend c_iap_to_host_int, -#endif - chanend c_iap, -#ifdef IAP_EA_NATIVE_TRANS - chanend c_iap_ea_native_out, - chanend c_iap_ea_native_in, - chanend c_iap_ea_native_ctrl, - chanend c_iap_ea_native_data, -#endif -#endif #if (SPDIF_RX) || (ADAT_RX) chanend ?c_int, chanend ?c_clk_int, @@ -59,10 +45,13 @@ void XUA_Buffer( chanend c_sof, chanend c_aud_ctl, in port p_off_mclk -#if( 0 < HID_CONTROLS ) +#if (HID_CONTROLS ) , chanend c_hid #endif , chanend c_aud +#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) + , out port p_sync +#endif ); void XUA_Buffer_Ep(chanend c_aud_out, @@ -77,20 +66,6 @@ void XUA_Buffer_Ep(chanend c_aud_out, chanend c_midi_to_host, chanend c_midi, #endif -#ifdef IAP - chanend c_iap_from_host, - chanend c_iap_to_host, -#ifdef IAP_INT_EP - chanend c_iap_to_host_int, -#endif - chanend c_iap, -#ifdef IAP_EA_NATIVE_TRANS - chanend c_iap_ea_native_out, - chanend c_iap_ea_native_in, - chanend c_iap_ea_native_ctrl, - chanend c_iap_ea_native_data, -#endif -#endif #if (SPDIF_RX) || (ADAT_RX) chanend ?c_int, chanend ?c_clk_int, @@ -98,11 +73,14 @@ void XUA_Buffer_Ep(chanend c_aud_out, chanend c_sof, chanend c_aud_ctl, in port p_off_mclk -#if( 0 < HID_CONTROLS ) +#if (HID_CONTROLS) , chanend c_hid #endif #ifdef CHAN_BUFF_CTRL , chanend c_buff_ctrl +#endif +#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) + , out port p_sync #endif ); diff --git a/lib_xua/api/xua_conf_default.h b/lib_xua/api/xua_conf_default.h index a672cd0c..0fd5b421 100644 --- a/lib_xua/api/xua_conf_default.h +++ b/lib_xua/api/xua_conf_default.h @@ -1460,3 +1460,9 @@ enum USBEndpointNumber_Out #ifndef XUA_SYNCMODE #define XUA_SYNCMODE XUA_SYNCMODE_ASYNC #endif + +#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) + #if (SPDIF_RX || ADAT_RX) + #error "Digital input streams not supported in Sync mode" + #endif +#endif diff --git a/lib_xua/src/core/buffer/ep/ep_buffer.xc b/lib_xua/src/core/buffer/ep/ep_buffer.xc index ec2ba41d..391b106a 100644 --- a/lib_xua/src/core/buffer/ep/ep_buffer.xc +++ b/lib_xua/src/core/buffer/ep/ep_buffer.xc @@ -91,43 +91,32 @@ unsigned int fb_clocks[4]; #define FB_TOLERANCE 0x100 void XUA_Buffer( - register chanend c_aud_out, + register chanend c_aud_out, #if (NUM_USB_CHAN_IN > 0) - register chanend c_aud_in, + register chanend c_aud_in, #endif #if (NUM_USB_CHAN_IN == 0) || defined (UAC_FORCE_FEEDBACK_EP) - chanend c_aud_fb, + chanend c_aud_fb, #endif #ifdef MIDI - chanend c_midi_from_host, - chanend c_midi_to_host, - chanend c_midi, -#endif -#ifdef IAP - chanend c_iap_from_host, - chanend c_iap_to_host, -#ifdef IAP_INT_EP - chanend c_iap_to_host_int, -#endif - chanend c_iap, -#ifdef IAP_EA_NATIVE_TRANS - chanend c_iap_ea_native_out, - chanend c_iap_ea_native_in, - chanend c_iap_ea_native_ctrl, - chanend c_iap_ea_native_data, -#endif + chanend c_midi_from_host, + chanend c_midi_to_host, + chanend c_midi, #endif #if (SPDIF_RX) || (ADAT_RX) - chanend ?c_ep_int, - chanend ?c_clk_int, + chanend ?c_ep_int, + chanend ?c_clk_int, #endif - chanend c_sof, - chanend c_aud_ctl, - in port p_off_mclk -#if( 0 < HID_CONTROLS ) - , chanend c_hid + chanend c_sof, + chanend c_aud_ctl, + in port p_off_mclk +#if (HID_CONTROLS ) + , chanend c_hid +#endif + , chanend c_aud +#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) + , out port p_sync #endif - , chanend c_aud ) { #ifdef CHAN_BUFF_CTRL @@ -148,20 +137,6 @@ void XUA_Buffer( c_midi_to_host, /* MIDI In */ // 4 c_midi, #endif -#ifdef IAP - c_iap_from_host, /* iAP Out */ - c_iap_to_host, /* iAP In */ -#ifdef IAP_INT_EP - c_iap_to_host_int, /* iAP Interrupt In */ -#endif - c_iap, -#ifdef IAP_EA_NATIVE_TRANS - c_iap_ea_native_out, - c_iap_ea_native_in, - c_EANativeTransport_ctrl, - c_ea_data, -#endif -#endif #if (SPDIF_RX) || (ADAT_RX) /* Audio Interrupt - only used for interrupts on external clock change */ c_ep_int, @@ -173,6 +148,9 @@ void XUA_Buffer( #endif #ifdef CHAN_BUFF_CTRL , c_buff_ctrl +#endif +#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) + , p_sync #endif ); @@ -204,38 +182,27 @@ void XUA_Buffer_Ep(register chanend c_aud_out, chanend c_aud_fb, #endif #ifdef MIDI - chanend c_midi_from_host, - chanend c_midi_to_host, - chanend c_midi, -#endif -#ifdef IAP - chanend c_iap_from_host, - chanend c_iap_to_host, -#ifdef IAP_INT_EP - chanend c_iap_to_host_int, -#endif - chanend c_iap, -#ifdef IAP_EA_NATIVE_TRANS - chanend c_iap_ea_native_out, - chanend c_iap_ea_native_in, - chanend c_iap_ea_native_ctrl, - chanend c_iap_ea_native_data, -#endif + chanend c_midi_from_host, + chanend c_midi_to_host, + chanend c_midi, #endif #if (SPDIF_RX) || (ADAT_RX) - chanend ?c_ep_int, - chanend ?c_clk_int, + chanend ?c_ep_int, + chanend ?c_clk_int, #endif - chanend c_sof, - chanend c_aud_ctl, - in port p_off_mclk -#if( 0 < HID_CONTROLS ) - , chanend c_hid + chanend c_sof, + chanend c_aud_ctl, + in port p_off_mclk +#if(HID_CONTROLS) + , chanend c_hid #endif #ifdef CHAN_BUFF_CTRL - , chanend c_buff_ctrl + , chanend c_buff_ctrl #endif - ) +#if XUA_SYNCMODE == XUA_SYNCMODE_SYNC + , out port p_sync +#endif + ) { XUD_ep ep_aud_out = XUD_InitEp(c_aud_out); @@ -542,6 +509,30 @@ void XUA_Buffer_Ep(register chanend c_aud_out, /* SOF notification from XUD_Manager() */ case inuint_byref(c_sof, u_tmp): +#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) + /* This really could (shoud) be done in decouple. However, for a quick demo this is okay + * Decouple expects a 16:16 number in fixed point stored in the global g_speed */ + + unsigned usbSpeed; + int framesPerSec; + GET_SHARED_GLOBAL(usbSpeed, g_curUsbSpeed); + static int sofCount = 0; + static unsigned syncPinVal = 0; + + framesPerSec = (usbSpeed == XUD_SPEED_HS) ? 8000 : 1000; + float float_clocks = sampleFreq/framesPerSec ; + + clocks = (unsigned) (float_clocks * (1 << 16)); + asm volatile("stw %0, dp[g_speed]"::"r"(clocks)); + + sofCount += 1000; + if (sofCount == framesPerSec) + { + p_sync <: syncPinVal; + syncPinVal = ~syncPinVal; + sofCount = 0; + } +#else /* NOTE our feedback will be wrong for a couple of SOF's after a SF change due to * lastClock being incorrect */ @@ -711,7 +702,8 @@ void XUA_Buffer_Ep(register chanend c_aud_out, #endif sofCount++; } - break; +#endif + break; #if (NUM_USB_CHAN_IN > 0) /* Sent audio packet DEVICE -> HOST */ @@ -724,7 +716,7 @@ void XUA_Buffer_Ep(register chanend c_aud_out, #endif #if (NUM_USB_CHAN_OUT > 0) -#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) +#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) && (XUA_SYNCMODE == XUA_SYNCMODE_ASYNC) /* Feedback Pipe */ case XUD_SetData_Select(c_aud_fb, ep_aud_fb, result): { diff --git a/lib_xua/src/core/endpoint0/xua_endpoint0.c b/lib_xua/src/core/endpoint0/xua_endpoint0.c index 78467972..ae74bc94 100755 --- a/lib_xua/src/core/endpoint0/xua_endpoint0.c +++ b/lib_xua/src/core/endpoint0/xua_endpoint0.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "xua.h" @@ -482,7 +483,7 @@ void XUA_Endpoint0_init(chanend c_ep0_out, chanend c_ep0_in, NULLABLE_RESOURCE(c /* Check if device has started in DFU mode */ if (DFUReportResetState(null)) { - assert((c_audioControl != NULL) && msg("DFU not supported when c_audioControl is null")); + assert(((unsigned)c_audioControl != 0) && msg("DFU not supported when c_audioControl is null")); /* Stop audio */ outuint(c_audioControl, SET_SAMPLE_FREQ); diff --git a/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h b/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h index 139fd628..3b284a0a 100644 --- a/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h +++ b/lib_xua/src/core/endpoint0/xua_ep0_descriptors.h @@ -2690,7 +2690,6 @@ unsigned char cfgDesc_Audio1[] = 0x00, /* bRefresh */ #if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP) && (XUA_SYNCMODE == XUA_SYNCMODE_ASYNC) ENDPOINT_ADDRESS_IN_FEEDBACK, /* bSynchAdddress - address of EP used to communicate sync info */ -#error #else /* Bi-directional in/out device */ #if (XUA_SYNCMODE == XUA_SYNCMODE_ASYNC) ENDPOINT_ADDRESS_IN_AUDIO, diff --git a/lib_xua/src/core/main.xc b/lib_xua/src/core/main.xc index 79b70f6f..2eb9acab 100755 --- a/lib_xua/src/core/main.xc +++ b/lib_xua/src/core/main.xc @@ -154,7 +154,12 @@ on stdcore[XUD_TILE] : buffered in port:32 p_adat_rx = PORT_ADAT_IN; on tile[XUD_TILE] : buffered in port:4 p_spdif_rx = PORT_SPDIF_IN; #endif -#if (SPDIF_RX == 1) || (ADAT_RX) +#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) +/* Reference to external clock multiplier */ +on tile[XUD_TILE] : out port p_pll_clk = PORT_PLL_REF; +#endif + +#if (SPDIF_RX) || (ADAT_RX) /* Reference to external clock multiplier */ on tile[AUDIO_IO_TILE] : out port p_pll_clk = PORT_PLL_REF; #endif @@ -280,20 +285,17 @@ void xscope_user_init() /* Core USB Audio functions - must be called on the Tile connected to the USB Phy */ void usb_audio_core(chanend c_mix_out #ifdef MIDI -, chanend c_midi + , chanend c_midi #endif -#ifdef IAP -, chanend c_iap -#ifdef IAP_EA_NATIVE_TRANS -, chanend c_ea_data + #ifdef MIXER + , chanend c_mix_ctl #endif + , chanend ?c_clk_int + , chanend ?c_clk_ctl + , client interface i_dfu ?dfuInterface +#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) + , out port p_sync #endif -#ifdef MIXER -, chanend c_mix_ctl -#endif -, chanend ?c_clk_int -, chanend ?c_clk_ctl -, client interface i_dfu ?dfuInterface VENDOR_REQUESTS_PARAMS_DEC_ ) { @@ -362,33 +364,22 @@ VENDOR_REQUESTS_PARAMS_DEC_ c_xud_in[ENDPOINT_NUMBER_IN_MIDI], /* MIDI In */ // 4 c_midi, #endif -#ifdef IAP - c_xud_out[ENDPOINT_NUMBER_OUT_IAP], /* iAP Out */ - c_xud_in[ENDPOINT_NUMBER_IN_IAP], /* iAP In */ -#ifdef IAP_INT_EP - c_xud_in[ENDPOINT_NUMBER_IN_IAP_INT], /* iAP Interrupt In */ -#endif - c_iap, -#ifdef IAP_EA_NATIVE_TRANS - c_xud_out[ENDPOINT_NUMBER_OUT_IAP_EA_NATIVE_TRANS], - c_xud_in[ENDPOINT_NUMBER_IN_IAP_EA_NATIVE_TRANS], - c_EANativeTransport_ctrl, - c_ea_data, -#endif -#endif #if (SPDIF_RX) || (ADAT_RX) /* Audio Interrupt - only used for interrupts on external clock change */ c_xud_in[ENDPOINT_NUMBER_IN_INTERRUPT], c_clk_int, #endif c_sof, c_aud_ctl, p_for_mclk_count -#if( 0 < HID_CONTROLS ) +#if (HID_CONTROLS) , c_xud_in[ENDPOINT_NUMBER_IN_HID] #endif #ifdef CHAN_BUFF_CTRL , c_buff_ctrl #endif , c_mix_out +#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) + , p_sync +#endif ); //: } @@ -629,6 +620,9 @@ int main() , c_mix_ctl #endif , c_clk_int, c_clk_ctl, dfuInterface +#if (XUA_SYNCMODE == XUA_SYNCMODE_SYNC) + , p_pll_clk +#endif VENDOR_REQUESTS_PARAMS_ );