/** * @file main.xc * @brief Top level for XMOS USB 2.0 Audio 2.0 Reference Designs. * @author Ross Owen, XMOS Semiconductor Ltd */ #include #include #include #include #include #include #include "xud.h" /* XMOS USB Device Layer defines and functions */ #include "usb.h" /* Defines from the USB 2.0 Specification */ #include "devicedefines.h" /* Device specific defines */ #include "endpoint0.h" #include "usb_buffer.h" #include "decouple.h" #include "usb_midi.h" #include "audio.h" #include "ports.h" /* Portmap defines and ports for current app instance */ /* Audio I/O */ #if I2S_WIRES_DAC > 0 on stdcore[0] : buffered out port:32 p_i2s_dac[I2S_WIRES_DAC] = {PORT_I2S_DAC0, #endif #if I2S_WIRES_DAC > 1 PORT_I2S_DAC1, #endif #if I2S_WIRES_DAC > 2 PORT_I2S_DAC2, #endif #if I2S_WIRES_DAC > 3 PORT_I2S_DAC3, #endif #if I2S_WIRES_DAC > 4 PORT_I2S_DAC4, #endif #if I2S_WIRES_DAC > 5 PORT_I2S_DAC5, #endif #if I2S_WIRES_DAC > 6 PORT_I2S_DAC6, #endif #if I2S_WIRES_DAC > 7 #error Not supported #endif #if I2S_WIRES_DAC > 0 }; #endif #if I2S_WIRES_ADC > 0 on stdcore[0] : buffered in port:32 p_i2s_adc[I2S_WIRES_ADC] = {PORT_I2S_ADC0, #endif #if I2S_WIRES_ADC > 1 PORT_I2S_ADC1, #endif #if I2S_WIRES_ADC > 2 PORT_I2S_ADC2, #endif #if I2S_WIRES_ADC > 3 PORT_I2S_ADC3, #endif #if I2S_WIRES_ADC > 4 PORT_I2S_ADC4, #endif #if I2S_WIRES_ADC > 5 PORT_I2S_ADC5, #endif #if I2S_WIRES_ADC > 6 PORT_I2S_ADC6, #endif #if I2S_WIRES_ADC > 7 #error Not supported #endif #if I2S_WIRES_ADC > 0 }; #endif on stdcore[0] : buffered out port:32 p_lrclk = PORT_I2S_LRCLK; on stdcore[0] : buffered out port:32 p_bclk = PORT_I2S_BCLK; on stdcore[0] : port p_mclk = PORT_MCLK_IN; on stdcore[0] : in port p_for_mclk_count = PORT_MCLK_COUNT; #ifdef SPDIF on stdcore[0] : buffered out port:32 p_spdif_tx = PORT_SPDIF_OUT; #endif #ifdef MIDI on stdcore[0] : port p_midi_tx = PORT_MIDI_OUT; on stdcore[0] : port p_midi_rx = PORT_MIDI_IN; #endif /* Clock blocks */ #ifdef MIDI on stdcore[0] : clock clk_midi = XS1_CLKBLK_REF; #endif on stdcore[0] : clock clk_audio_mclk = XS1_CLKBLK_2; /* Master clock */ on stdcore[0] : clock clk_audio_bclk = XS1_CLKBLK_3; /* Bit clock */ #ifdef SPDIF on stdcore[0] : clock clk_mst_spd = XS1_CLKBLK_1; #endif /* L Series needs a port to use for USB reset */ #ifdef ARCH_L #ifdef PORT_USB_RESET on stdcore[0] : out port p_usb_rst = PORT_USB_RESET; #else #error Need a USB Reset port for L series #endif /* L Series also needs a clock for this port */ clock clk = XS1_CLKBLK_4; #else /* Reset port not required for SU1 due to built in Phy */ #define p_usb_rst null #define clk null #endif /* Endpoint type tables for XUD */ XUD_EpType epTypeTableOut[NUM_EP_OUT] = { XUD_EPTYPE_CTL | XUD_STATUS_ENABLE, XUD_EPTYPE_ISO, /* Audio */ #ifdef MIDI XUD_EPTYPE_BUL /* MIDI */ #endif }; XUD_EpType epTypeTableIn[NUM_EP_IN] = { XUD_EPTYPE_CTL | XUD_STATUS_ENABLE, XUD_EPTYPE_ISO, XUD_EPTYPE_ISO, XUD_EPTYPE_BUL, #ifdef MIDI XUD_EPTYPE_BUL, #endif #ifdef HID_CONTROLS XUD_EPTYPE_BUL, #endif }; #define FAST_MODE 0 void thread_speed() { #if (FAST_MODE) set_thread_fast_mode_on(); #else set_thread_fast_mode_off(); #endif } #ifdef XSCOPE void xscope_user_init() { xscope_register(0, 0, "", 0, ""); xscope_config_io(XSCOPE_IO_BASIC); } #endif int main() { chan c_sof; chan c_xud_out[NUM_EP_OUT]; /* Endpoint channels for XUD */ chan c_xud_in[NUM_EP_IN]; chan c_aud_ctl; chan c_mix_out; #ifdef MIDI chan c_midi; #endif #ifdef TEST_MODE_SUPPORT #warning Building with test mode support chan c_usb_test; #else #define c_usb_test null #endif #ifdef SU1_ADC chan c_adc; #else #define c_adc null #endif //SPI_SS Mux - disable access to SPI_SS //p_gpio <: 1; par { /* USB Interface */ #if (AUDIO_CLASS==2) on stdcore[0]: XUD_Manager(c_xud_out, NUM_EP_OUT, c_xud_in, NUM_EP_IN, c_sof, epTypeTableOut, epTypeTableIn, p_usb_rst, clk, 1, XUD_SPEED_HS, c_usb_test); #else on stdcore[0]:XUD_Manager(c_xud_out, NUM_EP_OUT, c_xud_in, NUM_EP_IN, c_sof, epTypeTableOut, epTypeTableIn, p_usb_rst, clk, 1, XUD_SPEED_FS, c_usb_test); #endif /* Endpoint 0 */ on stdcore[0]:{ thread_speed(); Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, null,null, c_usb_test); } on stdcore[0]: { thread_speed(); /* Attach mclk count port to mclk clock-block (for feedback) */ //set_port_clock(p_for_mclk_count, clk_audio_mclk); { unsigned x; asm("ldw %0, dp[clk_audio_mclk]":"=r"(x)); asm("setclk res[%0], %1"::"r"(p_for_mclk_count), "r"(x)); } buffer(c_xud_out[EP_NUM_OUT_AUD],/* Audio Out*/ c_xud_in[EP_NUM_IN_AUD], /* Audio In */ c_xud_in[EP_NUM_IN_FB], /* Audio FB */ #ifdef MIDI c_xud_out[EP_NUM_OUT_MIDI], /* MIDI Out */ // 2 c_xud_in[EP_NUM_IN_MIDI], /* MIDI In */ // 4 c_midi, #endif c_xud_in[EP_NUM_IN_AUD_INT], /* Int */ c_sof, c_aud_ctl, p_for_mclk_count #ifdef HID_CONTROLS ,c_xud_in[EP_NUM_IN_HID] #endif ); } on stdcore[0]: { thread_speed(); decouple(c_mix_out, null); } on stdcore[0]: { thread_speed(); /* Audio I/O (pars additional S/PDIF TX thread) */ audio(c_mix_out, null, null, c_adc); } //on stdcore[0]: test(c_adc2); #ifdef MIDI on stdcore[0]: { thread_speed(); usb_midi(p_midi_rx, p_midi_tx, clk_midi, c_midi, 0, null, null, null, null); } #endif #ifdef SU1_ADC xs1_su_adc_service(c_adc); #endif } return 0; }