diff --git a/CHANGELOG.rst b/CHANGELOG.rst index d23d93e6..661c3f07 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,10 +1,27 @@ sc_usb_audio Change Log ======================= +7.0.0 +------ + +6.30.0 +------ + - RESOLVED: Number of PDM microphone channels configured now based on + NUM_PDM_MICS define (previously hard-coded) + - RESOLVED: PDM microphone clock divide now based MCLK defines (previously hard-coded) + - CHANGE: Second microphone decimation core only run if NUM_PDM_MICS > 4 + +6.20.0 +------ + - RESOLVED: Intra-frame sample delays of 1/2 samples on input streaming in TDM mode + - RESOLVED: Build issue with NUM_USB_CHAN_OUT set to 0 and MIXER enabled + - RESOLVED: SPDIF_TX_INDEX not defined build warning only emitted when SPDIF_TX defined + - RESOLVED: Failure to enter DFU mode when configured without input volume control + 6.19.0 ------ - - RESOLVED: SPDIF_TX_INDEX not defined build warning only emitted when SPDIF_TX defined - - RESOLVED: Failure to enter DFU mode when configured without input volume control + - RESOLVED: SPDIF_TX_INDEX not defined build warning only emitted when SPDIF_TX defined + - RESOLVED: Failure to enter DFU mode when configured without input volume control 6.18.1 ------ diff --git a/README.rst b/README.rst index 3e501ac5..6d13ed99 100644 --- a/README.rst +++ b/README.rst @@ -1,7 +1,7 @@ USB Audio Shared ................ -:Latest release: 6.18.1alpha0 +:Latest release: 6.19.0alpha0 :Maintainer: xross :Description: USB Audio Shared Components. For use in the XMOS USB Audio Refererence Designs. diff --git a/module_dfu/src/dfu.xc b/module_dfu/src/dfu.xc index 559842be..5a528334 100644 --- a/module_dfu/src/dfu.xc +++ b/module_dfu/src/dfu.xc @@ -203,7 +203,7 @@ static int DFU_Dnload(unsigned int request_len, unsigned int block_num, const un static int DFU_Upload(unsigned int request_len, unsigned int block_num, unsigned data_out[16], unsigned &DFU_state) { - unsigned int cmd_data[16]; + unsigned int cmd_data[1]; unsigned int firstRead = 0; // Start at flash address 0 @@ -236,8 +236,8 @@ static int DFU_Upload(unsigned int request_len, unsigned int block_num, unsigned { cmd_data[0] = !firstRead; - // Read whole (256bytes) page from the image on the flash - flash_cmd_read_page((cmd_data, unsigned char[64])); + // Read whole (256bytes) page from the image on the flash into a memory buffer + flash_cmd_read_page((cmd_data, unsigned char[1])); subPagesLeft = 4; // If address out of range, terminate! diff --git a/module_usb_audio/audio_io/audio_io.xc b/module_usb_audio/audio_io/audio_io.xc index a804857b..b685b508 100755 --- a/module_usb_audio/audio_io/audio_io.xc +++ b/module_usb_audio/audio_io/audio_io.xc @@ -12,10 +12,11 @@ #include #include #include +#include #include "devicedefines.h" -#include "dfu_interface.h" +#include "xua_audio.h" #include "audioports.h" #include "audiohw.h" #ifdef SPDIF_TX @@ -23,22 +24,50 @@ #endif #ifdef ADAT_TX #include "adat_tx.h" - #ifndef ADAT_TX_USE_SHARED_BUFF #error Designed for ADAT tx shared buffer mode ONLY #endif #endif -#include "xua_audio.h" - #include "commands.h" #include "xc_ptr.h" -/* TODO 32 is max expected channels */ -static unsigned samplesOut[32]; +#define MAX(x,y) ((x)>(y) ? (x) : (y)) -/* Two buffers for ADC data to allow for DAC and ADC ports being offset */ -static unsigned samplesIn[2][32]; +static unsigned samplesOut[MAX(NUM_USB_CHAN_OUT, I2S_CHANS_DAC)]; + +#ifndef ADAT_RX +#define ADAT_RX 0 +#endif + +#ifndef SPDIF_RX +#define SPDIF_RX 0 +#endif + +/* Two buffers for ADC data to allow for DAC and ADC I2S ports being offset */ +#define IN_CHAN_COUNT (I2S_CHANS_ADC + NUM_PDM_MICS + (8*ADAT_RX) + (2*SPDIF_RX)) + +static unsigned samplesIn[2][MAX(NUM_USB_CHAN_IN, IN_CHAN_COUNT)]; + +#if defined(ADAT_RX) && (ADAT_RX ==0) +#undef ADAT_RX +#endif + +#if defined(SPDIF_RX) && (SPDIF_RX ==0) +#undef SPDIF_RX +#endif + +static int downsamplingCounter = 0; +#if (I2S_DOWNSAMPLE_FACTOR > 1) +#include "src.h" +static union ds3Data +{ + long long doubleWordAlignmentEnsured; + /* [Number of I2S channels][Number of samples/phases][Taps per phase] */ + int32_t delayLine[I2S_DOWNSAMPLE_CHANS][I2S_DOWNSAMPLE_FACTOR][24]; +} ds3Data; +static int64_t ds3Sum[I2S_DOWNSAMPLE_CHANS]; +#endif #if (DSD_CHANS_DAC != 0) extern buffered out port:32 p_dsd_dac[DSD_CHANS_DAC]; @@ -222,7 +251,7 @@ static inline void TransferAdatTxSamples(chanend c_adat_out, const unsigned samp } #endif -/* sampsFromUsbToAudio: The sample frame the device has recived from the host and is going to play to the output audio interfaces */ +/* sampsFromUsbToAudio: The sample frame the device has received from the host and is going to play to the output audio interfaces */ /* sampsFromAudioToUsb: The sample frame that was received from the audio interfaces and that the device is going to send to the host */ void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[], client audManage_if i_audMan); @@ -276,7 +305,7 @@ static inline unsigned DoSampleTransfer(chanend c_out, const int readBuffNo, con for(int i = 0; i < NUM_USB_CHAN_IN; i++) { outuint(c_out, samplesIn[readBuffNo][i]); - } + } #endif } @@ -468,6 +497,10 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, } #endif +#if (I2S_DOWNSAMPLE_FACTOR > 1) + memset(&ds3Data.delayLine, 0, sizeof ds3Data); +#endif + unsigned command = DoSampleTransfer(c_out, readBuffNo, underflowWord, i_audMan); #ifdef ADAT_TX @@ -482,6 +515,8 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, return command; } + downsamplingCounter = 0; + InitPorts(divide); /* TODO In master mode, the i/o loop assumes L/RCLK = 32bit clocks. We should check this every interation @@ -597,11 +632,17 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, else #endif { +#if (I2S_DOWNSAMPLE_FACTOR > 1) + if (0 == downsamplingCounter) + { + memset(&ds3Sum, 0, sizeof ds3Sum); + } +#endif #if (I2S_CHANS_ADC != 0) /* Input previous L sample into L in buffer */ index = 0; /* First input (i.e. frameCount == 0) we read last ADC channel of previous frame.. */ - unsigned buffIndex = (frameCount < 3) ? !readBuffNo : readBuffNo; + unsigned buffIndex = (frameCount > 1) ? !readBuffNo : readBuffNo; #pragma loop unroll /* First time around we get channel 7 of TDM8 */ @@ -614,6 +655,26 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, /* Note the use of readBuffNo changes based on frameCount */ samplesIn[buffIndex][((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 0, 2, 4.. on each line. +#if (I2S_DOWNSAMPLE_FACTOR > 1) + if ((I2S_DOWNSAMPLE_FACTOR - 1) == downsamplingCounter) + { + samplesIn[readBuffNo][((frameCount-2)&(I2S_CHANS_PER_FRAME-1))] = + src_ds3_voice_add_final_sample( + ds3Sum[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i], + ds3Data.delayLine[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i][downsamplingCounter], + src_ff3v_ds3_voice_coefs[downsamplingCounter], + samplesIn[readBuffNo][((frameCount-2)&(I2S_CHANS_PER_FRAME-1))]); + } + else + { + ds3Sum[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i] = + src_ds3_voice_add_sample( + ds3Sum[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i], + ds3Data.delayLine[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i][downsamplingCounter], + src_ff3v_ds3_voice_coefs[downsamplingCounter], + samplesIn[readBuffNo][((frameCount-2)&(I2S_CHANS_PER_FRAME-1))]); + } +#endif // (I2S_DOWNSAMPLE_FACTOR > 1) } #endif @@ -687,20 +748,22 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, #endif #if (NUM_PDM_MICS > 0) - /* Get samples from PDM->PCM comverter */ - c_pdm_pcm <: 1; - master + if ((I2S_DOWNSAMPLE_FACTOR - 1) == downsamplingCounter) { + /* Get samples from PDM->PCM comverter */ + c_pdm_pcm <: 1; + master + { #pragma loop unroll - for(int i = 0; i < NUM_PDM_MICS; i++) - { - c_pdm_pcm :> samplesIn[readBuffNo][i]; - } + for(int i = PDM_MIC_INDEX; i < (NUM_PDM_MICS + PDM_MIC_INDEX); i++) + { + c_pdm_pcm :> samplesIn[readBuffNo][i]; + } + } } #endif } - #if (I2S_CHANS_ADC != 0) index = 0; /* Channels 0, 2, 4.. on each line */ @@ -712,6 +775,26 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++])); samplesIn[buffIndex][((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 1, 3, 5.. on each line. +#if ((I2S_DOWNSAMPLE_FACTOR > 1) && !I2S_DOWNSAMPLE_MONO) + if ((I2S_DOWNSAMPLE_FACTOR - 1) == downsamplingCounter) + { + samplesIn[buffIndex][((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = + src_ds3_voice_add_final_sample( + ds3Sum[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i], + ds3Data.delayLine[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i][downsamplingCounter], + src_ff3v_ds3_voice_coefs[downsamplingCounter], + samplesIn[readBuffNo][((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i]); + } + else + { + ds3Sum[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i] = + src_ds3_voice_add_sample( + ds3Sum[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i], + ds3Data.delayLine[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i][downsamplingCounter], + src_ff3v_ds3_voice_coefs[downsamplingCounter], + samplesIn[readBuffNo][((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i]); + } +#endif // ((I2S_DOWNSAMPLE_FACTOR > 1) && !I2S_DOWNSAMPLE_MONO) } #endif @@ -797,22 +880,30 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out, if(frameCount == I2S_CHANS_PER_FRAME) #endif { - /* Do samples transfer */ - /* The below looks a bit odd but forces the compiler to inline twice */ - unsigned command; - if(readBuffNo) - command = DoSampleTransfer(c_out, 1, underflowWord, i_audMan); - else - command = DoSampleTransfer(c_out, 0, underflowWord, i_audMan); - - if(command) + if ((I2S_DOWNSAMPLE_FACTOR - 1) == downsamplingCounter) { - return command; - } + /* Do samples transfer */ + /* The below looks a bit odd but forces the compiler to inline twice */ + unsigned command; + if(readBuffNo) + command = DoSampleTransfer(c_out, 1, underflowWord, i_audMan); + else + command = DoSampleTransfer(c_out, 0, underflowWord, i_audMan); - /* Reset frame counter and flip the ADC buffer */ - frameCount = 0; - readBuffNo = !readBuffNo; + if(command) + { + return command; + } + + /* Reset frame counter and flip the ADC buffer */ + downsamplingCounter = 0; + frameCount = 0; + readBuffNo = !readBuffNo; + } + else + { + ++downsamplingCounter; + } } } @@ -927,7 +1018,7 @@ chanend ?c_config, chanend ?c unsigned adatMultiple = 0; #endif - unsigned curSamFreq = DEFAULT_FREQ; + unsigned curSamFreq = DEFAULT_FREQ * I2S_DOWNSAMPLE_FACTOR; unsigned curSamRes_DAC = STREAM_FORMAT_OUTPUT_1_RESOLUTION_BITS; /* Default to something reasonable */ unsigned curSamRes_ADC = STREAM_FORMAT_INPUT_1_RESOLUTION_BITS; /* Default to something reasonable - note, currently this never changes*/ unsigned command; @@ -1082,7 +1173,7 @@ chanend ?c_config, chanend ?c { /* TODO wait for good mclk instead of delay */ /* No delay for DFU modes */ - if ((curSamFreq != AUDIO_REBOOT_FROM_DFU) && (curSamFreq != AUDIO_STOP_FOR_DFU) && command) + if (((curSamFreq / I2S_DOWNSAMPLE_FACTOR) != AUDIO_REBOOT_FROM_DFU) && ((curSamFreq / I2S_DOWNSAMPLE_FACTOR) != AUDIO_STOP_FOR_DFU) && command) { #if 0 /* User should ensure MCLK is stable in AudioHwConfig */ @@ -1125,7 +1216,7 @@ chanend ?c_config, chanend ?c #if NUM_PDM_MICS > 0 /* Send decimation factor to PDM task(s) */ - c_pdm_in <: curSamFreq; + c_pdm_in <: curSamFreq / I2S_DOWNSAMPLE_FACTOR; #endif #ifdef ADAT_TX @@ -1158,15 +1249,12 @@ chanend ?c_config, chanend ?c #if (NUM_PDM_MICS > 0) c_pdm_in, #endif - null -//#ifdef RUN_DSP_TASK - , i_audMan -//#endif + null, i_audMan ); if(command == SET_SAMPLE_FREQ) { - curSamFreq = inuint(c_mix_out); + curSamFreq = inuint(c_mix_out) * I2S_DOWNSAMPLE_FACTOR; } else if(command == SET_STREAM_FORMAT_OUT) { @@ -1179,7 +1267,7 @@ chanend ?c_config, chanend ?c } /* Currently no more audio will happen after this point */ - if (curSamFreq == AUDIO_STOP_FOR_DFU) + if ((curSamFreq / I2S_DOWNSAMPLE_FACTOR) == AUDIO_STOP_FOR_DFU) { outct(c_mix_out, XS1_CT_END); diff --git a/module_usb_audio/audio_io/userbuffermanagement.c b/module_usb_audio/audio_io/userbuffermanagement.c index 25cddcc7..fa4b07b7 100644 --- a/module_usb_audio/audio_io/userbuffermanagement.c +++ b/module_usb_audio/audio_io/userbuffermanagement.c @@ -4,10 +4,10 @@ /* Default implentation for UserBufferManagement() */ void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[] - , unsigned i_dsp + , unsigned i_audMan ) __attribute__ ((weak)); void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[] - , unsigned i_dsp + , unsigned i_audMan ) { /* Do nothing */ diff --git a/module_usb_audio/audio_io/xua_audio.h b/module_usb_audio/audio_io/xua_audio.h index 473dfe9a..f2a65f6b 100644 --- a/module_usb_audio/audio_io/xua_audio.h +++ b/module_usb_audio/audio_io/xua_audio.h @@ -1,10 +1,7 @@ #ifndef __audio_h__ #define __audio_h__ -//#include "devicedefines.h" #include "dfu_interface.h" -//#include "xua_dsp.h" - typedef interface audManage_if { @@ -18,8 +15,6 @@ typedef interface audManage_if } audManage_if; - - /** The audio driver thread. * * This function drives I2S ports and handles samples to/from other digital @@ -46,9 +41,7 @@ void audio(chanend c_in, #if (NUM_PDM_MICS > 0) , chanend c_pdm_in #endif -//#ifdef RUN_DSP_TASK , client audManage_if i_audMan -//#endif ); void SpdifTxWrapper(chanend c_spdif_tx); diff --git a/module_usb_audio/devicedefines.h b/module_usb_audio/devicedefines.h index b1269782..09bd51ee 100644 --- a/module_usb_audio/devicedefines.h +++ b/module_usb_audio/devicedefines.h @@ -121,6 +121,41 @@ #define I2S_WIRES_ADC (I2S_CHANS_ADC / I2S_CHANS_PER_FRAME) #endif +/** + * @brief Incoming I2S (device to host) channels can be downsampled by a factor of 3. + * + * Default: 1 i.e. downsampling is disabled. + */ +#ifndef I2S_DOWNSAMPLE_FACTOR +#define I2S_DOWNSAMPLE_FACTOR (1) +#else + #if (I2S_DOWNSAMPLE_FACTOR != 3) && (I2S_DOWNSAMPLE_FACTOR != 1) + #error Unsupported I2S downsampling configuration + #endif +#endif + +/** + * @brief Only downsample one channel per I2S frame. + * + * Default: 0 i.e. mono mode is disabled, all channels will be downsampled. + */ +#ifndef I2S_DOWNSAMPLE_MONO +#define I2S_DOWNSAMPLE_MONO (0) +#endif + +/** + * @brief Number of incoming (device to host) I2S channels to downsample. + * + * Default: The number of I2S incoming channels, or half this if mono downsampling is enabled. + */ +#if (I2S_DOWNSAMPLE_MONO == 1) + #define I2S_DOWNSAMPLE_CHANS (I2S_CHANS_ADC / 2) + #if ((I2S_DOWNSAMPLE_FACTOR > 1) && (I2S_MODE_TDM == 1)) + #error Mono I2S downsampling is not avaliable in TDM mode + #endif +#else +#define I2S_DOWNSAMPLE_CHANS I2S_CHANS_ADC +#endif /** * @brief Max supported sample frequency for device (Hz). Default: 192000 @@ -468,14 +503,14 @@ * @brief Device firmware version number in Binary Coded Decimal format: 0xJJMN where JJ: major, M: minor, N: sub-minor version number. */ #ifndef BCD_DEVICE_J -#define BCD_DEVICE_J 6 +#define BCD_DEVICE_J 7 #endif /** * @brief Device firmware version number in Binary Coded Decimal format: 0xJJMN where JJ: major, M: minor, N: sub-minor version number. */ #ifndef BCD_DEVICE_M -#define BCD_DEVICE_M 19 +#define BCD_DEVICE_M 0 #endif /** @@ -1046,7 +1081,7 @@ #undef OUT_VOLUME_IN_MIXER #else #if defined(MIXER) -// Enabled by default +// Disabled by default //#define OUT_VOLUME_IN_MIXER #endif #endif @@ -1066,7 +1101,7 @@ #undef IN_VOLUME_IN_MIXER #else #if defined(MIXER) -/* Enabled by default */ +/* Disabled by default */ //#define IN_VOLUME_IN_MIXER #endif #endif @@ -1218,7 +1253,11 @@ enum USBEndpointNumber_Out #define DFU_VENDOR_ID VENDOR_ID #define DFU_BCD_DEVICE BCD_DEVICE #define DFU_MANUFACTURER_STR_INDEX offsetof(StringDescTable_t, vendorStr)/sizeof(char *) +#if (AUDIO_CLASS == 2) #define DFU_PRODUCT_STR_INDEX offsetof(StringDescTable_t, productStr_Audio2)/sizeof(char *) +#else +#define DFU_PRODUCT_STR_INDEX offsetof(StringDescTable_t, productStr_Audio1)/sizeof(char *) +#endif #endif /* USB test mode support enabled by default (Required for compliance testing) */ diff --git a/module_usb_audio/endpoint0/audiorequests.xc b/module_usb_audio/endpoint0/audiorequests.xc index 591d36fb..7a09bfa5 100644 --- a/module_usb_audio/endpoint0/audiorequests.xc +++ b/module_usb_audio/endpoint0/audiorequests.xc @@ -45,9 +45,9 @@ extern unsigned char mixSel[MAX_MIX_COUNT][MIX_INPUTS]; /* Global var for current frequency, set to default freq */ unsigned int g_curSamFreq = DEFAULT_FREQ; -//unsigned int g_curSamFreq48000Family = DEFAULT_FREQ % 48000 == 0; - #if 0 +unsigned int g_curSamFreq48000Family = DEFAULT_FREQ % 48000 == 0; + /* Original feedback implementation */ long long g_curSamFreqMultiplier = (DEFAULT_FREQ * 512 * 4) / (DEFAULT_MCLK_FREQ); #endif @@ -131,6 +131,7 @@ static void setG_curSamFreqMultiplier(unsigned x) } #endif +#if (OUTPUT_VOLUME_CONTROL == 1) || (INPUT_VOLUME_CONTROL == 1) /* Update master volume i.e. i.e update weights for all channels */ static void updateMasterVol( int unitID, chanend ?c_mix_ctl) { @@ -266,6 +267,7 @@ static void updateVol(int unitID, int channel, chanend ?c_mix_ctl) } } } +#endif /* Handles the audio class specific requests * returns: XUD_RES_OKAY if request dealt with successfully without error, @@ -275,7 +277,7 @@ static void updateVol(int unitID, int channel, chanend ?c_mix_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 ) { - unsigned char buffer[512]; + unsigned char buffer[128]; int unitID; XUD_Result_t result; unsigned datalength; @@ -312,6 +314,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c return result; } +#if MAX_FREQ != MIN_FREQ if(datalength == 4) { /* Re-construct Sample Freq */ @@ -369,7 +372,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c /* Allow time for our feedback to stabilise*/ FeedbackStabilityDelay(); } - +#endif /* MAX_FREQ != MIN_FREQ */ /* Send 0 Length as status stage */ XUD_DoSetRequestStatus(ep0_in); } @@ -514,6 +517,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c break; } +#if (OUTPUT_VOLUME_CONTROL == 1) || (INPUT_VOLUME_CONTROL == 1) /* Feature Units */ case FU_USBOUT: case FU_USBIN: @@ -629,6 +633,7 @@ int AudioClassRequests_2(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c } break; /* FU_USBIN */ +#endif #if defined(MIXER) && (MAX_MIX_COUNT > 0) case ID_XU_OUT: @@ -1076,7 +1081,7 @@ int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp */ XUD_Result_t result; - unsigned char buffer[1024]; + unsigned char buffer[128]; unsigned length; /* Host to Device */ @@ -1094,7 +1099,7 @@ int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp { return result; } - +#if (MAX_FREQ != MIN_FREQ) if(controlSelector == SAMPLING_FREQ_CONTROL) { /* Expect length 3 for sample rate */ @@ -1116,22 +1121,6 @@ int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp if(curSamFreq48000Family || curSamFreq44100Family) { g_curSamFreq = newSampleRate; -#if 0 - /* Original feedback implementation */ - - int newMasterClock; - - if(g_curSamFreq48000Family) - { - newMasterClock = MCLK_48; - } - else - { - newMasterClock = MCLK_441; - } - - setG_curSamFreqMultiplier((g_curSamFreq*512*4)/newMasterClock); -#endif /* Instruct audio thread to change sample freq */ outuint(c_audioControl, SET_SAMPLE_FREQ); @@ -1147,6 +1136,9 @@ int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp return XUD_SetBuffer(ep0_in, buffer, 0); } } +#else + return XUD_SetBuffer(ep0_in, buffer, 0); +#endif } break; } @@ -1171,12 +1163,13 @@ int AudioEndpointRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp 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]; + unsigned char buffer[128]; unsigned unitID; XUD_Result_t result; /* Inspect request */ /* Note we could check sp.bmRequestType.Direction if we wanted to be really careful */ +#if (OUTPUT_VOLUME_CONTROL == 1) || (INPUT_VOLUME_CONTROL == 1) switch(sp.bRequest) { case UAC_B_REQ_SET_CUR: @@ -1288,7 +1281,7 @@ int AudioClassRequests_1(XUD_ep ep0_out, XUD_ep ep0_in, USB_SetupPacket_t &sp, c buffer[1] = (VOLUME_RES_MIXER >> 8); return XUD_DoGetRequest(ep0_out, ep0_in, buffer, 2, sp.wLength); } - +#endif return 1; } #endif diff --git a/module_usb_audio/endpoint0/descriptors.h b/module_usb_audio/endpoint0/descriptors.h index aa2d1037..866bf029 100644 --- a/module_usb_audio/endpoint0/descriptors.h +++ b/module_usb_audio/endpoint0/descriptors.h @@ -35,13 +35,14 @@ typedef struct STR_TABLE_ENTRY(vendorStr); STR_TABLE_ENTRY(serialStr); +#if (AUDIO_CLASS == 2) /* Audio 2.0 Strings */ STR_TABLE_ENTRY(productStr_Audio2); /* Product string for Audio 2 */ STR_TABLE_ENTRY(outputInterfaceStr_Audio2); /* iInterface for streaming intefaces */ STR_TABLE_ENTRY(inputInterfaceStr_Audio2); /* iInterface for streaming intefaces */ STR_TABLE_ENTRY(usbInputTermStr_Audio2); /* Users sees as output from host */ STR_TABLE_ENTRY(usbOutputTermStr_Audio2); /* User sees as input to host */ - +#endif #if defined (AUDIO_CLASS_FALLBACK) || (AUDIO_CLASS == 1) /* Audio 1.0 Strings */ STR_TABLE_ENTRY(productStr_Audio1); /* Product string for Audio 1 */ @@ -50,6 +51,7 @@ typedef struct STR_TABLE_ENTRY(usbInputTermStr_Audio1); /* Users sees as output from host */ STR_TABLE_ENTRY(usbOutputTermStr_Audio1); /* User sees as input to host */ #endif +#if (AUDIO_CLASS == 2) STR_TABLE_ENTRY(clockSelectorStr); /* iClockSel */ STR_TABLE_ENTRY(internalClockSourceStr); /* iClockSource for internal clock */ #ifdef SPDIF_RX @@ -58,6 +60,7 @@ typedef struct #ifdef ADAT_RX STR_TABLE_ENTRY(adatClockSourceStr); /* iClockSource for external S/PDIF clock */ #endif +#endif #ifdef DFU STR_TABLE_ENTRY(dfuStr); /* iInterface for DFU interface */ #endif @@ -291,7 +294,9 @@ typedef struct #if defined(MIXER) && (MAX_MIX_COUNT > 7) STR_TABLE_ENTRY(mixOutStr_8); #endif +#ifdef IAP STR_TABLE_ENTRY(iAPInterfaceStr); +#endif #ifdef IAP_EA_NATIVE_TRANS STR_TABLE_ENTRY(iAP_EANativeTransport_InterfaceStr); #endif @@ -302,12 +307,13 @@ StringDescTable_t g_strTable = .langID = "\x09\x04", /* US English */ .vendorStr = VENDOR_STR, .serialStr = "", +#if (AUDIO_CLASS == 2) .productStr_Audio2 = PRODUCT_STR_A2, .outputInterfaceStr_Audio2 = APPEND_PRODUCT_STR_A2(), .inputInterfaceStr_Audio2 = APPEND_PRODUCT_STR_A2(), .usbInputTermStr_Audio2 = APPEND_PRODUCT_STR_A2(), .usbOutputTermStr_Audio2 = APPEND_PRODUCT_STR_A2(), - +#endif #if defined (AUDIO_CLASS_FALLBACK) || (AUDIO_CLASS == 1) .productStr_Audio1 = PRODUCT_STR_A1, .outputInterfaceStr_Audio1 = APPEND_PRODUCT_STR_A1(), @@ -315,6 +321,7 @@ StringDescTable_t g_strTable = .usbInputTermStr_Audio1 = APPEND_PRODUCT_STR_A1(), .usbOutputTermStr_Audio1 = APPEND_PRODUCT_STR_A1(), #endif +#if (AUDIO_CLASS == 2) .clockSelectorStr = APPEND_VENDOR_STR(Clock Selector), .internalClockSourceStr = APPEND_VENDOR_STR(Internal Clock), #ifdef SPDIF_RX @@ -323,6 +330,7 @@ StringDescTable_t g_strTable = #ifdef ADAT_RX .adatClockSourceStr = APPEND_VENDOR_STR(ADAT Clock), #endif +#endif #ifdef DFU .dfuStr = APPEND_VENDOR_STR(DFU), #endif @@ -368,7 +376,9 @@ StringDescTable_t g_strTable = #if defined(MIXER) && (MAX_MIX_COUNT > 8) #error #endif +#ifdef IAP .iAPInterfaceStr = "iAP Interface", +#endif #ifdef IAP_EA_NATIVE_TRANS .iAP_EANativeTransport_InterfaceStr = IAP2_EA_NATIVE_TRANS_PROTOCOL_NAME, #endif @@ -397,6 +407,7 @@ USB_Descriptor_Device_t devDesc_Audio1 = }; #endif +#if (AUDIO_CLASS == 2) /* Device Descriptor for Audio Class 2.0 (Assumes High-Speed ) */ USB_Descriptor_Device_t devDesc_Audio2 = { @@ -438,7 +449,7 @@ unsigned char devDesc_Null[] = 0, /* 16 iSerialNumber : Index of serial number decriptor */ 0x01 /* 17 bNumConfigurations : Number of possible configs */ }; - +#endif /****** Device Qualifier Descriptors *****/ @@ -751,7 +762,7 @@ typedef struct }__attribute__((packed)) USB_Config_Descriptor_Audio2_t; -#if 1 +#if (AUDIO_CLASS == 2) USB_Config_Descriptor_Audio2_t cfgDesc_Audio2= { .Config = @@ -2252,7 +2263,10 @@ const unsigned num_freqs_a1 = MAX(3, (0 #define NUM_CONTROL_INTERFACES 0 #endif -#define AC_TOTAL_LENGTH (AC_LENGTH + (INPUT_INTERFACES_A1 * (17 + NUM_USB_CHAN_IN_FS + num_freqs_a1 * 3)) + (OUTPUT_INTERFACES_A1 * (17 + NUM_USB_CHAN_OUT_FS + (num_freqs_a1 *3)))) +#define AC_TOTAL_LENGTH (AC_LENGTH + \ + (INPUT_INTERFACES_A1 * (9 + (7* INPUT_VOLUME_CONTROL) + (NUM_USB_CHAN_IN_FS * INPUT_VOLUME_CONTROL) + num_freqs_a1 * 3)) +\ + (OUTPUT_INTERFACES_A1 * (9 + (7 * OUTPUT_VOLUME_CONTROL) + (NUM_USB_CHAN_OUT_FS * OUTPUT_VOLUME_CONTROL) + (num_freqs_a1 *3)))) + #define STREAMING_INTERFACES (INPUT_INTERFACES_A1 + OUTPUT_INTERFACES_A1) /* Number of interfaces for Audio 1.0 (+1 for control ) */ @@ -2268,7 +2282,7 @@ const unsigned num_freqs_a1 = MAX(3, (0 #define CHARIFY_SR(x) (x & 0xff),((x & 0xff00)>> 8),((x & 0xff0000)>> 16) #if (MIN_FREQ_FS < 12000) && (MAX_FREQ_FS > 48000) -#error SAMPLE RATE RANGE TO GREAT FOR UAC1 ON WINDOWS +#error SAMPLE RATE RANGE TOO GREAT FOR UAC1 ON WINDOWS #endif unsigned char cfgDesc_Audio1[] = @@ -2297,7 +2311,7 @@ unsigned char cfgDesc_Audio1[] = USB_CLASS_AUDIO, UAC_INT_SUBCLASS_AUDIOCONTROL, 0x00, /* Unused */ - 8, /* iInterface - re-use iProduct */ + offsetof(StringDescTable_t, productStr_Audio1)/sizeof(char *), /* iInterface - re-use iProduct */ /* CS (Class Specific) AudioControl interface header descriptor (4.3.2) */ AC_LENGTH, @@ -2325,8 +2339,9 @@ unsigned char cfgDesc_Audio1[] = NUM_USB_CHAN_OUT_FS, /* bNrChannels */ 0x03, 0x00, /* wChannelConfig */ offsetof(StringDescTable_t, outputChanStr_1)/sizeof(char *), /* iChannelNames */ - 11, /* iTerminal */ + offsetof(StringDescTable_t, usbInputTermStr_Audio1)/sizeof(char *), /* iTerminal */ +#if (OUTPUT_VOLUME_CONTROL == 1) /* CS_Interface class specific AC interface feature unit descriptor - mute & volume for dac */ (8 + NUM_USB_CHAN_OUT_FS), UAC_CS_DESCTYPE_INTERFACE, @@ -2364,6 +2379,7 @@ unsigned char cfgDesc_Audio1[] = #error NUM_USB_CHAN_OUT_FS > 8 currently supported #endif 0x00, /* String table index */ +#endif /* CS_Interface Output Terminal Descriptor - Analogue out to speaker */ 0x09, @@ -2372,7 +2388,11 @@ unsigned char cfgDesc_Audio1[] = 0x06, /* Terminal ID */ 0x01, 0x03, /* Type - streaming out, speaker */ 0x00, /* Associated terminal - unused */ - 0x0A, /* sourceID */ +#if (OUTPUT_VOLUME_CONTROL == 1) + 0x0A, /* sourceID - FU */ +#else + 0x01, /* sourceID - IT */ +#endif 0x00, /* Unused */ #endif @@ -2387,7 +2407,7 @@ unsigned char cfgDesc_Audio1[] = NUM_USB_CHAN_IN_FS, /* bNrChannels */ 0x03, 0x00, /* wChannelConfigs */ offsetof(StringDescTable_t, inputChanStr_1)/sizeof(char *), /* iChannelNames */ - 12, /* iTerminal */ + offsetof(StringDescTable_t, usbOutputTermStr_Audio1)/sizeof(char *), /* iTerminal */ /* CS_Interface Output Terminal Descriptor - USB Streaming Device to Host*/ 0x09, @@ -2396,9 +2416,14 @@ unsigned char cfgDesc_Audio1[] = 0x07, /* Terminal ID */ 0x01, 0x01, /* Type - streaming */ 0x01, /* Associated terminal - unused */ - 0x0B, /* sourceID - from selector unit ?? */ +#if INPUT_VOLUME_CONTROL + 0x0B, /* sourceID - FU */ +#else + 0x02, /* sourceID - IT */ +#endif 0x00, /* Unused */ +#if (INPUT_VOLUME_CONTROL == 1) /* CS_Interface class specific AC interface feature unit descriptor - mute & volume for adc */ (8 + NUM_USB_CHAN_IN_FS), UAC_CS_DESCTYPE_INTERFACE, @@ -2436,6 +2461,7 @@ unsigned char cfgDesc_Audio1[] = #endif 0x00, /* String table index */ #endif +#endif #if (NUM_USB_CHAN_OUT > 0) /* Standard AS Interface Descriptor (4.5.1) */ @@ -2447,7 +2473,7 @@ unsigned char cfgDesc_Audio1[] = 0x01, /* bInterfaceClass - AUDIO */ 0x02, /* bInterfaceSubclass - AUDIO_STREAMING */ 0x00, /* bInterfaceProtocol - Not used */ - 0x09, /* iInterface */ + offsetof(StringDescTable_t, outputInterfaceStr_Audio1)/sizeof(char *), /* iInterface */ /* Standard As Interface Descriptor (4.5.1) */ 0x09, @@ -2462,7 +2488,7 @@ unsigned char cfgDesc_Audio1[] = 0x01, /* Interface class - AUDIO */ 0x02, /* subclass - AUDIO_STREAMING */ 0x00, /* Unused */ - 0x09, /* String table index */ + offsetof(StringDescTable_t, outputInterfaceStr_Audio1)/sizeof(char *), /* iInterface */ /* Class-Specific AS Interface Descriptor (4.5.2) */ 0x07, @@ -2580,7 +2606,7 @@ unsigned char cfgDesc_Audio1[] = 0x01, /* Interface class - AUDIO */ 0x02, /* subclass - AUDIO_STREAMING */ 0x00, /* Unused */ - 0x0A, /* iInterface */ + offsetof(StringDescTable_t, inputInterfaceStr_Audio1)/sizeof(char *), /* Standard Interface Descriptor - Audio streaming IN */ 0x09, @@ -2591,7 +2617,7 @@ unsigned char cfgDesc_Audio1[] = 0x01, /* Interface class - AUDIO */ 0x02, /* Subclass - AUDIO_STREAMING */ 0x00, /* Unused */ - 0x0A, /* iInterface*/ + offsetof(StringDescTable_t, inputInterfaceStr_Audio1)/sizeof(char *), /* CS_Interface AC interface header descriptor */ 0x07, @@ -2688,7 +2714,7 @@ unsigned char cfgDesc_Audio1[] = #ifdef XVSM /* Standard DFU class Interface descriptor */ - 0x09, /* 0 bLength : Size of this descriptor, in bytes. (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) */ (OUTPUT_INTERFACES_A1 + 2), /* bInterfaceNumber */ 0x00, /* 3 bAlternateSetting : Index of this setting. (field size 1 bytes) */ diff --git a/module_usb_audio/endpoint0/endpoint0.c b/module_usb_audio/endpoint0/endpoint0.c index 981fccd3..f7a46f81 100755 --- a/module_usb_audio/endpoint0/endpoint0.c +++ b/module_usb_audio/endpoint0/endpoint0.c @@ -206,6 +206,8 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, XUD_ep ep0_out = XUD_InitEp(c_ep0_out); XUD_ep ep0_in = XUD_InitEp(c_ep0_in); +#if 0 + /* Dont need to init globals.. */ /* Init tables for volumes (+ 1 for master) */ for(int i = 0; i < NUM_USB_CHAN_OUT + 1; i++) { @@ -218,7 +220,7 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, volsIn[i] = 0; mutesIn[i] = 0; } - +#endif VendorRequests_Init(VENDOR_REQUESTS_PARAMS); #ifdef MIXER @@ -295,7 +297,7 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, { /* Returns XUD_RES_OKAY for success, XUD_RES_RST for bus reset */ XUD_Result_t result = USB_GetSetupPacket(ep0_out, ep0_in, &sp); - + if (result == XUD_RES_OKAY) { result = XUD_RES_ERR; @@ -311,7 +313,7 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, switch (sp.wIndex) { /* Check for audio stream from host start/stop */ -#if (NUM_USB_CHAN_OUT > 0) +#if (NUM_USB_CHAN_OUT > 0) && (AUDIO_CLASS == 2) case INTERFACE_NUMBER_AUDIO_OUTPUT: /* Check the alt is in range */ if(sp.wValue <= OUTPUT_FORMAT_COUNT) @@ -346,7 +348,7 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl, break; #endif -#if (NUM_USB_CHAN_IN > 0) +#if (NUM_USB_CHAN_IN > 0) && (AUDIO_CLASS == 2) case INTERFACE_NUMBER_AUDIO_INPUT: /* Check the alt is in range */ if(sp.wValue <= INPUT_FORMAT_COUNT) diff --git a/module_usb_audio/flashlib_user.c b/module_usb_audio/flashlib_user.c index ac8387b0..834adee7 100644 --- a/module_usb_audio/flashlib_user.c +++ b/module_usb_audio/flashlib_user.c @@ -19,9 +19,15 @@ #define portout(a,b) {__asm__ __volatile__("out res[%0], %1": : "r" (a) , "r" (b));} #ifdef DFU_FLASH_DEVICE + +#ifdef QUAD_SPI_FLASH +/* Using specified flash device rather than all supported in tools */ +fl_QuadDeviceSpec flash_devices[] = {DFU_FLASH_DEVICE}; +#else /* Using specified flash device rather than all supported in tools */ fl_DeviceSpec flash_devices[] = {DFU_FLASH_DEVICE}; #endif +#endif #ifdef QUAD_SPI_FLASH /* @@ -83,7 +89,11 @@ int flash_cmd_enable_ports() #endif #ifdef DFU_FLASH_DEVICE +#ifdef QUAD_SPI_FLASH + result = fl_connectToDevice(&p_qflash, flash_devices, 1); +#else result = fl_connectToDevice(&p_flash, flash_devices, 1); +#endif #else /* Use default flash list */ #ifdef QUAD_SPI_FLASH diff --git a/module_usb_audio/main.xc b/module_usb_audio/main.xc index ba5c232c..868011c1 100755 --- a/module_usb_audio/main.xc +++ b/module_usb_audio/main.xc @@ -317,9 +317,12 @@ VENDOR_REQUESTS_PARAMS_DEC_ c_sof, epTypeTableOut, epTypeTableIn, p_usb_rst, clk, 1, XUD_SPEED_HS, XUD_PWR_CFG); #else + { + set_core_high_priority_on(); XUD_Manager(c_xud_out, ENDPOINT_COUNT_OUT, c_xud_in, ENDPOINT_COUNT_IN, c_sof, epTypeTableOut, epTypeTableIn, p_usb_rst, clk, 1, XUD_SPEED_FS, XUD_PWR_CFG); + } #endif /* USB Packet buffering Core */ @@ -485,6 +488,8 @@ void usb_audio_io(chanend c_aud_in, chanend ?c_adc, #define USER_MAIN_CORES #endif +#ifndef EXCLUDE_USB_AUDIO_MAIN + /* Main for USB Audio Applications */ int main() { @@ -558,6 +563,8 @@ int main() USER_MAIN_DECLARATIONS par { + USER_MAIN_CORES + on tile[XUD_TILE]: par { @@ -668,17 +675,17 @@ int main() #ifdef MIC_PROCESSING_USE_INTERFACE on stdcore[PDM_TILE].core[0]: pdm_buffer(c_ds_output, c_pdm_pcm, i_mic_process); #else - on stdcore[PDM_TILE]: pdm_buffer(c_ds_output, c_pdm_pcm); + on stdcore[PDM_TILE].core[0]: pdm_buffer(c_ds_output, c_pdm_pcm); #endif #endif - USER_MAIN_CORES - } #ifdef SU1_ADC_ENABLE xs1_su_adc_service(c_adc); #endif + } return 0; } +#endif diff --git a/module_usb_audio/mixer/mixer.xc b/module_usb_audio/mixer/mixer.xc index e251e401..44e4b54b 100644 --- a/module_usb_audio/mixer/mixer.xc +++ b/module_usb_audio/mixer/mixer.xc @@ -241,10 +241,10 @@ static inline void GetSamplesFromHost(chanend c) write_via_xc_ptr_indexed(samples_array, i, h); #else ptr_samples[i] = sample; -#endif #endif } } +#endif } #pragma unsafe arrays @@ -366,7 +366,7 @@ static void mixer1(chanend c_host, chanend c_mix_ctl, chanend c_mixer2) /* Forward on Request for data to decouple thread */ outuint(c_host, request); - /* Between request to decouple and respose ~ 400nS latency for interrupt to fire */ + /* Between request to decouple and response ~ 400nS latency for interrupt to fire */ select { case inuint_byref(c_mix_ctl, cmd): diff --git a/module_usb_audio/module_build_info b/module_usb_audio/module_build_info index 2872a33f..7c62a880 100644 --- a/module_usb_audio/module_build_info +++ b/module_usb_audio/module_build_info @@ -29,4 +29,7 @@ # EXCLUDE_FILES += descriptors_2.rst -MODULE_XCC_FLAGS += $(XCC_FLAGS) -falways-inline +#MODULE_XCC_FLAGS += $(XCC_FLAGS) -falways-inline + +XCC_FLAGS_endpoint0.c = -Os -mno-dual-issue $(XCC_FLAGS) +XCC_FLAGS_dbcalc.xc = -Os -mno-dual-issue $(XCC_FLAGS) diff --git a/module_usb_audio/pdm_mics/mic_array_conf.h b/module_usb_audio/pdm_mics/mic_array_conf.h index a57e7753..e894cd10 100644 --- a/module_usb_audio/pdm_mics/mic_array_conf.h +++ b/module_usb_audio/pdm_mics/mic_array_conf.h @@ -1,7 +1,9 @@ #ifndef MIC_ARRAY_CONF_H_ #define MIC_ARRAY_CONF_H_ +#include "customdefines.h" + #define MIC_ARRAY_MAX_FRAME_SIZE_LOG2 0 -#define MIC_ARRAY_NUM_MICS 8 +#define MIC_ARRAY_NUM_MICS (NUM_PDM_MICS) #endif /* MIC_ARRAY_CONF_H_ */ diff --git a/module_usb_audio/pdm_mics/pdm_mic.h b/module_usb_audio/pdm_mics/pdm_mic.h deleted file mode 100644 index cf6f0e6d..00000000 --- a/module_usb_audio/pdm_mics/pdm_mic.h +++ /dev/null @@ -1,37 +0,0 @@ - -#include "mic_array.h" - -#ifdef MIC_PROCESSING_USE_INTERFACE -/* Interface based user processing */ -typedef interface mic_process_if -{ - void transfer_buffers(mic_array_frame_time_domain * unsafe audio, int output[]); - void init(); -} mic_process_if; - - -[[combinable]] -void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio -#ifdef MIC_PROCESSING_USE_INTERFACE - , client mic_process_if i_mic_process -#endif -); - -[[combinable]] -void user_pdm_process(server mic_process_if i_mic_data); - -/* PDM interface and decimation cores */ -void pdm_mic(streaming chanend c_ds_output[2]); - -#else - -/* Simple user hooks/call-backs */ -unsafe void user_pdm_process(mic_array_frame_time_domain * unsafe audio, int output[]); - -void user_pdm_init(); - -/* PDM interface and decimation cores */ -void pdm_mic(streaming chanend c_ds_output[2]); - -#endif - diff --git a/module_usb_audio/pdm_mics/pdm_mic.xc b/module_usb_audio/pdm_mics/pdm_mic.xc index 4284b14e..37953754 100644 --- a/module_usb_audio/pdm_mics/pdm_mic.xc +++ b/module_usb_audio/pdm_mics/pdm_mic.xc @@ -12,11 +12,12 @@ #include #include #include +#include #include "mic_array.h" #include "xua_pdm_mic.h" -#define MAX_DECIMATION_FACTOR 12 +#define MAX_DECIMATION_FACTOR (96000/MIN_FREQ) /* Hardware resources */ in port p_pdm_clk = PORT_PDM_CLK; @@ -35,11 +36,11 @@ mic_array_frame_time_domain mic_audio[2]; void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio, client mic_process_if i_mic_process) #else #pragma unsafe arrays +[[combinable]] void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio) #endif { unsigned buffer; - int output[NUM_PDM_MICS]; unsigned samplerate; #ifdef MIC_PROCESSING_USE_INTERFACE @@ -48,6 +49,12 @@ void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio) user_pdm_init(); #endif +#if NUM_PDM_MICS > 4 + unsigned decimatorCount = 2; +#else + unsigned decimatorCount = 1; +#endif + mic_array_decimator_conf_common_t dcc; const int * unsafe fir_coefs[7]; mic_array_frame_time_domain * unsafe current; @@ -105,20 +112,21 @@ void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio) dc[1].mic_gain_compensation[3]=0; dc[1].channel_count = 4; - mic_array_decimator_configure(c_ds_output, 2, dc); + mic_array_decimator_configure(c_ds_output, decimatorCount, dc); - mic_array_init_time_domain_frame(c_ds_output, 2, buffer, mic_audio, dc); + mic_array_init_time_domain_frame(c_ds_output, decimatorCount, buffer, mic_audio, dc); /* Grab a first frame of mic data */ /* Note, loop is unrolled once - allows for while(1) select {} and thus combinable */ - current = mic_array_get_next_time_domain_frame(c_ds_output, 2, buffer, mic_audio, dc); + current = mic_array_get_next_time_domain_frame(c_ds_output, decimatorCount, buffer, mic_audio, dc); } /* Run user code */ + /* TODO ideally processing done inplace - it then doesn't matter if it is run or not */ #ifdef MIC_PROCESSING_USE_INTERFACE - i_mic_process.transfer_buffers(current, output); + i_mic_process.transfer_buffers(current); #else - user_pdm_process(current, output); + user_pdm_process(current); #endif int req; while(1) @@ -135,18 +143,18 @@ void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio) #pragma loop unroll for(int i = 0; i < NUM_PDM_MICS; i++) { - c_audio <: output[i]; + c_audio <: current->data[i][0]; } } /* Get a new frame of mic data */ - mic_array_frame_time_domain * unsafe current = mic_array_get_next_time_domain_frame(c_ds_output, 2, buffer, mic_audio, dc); + mic_array_frame_time_domain * unsafe current = mic_array_get_next_time_domain_frame(c_ds_output, decimatorCount, buffer, mic_audio, dc); /* Run user code */ #ifdef MIC_PROCESSING_USE_INTERFACE - i_mic_process.transfer_buffers(current, output); + i_mic_process.transfer_buffers(current); #else - user_pdm_process(current, output); + user_pdm_process(current); #endif } else @@ -159,17 +167,17 @@ void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio) dcc.output_decimation_factor = decimationfactor; dcc.coefs=fir_coefs[decimationfactor/2]; dcc.fir_gain_compensation = fir_gain_compen[decimationfactor/2]; - mic_array_decimator_configure(c_ds_output, 2, dc); - mic_array_init_time_domain_frame(c_ds_output, 2, buffer, mic_audio, dc); + mic_array_decimator_configure(c_ds_output, decimatorCount, dc); + mic_array_init_time_domain_frame(c_ds_output, decimatorCount, buffer, mic_audio, dc); /* Get a new mic data frame */ - mic_array_frame_time_domain * unsafe current = mic_array_get_next_time_domain_frame(c_ds_output, 2, buffer, mic_audio, dc); + mic_array_frame_time_domain * unsafe current = mic_array_get_next_time_domain_frame(c_ds_output, decimatorCount, buffer, mic_audio, dc); /* Run user code */ #ifdef MIC_PROCESSING_USE_INTERFACE - i_mic_process.transfer_buffers(current, output); + i_mic_process.transfer_buffers(current); #else - user_pdm_process(current, output); + user_pdm_process(current); #endif } break; @@ -183,10 +191,23 @@ void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio) void pdm_mic(streaming chanend c_ds_output[2]) { - streaming chan c_4x_pdm_mic_0, c_4x_pdm_mic_1; + streaming chan c_4x_pdm_mic_0; +#if (NUM_PDM_MICS > 4) + streaming chan c_4x_pdm_mic_1; +#else + #define c_4x_pdm_mic_1 null +#endif - /* Note, this divide should be based on master clock freq */ - configure_clock_src_divide(pdmclk, p_mclk, 2); + /* Mics expect a clock in the 3Mhz range, calculate the divide based on mclk */ + /* e.g. For a 48kHz range mclk we expect a 3072000Hz mic clock */ + /* e.g. For a 44.1kHz range mclk we expect a 2822400Hz mic clock */ + + /* Note, codebase currently does not handle a different divide for each clock */ + assert((MCLK_48 / 3072000) == (MCLK_441 / 2822400)); + + unsigned micDiv = MCLK_48/3072000; + + configure_clock_src_divide(pdmclk, p_mclk, micDiv/2); configure_port_clock_output(p_pdm_clk, pdmclk); configure_in_port(p_pdm_mics, pdmclk); start_clock(pdmclk); @@ -195,7 +216,9 @@ void pdm_mic(streaming chanend c_ds_output[2]) { mic_array_pdm_rx(p_pdm_mics, c_4x_pdm_mic_0, c_4x_pdm_mic_1); mic_array_decimate_to_pcm_4ch(c_4x_pdm_mic_0, c_ds_output[0], MIC_ARRAY_NO_INTERNAL_CHANS); +#if (NUM_PDM_MICS > 4) mic_array_decimate_to_pcm_4ch(c_4x_pdm_mic_1, c_ds_output[1], MIC_ARRAY_NO_INTERNAL_CHANS); +#endif } } #endif diff --git a/module_usb_audio/pdm_mics/pdm_mic_user.c b/module_usb_audio/pdm_mics/pdm_mic_user.c new file mode 100644 index 00000000..13870738 --- /dev/null +++ b/module_usb_audio/pdm_mics/pdm_mic_user.c @@ -0,0 +1,22 @@ + +#include "devicedefines.h" + +#if (NUM_PDM_MICS > 0) && !defined(MIC_PROCESSING_USE_INTERFACE) + +#include "mic_array_frame.h" + +/* Deafult implementations of user_pdm_init() and user_pdm_process(). Both can be over-ridden */ +void user_pdm_init() __attribute__ ((weak)); +void user_pdm_init() +{ + return; +} + + +void user_pdm_process() __attribute__ ((weak)); +void user_pdm_process(mic_array_frame_time_domain * audio) +{ + return; +} + +#endif diff --git a/module_usb_audio/pdm_mics/xua_pdm_mic.h b/module_usb_audio/pdm_mics/xua_pdm_mic.h index 69e52d5c..e962c6bb 100644 --- a/module_usb_audio/pdm_mics/xua_pdm_mic.h +++ b/module_usb_audio/pdm_mics/xua_pdm_mic.h @@ -5,7 +5,7 @@ /* Interface based user processing */ typedef interface mic_process_if { - void transfer_buffers(mic_array_frame_time_domain * unsafe audio, int output[]); + void transfer_buffers(mic_array_frame_time_domain * unsafe audio); void init(); } mic_process_if; @@ -26,11 +26,12 @@ void pdm_mic(streaming chanend c_ds_output[2]); #else /* Simple user hooks/call-backs */ -void user_pdm_process(mic_array_frame_time_domain * unsafe audio, int output[]); +void user_pdm_process(mic_array_frame_time_domain * unsafe audio); void user_pdm_init(); /* PDM interface and decimation cores */ +[[combinable]] void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio); /* PDM interface and decimation cores */ diff --git a/module_usb_audio/usb_buffer/decouple.xc b/module_usb_audio/usb_buffer/decouple.xc index e05101d3..eb7ded32 100644 --- a/module_usb_audio/usb_buffer/decouple.xc +++ b/module_usb_audio/usb_buffer/decouple.xc @@ -14,25 +14,47 @@ #endif #define MAX(x,y) ((x)>(y) ? (x) : (y)) -#define HS_PACKET_SIZE ((((MAX_FREQ+7999)/8000))+3) // Samples per channel -#define FS_PACKET_SIZE ((((MAX_FREQ_FS+999)/1000))+3) // Samples per channel - /* TODO use SLOTSIZE to potentially save memory */ -#define BUFF_SIZE_OUT MAX(4 * HS_PACKET_SIZE * NUM_USB_CHAN_OUT, 4 * FS_PACKET_SIZE * NUM_USB_CHAN_OUT_FS) -#define BUFF_SIZE_IN MAX(4 * HS_PACKET_SIZE * NUM_USB_CHAN_IN, 4 * FS_PACKET_SIZE * NUM_USB_CHAN_IN_FS) +/* Note we could improve on this, for one subslot is set to 4 */ +/* The *4 is conversion to bytes, note we're assuming a slotsize of 4 here whic is potentially as waste */ +#define MAX_DEVICE_AUD_PACKET_SIZE_MULT_HS ((MAX_FREQ/8000+1)*4) +#define MAX_DEVICE_AUD_PACKET_SIZE_MULT_FS ((MAX_FREQ_FS/1000+1)*4) -/* Maximum USB buffer size (1024 bytes + 1 word to store length) */ -#define MAX_USB_AUD_PACKET_SIZE 1028 +/*** IN PACKET SIZES ***/ +/* Max packet sizes in bytes. Note the +4 is because we store packet lengths in the buffer */ +#define MAX_DEVICE_AUD_PACKET_SIZE_IN_HS (MAX_DEVICE_AUD_PACKET_SIZE_MULT_HS * NUM_USB_CHAN_IN + 4) +#define MAX_DEVICE_AUD_PACKET_SIZE_IN_FS (MAX_DEVICE_AUD_PACKET_SIZE_MULT_FS * NUM_USB_CHAN_IN_FS + 4) -#define OUT_BUFFER_PREFILL (MAX(NUM_USB_CHAN_OUT_FS*FS_PACKET_SIZE*3+4,NUM_USB_CHAN_OUT*HS_PACKET_SIZE*4+4)*1) -#define IN_BUFFER_PREFILL (MAX(FS_PACKET_SIZE*2+4, NUM_USB_CHAN_IN*HS_PACKET_SIZE*4+4)*2) +#define MAX_DEVICE_AUD_PACKET_SIZE_IN (MAX(MAX_DEVICE_AUD_PACKET_SIZE_IN_FS, MAX_DEVICE_AUD_PACKET_SIZE_IN_HS)) + +/*** OUT PACKET SIZES ***/ +#define MAX_DEVICE_AUD_PACKET_SIZE_OUT_HS (MAX_DEVICE_AUD_PACKET_SIZE_MULT_HS * NUM_USB_CHAN_OUT + 4) +#define MAX_DEVICE_AUD_PACKET_SIZE_OUT_FS (MAX_DEVICE_AUD_PACKET_SIZE_MULT_FS * NUM_USB_CHAN_OUT_FS + 4) + +#define MAX_DEVICE_AUD_PACKET_SIZE_OUT (MAX(MAX_DEVICE_AUD_PACKET_SIZE_OUT_FS, MAX_DEVICE_AUD_PACKET_SIZE_OUT_HS)) + +/*** BUFFER SIZES ***/ + +#define BUFFER_PACKET_COUNT 3 /* How many packets too allow for in buffer - minimum is 3! */ + +#define BUFF_SIZE_OUT_HS MAX_DEVICE_AUD_PACKET_SIZE_OUT_HS * BUFFER_PACKET_COUNT +#define BUFF_SIZE_OUT_FS MAX_DEVICE_AUD_PACKET_SIZE_OUT_FS * BUFFER_PACKET_COUNT + +#define BUFF_SIZE_IN_HS MAX_DEVICE_AUD_PACKET_SIZE_IN_HS * BUFFER_PACKET_COUNT +#define BUFF_SIZE_IN_FS MAX_DEVICE_AUD_PACKET_SIZE_IN_FS * BUFFER_PACKET_COUNT + +#define BUFF_SIZE_OUT MAX(BUFF_SIZE_OUT_HS, BUFF_SIZE_OUT_FS) +#define BUFF_SIZE_IN MAX(BUFF_SIZE_IN_HS, BUFF_SIZE_IN_FS) + +#define OUT_BUFFER_PREFILL (MAX(MAX_DEVICE_AUD_PACKET_SIZE_OUT_HS, MAX_DEVICE_AUD_PACKET_SIZE_OUT_FS)) +#define IN_BUFFER_PREFILL (MAX(MAX_DEVICE_AUD_PACKET_SIZE_IN_HS, MAX_DEVICE_AUD_PACKET_SIZE_IN_FS)*2) /* Volume and mute tables */ -#ifndef OUT_VOLUME_IN_MIXER +#if !defined(OUT_VOLUME_IN_MIXER) && (OUTPUT_VOLUME_CONTROL == 1) unsigned int multOut[NUM_USB_CHAN_OUT + 1]; static xc_ptr p_multOut; #endif -#ifndef IN_VOLUME_IN_MIXER +#if !defined(IN_VOLUME_IN_MIXER) && (INPUT_VOLUME_CONTROL == 1) unsigned int multIn[NUM_USB_CHAN_IN + 1]; static xc_ptr p_multIn; #endif @@ -41,20 +63,12 @@ static xc_ptr p_multIn; unsigned g_numUsbChan_Out = NUM_USB_CHAN_OUT; unsigned g_numUsbChan_In = NUM_USB_CHAN_IN; -/* Note we could improve on this, for one subslot is set to 4 */ -#define MAX_DEVICE_AUD_PACKET_SIZE_MULT_HS ((MAX_FREQ/8000+1)*4) -#define MAX_DEVICE_AUD_PACKET_SIZE_MULT_FS ((MAX_FREQ_FS/1000+1)*4) - -#define MAX_DEVICE_AUD_PACKET_SIZE_HS ((MAX_FREQ/8000+1)*NUM_USB_CHAN_IN*4) -#define MAX_DEVICE_AUD_PACKET_SIZE_FS ((MAX_FREQ_FS/1000+1)*NUM_USB_CHAN_IN_FS*4) - -#define MAX_DEVICE_AUD_PACKET_SIZE (MAX(MAX_DEVICE_AUD_PACKET_SIZE_FS, MAX_DEVICE_AUD_PACKET_SIZE_HS)) - /* Circular audio buffers */ -unsigned outAudioBuff[BUFF_SIZE_OUT + (MAX_USB_AUD_PACKET_SIZE>>2) + 4]; -unsigned audioBuffIn[BUFF_SIZE_IN + (MAX_DEVICE_AUD_PACKET_SIZE>>2) + 4]; +unsigned outAudioBuff[(BUFF_SIZE_OUT >> 2)+ (MAX_DEVICE_AUD_PACKET_SIZE_OUT >> 2)]; +unsigned audioBuffIn[(BUFF_SIZE_IN >> 2)+ (MAX_DEVICE_AUD_PACKET_SIZE_IN >> 2)]; -unsigned inZeroBuff[(MAX_DEVICE_AUD_PACKET_SIZE>>2)+4]; +/* Shift down accounts for bytes -> words */ +unsigned inZeroBuff[(MAX_DEVICE_AUD_PACKET_SIZE_IN >> 2)]; void GetADCCounts(unsigned samFreq, int &min, int &mid, int &max); @@ -91,8 +105,13 @@ xc_ptr g_aud_to_host_wrptr; xc_ptr g_aud_to_host_dptr; xc_ptr g_aud_to_host_rdptr; xc_ptr g_aud_to_host_zeros; +#if (AUDIO_CLASS == 2) int sampsToWrite = DEFAULT_FREQ/8000; /* HS assumed here. Expect to be junked during a overflow before stream start */ int totalSampsToWrite = DEFAULT_FREQ/8000; +#else +int sampsToWrite = DEFAULT_FREQ/1000; /* HS assumed here. Expect to be junked during a overflow before stream start */ +int totalSampsToWrite = DEFAULT_FREQ/1000; +#endif int aud_data_remaining_to_device = 0; /* Audio over/under flow flags */ @@ -109,15 +128,21 @@ unsigned unpackData = 0; unsigned packState = 0; unsigned packData = 0; -/* Default to something sensible but the following are setup at stream start: */ +/* Default to something sensible but the following are setup at stream start (unless UAC1 only..) */ +#if (AUDIO_CLASS == 2) unsigned g_curSubSlot_Out = HS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES; unsigned g_curSubSlot_In = HS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES; - -/* Init to something sensible, but expect to be re-set before stream start */ -#if (AUDIO_CLASS==2) -int g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_HS; #else -int g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_FS; +unsigned g_curSubSlot_Out = FS_STREAM_FORMAT_OUTPUT_1_SUBSLOT_BYTES; +unsigned g_curSubSlot_In = FS_STREAM_FORMAT_INPUT_1_SUBSLOT_BYTES; +#endif + + +/* IN packet size. Init to something sensible, but expect to be re-set before stream start */ +#if (AUDIO_CLASS==2) +int g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_IN_HS; +#else +int g_maxPacketSize = MAX_DEVICE_AUD_PACKET_SIZE_IN_FS; #endif #pragma select handler @@ -146,7 +171,7 @@ void handle_audio_request(chanend c_mix_out) outSamps = g_aud_from_host_wrptr - g_aud_from_host_rdptr; if (outSamps < 0) { - outSamps += BUFF_SIZE_OUT*4; + outSamps += BUFF_SIZE_OUT; } /* If we have a decent number of samples, come out of underflow cond */ @@ -505,7 +530,7 @@ __builtin_unreachable(); space_left += datalength; SET_SHARED_GLOBAL(g_aud_to_host_rdptr, rdPtr); - } while(space_left < (BUFF_SIZE_IN*4/2)); + } while(space_left < (BUFF_SIZE_IN/2)); } sampsToWrite = totalSampsToWrite; @@ -594,22 +619,22 @@ void decouple(chanend c_mix_out int t = array_to_xc_ptr(outAudioBuff); -#ifndef OUT_VOLUME_IN_MIXER +#if !defined(OUT_VOLUME_IN_MIXER) && (OUTPUT_VOLUME_CONTROL == 1) p_multOut = array_to_xc_ptr(multOut); #endif -#ifndef IN_VOLUME_IN_MIXER +#if !defined(IN_VOLUME_IN_MIXER) && (INPUT_VOLUME_CONTROL == 1) p_multIn = array_to_xc_ptr(multIn); #endif aud_from_host_fifo_start = t; - aud_from_host_fifo_end = aud_from_host_fifo_start + BUFF_SIZE_OUT*4; + aud_from_host_fifo_end = aud_from_host_fifo_start + BUFF_SIZE_OUT; g_aud_from_host_wrptr = aud_from_host_fifo_start; g_aud_from_host_rdptr = aud_from_host_fifo_start; t = array_to_xc_ptr(audioBuffIn); aud_to_host_fifo_start = t; - aud_to_host_fifo_end = aud_to_host_fifo_start + BUFF_SIZE_IN*4; + aud_to_host_fifo_end = aud_to_host_fifo_start + BUFF_SIZE_IN; g_aud_to_host_wrptr = aud_to_host_fifo_start; g_aud_to_host_rdptr = aud_to_host_fifo_start; g_aud_to_host_dptr = aud_to_host_fifo_start + 4; @@ -622,14 +647,14 @@ void decouple(chanend c_mix_out g_aud_to_host_zeros = t; /* Init vol mult tables */ -#ifndef OUT_VOLUME_IN_MIXER +#if !defined(OUT_VOLUME_IN_MIXER) && (OUTPUT_VOLUME_CONTROL == 1) for (int i = 0; i < NUM_USB_CHAN_OUT + 1; i++) { asm volatile("stw %0, %1[%2]"::"r"(MAX_VOL),"r"(p_multOut),"r"(i)); } #endif -#ifndef IN_VOLUME_IN_MIXER +#if !defined(IN_VOLUME_IN_MIXER) && (INPUT_VOLUME_CONTROL == 1) for (int i = 0; i < NUM_USB_CHAN_IN + 1; i++) { asm volatile("stw %0, %1[%2]"::"r"(MAX_VOL),"r"(p_multIn),"r"(i)); @@ -664,10 +689,16 @@ void decouple(chanend c_mix_out aud_to_host_flag = 0; SET_SHARED_GLOBAL(g_aud_to_host_flag, aud_to_host_flag); - /* NOTE: IN EP not marked ready at this point - Initial size of zero buffer not known + /* NOTE: For UAC2 IN EP not marked ready at this point - Initial size of zero buffer not known * since we don't know the USB bus-speed yet. * The host will send a SetAltInterface before streaming which will lead to this core * getting a SET_CHANNEL_COUNT_IN. This will setup the EP for the first packet */ +#if (AUDIO_CLASS == 1) + /* For UAC1 we know we only run at FS */ + /* Set buffer back to zeros buffer */ + SET_SHARED_GLOBAL(g_aud_to_host_buffer, g_aud_to_host_zeros); + SetupZerosSendBuffer(aud_to_host_usb_ep, sampFreq, g_curSubSlot_In); +#endif #endif while(1) @@ -687,12 +718,12 @@ void decouple(chanend c_mix_out /* Check for freq change or other update */ GET_SHARED_GLOBAL(tmp, g_freqChange_flag); +#if (MIN_FREQ != MAX_FREQ) if (tmp == SET_SAMPLE_FREQ) { SET_SHARED_GLOBAL(g_freqChange_flag, 0); GET_SHARED_GLOBAL(sampFreq, g_freqChange_sampFreq); - /* Pass on to mixer */ DISABLE_INTERRUPTS(); inuint(c_mix_out); @@ -734,7 +765,12 @@ void decouple(chanend c_mix_out speedRem = 0; continue; } - else if(tmp == SET_STREAM_FORMAT_IN) +#endif +#if (AUDIO_CLASS == 2) +#if (MIN_FREQ != MAX_FREQ) + else +#endif + if(tmp == SET_STREAM_FORMAT_IN) { unsigned dataFormat, usbSpeed; @@ -790,6 +826,7 @@ void decouple(chanend c_mix_out SET_SHARED_GLOBAL(g_aud_from_host_rdptr, aud_from_host_fifo_start); SET_SHARED_GLOBAL(g_aud_from_host_wrptr, aud_from_host_fifo_start); + /* NOTE, this is potentially usefull for UAC1 */ unpackState = 0; outUnderflow = 1; @@ -819,6 +856,7 @@ void decouple(chanend c_mix_out SET_SHARED_GLOBAL(g_freqChange, 0); ENABLE_INTERRUPTS(); } +#endif } #if (NUM_USB_CHAN_OUT > 0) @@ -865,7 +903,7 @@ void decouple(chanend c_mix_out space_left = aud_from_host_fifo_end - g_aud_from_host_wrptr; } - if (space_left <= 0 || space_left >= MAX_USB_AUD_PACKET_SIZE) + if (space_left <= 0 || space_left >= MAX_DEVICE_AUD_PACKET_SIZE_OUT) { SET_SHARED_GLOBAL(g_aud_from_host_buffer, aud_from_host_wrptr); XUD_SetReady_OutPtr(aud_from_host_usb_ep, aud_from_host_wrptr+4); @@ -890,8 +928,8 @@ void decouple(chanend c_mix_out GET_SHARED_GLOBAL(aud_from_host_rdptr, g_aud_from_host_rdptr); space_left = aud_from_host_rdptr - aud_from_host_wrptr; if (space_left <= 0) - space_left += BUFF_SIZE_OUT*4; - if (space_left >= (BUFF_SIZE_OUT*4/2)) + space_left += BUFF_SIZE_OUT; + if (space_left >= (BUFF_SIZE_OUT/2)) { /* Come out of OUT overflow state */ outOverflow = 0; @@ -907,10 +945,10 @@ void decouple(chanend c_mix_out #if (NUM_USB_CHAN_IN > 0) { /* Check if buffer() has sent a packet to host - uses shared mem flag to save chanends */ - int tmp; - GET_SHARED_GLOBAL(tmp, g_aud_to_host_flag); + int sentPkt; + GET_SHARED_GLOBAL(sentPkt, g_aud_to_host_flag); //case inuint_byref(c_buf_in, tmp): - if (tmp) + if (sentPkt) { /* Signals that the IN endpoint has sent data from the passed buffer */ /* Reset flag */ @@ -928,7 +966,7 @@ void decouple(chanend c_mix_out fill_level = aud_to_host_wrptr - aud_to_host_rdptr; if (fill_level < 0) - fill_level += BUFF_SIZE_IN*4; + fill_level += BUFF_SIZE_IN; if (fill_level >= IN_BUFFER_PREFILL) { diff --git a/module_usb_audio/usb_buffer/interrupt.h b/module_usb_audio/usb_buffer/interrupt.h index a65a9ad4..477d55e7 100644 --- a/module_usb_audio/usb_buffer/interrupt.h +++ b/module_usb_audio/usb_buffer/interrupt.h @@ -81,6 +81,7 @@ #define do_interrupt_handler(f,args) \ asm(ISSUE_MODE_SINGLE\ ".align 4\n" \ + ".cc_top __"#f"_handler.function,__"#f"_handler\n" \ "__" #f "_handler:\n" \ "ENTSP_lu6 0\n" \ "kentsp " #args "/2*2 + 20\n" \ @@ -91,7 +92,8 @@ restore_state(f,args) \ "krestsp " #args "/2*2 + 20 \n" \ "__kret:\n" \ - "kret\n"); + "kret\n" \ + ".cc_bottom __"#f"_handler.function"); #define register_interrupt_handler(f, args, nstackwords) \ asm (" .section .dp.data, \"adw\", @progbits\n" \ @@ -99,7 +101,7 @@ " .globl __" #f "_handler\n" \ " .align 8\n" \ "__" #f "_kernel_stack:\n" \ - " .space " #nstackwords ", 0\n" \ + " .space " #nstackwords ", 0\n" \ "__" #f "_kernel_stack_end:\n" \ " .space 4\n"\ " .text\n"); \ diff --git a/module_usb_audio/usb_buffer/usb_buffer.xc b/module_usb_audio/usb_buffer/usb_buffer.xc index 72b85491..754f9e55 100644 --- a/module_usb_audio/usb_buffer/usb_buffer.xc +++ b/module_usb_audio/usb_buffer/usb_buffer.xc @@ -258,6 +258,11 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, XUD_SetReady_In(ep_hid, g_hidData, 1); #endif +#if (AUDIO_CLASS == 1) + /* In UAC1 we dont use a stream start event (and we are always FS) so mark FB EP ready now */ + XUD_SetReady_In(ep_aud_fb, fb_clocks, 3); +#endif + while(1) { XUD_Result_t result; @@ -305,6 +310,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, { unsigned cmd = inuint(c_aud_ctl); +#if (MAX_FREQ != MIN_FREQ) if(cmd == SET_SAMPLE_FREQ) { unsigned receivedSampleFreq = inuint(c_aud_ctl); @@ -344,7 +350,10 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, * handshake elsewhere */ SET_SHARED_GLOBAL(g_freqChange_sampFreq, receivedSampleFreq); } - else if(cmd == SET_STREAM_FORMAT_IN) + else +#endif +#if (AUDIO_CLASS == 2) + if(cmd == SET_STREAM_FORMAT_IN) { unsigned formatChange_DataFormat = inuint(c_aud_ctl); unsigned formatChange_NumChans = inuint(c_aud_ctl); @@ -356,8 +365,10 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, SET_SHARED_GLOBAL(g_formatChange_DataFormat, formatChange_DataFormat); SET_SHARED_GLOBAL(g_formatChange_SampRes, formatChange_SampRes); } + /* FIXME when FB EP is enabled there is no inital XUD_SetReady */ else if (cmd == SET_STREAM_FORMAT_OUT) { + XUD_BusSpeed_t busSpeed; unsigned formatChange_DataFormat = inuint(c_aud_ctl); unsigned formatChange_NumChans = inuint(c_aud_ctl); @@ -385,6 +396,7 @@ void buffer(register chanend c_aud_out, register chanend c_aud_in, } #endif } +#endif /* Pass on sample freq change to decouple() via global flag (saves a chanend) */ /* Note: freqChange flags now used to communicate other commands also */ SET_SHARED_GLOBAL0(g_freqChange, cmd); /* Set command */ diff --git a/module_usb_audio/warnings.xc b/module_usb_audio/warnings.xc index 10b859ac..ee85a3ca 100644 --- a/module_usb_audio/warnings.xc +++ b/module_usb_audio/warnings.xc @@ -65,11 +65,10 @@ Warnings relating to configuration defines located in this XC source file rather /* Sanity check on FS channel counts */ #if (NUM_USB_CHAN_OUT_FS > NUM_USB_CHAN_OUT) -#error NUM_USB_CHAN_OUT expected to be less than or equal to NUM_USB_CHAN_OUT +#error NUM_USB_CHAN_OUT_FS expected to be less than or equal to NUM_USB_CHAN_OUT #endif #if (NUM_USB_CHAN_IN_FS > NUM_USB_CHAN_IN) -#error NUM_USB_CHAN_IN expected to be less than or equal to NUM_USB_CHAN_IN +#error NUM_USB_CHAN_IN_FS expected to be less than or equal to NUM_USB_CHAN_IN #endif - diff --git a/xpd.xml b/xpd.xml index 266f4360..2a6788db 100644 --- a/xpd.xml +++ b/xpd.xml @@ -15,7 +15,7 @@ - module_queue + module_queue MIDI @@ -104,7 +104,8 @@ - + + XM-004720-SM XMOS