From e7d23603a45d355a3e79a24df7cf7f161d72e04d Mon Sep 17 00:00:00 2001 From: Ross Owen Date: Wed, 8 May 2013 14:24:34 +0100 Subject: [PATCH] Tidy --- module_dfu/src/dfu.h | 108 +-- module_dfu/src/dfu.xc | 10 +- module_usb_audio/audio.xc | 373 +++++---- module_usb_audio/audiohw.h | 14 + module_usb_audio/audiostream/audiostream.h | 4 +- module_usb_audio/{clocking => }/clocking.h | 9 - module_usb_audio/codec/codec.h | 14 - module_usb_audio/devicedefines.h | 1 - module_usb_audio/endpoint0/audiorequests.xc | 645 ++++++-------- module_usb_audio/endpoint0/descriptors_2.h | 94 ++- module_usb_audio/endpoint0/endpoint0.xc | 877 +++++++------------- module_usb_audio/usb_buffer/usb_buffer.xc | 28 +- module_usb_audio/xuduser/xuduser.xc | 13 +- 13 files changed, 909 insertions(+), 1281 deletions(-) create mode 100644 module_usb_audio/audiohw.h rename module_usb_audio/{clocking => }/clocking.h (66%) delete mode 100644 module_usb_audio/codec/codec.h diff --git a/module_dfu/src/dfu.h b/module_dfu/src/dfu.h index 5dc57e05..dcad54c3 100644 --- a/module_dfu/src/dfu.h +++ b/module_dfu/src/dfu.h @@ -53,27 +53,27 @@ unsigned char DFUdevDesc[] = { }; unsigned char DFUcfgDesc[] = { - /* Standard USB device descriptor */ - 0x09, /* 0 bLength */ - CONFIGURATION, /* 1 bDescriptorType */ - 0x1b, /* 2 wTotalLength */ - 0x00, /* 3 wTotalLength */ - 1, /* 4 bNumInterface: Number of interfaces*/ - 0x01, /* 5 bConfigurationValue */ - 0x00, /* 6 iConfiguration */ - 0xC0, /* 7 bmAttributes */ - 0x32, /* 8 bMaxPower */ + /* Standard USB device descriptor */ + 0x09, /* 0 bLength */ + USB_CONFIGURATION, /* 1 bDescriptorType */ + 0x1b, /* 2 wTotalLength */ + 0x00, /* 3 wTotalLength */ + 1, /* 4 bNumInterface: Number of interfaces*/ + 0x01, /* 5 bConfigurationValue */ + 0x00, /* 6 iConfiguration */ + 0xC0, /* 7 bmAttributes */ + 0x32, /* 8 bMaxPower */ /* Standard DFU class interface descriptor */ - 0x09, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */ - 0x04, /* 1 bDescriptorType : INTERFACE descriptor. (field size 1 bytes) */ - 0x00, /* 2 bInterfaceNumber : Index of this interface. (field size 1 bytes) */ - 0x00, /* 3 bAlternateSetting : Index of this setting. (field size 1 bytes) */ - 0x00, /* 4 bNumEndpoints : 0 endpoints. (field size 1 bytes) */ - 0xFE, /* 5 bInterfaceClass : AUDIO. (field size 1 bytes) */ - 0x01, /* 6 bInterfaceSubclass : AUDIO_CONTROL. (field size 1 bytes) */ - 0x02, /* 7 bInterfaceProtocol : Unused. (field size 1 bytes) */ - 0x00, /* 8 iInterface : Unused. (field size 1 bytes) */ + 0x09, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */ + 0x04, /* 1 bDescriptorType : INTERFACE descriptor. (field size 1 bytes) */ + 0x00, /* 2 bInterfaceNumber : Index of this interface. (field size 1 bytes) */ + 0x00, /* 3 bAlternateSetting : Index of this setting. (field size 1 bytes) */ + 0x00, /* 4 bNumEndpoints : 0 endpoints. (field size 1 bytes) */ + 0xFE, /* 5 bInterfaceClass : AUDIO. (field size 1 bytes) */ + 0x01, /* 6 bInterfaceSubclass : AUDIO_CONTROL. (field size 1 bytes) */ + 0x02, /* 7 bInterfaceProtocol : Unused. (field size 1 bytes) */ + 0x00, /* 8 iInterface : Unused. (field size 1 bytes) */ #if 0 /* DFU 1.0 Standard DFU class functional descriptor */ @@ -86,72 +86,22 @@ unsigned char DFUcfgDesc[] = { 0x00 #else /* DFU 1.1 Run-Time DFU Functional Descriptor */ - 0x09, /* 0 Size */ - 0x21, /* 1 bDescriptorType : DFU FUNCTIONAL */ - 0x07, /* 2 bmAttributes */ - 0xFA, /* 3 wDetachTimeOut */ - 0x00, /* 4 wDetachTimeOut */ - 0x40, /* 5 wTransferSize */ - 0x00, /* 6 wTransferSize */ - 0x10, /* 7 bcdDFUVersion */ - 0x01, /* 7 bcdDFUVersion */ + 0x09, /* 0 Size */ + 0x21, /* 1 bDescriptorType : DFU FUNCTIONAL */ + 0x07, /* 2 bmAttributes */ + 0xFA, /* 3 wDetachTimeOut */ + 0x00, /* 4 wDetachTimeOut */ + 0x40, /* 5 wTransferSize */ + 0x00, /* 6 wTransferSize */ + 0x10, /* 7 bcdDFUVersion */ + 0x01, /* 7 bcdDFUVersion */ #endif }; -unsigned char DFUoSpeedCfgDesc[] = -{ - /* Standard USB device descriptor */ - 0x09, /* 0 bLength */ - OTHER_SPEED_CONFIGURATION, /* 1 bDescriptorType */ - 0x1b, /* 2 wTotalLength */ - 0x00, /* 3 wTotalLength */ - 1, /* 4 bNumInterface: Number of interfaces*/ - 0x01, /* 5 bConfigurationValue */ - 0x00, /* 6 iConfiguration */ - 0xC0, /* 7 bmAttributes */ - 0x32, /* 8 bMaxPower */ - - /* Standard DFU class interface descriptor */ - 0x09, /* 0 bLength : Size of this descriptor, in bytes. (field size 1 bytes) */ - 0x04, /* 1 bDescriptorType : INTERFACE descriptor. (field size 1 bytes) */ - 0x00, /* 2 bInterfaceNumber : Index of this interface. (field size 1 bytes) */ - 0x00, /* 3 bAlternateSetting : Index of this setting. (field size 1 bytes) */ - 0x00, /* 4 bNumEndpoints : 0 endpoints. (field size 1 bytes) */ - 0xFE, /* 5 bInterfaceClass : AUDIO. (field size 1 bytes) */ - 0x01, /* 6 bInterfaceSubclass : AUDIO_CONTROL. (field size 1 bytes) */ - 0x02, /* 7 bInterfaceProtocol : Unused. (field size 1 bytes) */ - 0x00, /* 8 iInterface : Unused. (field size 1 bytes) */ - - /* DFU 1.1 Run-Time DFU Functional Descriptor */ - 0x09, /* 0 Size */ - 0x21, /* 1 bDescriptorType : DFU FUNCTIONAL */ - 0x07, /* 2 bmAttributes */ - 0xFA, /* 3 wDetachTimeOut */ - 0x00, /* 4 wDetachTimeOut */ - 0x40, /* 5 wTransferSize */ - 0x00, /* 6 wTransferSize */ - 0x10, /* 7 bcdDFUVersion */ - 0x01, /* 7 bcdDFUVersion */ -}; - -unsigned char DFUdevQualDesc[] = -{ - 10, /* 0 bLength : Size of descriptor in Bytes (18 Bytes) */ - DEVICE_QUALIFIER, /* 1 bdescriptorType */ - 0, /* 2 bcdUSB */ - 2, /* 3 bcdUSB */ - 0xfe, /* 4 bDeviceClass */ - 1, /* 5 bDeviceSubClass */ - 0, /* 6 bDeviceProtocol */ - 64, /* 7 bMaxPacketSize */ - 0x01, /* 8 bNumConfigurations : Number of possible configs */ \ - 0x00 /* 9 bReserved (must be zero) */ \ -}; - int DFUReportResetState(chanend ?c_user_cmd); -int DFUDeviceRequests(XUD_ep c_ep0_out, XUD_ep &?ep0_in, SetupPacket &sp, chanend ?c_user_cmd, unsigned int altInterface, unsigned int user_reset); +int DFUDeviceRequests(XUD_ep c_ep0_out, XUD_ep &?ep0_in, USB_SetupPacket_t &sp, chanend ?c_user_cmd, unsigned int altInterface, unsigned int user_reset); diff --git a/module_dfu/src/dfu.xc b/module_dfu/src/dfu.xc index afabe9f3..8bb1c90d 100644 --- a/module_dfu/src/dfu.xc +++ b/module_dfu/src/dfu.xc @@ -390,14 +390,14 @@ int XMOS_DFU_LoadState() return 0; } -int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, SetupPacket &sp, chanend ?c_user_cmd, unsigned int altInterface, unsigned int user_reset) +int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, USB_SetupPacket_t &sp, chanend ?c_user_cmd, unsigned int altInterface, unsigned int user_reset) { unsigned int return_data_len = 0; unsigned int data_buffer_len = 0; unsigned int data_buffer[17]; unsigned int reset_device_after_ack = 0; - if(sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_OUT) + if(sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_H2D) { // Host to device if (sp.wLength) @@ -465,7 +465,7 @@ int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, SetupPacket &sp, chanend break; } - if (sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_IN && sp.wLength != 0) + if (sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_D2H && sp.wLength != 0) { // Device to host #ifdef ARCH_G @@ -477,9 +477,9 @@ int DFUDeviceRequests(XUD_ep ep0_out, XUD_ep &?ep0_in, SetupPacket &sp, chanend else { #ifdef ARCH_G - XUD_DoSetRequestStatus(ep0_out, 0); + XUD_DoSetRequestStatus(ep0_out); #else - XUD_DoSetRequestStatus(ep0_in, 0); + XUD_DoSetRequestStatus(ep0_in); #endif } diff --git a/module_usb_audio/audio.xc b/module_usb_audio/audio.xc index 315f35f2..2beb578b 100755 --- a/module_usb_audio/audio.xc +++ b/module_usb_audio/audio.xc @@ -14,12 +14,14 @@ #include #include -#include "clocking.h" #include "audioports.h" -#include "codec.h" +#include "audiohw.h" #include "devicedefines.h" #include "SpdifTransmit.h" +//#define DSD_OUTPUT 1 + + unsigned g_adcVal = 0; //#define RAMP_CHECK 1 @@ -30,18 +32,6 @@ unsigned g_adcVal = 0; //#pragma xta command "analyse path i2s_output_r i2s_output_l" //#pragma xta command "set required - 2000 ns" -#define DSD_OVER_PCM 1 -#ifdef DSD_OVER_PCM -unsigned dopMarkerCount = 0; -#define DOP_MARKER_1 0x05 -#define DOP_MARKER_2 0xFA -#define DOP_MARKER_XOR 0xFF -#define DOP_MARKER_THRESH 32 /* How many DSD markers we must see before switching to DSD mode */ -#define DSD_MASK_IN(x) ((x & 0xFF000000) >> 24) - -unsigned dopMarker = DOP_MARKER_1; -#endif - /* I2S Data I/O*/ #if (I2S_CHANS_DAC != 0) extern buffered out port:32 p_i2s_dac[I2S_WIRES_DAC]; @@ -60,26 +50,35 @@ extern in port p_lrclk; extern in port p_bclk; #endif +unsigned dsdMode = 0; +#ifdef DSD_OUTPUT +#define p_dsd_clk p_i2s_dac[1] +#define p_dsd_left p_i2s_dac[0] +#define p_dsd_right p_lrclk +#define DSD_MARKER_1 0xFA +#define DSD_MARKER_2 0x05 +#define DSD_MARKER_XOR 0xFF +#define DSD_EN_THRESH 32 /* Number of consecutive DSD markers before switching to DSD mode */ +#define DSD_MASK(x) ((x >> 24) & 0xff) +#endif + + /* Master clock input */ extern port p_mclk; #ifdef SPDIF extern buffered out port:32 p_spdif_tx; -extern clock clk_mst_spd; #endif extern clock clk_audio_mclk; extern clock clk_audio_bclk; +extern clock clk_mst_spd; extern void device_reboot(void); /* I2S delivery thread */ #pragma unsafe arrays -unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_dig_rx, chanend ?c_adc -#ifdef DSD_OVER_PCM -, int dop -#endif -) +unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_dig_rx, chanend ?c_adc) { unsigned sample; #if NUM_USB_CHAN_OUT > 0 @@ -98,7 +97,13 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_ int started = 0; #endif - int dsdmode = 0; +#ifdef DSD_OUTPUT + unsigned dsdMarker = DSD_MARKER_2; /* This alternates between DSD_MARKER_1 and DSD_MARKER_2 */ + int dsdCount = 0; + int everyOther = 0; + unsigned dsdSample_l = 0; + unsigned dsdSample_r = 0; +#endif #if NUM_USB_CHAN_IN > 0 @@ -218,7 +223,7 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_ #endif p_lrclk <: 0x7FFFFFFF; - p_bclk <: 0xAAAAAAAA; + p_bclk <: 0xAAAAAAAA;//32clks p_bclk <: 0xAAAAAAAA; } #else @@ -322,57 +327,101 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_ asm("ldw %0, dp[g_digData+36]":"=r"(samplesIn[ADAT_RX_INDEX + 7])); #endif -#ifdef DSD_OVER_PCM - /* Inspect for DSD markers */ - if((DSD_MASK_IN(samplesOut[0]) == dopMarker) && (DSD_MASK_IN(samplesOut[1]) == dopMarker)) - { - dopMarker ^= DOP_MARKER_XOR; - - dopMarkerCount++; - - if(!dsdmode) - { - if(dopMarkerCount >= DOP_MARKER_THRESH) - { - dopMarkerCount=0; - dopMarker ^= DOP_MARKER_XOR; - printstr("DSD\n"); - dsdmode = 1; - //return 0; - } - } - } - else - { - /* Reset DOP detect state */ - dopMarkerCount = 0; - if(dsdmode) - { - //if(samplesOut[0] == 0) - //else - if(DSD_MASK_IN(samplesOut[0]) == (dopMarker ^ 0xff)) - { - printstr("almost stopped"); - //dopMarker ^= 0xff; - } - else - { - /* We were running in DOP mode, but it stopped... */ - //return 0; - dsdmode = 0; - printstr("PCM\n"); - } - } - } -#endif - #if defined(SPDIF_RX) || defined(ADAT_RX) /* Request digital data (with prefill) */ outuint(c_dig_rx, 0); #endif tmp = 0; +#ifdef DSD_OUTPUT +#error + if(dsdMode) + { + //while(1) + { + if(!everyOther) + { + dsdSample_l = ((samplesOut[0] & 0xffff00) << 8); + dsdSample_r = ((samplesOut[1] & 0xffff00) << 8); + + everyOther = 1; + + switch (divide*4) + { + case 8: + p_bclk <: 0xF0F0F0F0; + p_bclk <: 0xF0F0F0F0; + p_bclk <: 0xF0F0F0F0; + p_bclk <: 0xF0F0F0F0; + //p_bclk <: 0xF0F0F0F0; + //p_bclk <: 0xF0F0F0F0; + //p_bclk <: 0xF0F0F0F0; + //p_bclk <: 0xF0F0F0F0; + break; + + case 4: + p_bclk <: 0xCCCCCCCC; + p_bclk <: 0xCCCCCCCC; + //p_bclk <: 0xCCCCCCCC; + //p_bclk <: 0xCCCCCCCC; + break; + + case 2: + //p_bclk <: 0xAAAAAAAA; + p_bclk <: 0xAAAAAAAA; + break; + case 1: + break; + } + } + else if(everyOther) + { + everyOther = 0; + dsdSample_l = dsdSample_l | ((samplesOut[0] & 0xffff00) >> 8); + dsdSample_r = dsdSample_r | ((samplesOut[1] & 0xffff00) >> 8); + + + // Output 16 clocks DSD to all + p_dsd_left <: bitrev(dsdSample_l); + p_dsd_right <: bitrev(dsdSample_r); + switch (divide*4) + { + case 8: + p_bclk <: 0xF0F0F0F0; + p_bclk <: 0xF0F0F0F0; + p_bclk <: 0xF0F0F0F0; + p_bclk <: 0xF0F0F0F0; + //p_bclk <: 0xF0F0F0F0; + //p_bclk <: 0xF0F0F0F0; + //p_bclk <: 0xF0F0F0F0; + //p_bclk <: 0xF0F0F0F0; + break; + + case 4: + p_bclk <: 0xCCCCCCCC; + p_bclk <: 0xCCCCCCCC; + //p_bclk <: 0xCCCCCCCC; + //p_bclk <: 0xCCCCCCCC; + break; + + case 2: + //p_bclk <: 0xAAAAAAAA; + p_bclk <: 0xAAAAAAAA; + break; + case 1: + break; + } + + } + } + } + else +#endif + { + + #pragma xta endpoint "i2s_output_l" + #if (I2S_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT != 0) #pragma loop unroll for(int i = 0; i < I2S_CHANS_DAC; i+=2) @@ -439,13 +488,11 @@ unsigned deliver(chanend c_out, chanend ?c_spd_out, unsigned divide, chanend ?c_ #endif } #endif - -#if defined(SPDIF) && (NUM_USB_CHAN_OUT > 0) -if(!dop) -{ outuint(c_spd_out, samplesOut[SPDIF_TX_INDEX]); /* Forward sample to SPDIF txt thread */ + + #if defined(SPDIF) && (NUM_USB_CHAN_OUT > 0) + outuint(c_spd_out, samplesOut[SPDIF_TX_INDEX]); /* Forward sample to SPDIF txt thread */ sample = samplesOut[SPDIF_TX_INDEX + 1]; outuint(c_spd_out, sample); /* Forward sample to SPDIF txt thread */ -} #ifdef RAMP_CHECK sample >>= 8; if (started<10000) { @@ -461,8 +508,7 @@ if(!dop) prev = sample; #endif -#endif - +#endif tmp = 0; #pragma xta endpoint "i2s_output_r" #if (I2S_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT != 0) @@ -512,8 +558,6 @@ if(!dop) } #endif - - #if (I2S_CHANS_ADC != 0) /* Input previous L ADC sample */ @@ -538,6 +582,48 @@ if(!dop) } #endif #endif + + } // !dsdMode +#if defined (DSD_OUTPUT) && (NUM_USB_CHAN_OUT > 0) +#error + /* Check for DSD */ + /* Currently we only check on channel 0 - we get all 0's on channels without data */ + + if(!dsdMode) + { + if((DSD_MASK(samplesOut[0]) == dsdMarker) && (DSD_MASK(samplesOut[1]) == dsdMarker)) + { + dsdCount++; + dsdMarker ^= DSD_MARKER_XOR; + if(dsdCount == DSD_EN_THRESH) + { + dsdMode = 1; + dsdCount = 0; + dsdMarker = DSD_MARKER_2; + return 0; + } + } + else + { + dsdCount = 0; + dsdMarker = DSD_MARKER_2; + } + } + else // DSD Mode + { + if((DSD_MASK(samplesOut[0]) != dsdMarker) && (DSD_MASK(samplesOut[1]) != dsdMarker)) + { + if(!((dsdCount == 0) && (DSD_MASK(samplesOut[0]) == (dsdMarker ^DSD_MARKER_XOR)) + && (DSD_MASK(samplesOut[1]) == (dsdMarker ^ DSD_MARKER_XOR)))) + { + dsdCount = 0; + dsdMode = 0; + return 0; + } + } + } +#endif + } return 0; } @@ -601,12 +687,10 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c) chan c_spdif_out; #endif unsigned curSamFreq = DEFAULT_FREQ; + unsigned retVal; unsigned mClk; unsigned divide; unsigned firstRun = 1; -#ifdef DSD_OVER_PCM - unsigned dop = 0; -#endif #ifdef SU1_ADC_ENABLE /* Setup galaxian ADC */ @@ -646,112 +730,92 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c) #endif /* Initialise master clock generation */ - ClockingInit(c_config); + //ClockingInit(c_config); /* Perform required CODEC/ADC/DAC initialisation */ - CodecInit(c_config); + AudioHwInit(c_config); while(1) { - - if(curSamFreq) + /* Calculate what master clock we should be using */ + if ((curSamFreq % 22050) == 0) { + mClk = MCLK_441; + } + else if ((curSamFreq % 24000) == 0) + { + mClk = MCLK_48; + } + + /* Calculate divide required for bit clock e.g. 11.289600 / (176400 * 64) = 1 */ + divide = mClk / ( curSamFreq * 64 ); + + /* Configure clocking for required master clock */ + //ClockingConfig(mClk, c_config); + + /* Configure CODEC/DAC/ADC for SampleFreq/MClk */ + AudioHwConfig(curSamFreq, mClk, c_config, dsdMode); + + /* Configure audio ports */ + ConfigAudioPorts(divide); + + if(!firstRun) + { + /* TODO wait for good mclk instead of delay */ + /* No delay for DFU modes */ + if ((curSamFreq != AUDIO_REBOOT_FROM_DFU) && (curSamFreq != AUDIO_STOP_FOR_DFU) && retVal) + { + timer t; + unsigned time; + t :> time; + t when timerafter(time+AUDIO_PLL_LOCK_DELAY) :> void; + + /* Handshake back */ + outct(c_mix_out, XS1_CT_END); + } + } + firstRun = 0; - /* Calculate what master clock we should be using */ - if ((curSamFreq % 22050) == 0) - { - mClk = MCLK_441; - } - else if ((curSamFreq % 24000) == 0) - { - mClk = MCLK_48; - } - /* Calculate divide required for bit clock e.g. 11.289600 / (176400 * 64) = 1 */ - divide = mClk / ( curSamFreq * 64 ); - - /* Configure clocking for required master clock */ - ClockingConfig(mClk, c_config); - - if(!firstRun) - { - /* TODO wait for good mclk instead of delay */ - /* No delay for DFU modes */ - if ((curSamFreq != AUDIO_REBOOT_FROM_DFU) && (curSamFreq != AUDIO_STOP_FOR_DFU)) - { - timer t; - unsigned time; - t :> time; - t when timerafter(time+AUDIO_PLL_LOCK_DELAY) :> void; - - /* Handshake back */ - outct(c_mix_out, XS1_CT_END); - } - } - firstRun = 0; - - /* Configure CODEC/DAC/ADC for SampleFreq/MClk */ - CodecConfig(curSamFreq, mClk, c_config); - - /* Configure audio ports */ - ConfigAudioPorts(divide); - } - else - { - if(!dop) - { - /* DOP detected! */ - printstrln("DOP Detect"); - dop = 1; - /* TODO: - * Config ports for DSD - * Config CODEC for DSD - */ - } - else - { - /* DOP mode end */ - printstrln("DOP end"); - dop = 0; - } - } par { #ifdef SPDIF - - { - if(!dop) - { - set_thread_fast_mode_on(); - SpdifTransmit(p_spdif_tx, c_spdif_out); - } + set_thread_fast_mode_on(); + SpdifTransmit(p_spdif_tx, c_spdif_out); } #endif { #ifdef SPDIF - if(!dop) - { /* Communicate master clock and sample freq to S/PDIF thread */ outuint(c_spdif_out, curSamFreq); outuint(c_spdif_out, mClk); - } #endif - curSamFreq = deliver(c_mix_out, + retVal = deliver(c_mix_out, #ifdef SPDIF c_spdif_out, #else null, #endif - divide, c_dig_rx, c -#ifdef DSD_OVER_PCM - , dop + divide, c_dig_rx, c); + +#ifdef DSD_OUTPUT + if(retVal == 0) + { + // Check DSD mode here.. + } + else + { + curSamFreq = retVal; + } + +#else + curSamFreq = retVal; #endif - ); // Currently no more audio will happen after this point if (curSamFreq == AUDIO_STOP_FOR_DFU) @@ -773,7 +837,6 @@ void audio(chanend c_mix_out, chanend ?c_dig_rx, chanend ?c_config, chanend ?c) #ifdef SPDIF /* Notify S/PDIF thread of impending new freq... */ - if(!dop) outct(c_spdif_out, XS1_CT_END); #endif } diff --git a/module_usb_audio/audiohw.h b/module_usb_audio/audiohw.h new file mode 100644 index 00000000..4efe8e33 --- /dev/null +++ b/module_usb_audio/audiohw.h @@ -0,0 +1,14 @@ +#ifndef _CODEC_H_ +#define _CODEC_H_ + +/* These functions must be implemented for the CODEC/ADC/DAC arrangement of a specific design */ + +/* TODO Are the channel args required? */ + +/* Any required clocking and CODEC initialisation - run once at start up */ +void AudioHwInit(chanend ?c_codec); + +/* Configure audio hardware (clocking, CODECs etc) for a specific mClk/Sample frquency - run on every sample frequency change */ +void AudioHwConfig(unsigned samFreq, unsigned mClk, chanend ?c_codec, int dsdMode); + +#endif diff --git a/module_usb_audio/audiostream/audiostream.h b/module_usb_audio/audiostream/audiostream.h index 8c9862a7..1eb9ed5f 100644 --- a/module_usb_audio/audiostream/audiostream.h +++ b/module_usb_audio/audiostream/audiostream.h @@ -8,10 +8,10 @@ * */ /* Any actions required for stream start e.g. DAC un-mute - run every stream start */ -void AudioStreamStart(void); +void UserAudioStreamStart(void); /* Any actions required on stream stop e.g. DAC mute - run every steam stop */ -void AudioStreamStop(void); +void UserAudioStreamStop(void); #endif diff --git a/module_usb_audio/clocking/clocking.h b/module_usb_audio/clocking.h similarity index 66% rename from module_usb_audio/clocking/clocking.h rename to module_usb_audio/clocking.h index a02ebf15..cd6e7a71 100644 --- a/module_usb_audio/clocking/clocking.h +++ b/module_usb_audio/clocking.h @@ -2,15 +2,6 @@ #ifndef _CLOCKING_H_ #define _CLOCKING_H_ -/* Functions that handle master clock generation. These need modifying for an existing design */ - -/* Any initialisation required for master clock generation - run once at start up */ -void ClockingInit(chanend ?c); - -/* Configuration for a specific master clock frequency - run every sample frequency change */ -void ClockingConfig(unsigned mClkFreq, chanend ?c); - - /** Clock generation and digital audio I/O handling. * * \param c_spdif_rx channel connected to S/PDIF receive thread diff --git a/module_usb_audio/codec/codec.h b/module_usb_audio/codec/codec.h deleted file mode 100644 index 452ac900..00000000 --- a/module_usb_audio/codec/codec.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _CODEC_H_ -#define _CODEC_H_ - -/* These functions must be implemented for the CODEC/ADC/DAC arrangement of a specific design */ - -/* TODO Are the channel args required? */ - -/* Any required CODEC initialisation - run once at start up */ -void CodecInit(chanend ?c_codec); - -/* Configure condec for a specific mClk/Sample frquency - run on every sample frequency change */ -void CodecConfig(unsigned samFreq, unsigned mClk, chanend ?c_codec); - -#endif diff --git a/module_usb_audio/devicedefines.h b/module_usb_audio/devicedefines.h index 19525da1..a88bcdf5 100644 --- a/module_usb_audio/devicedefines.h +++ b/module_usb_audio/devicedefines.h @@ -1,5 +1,4 @@ /** - * @file internaldefines.h * @brief Defines relating to device configuration and customisation. * @author Ross Owen, XMOS Limited */ diff --git a/module_usb_audio/endpoint0/audiorequests.xc b/module_usb_audio/endpoint0/audiorequests.xc index d5111db6..0aed6405 100644 --- a/module_usb_audio/endpoint0/audiorequests.xc +++ b/module_usb_audio/endpoint0/audiorequests.xc @@ -7,6 +7,7 @@ #include "xud.h" #include "usb.h" #include "usbaudio20.h" +#include "usbaudio10.h" #include "dbcalc.h" #include "devicedefines.h" #include "clockcmds.h" @@ -70,13 +71,13 @@ void storeShort(unsigned char buffer[], int index, short val) void storeFreq(unsigned char buffer[], int &i, int freq) { - storeInt(buffer, i, freq); - i+=4; - storeInt(buffer, i, freq); - i+=4; - storeInt(buffer, i, 0); - i+=4; - return; + storeInt(buffer, i, freq); + i+=4; + storeInt(buffer, i, freq); + i+=4; + storeInt(buffer, i, 0); + i+=4; + return; } @@ -185,76 +186,57 @@ void updateVol(int unitID, int channel, chanend ?c_mix_ctl) { switch( unitID ) { - case FU_USBOUT: { - /* Calc multipliers with 29 fractional bits from a db value with 8 fractional bits */ - /* 0x8000 is a special value representing -inf (i.e. mute) */ - unsigned master_vol = volsOut[0] == 0x8000 ? 0 : db_to_mult(volsOut[0], 8, 29); - unsigned vol = volsOut[channel] == 0x8000 ? 0 : db_to_mult(volsOut[channel], 8, 29); + case FU_USBOUT: + { + /* Calc multipliers with 29 fractional bits from a db value with 8 fractional bits */ + /* 0x8000 is a special value representing -inf (i.e. mute) */ + unsigned master_vol = volsOut[0] == 0x8000 ? 0 : db_to_mult(volsOut[0], 8, 29); + unsigned vol = volsOut[channel] == 0x8000 ? 0 : db_to_mult(volsOut[channel], 8, 29); - x = longMul(master_vol, vol, 29) * !mutesOut[0] * !mutesOut[channel]; + x = longMul(master_vol, vol, 29) * !mutesOut[0] * !mutesOut[channel]; #ifdef OUT_VOLUME_IN_MIXER - if (!isnull(c_mix_ctl)) + if (!isnull(c_mix_ctl)) { - //master { - // c_mix_ctl <: SET_MIX_OUT_VOL; - // c_mix_ctl <: channel-1; - // /c_mix_ctl <: x; - //} - outuint(c_mix_ctl, SET_MIX_OUT_VOL); - outuint(c_mix_ctl, channel-1); - outuint(c_mix_ctl, x); - outct(c_mix_ctl, XS1_CT_END); - - } - - - + outuint(c_mix_ctl, SET_MIX_OUT_VOL); + outuint(c_mix_ctl, channel-1); + outuint(c_mix_ctl, x); + outct(c_mix_ctl, XS1_CT_END); + } #else asm("stw %0, %1[%2]"::"r"(x),"r"(p_multOut),"r"(channel-1)); #endif - - break; } - case FU_USBIN: { - /* Calc multipliers with 29 fractional bits from a db value with 8 fractional bits */ - /* 0x8000 is a special value representing -inf (i.e. mute) */ - unsigned master_vol = volsIn[0] == 0x8000 ? 0 : db_to_mult(volsIn[0], 8, 29); - unsigned vol = volsIn[channel] == 0x8000 ? 0 : db_to_mult(volsIn[channel], 8, 29); + case FU_USBIN: + { + /* Calc multipliers with 29 fractional bits from a db value with 8 fractional bits */ + /* 0x8000 is a special value representing -inf (i.e. mute) */ + unsigned master_vol = volsIn[0] == 0x8000 ? 0 : db_to_mult(volsIn[0], 8, 29); + unsigned vol = volsIn[channel] == 0x8000 ? 0 : db_to_mult(volsIn[channel], 8, 29); - x = longMul(master_vol, vol, 29) * !mutesIn[0] * !mutesIn[channel]; + x = longMul(master_vol, vol, 29) * !mutesIn[0] * !mutesIn[channel]; #ifdef IN_VOLUME_IN_MIXER - if (!isnull(c_mix_ctl)) { - //master { - // c_mix_ctl <: SET_MIX_IN_VOL; - // c_mix_ctl <: channel-1; - // c_mix_ctl <: x; - //} - outuint(c_mix_ctl, SET_MIX_IN_VOL); - outuint(c_mix_ctl, channel-1); - outuint(c_mix_ctl, x); - outct(c_mix_ctl, XS1_CT_END); - - - } + if (!isnull(c_mix_ctl)) + { + outuint(c_mix_ctl, SET_MIX_IN_VOL); + outuint(c_mix_ctl, channel-1); + outuint(c_mix_ctl, x); + outct(c_mix_ctl, XS1_CT_END); + } #else asm("stw %0, %1[%2]"::"r"(x),"r"(p_multIn),"r"(channel-1)); #endif - break; - } - default: - /* Don't hit - We hope */ - //"Vol: No such unit: unitID; break; + } } } } /* Handles the audio class specific requests - * returns: 0 if request delt with successfully without error, - * <0 for device reset suspend + * returns: 0 if request dealt with successfully without error, + * <0 for device reset * else 1 */ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl @@ -290,7 +272,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c case CS_SAM_FREQ_CONTROL: { /* Direction: Host-to-device */ - if( sp.bmRequestType.Direction == 0 ) + if(sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_H2D) { /* Get OUT data with Sample Rate into buffer*/ datalength = XUD_GetBuffer(ep0_out, buffer); @@ -303,7 +285,6 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c if(datalength == 4) { - /* Re-construct Sample Freq */ i_tmp = buffer[0] | (buffer[1] << 8) | buffer[2] << 16 | buffer[3] << 24; @@ -342,8 +323,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c } /* Send 0 Length as status stage */ - return XUD_SetBuffer(ep0_in, buffer, 0); - + XUD_DoSetRequestStatus(ep0_in); } /* Direction: Device-to-host: Send Current Sample Freq */ else @@ -352,7 +332,6 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c { case ID_CLKSRC_EXT: case ID_CLKSRC_ADAT: - #ifdef REPORT_SPDIF_FREQ /* Interogate clockgen thread for SPDIF freq */ if (!isnull(c_clk_ctl)) @@ -360,30 +339,29 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c outuint(c_clk_ctl, GET_FREQ); outuint(c_clk_ctl, CLOCK_SPDIF_INDEX); outct(c_clk_ctl, XS1_CT_END); - (buffer, unsigned[])[0] = inuint(c_clk_ctl); chkct(c_clk_ctl, XS1_CT_END); + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 4, sp.wLength ); } else { - (buffer, unsigned[])[0] = g_curSamFreq; + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 4, sp.wLength ); } break; #endif case ID_CLKSRC_INT: - /* Always report our current operating frequency */ (buffer, unsigned[])[0] = g_curSamFreq; + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 4, sp.wLength ); break; default: - // XUD_Error_hex("Unknown Unit ID in Sample Frequency Control Request", unitID); + /* Unknown Unit ID in Sample Frequency Control Request: unitID */ break; } - return XUD_DoGetRequest(ep0_out, ep0_in, buffer, sp.wLength, sp.wLength ); } break; } @@ -397,6 +375,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c /* Internal clock always valid */ buffer[0] = 1; + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 1, sp.wLength); break; case ID_CLKSRC_EXT: @@ -409,6 +388,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c outct(c_clk_ctl, XS1_CT_END); buffer[0] = inuint(c_clk_ctl); chkct(c_clk_ctl, XS1_CT_END); + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 1, sp.wLength); } break; @@ -422,23 +402,19 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c outct(c_clk_ctl, XS1_CT_END); buffer[0] = inuint(c_clk_ctl); chkct(c_clk_ctl, XS1_CT_END); + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 1, sp.wLength); } - - break; default: - //XUD_Error_hex("Unknown Unit ID in Clock Valid Control Request: ", unitID); + //Unknown Unit ID in Clock Valid Control Request break; } - - return XUD_DoGetRequest( ep0_out, ep0_in, buffer, sp.wLength, sp.wLength ); - break; } default: - //XUD_Error_hex("Unknown Control Selector for Clock Unit: ", sp.wValue >> 8 ); + //Unknown Control Selector for Clock Unit: sp.wValue >> 8 break; } @@ -450,9 +426,9 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c { if ((sp.wValue >> 8) == CX_CLOCK_SELECTOR_CONTROL) { - if( sp.bmRequestType.Direction == 0 ) + /* Direction: Host-to-device */ + if(sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_H2D ) { - /* Direction: Host-to-device */ datalength = XUD_GetBuffer(ep0_out, buffer); if(datalength < 0) @@ -461,24 +437,21 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c /* Check for correct datalength for clock sel */ if(datalength == 1) { - if (!isnull(c_clk_ctl)) { outuint(c_clk_ctl, SET_SEL); outuint(c_clk_ctl, buffer[0]); outct(c_clk_ctl, XS1_CT_END); } + /* Send 0 Length as status stage */ + return XUD_DoSetRequestStatus(ep0_in); } - /* Send 0 Length as status stage */ - return XUD_DoSetRequestStatus(ep0_in); } else { - buffer[0] = 1; - /* Direction: Device-to-host: Send Current Selection */ - + buffer[0] = 1; if (!isnull(c_clk_ctl)) { outuint(c_clk_ctl, GET_SEL); @@ -486,14 +459,10 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c buffer[0] = inuint(c_clk_ctl); chkct(c_clk_ctl, XS1_CT_END); } - return XUD_DoGetRequest( ep0_out, ep0_in, buffer, 1, sp.wLength ); + } } - else - { - //Unknown control on clock selector: sp.wValue - } break; } @@ -506,79 +475,61 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c { case FU_VOLUME_CONTROL: - if(sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_OUT) /* Direction: Host-to-device */ + if(sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_H2D) { - - /* Expect OUT here (with v2yyolume) */ + /* Expect OUT here (with volume) */ loop = XUD_GetBuffer(ep0_out, buffer); - /* Check for rst/suspend */ + /* Check for reset */ if(loop < 0) - { - printintln(loop); return loop; - } -#if 1 if(unitID == FU_USBOUT) { - if ((sp.wValue & 0xff) <= NUM_USB_CHAN_OUT) { - volsOut[ sp.wValue&0xff ] = buffer[0] | (((int) (signed char) buffer[1]) << 8); - updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl ); - } + if ((sp.wValue & 0xff) <= NUM_USB_CHAN_OUT) + { + volsOut[ sp.wValue&0xff ] = buffer[0] | (((int) (signed char) buffer[1]) << 8); + updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl ); + return XUD_DoSetRequestStatus(ep0_in); + } } else { - if ((sp.wValue & 0xff) <= NUM_USB_CHAN_IN) { - volsIn[ sp.wValue&0xff ] = buffer[0] | (((int) (signed char) buffer[1]) << 8); - updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl ); - } + if ((sp.wValue & 0xff) <= NUM_USB_CHAN_IN) + { + volsIn[ sp.wValue&0xff ] = buffer[0] | (((int) (signed char) buffer[1]) << 8); + updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl ); + return XUD_DoSetRequestStatus(ep0_in); + } } -#endif - - /* Send 0 Length as status stage */ - return XUD_DoSetRequestStatus(ep0_in); } else /* Direction: Device-to-host */ { if(unitID == FU_USBOUT) { - if ((sp.wValue & 0xff) <= NUM_USB_CHAN_OUT) { - buffer[0] = volsOut[ sp.wValue&0xff ]; - buffer[1] = volsOut[ sp.wValue&0xff ] >> 8; - } - else { - buffer[0] = buffer[1] = 0; - } + if ((sp.wValue & 0xff) <= NUM_USB_CHAN_OUT) + { + buffer[0] = volsOut[ sp.wValue&0xff ]; + buffer[1] = volsOut[ sp.wValue&0xff ] >> 8; + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 2, sp.wLength); + } } else { - if ((sp.wValue & 0xff) <= NUM_USB_CHAN_IN) { - buffer[0] = volsIn[ sp.wValue&0xff ]; - buffer[1] = volsIn[ sp.wValue&0xff ] >> 8; - } - else { - buffer[0] = buffer[1] = 0; - } + if ((sp.wValue & 0xff) <= NUM_USB_CHAN_IN) + { + buffer[0] = volsIn[ sp.wValue&0xff ]; + buffer[1] = volsIn[ sp.wValue&0xff ] >> 8; + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 2, sp.wLength); + } } - return XUD_DoGetRequest(ep0_out, ep0_in, buffer, sp.wLength, sp.wLength); } break; /* FU_VOLUME_CONTROL */ case FU_MUTE_CONTROL: - if(sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_OUT) // Direction: Host-to-device + if(sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_H2D) { - - - { - unsigned time; - timer t; - t :> time; - t when timerafter(time+10000000):> void; - - } - /* Expect OUT here with mute */ loop = XUD_GetBuffer(ep0_out, buffer); @@ -587,41 +538,46 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c if (unitID == FU_USBOUT) { - if ((sp.wValue & 0xff) <= NUM_USB_CHAN_OUT) { - mutesOut[sp.wValue & 0xff] = buffer[0]; - updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl); - } + if ((sp.wValue & 0xff) <= NUM_USB_CHAN_OUT) + { + mutesOut[sp.wValue & 0xff] = buffer[0]; + updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl); + return XUD_DoSetRequestStatus(ep0_in); + } } else { - mutesIn[ sp.wValue&0xff ] = buffer[0]; - updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl); + if((sp.wValue & 0xff) <= NUM_USB_CHAN_IN) + { + mutesIn[ sp.wValue&0xff ] = buffer[0]; + updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl); + return XUD_DoSetRequestStatus(ep0_in); + } } - - /* Send 0 Length as status stage */ - return XUD_DoSetRequestStatus(ep0_in); } else // Direction: Device-to-host { if(unitID == FU_USBOUT) { - if ((sp.wValue & 0xff) <= NUM_USB_CHAN_OUT) { - buffer[0] = mutesOut[sp.wValue&0xff]; - } - else { - buffer[0] = 0; - } + if ((sp.wValue & 0xff) <= NUM_USB_CHAN_OUT) + { + buffer[0] = mutesOut[sp.wValue&0xff]; + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, sp.wLength, sp.wLength); + } } else { - buffer[0] = mutesIn[ sp.wValue&0xff ]; + if((sp.wValue & 0xff) <= NUM_USB_CHAN_IN) + { + buffer[0] = mutesIn[ sp.wValue&0xff ]; + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, sp.wLength, sp.wLength); + } } - return XUD_DoGetRequest(ep0_out, ep0_in, buffer, sp.wLength, sp.wLength); } break; default: - // Unknown Control Selector for FU + // Unknown Control Selector for FU break; } @@ -630,7 +586,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c #ifdef MIXER case ID_XU_OUT: { - if(sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_OUT) /* Direction: Host-to-device */ + if(sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_H2D) /* Direction: Host-to-device */ { unsigned volume = 0; int c = sp.wValue & 0xff; @@ -646,21 +602,15 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c { if (c < NUM_USB_CHAN_OUT) { - //master { - // c_mix_ctl <: SET_SAMPLES_TO_DEVICE_MAP; - // c_mix_ctl <: c; - // c_mix_ctl <: (int) channelMapAud[c]; - //} outuint(c_mix_ctl, SET_SAMPLES_TO_DEVICE_MAP); outuint(c_mix_ctl, c); outuint(c_mix_ctl, channelMapAud[c]); outct(c_mix_ctl, XS1_CT_END); - + /* Send 0 Length as status stage */ + return XUD_DoSetRequestStatus(ep0_in); } } - /* Send 0 Length as status stage */ - return XUD_DoSetRequestStatus(ep0_in); } else { @@ -674,8 +624,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c break; case ID_XU_IN: - { - if(sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_OUT) /* Direction: Host-to-device */ + if(sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_H2D) /* Direction: Host-to-device */ { unsigned volume = 0; int c = sp.wValue & 0xff; @@ -687,41 +636,30 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c channelMapUsb[c] = buffer[0] | buffer[1] << 8; - if (!isnull(c_mix_ctl)) + if (c < NUM_USB_CHAN_IN) { - if (c < NUM_USB_CHAN_IN) + if (!isnull(c_mix_ctl)) { - //master { - // c_mix_ctl <: SET_SAMPLES_TO_HOST_MAP; - // c_mix_ctl <: c; - // c_mix_ctl <: (int) channelMapUsb[c]; - //} outuint(c_mix_ctl, SET_SAMPLES_TO_HOST_MAP); outuint(c_mix_ctl, c); outuint(c_mix_ctl, channelMapUsb[c]); outct(c_mix_ctl, XS1_CT_END); - + return XUD_DoSetRequestStatus(ep0_in); } } - - /* Send 0 Length as status stage */ - return XUD_DoSetRequestStatus(ep0_in); } else { + /* Direction: Device-to-host */ buffer[0] = channelMapUsb[sp.wValue & 0xff]; buffer[1] = 0; - return XUD_DoGetRequest(ep0_out, ep0_in, buffer, sp.wLength, sp.wLength); } - - } break; - case ID_XU_MIXSEL: { - int cs = sp.wValue >> 8; /* Control Selector */ + int cs = sp.wValue >> 8; /* Control Selector */ int cn = sp.wValue & 0xff; /* Channel number */ /* Check for Get or Set */ @@ -730,12 +668,10 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c /* Direction: Host-to-device */ /* Host-to-device */ datalength = XUD_GetBuffer(ep0_out, buffer); - /* Check for reset/suspend */ + /* Check for reset */ if(datalength < 0) - { return datalength; - } - + if(datalength > 0) { /* cn bounds check for safety..*/ @@ -758,15 +694,10 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c outuint(c_mix_ctl, (int) mixSel[cn]); /* Source */ outct(c_mix_ctl, XS1_CT_END); } + return XUD_DoSetRequestStatus(ep0_in); } } - } - - /* Send 0 Length as status stage */ - return XUD_DoSetRequestStatus(ep0_in); - - } else { @@ -780,12 +711,9 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c if(cs == CS_XU_MIXSEL) { buffer[0] = mixSel[cn]; + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 1, 1 ); } } - - return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 1, 1 ); - - } break; } @@ -795,34 +723,29 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c if(sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_OUT) /* Direction: Host-to-device */ { unsigned volume = 0; + /* Expect OUT here with mute */ loop = XUD_GetBuffer(ep0_out, buffer); - if(loop < 0) return loop; mixer1Weights[sp.wValue & 0xff] = buffer[0] | buffer[1] << 8; - if (mixer1Weights[sp.wValue & 0xff] == 0x8000) { - volume = 0; + if (mixer1Weights[sp.wValue & 0xff] == 0x8000) + { + volume = 0; } - else { - volume = db_to_mult(mixer1Weights[sp.wValue & 0xff], 8, 25); + else + { + volume = db_to_mult(mixer1Weights[sp.wValue & 0xff], 8, 25); } if (!isnull(c_mix_ctl)) { - //master { - // c_mix_ctl <: SET_MIX_MULT; - //c_mix_ctl <: (sp.wValue & 0xff) % 8; - //c_mix_ctl <: (sp.wValue & 0xff) / 8; - ///c_mix_ctl <: volume; - //}/ outuint(c_mix_ctl, SET_MIX_MULT); outuint(c_mix_ctl, (sp.wValue & 0xff) % 8); outuint(c_mix_ctl, (sp.wValue & 0xff) / 8); outuint(c_mix_ctl, volume); outct(c_mix_ctl, XS1_CT_END); - } /* Send 0 Length as status stage */ @@ -839,11 +762,9 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c break; #endif - //default: - - ///* We dont have a unit with this ID! */ - //XUD_Error_hex("ERR: Unknown control unit: ", sp.wIndex); - //break; + default: + /* We dont have a unit with this ID! */ + break; } /* switch(sp.wIndex >> 8) i.e Unit ID */ break; @@ -936,14 +857,12 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c storeShort(buffer, 2, MIN_VOLUME); storeShort(buffer, 4, MAX_VOLUME); storeShort(buffer, 6, VOLUME_RES); - return XUD_DoGetRequest(ep0_out, ep0_in, buffer, sp.wLength, sp.wLength); - break; - default: - //Unknown control selector for FU: ", sp.wValue); - break; + default: + /* Unknown control selector for FU */ + break; } break; @@ -951,25 +870,21 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c #ifdef MIXER /* Mixer Unit */ case ID_MIXER_1: - storeShort(buffer, 0, 1); storeShort(buffer, 2, MIN_MIXER_VOLUME); storeShort(buffer, 4, MAX_MIXER_VOLUME); storeShort(buffer, 6, VOLUME_RES_MIXER); - return XUD_DoGetRequest(ep0_out, ep0_in, buffer, sp.wLength, sp.wLength); - break; #endif - - default: - //XUD_Error_hex("Unknown Unit ID in Range Request selector for FU: ", sp.wIndex >> 8); - break; + default: + /* Unknown Unit ID in Range Request selector for FU */ + break; } - break; + break; /* case: RANGE */ } #ifdef MIXER @@ -1033,7 +948,8 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c for(int i = 0; i < MAX_MIX_COUNT; i++) { - if (!isnull(c_mix_ctl)) { + if (!isnull(c_mix_ctl)) + { outuint(c_mix_ctl, GET_OUTPUT_LEVELS); outuint(c_mix_ctl, i); outct(c_mix_ctl, XS1_CT_END); @@ -1042,7 +958,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c } else { - storeShort(buffer, i*2, 0); + storeShort(buffer, i*2, 0); } } @@ -1050,31 +966,10 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c } return XUD_DoGetRequest(ep0_out, ep0_in, buffer, length, sp.wLength); } - else - { - /* Host-to-device (SET) */ - /* Currently no action for set mem request for any offset */ - datalength = XUD_GetBuffer(ep0_out, buffer); - - /* Check for reset/suspend */ - if(datalength < 0) - { - return datalength; - } - - /* Send 0 Length as status stage */ - return XUD_DoSetRequestStatus(ep0_in); - - } break; } - break; - - - #endif - } /* Didn't deal with request, return 1 */ @@ -1083,8 +978,110 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c } #if defined (AUDIO_CLASS_FALLBACK) || (AUDIO_CLASS==1) + +int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl) +{ + /* At this point we know: + * bmRequestType.Recipient = Endpoint + * bmRequestType.Type = Class + * endpoint (wIndex & 0xff) is 0x01 or 0x82 + */ + + int retVal = 1; + unsigned char buffer[1024]; + + /* Host to Device */ + if(sp.bmRequestType.Direction == USB_BM_REQTYPE_DIRECTION_H2D) + { + /* Inspect for request */ + switch(sp.bRequest) + { + case UAC_B_REQ_SET_CUR: + { + /* Check Control Selector */ + unsigned short controlSelector = sp.wValue>>8; + + retVal = XUD_GetBuffer(ep0_out, buffer); + + /* Inspect for reset */ + if(retVal < 0) + return retVal; + + if(controlSelector == SAMPLING_FREQ_CONTROL) + { + /* Expect length 3 for sample rate */ + if((sp.wLength == 3)&&(retVal == 3)) + { + + /* Recontruct sample-freq */ + int i_tmp = buffer[0] | (buffer [1] << 8) | (buffer[2] << 16); + + if(i_tmp != g_curSamFreq) + { + int curSamFreq44100Family; + + /* Windows Audio Class driver has a nice habbit of sending invalid SF's (e.g. 48001Hz) + * when under stress. Lets double check it here and ignore if not valid. */ + g_curSamFreq48000Family = i_tmp % 48000 == 0; + curSamFreq44100Family = i_tmp % 44100 == 0; + + if(g_curSamFreq48000Family || curSamFreq44100Family) + { + g_curSamFreq = i_tmp; + + if(g_curSamFreq48000Family) + { + i_tmp = MCLK_48; + } + else + { + i_tmp = MCLK_441; + } + + //setG_curSamFreqMultiplier(g_curSamFreq/(i_tmp/512)); + setG_curSamFreqMultiplier((g_curSamFreq*512)/i_tmp); + + /* Instruct audio thread to change sample freq */ + outuint(c_audioControl, SET_SAMPLE_FREQ); + outuint(c_audioControl, g_curSamFreq); + + /* Wait for handshake back - i.e. pll locked and clocks okay */ + chkct(c_audioControl, XS1_CT_END); + + /* Allow time for the change - feedback to stabalise */ + { + timer t; + unsigned time; + t :> time; + t when timerafter(time+50000000):> void; + } + } + } + return XUD_SetBuffer(ep0_in, buffer, 0); + } + } + } + break; + } + } + else // sp.bmRequestType.Direction == BM_REQTYPE_DIRECTION_D2H + { + switch(sp.bRequest) + { + case UAC_B_REQ_GET_CUR: + (buffer, unsigned[])[0] = g_curSamFreq; + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 3, sp.wLength); + break; + } + } + + /* Return 1 for not handled */ + return 1; +} + + /* Handles the Audio Class 1.0 specific requests */ -int AudioClassRequests_1(XUD_ep c_ep0_out, XUD_ep c_ep0_in, USB_SetupPacket_t &sp, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl +int AudioClassRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl ) { unsigned char buffer[1024]; @@ -1092,27 +1089,17 @@ int AudioClassRequests_1(XUD_ep c_ep0_out, XUD_ep c_ep0_in, USB_SetupPacket_t &s int loop = 1; int i_tmp; - /* Inspect request, NOTE: these are class specific requests */ - switch( sp.bRequest ) + /* Inspect request */ + /* Note we could check sp.bmRequestType.Direction if we wanted to be really careful */ + switch(sp.bRequest) { - case SET_INTERFACE: + case UAC_B_REQ_SET_CUR: { - return XUD_SetBuffer(c_ep0_in, buffer, 0); + loop = XUD_GetBuffer(ep0_out, buffer); - break; - } - - case B_REQ_SET_CUR: - { - - loop = XUD_GetBuffer(c_ep0_out, buffer); - - /* Inspect for rst/suspend */ + /* Inspect for reset */ if(loop < 0) return loop; - - - unitID = sp.wIndex >> 8; @@ -1121,17 +1108,13 @@ int AudioClassRequests_1(XUD_ep c_ep0_out, XUD_ep c_ep0_in, USB_SetupPacket_t &s switch ((sp.wValue>>8) & 0xff) { case FU_VOLUME_CONTROL: - { - volsOut[ sp.wValue & 0xff ] = buffer[0] | (((int) (signed char) buffer[1]) << 8); + volsOut[ sp.wValue & 0xff ] = buffer[0] | (((int) (signed char) buffer[1]) << 8); updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl ); - break; - } + return XUD_DoSetRequestStatus(ep0_in); case FU_MUTE_CONTROL: - { mutesOut[ sp.wValue & 0xff ] = buffer[0]; updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl ); - break; - } + return XUD_DoSetRequestStatus(ep0_in); } } else if (unitID == FU_USBIN) @@ -1139,72 +1122,18 @@ int AudioClassRequests_1(XUD_ep c_ep0_out, XUD_ep c_ep0_in, USB_SetupPacket_t &s switch ((sp.wValue>>8) & 0xff) { case FU_VOLUME_CONTROL: - { - volsIn[ sp.wValue & 0xff ] = buffer[0] | (((int) (signed char) buffer[1]) << 8); + volsIn[ sp.wValue & 0xff ] = buffer[0] | (((int) (signed char) buffer[1]) << 8); updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl ); - break; - } + return XUD_DoSetRequestStatus(ep0_in); case FU_MUTE_CONTROL: - { mutesIn[ sp.wValue & 0xff ] = buffer[0]; updateVol( unitID, ( sp.wValue & 0xff ), c_mix_ctl ); - break; - } + return XUD_DoSetRequestStatus(ep0_in); } } - else if (unitID == 0) // sample freq - { - i_tmp = buffer[0] | (buffer [1] << 8) | (buffer[2] << 16); - - - if(i_tmp != g_curSamFreq) - { - int curSamFreq44100Family; - - /* Windows Audio Class driver has a nice habbit of sending invalid SF's (e.g. 48001Hz) - * when under stress. Lets double check it here and ignore if not valid. */ - g_curSamFreq48000Family = i_tmp % 48000 == 0; - curSamFreq44100Family = i_tmp % 44100 == 0; - - if(g_curSamFreq48000Family || curSamFreq44100Family) - { - g_curSamFreq = i_tmp; - - if(g_curSamFreq48000Family) - { - i_tmp = MCLK_48; - } - else - { - i_tmp = MCLK_441; - } - - //setG_curSamFreqMultiplier(g_curSamFreq/(i_tmp/512)); - setG_curSamFreqMultiplier((g_curSamFreq*512)/i_tmp); - - /* Instruct audio thread to change sample freq */ - outuint(c_audioControl, SET_SAMPLE_FREQ); - outuint(c_audioControl, g_curSamFreq); - - /* Wait for handshake back - i.e. pll locked and clocks okay */ - chkct(c_audioControl, XS1_CT_END); - - /* Allow time for the change - feedback to stabalise */ - { - timer t; - unsigned time; - t :> time; - t when timerafter(time+50000000):> void; - } - } - } - } - - return XUD_SetBuffer(c_ep0_in, buffer, 0); - break; } - case B_REQ_GET_CUR: + case UAC_B_REQ_GET_CUR: { unitID = sp.wIndex >> 8; if (unitID == FU_USBOUT) @@ -1215,11 +1144,13 @@ int AudioClassRequests_1(XUD_ep c_ep0_out, XUD_ep c_ep0_in, USB_SetupPacket_t &s { buffer[0] = volsOut[ sp.wValue&0xff ]; buffer[1] = volsOut[ sp.wValue&0xff ] >> 8; + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 2, sp.wLength); break; } case FU_MUTE_CONTROL: { buffer[0] = mutesOut[ sp.wValue & 0xff ]; + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 1, sp.wLength); break; } } @@ -1232,74 +1163,34 @@ int AudioClassRequests_1(XUD_ep c_ep0_out, XUD_ep c_ep0_in, USB_SetupPacket_t &s { buffer[0] = volsIn[ sp.wValue&0xff ]; buffer[1] = volsIn[ sp.wValue&0xff ] >> 8; - break; + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 2, sp.wLength); } case FU_MUTE_CONTROL: { buffer[0] = mutesIn[ sp.wValue & 0xff ]; - break; + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 1, sp.wLength); } } } - else if(unitID == 0) - { - //printintln(unitID); - } - - loop = XUD_SetBuffer(c_ep0_in, buffer, sp.wLength); - - if(loop < 0) - return loop; - - /* Status stage (0 length OUT) */ - return XUD_GetBuffer(c_ep0_out,buffer); - break; + break; } - case B_REQ_GET_MIN: - { + case UAC_B_REQ_GET_MIN: buffer[0] = (MIN_MIXER_VOLUME & 0xff); buffer[1] = (MIN_MIXER_VOLUME >> 8); - - loop = XUD_SetBuffer(c_ep0_in, buffer, sp.wLength); - - if(loop < 0) - return loop; - - // Status stage (0 length OUT) - return XUD_GetBuffer(c_ep0_out, buffer); - break; - } - case B_REQ_GET_MAX: - { + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 2, sp.wLength); + + case UAC_B_REQ_GET_MAX: buffer[0] = (MAX_MIXER_VOLUME & 0xff); buffer[1] = (MAX_MIXER_VOLUME >> 8); - - loop = XUD_SetBuffer(c_ep0_in, buffer, sp.wLength); - - if(loop < 0) - return 0; - - // Status stage (0 length OUT) - return XUD_GetBuffer(c_ep0_out, buffer); - break; - } - case B_REQ_GET_RES: - { + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 2, sp.wLength); + + case UAC_B_REQ_GET_RES: buffer[0] = (VOLUME_RES_MIXER & 0xff); buffer[1] = (VOLUME_RES_MIXER >> 8); - loop = XUD_SetBuffer(c_ep0_in, buffer, sp.wLength); - - if(loop < 0) - return loop; - - // Status stage (0 length OUT) - return XUD_GetBuffer(c_ep0_out, buffer); - break; - } + return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 2, sp.wLength); } return 1; - } #endif diff --git a/module_usb_audio/endpoint0/descriptors_2.h b/module_usb_audio/endpoint0/descriptors_2.h index b709ae13..0caa39e3 100644 --- a/module_usb_audio/endpoint0/descriptors_2.h +++ b/module_usb_audio/endpoint0/descriptors_2.h @@ -20,7 +20,7 @@ unsigned char devDesc_Audio1[] = { 18, /* 0 bLength : Size of descriptor in Bytes (18 Bytes) */ - DEVICE, /* 1 bdescriptorType */ + USB_DEVICE, /* 1 bdescriptorType */ 0x0, /* 2 bcd USB */ 0x1, /* 3 bcdUSB */ 0, /* 4 bDeviceClass */ @@ -34,8 +34,8 @@ unsigned char devDesc_Audio1[] = (BCD_DEVICE & 0xFF), /* 12 bcdDevice : Device release number */ (BCD_DEVICE >> 8), /* 13 bcdDevice : Device release number */ MANUFACTURER_STR_INDEX, /* 14 iManufacturer : Index of manufacturer string */ - PRODUCT_STR_INDEX, /* 15 iProduct : Index of product string descriptor */ - 0,//SERIAL_STR_INDEX, /* 16 iSerialNumber : Index of serial number decriptor */ + 8, /* 15 iProduct : Index of product string descriptor */ + 0,//SERIAL_STR_INDEX, /* 16 iSerialNumber : Index of serial number decriptor */ 0x01 /* 17 bNumConfigurations : Number of possible configs. */ }; #endif @@ -44,7 +44,7 @@ unsigned char devDesc_Audio1[] = unsigned char devDesc_Audio2[] = { 18, /* 0 bLength : Size of descriptor in Bytes (18 Bytes) */ - DEVICE, /* 1 bdescriptorType */ + USB_DEVICE, /* 1 bdescriptorType */ 0, /* 2 bcdUSB */ 2, /* 3 bcdUSB */ 0xEF, /* 4 bDeviceClass (See Audio Class Spec page 45) */ @@ -68,7 +68,7 @@ unsigned char devDesc_Audio2[] = unsigned char devDesc_Null[] = { 18, /* 0 bLength : Size of descriptor in Bytes (18 Bytes) */ - DEVICE, /* 1 bdescriptorType */ + USB_DEVICE, /* 1 bdescriptorType */ 0, /* 2 bcdUSB */ 2, /* 3 bcdUSB */ 0x0, /* 4 bDeviceClass */ @@ -94,7 +94,7 @@ unsigned char devDesc_Null[] = unsigned char devQualDesc_Audio2[] = { 10, /* 0 bLength (10 Bytes) */ - DEVICE_QUALIFIER, /* 1 bDescriptorType */ + USB_DEVICE_QUALIFIER, /* 1 bDescriptorType */ 0x00, /* 2 bcdUSB (Binary Coded Decimal of usb version) */ 0x02, /* 3 bcdUSB */ 0xEF, /* 4 bDeviceClass */ @@ -110,7 +110,7 @@ unsigned char devQualDesc_Audio2[] = unsigned char devQualDesc_Audio1[] = { 10, /* 0 bLength (10 Bytes) */ - DEVICE_QUALIFIER, /* 1 bDescriptorType */ + USB_DEVICE_QUALIFIER, /* 1 bDescriptorType */ 0x00, /* 2 bcdUSB (Binary Coded Decimal of usb version) */ 0x02, /* 3 bcdUSB */ 0x00, /* 4 bDeviceClass */ @@ -126,7 +126,7 @@ unsigned char devQualDesc_Audio1[] = unsigned char devQualDesc_Null[] = { 10, /* 0 bLength (10 Bytes) */ - DEVICE_QUALIFIER, /* 1 bDescriptorType */ + USB_DEVICE_QUALIFIER, /* 1 bDescriptorType */ 0x00, /* 2 bcdUSB (Binary Coded Decimal of usb version) */ 0x02, /* 3 bcdUSB */ 0x00, /* 4 bDeviceClass */ @@ -228,8 +228,8 @@ unsigned char devQualDesc_Null[] = #endif // Positions in strDescs_Audio2 -#define INTERNAL_CLOCK_STRING_INDEX 9 -#define SPDIF_CLOCK_STRING_INDEX 10 +#define INTERNAL_CLOCK_STRING_INDEX 14 +#define SPDIF_CLOCK_STRING_INDEX 15 #ifdef SPDIF_RX #define ADAT_CLOCK_STRING_INDEX (SPDIF_CLOCK_STRING_INDEX + 1) @@ -299,7 +299,7 @@ unsigned char hidReportDescriptor[] = { unsigned char cfgDesc_Audio2[] = { 0x09, /* 0 bLength */ - CONFIGURATION, /* 1 bDescriptorType */ + USB_CONFIGURATION, /* 1 bDescriptorType */ (CFG_TOTAL_LENGTH_A2 & 0xFF), /* 2 wTotalLength */ (CFG_TOTAL_LENGTH_A2 >> 8), /* 3 wTotalLength */ NUM_INTERFACES, /* 4 bNumInterface: Number of interfaces*/ @@ -325,7 +325,7 @@ unsigned char cfgDesc_Audio2[] = /* Standard Audio Control Interface Descriptor (Note: Must be first with lowest interface number)r */ 0x09, /* 0 bLength: 9 */ - INTERFACE, /* 1 bDescriptorType: INTERFACE */ + USB_INTERFACE, /* 1 bDescriptorType: INTERFACE */ 0x00, /* 2 bInterfaceNumber */ 0x00, /* 3 bAlternateSetting: Must be 0 */ #if defined(SPDIF_RX) || defined(ADAT_RX) @@ -780,7 +780,7 @@ unsigned char cfgDesc_Audio2[] = #ifdef OUTPUT /* Standard AS Interface Descriptor (4.9.1) */ 0x09, /* 0 bLength: (in bytes, 9) */ - INTERFACE, /* 1 bDescriptorType: INTERFACE */ + USB_INTERFACE, /* 1 bDescriptorType: INTERFACE */ 1, /* 2 bInterfaceNumber: Number of interface */ 0, /* 3 bAlternateSetting */ 0, /* 4 bNumEndpoints */ @@ -791,7 +791,7 @@ unsigned char cfgDesc_Audio2[] = /* Standard AS Interface Descriptor (4.9.1) (Alt) */ 0x09, /* 0 bLength: (in bytes, 9) */ - INTERFACE, /* 1 bDescriptorType: INTERFACE */ + USB_INTERFACE, /* 1 bDescriptorType: INTERFACE */ 1, /* 2 bInterfaceNumber: Number of interface */ 1, /* 3 bAlternateSetting */ 2, /* 4 bNumEndpoints */ @@ -822,7 +822,7 @@ unsigned char cfgDesc_Audio2[] = /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ 0x07, /* 0 bLength: 7 */ - ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ + USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ 0x01, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ 0x05, /* 3 bmAttributes (bitmap) */ 0,4, /* 4 wMaxPacketSize */ @@ -839,7 +839,7 @@ unsigned char cfgDesc_Audio2[] = /* Feedback EP */ 0x07, /* 0 bLength: 7 */ - ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ + USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ 0x81, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ 17, /* 3 bmAttributes (bitmap) */ 4,0, /* 4 wMaxPacketSize */ @@ -848,7 +848,7 @@ unsigned char cfgDesc_Audio2[] = #ifdef ADAT_TX /* Standard AS Interface Descriptor (4.9.1) (Alt) */ 0x09, /* 0 bLength: (in bytes, 9) */ - INTERFACE, /* 1 bDescriptorType: INTERFACE */ + USB_INTERFACE, /* 1 bDescriptorType: INTERFACE */ 1, /* 2 bInterfaceNumber: Number of interface */ 2, /* 3 bAlternateSetting */ 2, /* 4 bNumEndpoints */ @@ -879,7 +879,7 @@ unsigned char cfgDesc_Audio2[] = /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ 0x07, /* 0 bLength: 7 */ - ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ + USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ 0x01, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ 0x05, /* 3 bmAttributes (bitmap) */ 0,4, /* 4 wMaxPacketSize */ @@ -896,7 +896,7 @@ unsigned char cfgDesc_Audio2[] = /* Feedback EP */ 0x07, /* 0 bLength: 7 */ - ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ + USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ 0x81, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ 17, /* 3 bmAttributes (bitmap) */ 4,0, /* 4 wMaxPacketSize */ @@ -908,7 +908,7 @@ unsigned char cfgDesc_Audio2[] = #ifdef INPUT /* Standard AS Interface Descriptor (4.9.1) */ 0x09, /* 0 bLength: (in bytes, 9) */ - INTERFACE, /* 1 bDescriptorType: INTERFACE */ + USB_INTERFACE, /* 1 bDescriptorType: INTERFACE */ (OUTPUT_INTERFACES + 1), /* 2 bInterfaceNumber: Number of interface */ 0, /* 3 bAlternateSetting */ 0, /* 4 bNumEndpoints */ @@ -919,7 +919,7 @@ unsigned char cfgDesc_Audio2[] = /* Standard AS Interface Descriptor (4.9.1) (Alt) */ 0x09, /* 0 bLength: (in bytes, 9) */ - INTERFACE, /* 1 bDescriptorType: INTERFACE */ + USB_INTERFACE, /* 1 bDescriptorType: INTERFACE */ (OUTPUT_INTERFACES + 1), /* 2 bInterfaceNumber: Number of interface */ 1, /* 3 bAlternateSetting */ 1, /* 4 bNumEndpoints */ @@ -950,7 +950,7 @@ unsigned char cfgDesc_Audio2[] = /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ 0x07, /* 0 bLength: 7 */ - ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ + USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ 0x82, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ 5, /* 3 bmAttributes (bitmap) */ 0,4, /* 4 wMaxPacketSize */ @@ -968,7 +968,7 @@ unsigned char cfgDesc_Audio2[] = #ifdef ADAT_RX /* Standard AS Interface Descriptor (4.9.1) (Alt) */ 0x09, /* 0 bLength: (in bytes, 9) */ - INTERFACE, /* 1 bDescriptorType: INTERFACE */ + USB_INTERFACE, /* 1 bDescriptorType: INTERFACE */ (OUTPUT_INTERFACES + 1), /* 2 bInterfaceNumber: Number of interface */ 2, /* 3 bAlternateSetting */ 1, /* 4 bNumEndpoints */ @@ -999,7 +999,7 @@ unsigned char cfgDesc_Audio2[] = /* Standard AS Isochronous Audio Data Endpoint Descriptor (4.10.1.1) */ 0x07, /* 0 bLength: 7 */ - ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ + USB_ENDPOINT, /* 1 bDescriptorType: ENDPOINT */ 0x82, /* 2 bEndpointAddress (D7: 0:out, 1:in) */ 5, /* 3 bmAttributes (bitmap) */ 0,4, /* 4 wMaxPacketSize */ @@ -1342,20 +1342,29 @@ unsigned char cfgDesc_Audio2[] = #define STR_INDEX_OUT_CHAN (10 + SPDIF_RX_NUM_STRS + ADAT_RX_NUM_STRS + MIDI_NUM_STRS + DFU_NUM_STRS) #define STR_INDEX_IN_CHAN (STR_INDEX_OUT_CHAN + NUM_USB_CHAN_OUT) -static unsigned char strDescs_Audio2[][40] = +static unsigned char strDescs[][40] = { "Langids", /* String 0 (LangIDs) place holder */ APPEND_VENDOR_STR( ), // 1 iManufacturer (at MANUFACTURER_STRING_INDEX) + + /* Audio 2.0 Strings */ APPEND_VENDOR_STR(USB Audio 2.0), // 2 iProduct and iInterface for control interface (at PRODUCT_STR_INDEX) - "",//SERIAL_STR, // 3 iSerialNumber (at SERIAL_STR_INDEX) + "",//SERIAL_STR, // 3 iSerialNumber (at SERIAL_STR_INDEX) APPEND_VENDOR_STR(USB 2.0 Audio Out), // 4 iInterface for Streaming interaces APPEND_VENDOR_STR(USB 2.0 Audio In), // 5 APPEND_VENDOR_STR(Audio 2.0 Output), // 6 "USB Input Terminal" (User sees as output from host) APPEND_VENDOR_STR(Audio 2.0 Input), // 7 "USB Output Terminal" (User sees as input to host) - - APPEND_VENDOR_STR(Clock Selector), // 8 iClockSel - APPEND_VENDOR_STR(Internal Clock), // 9 iClockSource + + /* Audio 1.0 Strings */ + APPEND_VENDOR_STR(USB Audio 1.0), // 8 iProduct and iInterface for control interface + APPEND_VENDOR_STR(USB 1.0 Audio Out), // 9 iInterface for Streaming interaces + APPEND_VENDOR_STR(USB 1.0 Audio In), // 10 + APPEND_VENDOR_STR(Audio 1.0 Output), // 11 "USB Input Terminal" (User sees as output from host) + APPEND_VENDOR_STR(Audio 1.0 Input), // 12 "USB Output Terminal" (User sees as input to host) + + APPEND_VENDOR_STR(Clock Selector), // 13 iClockSel + APPEND_VENDOR_STR(Internal Clock), // 14 iClockSource #ifdef SPDIF_RX APPEND_VENDOR_STR(S/PDIF Clock), // iClockSource #endif @@ -1526,7 +1535,7 @@ static unsigned char strDescs_Audio2[][40] = unsigned char cfgDesc_Null[] = { 0x09, /* 0 bLength */ - CONFIGURATION, /* 1 bDescriptorType */ + USB_CONFIGURATION, /* 1 bDescriptorType */ 0x12, /* 2 wTotalLength */ 0x00, /* 3 wTotalLength */ 0x01, /* 4 bNumInterface: Number of interfaces*/ @@ -1589,8 +1598,9 @@ unsigned char oSpeedCfgDesc[] = #ifdef AUDIO_CLASS_FALLBACK unsigned char cfgDesc_Audio1[] = { - /* Configuration descriptor */ 0x09, - CONFIGURATION, + /* Configuration descriptor */ + 0x09, + USB_CONFIGURATION, (CFG_TOTAL_LENGTH_A1 & 0xFF), /* wTotalLength */ (CFG_TOTAL_LENGTH_A1 >> 8), /* wTotalLength */ NUM_INTERFACES_A1, /* numInterfaces - we dont support MIDI in audio 1.0 mode*/ @@ -1606,22 +1616,22 @@ unsigned char cfgDesc_Audio1[] = /* Standard AC interface descriptor */ 0x09, - INTERFACE, + USB_INTERFACE, 0x00, /* Interface No */ 0x00, /* Alternate setting*/ 0x00, /* Num endpoints */ AUDIO, AUDIOCONTROL, 0x00, /* Unused */ - PRODUCT_STR_INDEX, /* iInterface - re-use iProduct */ + 8, /* iInterface - re-use iProduct */ /* CS (Class Specific) AudioControl interface header descriptor (4.3.2) */ AC_LENGTH, CS_INTERFACE, 0x01, /* HEADER */ 0x00, 0x01, /* Class spec revision - 1.0 */ - (AC_TOTAL_LENGTH & 0xFF), /* wTotallength (Combined length of this descriptor and all Unit and Terminal Descriptors) */ - (AC_TOTAL_LENGTH >> 8), /* wTotalLength */ + (AC_TOTAL_LENGTH & 0xFF), /* wTotallength (Combined length of this descriptor and all Unit and Terminal Descriptors) */ + (AC_TOTAL_LENGTH >> 8), /* wTotalLength */ STREAMING_INTERFACES, /* Num streaming interfaces */ #ifdef OUTPUT 0x01, /* AudioStreaming interface 1 belongs to AC interface */ @@ -1641,7 +1651,7 @@ unsigned char cfgDesc_Audio1[] = 2, /* bNrChannels */ 0x03, 0x00, /* wChannelConfig */ 0x00, /* iChannelNames - Unused */ - 0x06, /* iTerminal */ + 11, /* iTerminal */ /* CS_Interface class specific AC interface feature unit descriptor - mute & volume for dac */ 0x0A, @@ -1678,7 +1688,7 @@ unsigned char cfgDesc_Audio1[] = 2, /* bNrChannels */ 0x03, 0x00, /* wChannelConfigs */ 0x00, /* iChannelNames */ - 0x07, /* iTerminal */ + 12, /* iTerminal */ /* CS_Interface Output Terminal Descriptor - USB Streaming Device to Host*/ 0x09, @@ -1713,7 +1723,7 @@ unsigned char cfgDesc_Audio1[] = 0x01, /* bInterfaceClass - AUDIO */ 0x02, /* bInterfaceSubclass - AUDIO_STREAMING */ 0x00, /* bInterfaceProtocol - Not used */ - 0x04, /* iInterface */ + 0x09, /* iInterface */ /* Standard As Interface Descriptor (4.5.1) */ 0x09, @@ -1807,7 +1817,7 @@ unsigned char cfgDesc_Audio1[] = 0x01, /* Interface class - AUDIO */ 0x02, /* Subclass - AUDIO_STREAMING */ 0x00, /* Unused */ - 0x05, /* String table index */ + 0x0A, /* String table index */ /* CS_Interface AC interface header descriptor */ 0x07, @@ -1900,7 +1910,7 @@ unsigned char cfgDesc_Audio1[] = #endif #define APPEND_VENDOR_STR(x) VENDOR_STR#x - +#if 0 static unsigned char strDescs_Audio1[][40] = { "Langids", /* String 0 (LangIDs) place holder */ @@ -1916,5 +1926,5 @@ static unsigned char strDescs_Audio1[][40] = APPEND_VENDOR_STR(DFU) // 8 iInterface for DFU interface }; - +#endif #endif diff --git a/module_usb_audio/endpoint0/endpoint0.xc b/module_usb_audio/endpoint0/endpoint0.xc index b67bbd8f..e6e18725 100755 --- a/module_usb_audio/endpoint0/endpoint0.xc +++ b/module_usb_audio/endpoint0/endpoint0.xc @@ -13,10 +13,11 @@ #include "usbaudio20.h" /* Defines from USB Audio 2.0 spec */ #include "devicedefines.h" -#include "DescriptorRequests.h" /* Standard descriptor requests */ +#include "usb_device.h" /* Standard descriptor requests */ #include "descriptors_2.h" /* This devices descriptors */ #include "clockcmds.h" #include "audiostream.h" +#include "hostactive.h" #include "vendorrequests.h" #include "dfu_types.h" #include "xc_ptr.h" @@ -50,8 +51,9 @@ extern void device_reboot(chanend); #endif /* Handles Audio Class requests */ -int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, SetupPacket &sp, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl); -int AudioClassRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, SetupPacket &sp, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl); +int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl); +int AudioClassRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl); +int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl); /* Global var for current frequency, set to default freq */ unsigned int g_curSamFreq = DEFAULT_FREQ; @@ -84,57 +86,28 @@ unsigned char mixSel[MIX_INPUTS]; int min(int x, int y); -/* Records alt setting for each interface */ -int interfaceAlt[NUM_INTERFACES]; - /* Global current device config var*/ -unsigned g_config = 0; +extern unsigned char g_currentConfig; -/* Global endpoint status arrays */ -unsigned g_epStatusOut[EP_CNT_OUT]; -unsigned g_epStatusIn[EP_CNT_IN]; +/* Global endpoint status arrays - declared in usb_device.xc */ +extern unsigned char g_interfaceAlt[]; /* Global variable for current USB bus speed (i.e. FS/HS) */ unsigned g_curUsbSpeed = 0; -#ifdef HOST_ACTIVE_CALL -void VendorHostActive(int active); -#endif /* Global used for signalling reset to decouple */ #ifdef IAP extern unsigned g_iap_reset; #endif -/* Used when setting/clearing EP halt */ -void SetEndpointStatus(unsigned epNum, unsigned status) -{ - /* Inspect for IN bit */ - if( epNum & 0x80 ) - { - epNum &= 0x7f; - - /* Range check */ - if(epNum < EP_CNT_IN) - { - g_epStatusIn[ epNum & 0x7F ] = status; - } - } - else - { - if(epNum < EP_CNT_OUT) - { - g_epStatusOut[ epNum ] = status; - } - } -} #define STR_USENG 0x0409 #define DESC_STR_LANGIDS \ { \ - STR_USENG & 0xff, /* 2 wLangID[0] */ \ - STR_USENG>>8, /* 3 wLangID[0] */ \ + STR_USENG & 0xff, /* 2 wLangID[0] */ \ + STR_USENG>>8, /* 3 wLangID[0] */ \ '\0' \ } @@ -148,16 +121,9 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, chanend ?c_mix_ctl, chanend ?c_clk_ctl, chanend ?c_usb_test) { unsigned char buffer[2]; - SetupPacket sp; - XUD_ep ep0_out = XUD_Init_Ep(c_ep0_out); - XUD_ep ep0_in = XUD_Init_Ep(c_ep0_in); - - /* Init endpoint status tables */ - for (int i = 0; i++; i < EP_CNT_OUT) - g_epStatusOut[i] = 0; - - for (int i = 0; i++; i < EP_CNT_IN) - g_epStatusIn[i] = 0; + USB_SetupPacket_t sp; + XUD_ep ep0_out = XUD_InitEp(c_ep0_out); + XUD_ep ep0_in = XUD_InitEp(c_ep0_in); /* Init tables for volumes (+ 1 for master) */ for(int i = 0; i < NUM_USB_CHAN_OUT + 1; i++) @@ -227,40 +193,40 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, /* Copy langIDs string desc into string[0] */ /* TODO: Macro? */ #if defined(AUDIO_CLASS_FALLBACK) || (AUDIO_CLASS == 1) - safememcpy(strDescs_Audio1[0], strDesc_langIDs, sizeof(strDesc_langIDs)); + //safememcpy(strDescs_Audio1[0], strDesc_langIDs, sizeof(strDesc_langIDs)); #endif - safememcpy(strDescs_Audio2[0], strDesc_langIDs, sizeof(strDesc_langIDs)); + safememcpy(strDescs[0], strDesc_langIDs, sizeof(strDesc_langIDs)); /* Build up channel string table - By default all channels are marked as analogue * TODO We really want to do this an build time... */ #if defined(SPDIF_RX) && (SPDIF_RX_INDEX != 0) - safestrcpy(strDescs_Audio2[SPDIF_RX_INDEX + STR_INDEX_IN_CHAN], "S/PDIF 1"); - safestrcpy(strDescs_Audio2[SPDIF_RX_INDEX + STR_INDEX_IN_CHAN + 1], "S/PDIF 2"); + safestrcpy(strDescs[SPDIF_RX_INDEX + STR_INDEX_IN_CHAN], "S/PDIF 1"); + safestrcpy(strDescs[SPDIF_RX_INDEX + STR_INDEX_IN_CHAN + 1], "S/PDIF 2"); #endif #if defined(ADAT_RX) && (ADAT_RX_INDEX != 0) - safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + STR_INDEX_IN_CHAN], "ADAT 1"); - safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 1], "ADAT 2"); - safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 2], "ADAT 3"); - safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 3], "ADAT 4"); - safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 4], "ADAT 5"); - safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 5], "ADAT 6"); - safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 6], "ADAT 7"); - safestrcpy(strDescs_Audio2[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 7], "ADAT 8"); + safestrcpy(strDescs[ADAT_RX_INDEX + STR_INDEX_IN_CHAN], "ADAT 1"); + safestrcpy(strDescs[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 1], "ADAT 2"); + safestrcpy(strDescs[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 2], "ADAT 3"); + safestrcpy(strDescs[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 3], "ADAT 4"); + safestrcpy(strDescs[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 4], "ADAT 5"); + safestrcpy(strDescs[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 5], "ADAT 6"); + safestrcpy(strDescs[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 6], "ADAT 7"); + safestrcpy(strDescs[ADAT_RX_INDEX + STR_INDEX_IN_CHAN + 7], "ADAT 8"); #endif #if defined(SPDIF) && (SPDIF_TX_INDEX != 0) /* "Analogue naming gets priority */ - safestrcpy(strDescs_Audio2[SPDIF_TX_INDEX + STR_INDEX_OUT_CHAN], "S/PDIF 1"); - safestrcpy(strDescs_Audio2[SPDIF_TX_INDEX + STR_INDEX_OUT_CHAN + 1], "S/PDIF 2"); + safestrcpy(strDescs[SPDIF_TX_INDEX + STR_INDEX_OUT_CHAN], "S/PDIF 1"); + safestrcpy(strDescs[SPDIF_TX_INDEX + STR_INDEX_OUT_CHAN + 1], "S/PDIF 2"); #endif #if defined(ADAT_TX) && (ADAT_TX_INDEX != 0) - safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN], "ADAT 1"); - safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 1], "ADAT 2"); - safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 2], "ADAT 3"); - safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 3], "ADAT 4"); - safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 4], "ADAT 5"); - safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 5], "ADAT 6"); - safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 6], "ADAT 7"); - safestrcpy(strDescs_Audio2[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 7], "ADAT 8"); + safestrcpy(strDescs[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN], "ADAT 1"); + safestrcpy(strDescs[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 1], "ADAT 2"); + safestrcpy(strDescs[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 2], "ADAT 3"); + safestrcpy(strDescs[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 3], "ADAT 4"); + safestrcpy(strDescs[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 4], "ADAT 5"); + safestrcpy(strDescs[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 5], "ADAT 6"); + safestrcpy(strDescs[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 6], "ADAT 7"); + safestrcpy(strDescs[ADAT_TX_INDEX + STR_INDEX_OUT_CHAN + 7], "ADAT 8"); #endif #ifdef VENDOR_AUDIO_REQS @@ -282,356 +248,177 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, while(1) { - int retVal = 1; - - /* Do standard enumeration requests */ -#ifndef DFU - if(g_curUsbSpeed == XUD_SPEED_HS) - { + /* Returns 0 for success, -1 for bus reset */ + int retVal = USB_GetSetupPacket(ep0_out, ep0_in, sp); -#ifdef AUDIO_CLASS_FALLBACK - /* Return Audio 2.0 Descriptors with Audio 1.0 as fallback */ - cfgDesc_Audio2[1] = CONFIGURATION; - cfgDesc_Audio1[1] = OTHER_SPEED_CONFIGURATION; - - retVal = DescriptorRequests(ep0_out, ep0_in, - devDesc_Audio2, sizeof(devDesc_Audio2), - cfgDesc_Audio2, sizeof(cfgDesc_Audio2), - devQualDesc_Audio1, sizeof(devQualDesc_Audio1), - cfgDesc_Audio1, sizeof(cfgDesc_Audio1), - strDescs_Audio2, sp, c_usb_test); -#else - /* Return Audio 2.0 Descriptors */ - cfgDesc_Audio2[1] = CONFIGURATION; - cfgDesc_Null[1] = OTHER_SPEED_CONFIGURATION; - - retVal = DescriptorRequests(ep0_out, ep0_in, - devDesc_Audio2, sizeof(devDesc_Audio2), - cfgDesc_Audio2, sizeof(cfgDesc_Audio2), - devQualDesc_Null, sizeof(devQualDesc_Null), - cfgDesc_Null, sizeof(cfgDesc_Null), - strDescs_Audio2, sp, c_usb_test); -#endif - } - else + if (!retVal) { - /* Return descriptors for full-speed - Audio 1.0? */ -#ifdef AUDIO_CLASS_FALLBACK - cfgDesc_Audio1[1] = CONFIGURATION; - cfgDesc_Audio2[1] = OTHER_SPEED_CONFIGURATION; - - retVal = DescriptorRequests(ep0_out, ep0_in, - devDesc_Audio1, sizeof(devDesc_Audio1), - cfgDesc_Audio1, sizeof(cfgDesc_Audio1), - devQualDesc_Audio2, sizeof(devQualDesc_Audio2), - cfgDesc_Audio2, sizeof(cfgDesc_Audio2), - strDescs_Audio1, sp, c_usb_test); + retVal = 1; -#else - cfgDesc_Null[1] = CONFIGURATION; - cfgDesc_Audio2[1] = OTHER_SPEED_CONFIGURATION; - - retVal = DescriptorRequests(ep0_out, ep0_in, - devDesc_Null, sizeof(devDesc_Null), - cfgDesc_Null, sizeof(cfgDesc_Null), - devQualDesc_Audio2, sizeof(devQualDesc_Audio2), - cfgDesc_Audio2, sizeof(cfgDesc_Audio2), - strDescs_Audio2, sp, c_usb_test); -#endif - - } -#else /* ifndef DFU */ - if (!DFU_mode_active) - { - if(g_curUsbSpeed == XUD_SPEED_HS) + /* Inspect Request type and Receipient and direction */ + switch( (sp.bmRequestType.Direction << 7) | (sp.bmRequestType.Recipient ) | (sp.bmRequestType.Type << 5) ) { - -#ifdef AUDIO_CLASS_FALLBACK - /* Return Audio 2.0 Descriptors with Audio 1.0 as fallback */ - cfgDesc_Audio2[1] = CONFIGURATION; - cfgDesc_Audio1[1] = OTHER_SPEED_CONFIGURATION; - - retVal = DescriptorRequests(ep0_out, ep0_in, - devDesc_Audio2, sizeof(devDesc_Audio2), - cfgDesc_Audio2, sizeof(cfgDesc_Audio2), - devQualDesc_Audio1, sizeof(devQualDesc_Audio1), - cfgDesc_Audio1, sizeof(cfgDesc_Audio1), - strDescs_Audio2, sp, c_usb_test); -#else - /* Return Audio 2.0 Descriptors with Null device as fallback */ - cfgDesc_Audio2[1] = CONFIGURATION; - cfgDesc_Null[1] = OTHER_SPEED_CONFIGURATION; - - retVal = DescriptorRequests(ep0_out, ep0_in, - devDesc_Audio2, sizeof(devDesc_Audio2), - cfgDesc_Audio2, sizeof(cfgDesc_Audio2), - devQualDesc_Null, sizeof(devQualDesc_Null), - cfgDesc_Null, sizeof(cfgDesc_Null), - strDescs_Audio2, sp, c_usb_test); -#endif - - } - else - { - /* Return descriptors for full-speed - Audio 1.0? */ -#ifdef AUDIO_CLASS_FALLBACK - cfgDesc_Audio1[1] = CONFIGURATION; - cfgDesc_Audio2[1] = OTHER_SPEED_CONFIGURATION; - - retVal = DescriptorRequests(ep0_out, ep0_in, - devDesc_Audio1, sizeof(devDesc_Audio1), - cfgDesc_Audio1, sizeof(cfgDesc_Audio1), - devQualDesc_Audio2, sizeof(devQualDesc_Audio2), - cfgDesc_Audio2, sizeof(cfgDesc_Audio2), - strDescs_Audio1, sp, c_usb_test); -#else - cfgDesc_Null[1] = CONFIGURATION; - cfgDesc_Audio2[1] = OTHER_SPEED_CONFIGURATION; - - retVal = DescriptorRequests(ep0_out, ep0_in, - devDesc_Null, sizeof(devDesc_Null), - cfgDesc_Null, sizeof(cfgDesc_Null), - devQualDesc_Audio2, sizeof(devQualDesc_Audio2), - cfgDesc_Audio2, sizeof(cfgDesc_Audio2), - strDescs_Audio2, sp, c_usb_test); -#endif - - } - } - else - { - /* Running in DFU mode - always return same descs for DFU whether HS or FS */ - retVal = DescriptorRequests(ep0_out, ep0_in, - DFUdevDesc, sizeof(DFUdevDesc), - DFUcfgDesc, sizeof(DFUcfgDesc), - DFUdevQualDesc, sizeof(DFUdevQualDesc), - DFUoSpeedCfgDesc, sizeof(DFUoSpeedCfgDesc), - strDescs_Audio2, sp, c_usb_test); - } -#endif - - if (retVal == 1) - { - /* Request not covered by XUD_DoEnumReqs() so decode ourselves */ - /* Inspect Request type and Receipient */ - switch( (sp.bmRequestType.Recipient ) | (sp.bmRequestType.Type << 5) ) - { - case STANDARD_INTERFACE_REQUEST: - - switch(sp.bRequest) + case USB_BMREQ_H2D_STANDARD_INT: + + /* Over-riding USB_StandardRequests implementation */ + if(sp.bRequest == USB_SET_INTERFACE) { - /* Set Interface */ - case SET_INTERFACE: - - #if defined(OUTPUT) && defined(INPUT) - /* Check for stream start stop on output and input audio interfaces */ - if(sp.wValue && !interfaceAlt[1] && !interfaceAlt[2]) - { - /* If start and input AND output not currently running */ - AudioStreamStart(); - } - else if(((sp.wIndex == 1)&& (!sp.wValue)) && interfaceAlt[1] && (!interfaceAlt[2])) - { - /* if output stop and output running and input not running */ - AudioStreamStop(); - } - else if(((sp.wIndex == 2) && (!sp.wValue)) && interfaceAlt[2] && (!interfaceAlt[1])) - { - /* if input stop and input running and output not running */ - AudioStreamStop(); - } + /* Check for stream start stop on output and input audio interfaces */ + if(sp.wValue && !g_interfaceAlt[1] && !g_interfaceAlt[2]) + { + /* If start and input AND output not currently running */ + UserAudioStreamStart(); + } + else if(((sp.wIndex == 1) && (!sp.wValue)) && g_interfaceAlt[1] && (!g_interfaceAlt[2])) + { + /* if output stop and output running and input not running */ + UserAudioStreamStop(); + } + else if(((sp.wIndex == 2) && (!sp.wValue)) && g_interfaceAlt[2] && (!g_interfaceAlt[1])) + { + /* if input stop and input running and output not running */ + UserAudioStreamStop(); + } #elif defined(OUTPUT) || defined(INPUT) - if(sp.wValue && (!interfaceAlt[1])) - { - /* if start and not currently running */ - AudioStreamStart(); - } - else if (!sp.wValue && interfaceAlt[1]) - { - /* if stop and currently running */ - AudioStreamStop(); - } - + if(sp.wValue && (!g_interfaceAlt[1])) + { + /* if start and not currently running */ + UserAudioStreamStart(); + } + else if (!sp.wValue && g_interfaceAlt[1]) + { + /* if stop and currently running */ + UserAudioStreamStop(); + } #endif - /* Record interface change */ - if( sp.wIndex < NUM_INTERFACES ) - interfaceAlt[sp.wIndex] = sp.wValue; -#if 1 + /* Record interface change */ + if(sp.wIndex < NUM_INTERFACES) + g_interfaceAlt[sp.wIndex] = sp.wValue; - /* Check for audio stream from host start/stop */ - if(sp.wIndex == 1) // Ouput interface + /* Check for audio stream from host start/stop */ + if(sp.wIndex == 1) // Ouput interface + { + switch(sp.wValue) { - switch(sp.wValue) - { - case 0: - - break; - - case 1: - /* Stream active + 0 chans */ - /* NOTE there could be a difference between HS/UAC1 and FS/UAC1 channel count */ - /* Also note, currently we assume with won't be doing ADAT in FS/UAC1...*/ - if(g_curUsbSpeed == XUD_SPEED_HS) - { - outuint(c_audioControl, SET_CHAN_COUNT_OUT); - outuint(c_audioControl, NUM_USB_CHAN_OUT); - } - else - { - outuint(c_audioControl, SET_CHAN_COUNT_OUT); - outuint(c_audioControl, NUM_USB_CHAN_OUT_A1); - } - break; - } - + case 0: + break; + case 1: + /* Stream active + 0 chans */ + /* NOTE there could be a difference between HS/UAC1 and FS/UAC1 channel count */ + /* Also note, currently we assume with won't be doing ADAT in FS/UAC1...*/ + if(g_curUsbSpeed == XUD_SPEED_HS) + { + outuint(c_audioControl, SET_CHAN_COUNT_OUT); + outuint(c_audioControl, NUM_USB_CHAN_OUT); + } + else + { + outuint(c_audioControl, SET_CHAN_COUNT_OUT); + outuint(c_audioControl, NUM_USB_CHAN_OUT_A1); + } + break; } - else if(sp.wIndex == 2) // Input interface + } + else if(sp.wIndex == 2) // Input interface + { + switch(sp.wValue) { - switch(sp.wValue) - { - case 0: - - break; - - case 1: - /* Stream active + 0 chans */ - /* NOTE there could be a difference between HS/UAC1 and FS/UAC1 channel count */ - /* Also note, currently we assume with won't be doing ADAT in FS/UAC1...*/ - if(g_curUsbSpeed == XUD_SPEED_HS) - { - outuint(c_audioControl, SET_CHAN_COUNT_IN); - outuint(c_audioControl, NUM_USB_CHAN_IN); - } - else - { - outuint(c_audioControl, SET_CHAN_COUNT_IN); - outuint(c_audioControl, NUM_USB_CHAN_IN_A1); - } + case 0: + break; + case 1: + /* Stream active + 0 chans */ + /* NOTE there could be a difference between HS/UAC1 and FS/UAC1 channel count */ + /* Also note, currently we assume with won't be doing ADAT in FS/UAC1...*/ + if(g_curUsbSpeed == XUD_SPEED_HS) + { + outuint(c_audioControl, SET_CHAN_COUNT_IN); + outuint(c_audioControl, NUM_USB_CHAN_IN); + } + else + { + outuint(c_audioControl, SET_CHAN_COUNT_IN); + outuint(c_audioControl, NUM_USB_CHAN_IN_A1); + } #ifdef ADAT_RX - outuint(c_clk_ctl, SET_SMUX); - outuint(c_clk_ctl, 0); - outct(c_clk_ctl, XS1_CT_END); + outuint(c_clk_ctl, SET_SMUX); + outuint(c_clk_ctl, 0); + outct(c_clk_ctl, XS1_CT_END); #endif - - break; + break; #ifdef ADAT_RX - case 2: - - /* Stream active + 8 chans */ - outuint(c_audioControl, SET_CHAN_COUNT_IN); - outuint(c_audioControl, NUM_USB_CHAN_IN-4); - - outuint(c_clk_ctl, SET_SMUX); - outuint(c_clk_ctl, 1); - outct(c_clk_ctl, XS1_CT_END); - break; - - case 3: - outuint(c_audioControl, SET_CHAN_COUNT_IN); - outuint(c_audioControl, NUM_USB_CHAN_IN-6); - - - outuint(c_clk_ctl, SET_SMUX); - outuint(c_clk_ctl, 1); - outct(c_clk_ctl, XS1_CT_END); - /* Stream active + 8 chans */ - //outuint(c_audioControl, 8); - // Handshake - //chkct(c_audioControl, XS1_CT_END); - - break; + case 2: + /* Stream active + 8 chans */ + outuint(c_audioControl, SET_CHAN_COUNT_IN); + outuint(c_audioControl, NUM_USB_CHAN_IN-4); + outuint(c_clk_ctl, SET_SMUX); + outuint(c_clk_ctl, 1); + outct(c_clk_ctl, XS1_CT_END); + break; + case 3: + outuint(c_audioControl, SET_CHAN_COUNT_IN); + outuint(c_audioControl, NUM_USB_CHAN_IN-6); + outuint(c_clk_ctl, SET_SMUX); + outuint(c_clk_ctl, 1); + outct(c_clk_ctl, XS1_CT_END); + break; #endif + } + } + /* No data stage for this request, just do data stage */ + retVal = XUD_DoSetRequestStatus(ep0_in); + } /* if(sp.bRequest == SET_INTERFACE) */ + + break; /* BMREQ_H2D_STANDARD_INT */ + + case USB_BMREQ_D2H_STANDARD_INT: + + switch(sp.bRequest) + { - } - } -#endif - /* No data stage for this request, just do data stage */ - retVal = XUD_DoSetRequestStatus(ep0_in, 0); - break; - - /* A device must support the GetInterface request if it has alternate setting for that interface */ - case GET_INTERFACE: - - buffer[0] = 0; - - /* Bounds check */ - if( sp.wIndex < NUM_INTERFACES ) - buffer[0] = interfaceAlt[sp.wIndex]; - - retVal = XUD_DoGetRequest(ep0_out, ep0_in, buffer, 1, sp.wLength); - break; #ifdef HID_CONTROLS case GET_DESCRIPTOR: + /* Check what inteface request is for */ if(sp.wIndex == INTERFACE_NUM_HID) { - switch (sp.wValue>>8) + /* High byte of wValue is descriptor type */ + unsigned descriptorType = sp.wValue & 0xff00; + switch (descriptorType) { case REPORT: /* Return HID report descriptor */ retVal = XUD_DoGetRequest(ep0_out, ep0_in, hidReportDescriptor, - min(sizeof(hidReportDescriptor),sp.wLength), sp.wLength); + sizeof(hidReportDescriptor), sp.wLength); break; } } - break; #endif default: - //printstr("Unknown Standard Interface Request: "); - //printhexln(sp.bRequest); - //printhexln(sp.bmRequestType.Type); - //printhexln(sp.bmRequestType.Recipient); - //printhexln(sp.bmRequestType.Recipient | (sp.bmRequestType.Type << 5)); - break; + break; } break; /* Recipient: Device */ - case STANDARD_DEVICE_REQUEST: + case USB_BMREQ_H2D_STANDARD_DEV: - /* Standard Device requests (8) */ + /* Inspect for actual request */ switch( sp.bRequest ) { - - /* Set Device Address: This is a unique set request. */ - case SET_ADDRESS: - - /* Status stage: Send a zero length packet */ - retVal = XUD_SetBuffer(ep0_in, buffer, 0); - - /* TODO We should wait until ACK is received for status stage before changing address */ - //XUD_Sup_Delay(50000); - { - timer t; - unsigned time; - t :> time; - t when timerafter(time+50000) :> void; - } - - /* Set device address in XUD */ - XUD_SetDevAddr(sp.wValue); - - break; - - - /* TODO Check direction */ /* Standard request: SetConfiguration */ - case SET_CONFIGURATION: + /* Overriding implementation in USB_StandardRequests */ + case USB_SET_CONFIGURATION: - g_config = sp.wValue; - -#ifdef HOST_ACTIVE_CALL - if(g_config == 1) + g_currentConfig = sp.wValue; + //if(g_current_config == 1) { /* Consider host active with valid driver at this point */ - VendorHostActive(1); + UserHostActive(1); } -#endif #ifdef IAP { int iap_reset = 1; @@ -639,243 +426,190 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, } #endif /* No data stage for this request, just do status stage */ - retVal = XUD_DoSetRequestStatus(ep0_in, 0); + retVal = XUD_DoSetRequestStatus(ep0_in); break; - - case GET_CONFIGURATION: - buffer[0] = g_config; - retVal = XUD_DoGetRequest(ep0_out, ep0_in, buffer, 1, sp.wLength); - break; - - /* Get Status request */ - case GET_STATUS: - -#ifdef SELF_POWERED - buffer[0] = 1; // self powered -#else - buffer[0] = 0; // bus powered -#endif - buffer[1] = 0; // remote wakeup not supported - - retVal = XUD_DoGetRequest(ep0_out, ep0_in, buffer, 2, sp.wLength); - break; - - + default: - XUD_Error("Unknown device request"); + //Unknown device request" break; - } break; - - /* Receipient: Endpoint */ - case STANDARD_ENDPOINT_REQUEST: + + /* Audio Class 1.0 Sampling Freqency Requests go to Endpoint */ + case USB_BMREQ_H2D_CLASS_EP: + case USB_BMREQ_D2H_CLASS_EP: + { + unsigned epNum = sp.wIndex & 0xff; + + if ((epNum == 0x82) || (epNum == 0x01)) + { +#if (AUDIO_CLASS == 2) && defined(AUDIO_CLASS_FALLBACK) + if(g_curUsbSpeed == XUD_SPEED_FS) + { + retVal = AudioEndpointRequests_1(ep0_out, ep0_in, sp, c_audioControl, c_mix_ctl, c_clk_ctl); + } +#elif (AUDIO_CLASS==1) + retVal = AudioEndpointRequests_1(ep0_out, ep0_in, sp, c_audioControl, c_mix_ctl, c_clk_ctl); +#endif + } + + } + break; - /* Standard endpoint requests */ - switch ( sp.bRequest ) - { - - /* ClearFeature */ - case CLEAR_FEATURE: - - switch ( sp.wValue ) + case USB_BMREQ_H2D_CLASS_INT: + case USB_BMREQ_D2H_CLASS_INT: + { + unsigned interfaceNum = sp.wIndex & 0xff; + //unsigned request = (sp.bmRequestType.Recipient ) | (sp.bmRequestType.Type << 5); + + /* TODO Check on return value retval = */ +#ifdef DFU + unsigned DFU_IF = DFU_IF_NUM; + + /* DFU interface number changes based on which mode we are currently running in */ + if (DFU_mode_active) + { + DFU_IF = 0; + } + + if (interfaceNum == DFU_IF) + { + /* If running in application mode stop audio */ + /* Don't interupt audio for save and restore cmds */ + if ((DFU_IF == DFU_IF_NUM) && (sp.bRequest != XMOS_DFU_SAVESTATE) && + (sp.bRequest != XMOS_DFU_RESTORESTATE)) { - case ENDPOINT_HALT: - - /* Mark the endpoint status */ - - SetEndpointStatus(sp.wIndex, 0); - - /* No data stage for this request, just do status stage */ - retVal = XUD_DoSetRequestStatus(ep0_in, 0); - - break; - - - default: - XUD_Error( "Unknown request in Endpoint ClearFeature" ); - break; + // Stop audio + outuint(c_audioControl, SET_SAMPLE_FREQ); + outuint(c_audioControl, AUDIO_STOP_FOR_DFU); + // Handshake + chkct(c_audioControl, XS1_CT_END); } - break; /* B_REQ_CLRFEAR */ - - /* SetFeature */ - case SET_FEATURE: - - switch( sp.wValue ) + + /* This will return 1 if reset requested */ + if (DFUDeviceRequests(ep0_out, ep0_in, sp, null, g_interfaceAlt[sp.wIndex], 1)) { - case ENDPOINT_HALT: - - /* Check request is in range */ - SetEndpointStatus(sp.wIndex, 1); - - break; - - default: - XUD_Error("Unknown feature in SetFeature Request"); - break; + timer tmr; + unsigned s; + tmr :> s; + tmr when timerafter(s + 50000000) :> s; + device_reboot(c_audioControl); } - - retVal = XUD_DoSetRequestStatus(ep0_in, 0); - - break; - - - - /* Endpoint GetStatus Request */ - case GET_STATUS: - - buffer[0] = 0; - buffer[1] = 0; - - if( sp.wIndex & 0x80 ) + /* TODO we should not make the assumption that all DFU requests are handled */ + retVal = 0; + } +#endif + /* Check for: - Audio CONTROL interface request - always 0, note we check for DFU first + * - Audio STREAMING interface request (In or Out) + * - Audio endpoint request (Audio 1.0 Sampling freq requests are sent to the endpoint) + */ + if((interfaceNum == 0) || (interfaceNum == 1) || (interfaceNum == 2)) + { +#if (AUDIO_CLASS == 2) && defined(AUDIO_CLASS_FALLBACK) + if(g_curUsbSpeed == XUD_SPEED_HS) { - /* IN Endpoint */ - if((sp.wIndex&0x7f) < EP_CNT_IN) - { - buffer[0] = ( g_epStatusIn[ sp.wIndex & 0x7F ] & 0xff ); - buffer[1] = ( g_epStatusIn[ sp.wIndex & 0x7F ] >> 8 ); - } + retVal = AudioClassRequests_2(ep0_out, ep0_in, sp, c_audioControl, c_mix_ctl, c_clk_ctl); } else { - /* OUT Endpoint */ - if(sp.wIndex < EP_CNT_OUT) - { - buffer[0] = ( g_epStatusOut[ sp.wIndex ] & 0xff ); - buffer[1] = ( g_epStatusOut[ sp.wIndex ] >> 8 ); - } + retVal = AudioClassRequests_1(ep0_out, ep0_in, sp, c_audioControl, c_mix_ctl, c_clk_ctl); } - - retVal = XUD_DoGetRequest(ep0_out, ep0_in, buffer, 2, sp.wLength); - - break; - - default: - //printstrln("Unknown Standard Endpoint Request"); - break; - - } - break; - - case CLASS_INTERFACE_REQUEST: - case CLASS_ENDPOINT_REQUEST: - { - unsigned interfaceNum = sp.wIndex & 0xff; - unsigned request = (sp.bmRequestType.Recipient ) | (sp.bmRequestType.Type << 5); - - /* TODO Check interface number */ - /* TODO Check on return value retval = */ -#ifdef DFU - unsigned DFU_IF = DFU_IF_NUM; - - /* DFU interface number changes based on which mode we are currently running in */ - if (DFU_mode_active) - { - DFU_IF = 0; - } - - if (interfaceNum == DFU_IF) - { - - /* If running in application mode stop audio */ - /* Don't interupt audio for save and restore cmds */ - if ((DFU_IF == DFU_IF_NUM) && (sp.bRequest != XMOS_DFU_SAVESTATE) && (sp.bRequest != XMOS_DFU_RESTORESTATE)) - { - // Stop audio - outuint(c_audioControl, SET_SAMPLE_FREQ); - outuint(c_audioControl, AUDIO_STOP_FOR_DFU); - // Handshake - chkct(c_audioControl, XS1_CT_END); - - } - - - /* This will return 1 if reset requested */ - if (DFUDeviceRequests(ep0_out, ep0_in, sp, null, interfaceAlt[sp.wIndex], 1)) - { - timer tmr; - unsigned s; - tmr :> s; - tmr when timerafter(s + 50000000) :> s; - device_reboot(c_audioControl); - } - - /* TODO we should not make the assumption that all DFU requests are handled */ - retVal = 0; - } - /* Check for: - Audio CONTROL interface request - always 0, note we check for DFU first - * - Audio STREAMING interface request - * - Audio endpoint request - */ - else if(((request == CLASS_INTERFACE_REQUEST) && (interfaceNum == 0)) - || ((request == CLASS_INTERFACE_REQUEST) && (interfaceNum == 1 || interfaceNum == 2)) - || (request == CLASS_ENDPOINT_REQUEST && ((interfaceNum == 0x82) || (interfaceNum == 0x01)))) - { -#endif - -#if (AUDIO_CLASS == 2) && defined(AUDIO_CLASS_FALLBACK) - if(g_curUsbSpeed == XUD_SPEED_HS) - { - retVal = AudioClassRequests_2(ep0_out, ep0_in, sp, c_audioControl, c_mix_ctl, c_clk_ctl); - } - else - { - retVal = AudioClassRequests_1(ep0_out, ep0_in, sp, c_audioControl, c_mix_ctl, c_clk_ctl); - } #elif (AUDIO_CLASS==2) - retVal = AudioClassRequests_2(ep0_out, ep0_in, sp, c_audioControl, c_mix_ctl, c_clk_ctl); + retVal = AudioClassRequests_2(ep0_out, ep0_in, sp, c_audioControl, c_mix_ctl, c_clk_ctl); #else - retVal = AudioClassRequests_1(ep0_out, ep0_in, sp, c_audioControl, c_mix_ctl, c_clk_ctl); + retVal = AudioClassRequests_1(ep0_out, ep0_in, sp, c_audioControl, c_mix_ctl, c_clk_ctl); #endif #ifdef VENDOR_AUDIO_REQS - /* If retVal is 1 at this point, then request to audio interface not handled - handle vendor audio reqs */ - if(retVal == 1) - { - retVal = VendorAudioRequests(ep0_out, ep0_in, sp.bRequest, - sp.wValue >> 8, sp.wValue & 0xff, - sp.wIndex >> 8, sp.bmRequestType.Direction, - c_audioControl, c_mix_ctl, c_clk_ctl); - } + /* If retVal is 1 at this point, then request to audio interface not handled - handle vendor audio reqs */ + if(retVal == 1) + { + retVal = VendorAudioRequests(ep0_out, ep0_in, sp.bRequest, + sp.wValue >> 8, sp.wValue & 0xff, + sp.wIndex >> 8, sp.bmRequestType.Direction, + c_audioControl, c_mix_ctl, c_clk_ctl); + } #endif #ifdef DFU - } + } #endif - } + } break; default: - //printstr("unrecognised request\n"); - //printhexln(sp.bRequest); - //printhexln(sp.bmRequestType.Type); - //printhexln(sp.bmRequestType.Recipient); - //printhexln(sp.bmRequestType.Recipient | (sp.bmRequestType.Type << 5)); break; - - } } /* if(retVal == 0) */ - if(retVal == 1) + if(retVal > 0) { - /* Did not handle request - Protocol Stall Secion 8.4.5 of USB 2.0 spec - * Detailed in Section 8.5.3. Protocol stall is unique to control pipes. - Protocol stall differs from functional stall in meaning and duration. - A protocol STALL is returned during the Data or Status stage of a control - transfer, and the STALL condition terminates at the beginning of the - next control transfer (Setup). The remainder of this section refers to - the general case of a functional stall */ - XUD_SetStall_Out(0); - XUD_SetStall_In(0); +#ifndef DFU + +#ifdef AUDIO_CLASS_FALLBACK + /* Return Audio 2.0 Descriptors with Audio 1.0 as fallback */ + retVal = USB_StandardRequests(ep0_out, ep0_in, + devDesc_Audio2, sizeof(devDesc_Audio2), + cfgDesc_Audio2, sizeof(cfgDesc_Audio2), + devDesc_Audio1, sizeof(devDesc_Audio1), + cfgDesc_Audio1, sizeof(cfgDesc_Audio1), + strDescs, + sp, c_usb_test, g_curUsbSpeed); +#else + /* Return Audio 2.0 Descriptors */ + cfgDesc_Audio2[1] = CONFIGURATION; + cfgDesc_Null[1] = OTHER_SPEED_CONFIGURATION; + + retVal = USB_StandardRequests(ep0_out, ep0_in, + devDesc_Audio2, sizeof(devDesc_Audio2), + cfgDesc_Audio2, sizeof(cfgDesc_Audio2), + devDesc_Null, sizeof(devDesc_Null), + cfgDesc_Null, sizeof(cfgDesc_Null), + strDescs, + sp, c_usb_test, g_curUsbSpeed); +#endif + +#else /* ifndef DFU */ + if (!DFU_mode_active) + { +#ifdef AUDIO_CLASS_FALLBACK + /* Return Audio 2.0 Descriptors with Audio 1.0 as fallback */ + retVal = USB_StandardRequests(ep0_out, ep0_in, + devDesc_Audio2, sizeof(devDesc_Audio2), + cfgDesc_Audio2, sizeof(cfgDesc_Audio2), + devDesc_Audio1, sizeof(devDesc_Audio1), + cfgDesc_Audio1, sizeof(cfgDesc_Audio1), + strDescs, sp, c_usb_test, g_curUsbSpeed); +#else + /* Return Audio 2.0 Descriptors with Null device as fallback */ + retVal = USB_StandardRequests(ep0_out, ep0_in, + devDesc_Audio2, sizeof(devDesc_Audio2), + cfgDesc_Audio2, sizeof(cfgDesc_Audio2), + devDesc_Null, sizeof(devDesc_Null), + cfgDesc_Null, sizeof(cfgDesc_Null), + strDescs, sp, c_usb_test, g_curUsbSpeed); +#endif } + else + { + /* Running in DFU mode - always return same descs for DFU whether HS or FS */ + retVal = USB_StandardRequests(ep0_out, ep0_in, + DFUdevDesc, sizeof(DFUdevDesc), + DFUcfgDesc, sizeof(DFUcfgDesc), + null, 0, /* Used same descriptors for full and high-speed */ + null, 0, + strDescs, sp, c_usb_test, g_curUsbSpeed); + } +#endif /* ifndef DFU else */ + + } if (retVal < 0) { g_curUsbSpeed = XUD_ResetEndpoint(ep0_out, ep0_in); - g_config = 0; + g_currentConfig = 0; #ifdef DFU if (DFUReportResetState(null)) @@ -900,9 +634,6 @@ void Endpoint0( chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, DFU_mode_active = 0; // Send reboot command - //outuint(c_audioControl, SET_SAMPLE_FREQ); - //outuint(c_audioControl, AUDIO_REBOOT_FROM_DFU); - // No handshake on reboot tmr :> s; tmr when timerafter(s + 5000000) :> s; device_reboot(c_audioControl); diff --git a/module_usb_audio/usb_buffer/usb_buffer.xc b/module_usb_audio/usb_buffer/usb_buffer.xc index 254b575b..93d24fe6 100644 --- a/module_usb_audio/usb_buffer/usb_buffer.xc +++ b/module_usb_audio/usb_buffer/usb_buffer.xc @@ -2,12 +2,6 @@ #include #include -//In this file xud.h is not included since we are interpreting the -//assembly functions GetData/SetData as taking xc_ptrs -//#include "xud.h" - -#define XUD_SPEED_HS 2 - #include "usb.h" #include "devicedefines.h" #include "usb_midi.h" @@ -98,24 +92,24 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud #endif ) { - XUD_ep ep_aud_out = XUD_Init_Ep(c_aud_out); - XUD_ep ep_aud_in = XUD_Init_Ep(c_aud_in); - XUD_ep ep_aud_fb = XUD_Init_Ep(c_aud_fb); + XUD_ep ep_aud_out = XUD_InitEp(c_aud_out); + XUD_ep ep_aud_in = XUD_InitEp(c_aud_in); + XUD_ep ep_aud_fb = XUD_InitEp(c_aud_fb); #ifdef MIDI - XUD_ep ep_midi_from_host = XUD_Init_Ep(c_midi_from_host); - XUD_ep ep_midi_to_host = XUD_Init_Ep(c_midi_to_host); + XUD_ep ep_midi_from_host = XUD_InitEp(c_midi_from_host); + XUD_ep ep_midi_to_host = XUD_InitEp(c_midi_to_host); #endif #ifdef IAP - XUD_ep ep_iap_from_host = XUD_Init_Ep(c_iap_from_host); - XUD_ep ep_iap_to_host = XUD_Init_Ep(c_iap_to_host); - XUD_ep ep_iap_to_host_int = XUD_Init_Ep(c_iap_to_host_int); + XUD_ep ep_iap_from_host = XUD_InitEp(c_iap_from_host); + XUD_ep ep_iap_to_host = XUD_InitEp(c_iap_to_host); + XUD_ep ep_iap_to_host_int = XUD_InitEp(c_iap_to_host_int); #endif #if defined(SPDIF_RX) || defined(ADAT_RX) - XUD_ep ep_int = XUD_Init_Ep(c_int); + XUD_ep ep_int = XUD_InitEp(c_int); #endif #ifdef HID_CONTROLS - XUD_ep ep_hid = XUD_Init_Ep(c_hid); + XUD_ep ep_hid = XUD_InitEp(c_hid); #endif @@ -699,7 +693,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, chanend c_aud else { // Too many events from device - drop - printstr("DROP"); + //printstr("DROP"); } /* Once we have the whole message, sent it to host */ diff --git a/module_usb_audio/xuduser/xuduser.xc b/module_usb_audio/xuduser/xuduser.xc index 8a654439..564eeb11 100644 --- a/module_usb_audio/xuduser/xuduser.xc +++ b/module_usb_audio/xuduser/xuduser.xc @@ -1,23 +1,22 @@ #include "devicedefines.h" - -#ifdef HOST_ACTIVE_CALL -void VendorHostActive(int valid); +#include "hostactive.h" +#include "audiostream.h" void XUD_UserSuspend(void) { - VendorHostActive(0); + UserAudioStreamStop(); + UserHostActive(0); } void XUD_UserResume(void) { unsigned config; - asm("ldw %0, dp[g_config]" : "=r" (config):); + asm("ldw %0, dp[g_currentConfig]" : "=r" (config):); if(config == 1) { - VendorHostActive(1); + UserHostActive(1); } } -#endif