diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index a25c0058..b56f8eb0 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -1,13 +1,34 @@
sc_usb_audio Change Log
=======================
+6.18.1
+------
+ - ADDED: Vendor Specific control interface added to UAC1 descriptors to allow control of
+ XVSM params from Windows (via lib_usb)
+
+6.18.0
+------
+ - ADDED: Call to VendorRequests() and VendorRequests_Init() to Endpoint 0
+ - ADDED: VENDOR_REQUESTS_PARAMS define to allow for custom parameters to VendorRequest calls
+ - RESOLVED: FIR gain compensation set appropriately in lib_mic_array usage
+ - CHANGE: i_dsp interface renamed i_audManage
+
+6.16.0
+------
+ - ADDED: Call to UserBufferManagement()
+ - ADDED: PDM_MIC_INDEX in devicedefines.h and usage
+ - CHANGE: pdm_buffer() task now combinable
+ - CHANGE: Audio I/O task now takes i_dsp interface as a parameter
+ - CHANGE: Removed built-in support for A/U series internal ADC
+ - CHANGE: User PDM Microphone processing now uses an interface (previously function call)
+
6.15.2
------
- - RESOLVED: interrupt.h (used in audio buffering) now compatible with xCORE-200 ABI
+ - RESOLVED: interrupt.h (used in audio buffering) now compatible with xCORE-200 ABI
6.15.1
------
- - RESOLVED: DAC data mis-alignment issue in TDM slave mode
+ - RESOLVED: DAC data mis-alignment issue in TDM/I2S slave mode
- CHANGE: Updates to support API changes in lib_mic_array version 2.0
6.15.0
diff --git a/README.rst b/README.rst
index 39906d19..3e501ac5 100644
--- a/README.rst
+++ b/README.rst
@@ -1,7 +1,7 @@
USB Audio Shared
................
-:Latest release: 6.15.2rc0
+:Latest release: 6.18.1alpha0
:Maintainer: xross
:Description: USB Audio Shared Components. For use in the XMOS USB Audio Refererence Designs.
diff --git a/module_dfu/.cproject b/module_dfu/.cproject
index daca0c0a..4a5d77a6 100644
--- a/module_dfu/.cproject
+++ b/module_dfu/.cproject
@@ -156,8 +156,7 @@
-
-
+
@@ -272,8 +271,7 @@
-
-
+
@@ -394,8 +392,7 @@
-
-
+
diff --git a/module_dfu/src/flash_interface.c b/module_dfu/src/flash_interface.c
index e0578210..a122c413 100755
--- a/module_dfu/src/flash_interface.c
+++ b/module_dfu/src/flash_interface.c
@@ -102,7 +102,7 @@ int flash_cmd_read_page(unsigned char *data)
current_flash_subpage_index = 0;
- if (fl_readImageRead(current_flash_page_data) == 0)
+ if (fl_readImagePage(current_flash_page_data) == 0)
{
*(unsigned int *)data = 0;
}
diff --git a/module_queue/.cproject b/module_queue/.cproject
index 35767c9c..b009a5bc 100644
--- a/module_queue/.cproject
+++ b/module_queue/.cproject
@@ -156,8 +156,7 @@
-
-
+
@@ -270,8 +269,7 @@
-
-
+
@@ -390,8 +388,7 @@
-
-
+
diff --git a/module_usb_audio/.cproject b/module_usb_audio/.cproject
index c461ef06..688ad78d 100644
--- a/module_usb_audio/.cproject
+++ b/module_usb_audio/.cproject
@@ -156,9 +156,10 @@
-
+
+
@@ -281,9 +282,10 @@
-
+
+
@@ -412,9 +414,10 @@
-
+
+
diff --git a/module_usb_audio/audio.xc b/module_usb_audio/audio_io/audio_io.xc
similarity index 90%
rename from module_usb_audio/audio.xc
rename to module_usb_audio/audio_io/audio_io.xc
index 47a8cdab..a804857b 100755
--- a/module_usb_audio/audio.xc
+++ b/module_usb_audio/audio_io/audio_io.xc
@@ -29,24 +29,22 @@
#endif
#endif
+#include "xua_audio.h"
+
#include "commands.h"
#include "xc_ptr.h"
-#include "print.h"
-
-static unsigned samplesOut[NUM_USB_CHAN_OUT];
+/* TODO 32 is max expected channels */
+static unsigned samplesOut[32];
/* Two buffers for ADC data to allow for DAC and ADC ports being offset */
-static unsigned samplesIn_0[NUM_USB_CHAN_IN];
-static unsigned samplesIn_1[I2S_CHANS_ADC];
+static unsigned samplesIn[2][32];
#if (DSD_CHANS_DAC != 0)
extern buffered out port:32 p_dsd_dac[DSD_CHANS_DAC];
extern buffered out port:32 p_dsd_clk;
#endif
-unsigned g_adcVal = 0;
-
#ifdef XTA_TIMING_AUDIO
#pragma xta command "add exclusion received_command"
#pragma xta command "analyse path i2s_output_l i2s_output_r"
@@ -224,9 +222,12 @@ 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 */
+/* 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);
#pragma unsafe arrays
-static inline unsigned DoSampleTransfer(chanend c_out, const int readBuffNo, const unsigned underflowWord)
+static inline unsigned DoSampleTransfer(chanend c_out, const int readBuffNo, const unsigned underflowWord, client audManage_if i_audMan)
{
outuint(c_out, underflowWord);
@@ -268,30 +269,18 @@ static inline unsigned DoSampleTransfer(chanend c_out, const int readBuffNo, con
#else
inuint(c_out);
#endif
+ UserBufferManagement(samplesOut, samplesIn[readBuffNo], i_audMan);
+
#if NUM_USB_CHAN_IN > 0
#pragma loop unroll
-#if NUM_USB_CHAN_IN < I2S_CHANS_ADC
for(int i = 0; i < NUM_USB_CHAN_IN; i++)
-#else
- for(int i = 0; i < I2S_CHANS_ADC; i++)
-#endif
{
- if(readBuffNo)
- outuint(c_out, samplesIn_1[i]);
- else
- outuint(c_out, samplesIn_0[i]);
- }
- /* Send over the digi channels - no odd buffering required */
-#pragma loop unroll
- for(int i = I2S_CHANS_ADC; i < NUM_USB_CHAN_IN; i++)
- {
- outuint(c_out, samplesIn_0[i]);
- }
+ outuint(c_out, samplesIn[readBuffNo][i]);
+ }
#endif
}
return 0;
-
}
static inline void InitPorts(unsigned divide)
@@ -427,8 +416,6 @@ static inline void InitPorts(unsigned divide)
#endif
}
-
-
/* I2S delivery thread */
#pragma unsafe arrays
unsigned static deliver(chanend c_out, chanend ?c_spd_out,
@@ -443,8 +430,8 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
#if (NUM_PDM_MICS > 0)
chanend c_pdm_pcm,
#endif
-
- chanend ?c_adc)
+ chanend ?unused,
+ client audManage_if i_audMan)
{
/* Since DAC and ADC buffered ports off by one sample we buffer previous ADC frame */
@@ -481,7 +468,8 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
}
#endif
- unsigned command = DoSampleTransfer(c_out, readBuffNo, underflowWord);
+ unsigned command = DoSampleTransfer(c_out, readBuffNo, underflowWord, i_audMan);
+
#ifdef ADAT_TX
unsafe{
//TransferAdatTxSamples(c_adat_out, samplesOut, adatSmuxMode, 0);
@@ -502,7 +490,6 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
/* Main Audio I/O loop */
while (1)
{
-
#if (DSD_CHANS_DAC != 0) && (NUM_USB_CHAN_OUT > 0)
if(dsdMode == DSD_MODE_NATIVE)
{
@@ -626,10 +613,7 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
/* Note the use of readBuffNo changes based on frameCount */
- if(buffIndex)
- samplesIn_1[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 0, 2, 4.. on each line.
- else
- samplesIn_0[((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample);
+ samplesIn[buffIndex][((frameCount-2)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 0, 2, 4.. on each line.
}
#endif
@@ -644,7 +628,6 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
p_lrclk <: 0x00000000;
#else
p_lrclk <: 0x80000000;
-
#endif
#endif
@@ -676,22 +659,21 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
/* Sync with clockgen */
inuint(c_dig_rx);
- /* Note, digi-data we just store in samplesIn_0 - we only double buffer the I2S input data */
+ /* Note, digi-data we just store in samplesIn[readBuffNo] - we only double buffer the I2S input data */
#endif
#ifdef SPDIF_RX
- asm("ldw %0, dp[g_digData]":"=r"(samplesIn_0[SPDIF_RX_INDEX + 0]));
- asm("ldw %0, dp[g_digData+4]":"=r"(samplesIn_0[SPDIF_RX_INDEX + 1]));
-
+ asm("ldw %0, dp[g_digData]" :"=r"(samplesIn[readBuffNo][SPDIF_RX_INDEX + 0]));
+ asm("ldw %0, dp[g_digData+4]":"=r"(samplesIn[readBuffNo][SPDIF_RX_INDEX + 1]));
#endif
#ifdef ADAT_RX
- asm("ldw %0, dp[g_digData+8]":"=r"(samplesIn_0[ADAT_RX_INDEX]));
- asm("ldw %0, dp[g_digData+12]":"=r"(samplesIn_0[ADAT_RX_INDEX + 1]));
- asm("ldw %0, dp[g_digData+16]":"=r"(samplesIn_0[ADAT_RX_INDEX + 2]));
- asm("ldw %0, dp[g_digData+20]":"=r"(samplesIn_0[ADAT_RX_INDEX + 3]));
- asm("ldw %0, dp[g_digData+24]":"=r"(samplesIn_0[ADAT_RX_INDEX + 4]));
- asm("ldw %0, dp[g_digData+28]":"=r"(samplesIn_0[ADAT_RX_INDEX + 5]));
- asm("ldw %0, dp[g_digData+32]":"=r"(samplesIn_0[ADAT_RX_INDEX + 6]));
- asm("ldw %0, dp[g_digData+36]":"=r"(samplesIn_0[ADAT_RX_INDEX + 7]));
+ asm("ldw %0, dp[g_digData+8]" :"=r"(samplesIn[readBuffNo][ADAT_RX_INDEX]));
+ asm("ldw %0, dp[g_digData+12]":"=r"(samplesIn[readBuffNo][ADAT_RX_INDEX + 1]));
+ asm("ldw %0, dp[g_digData+16]":"=r"(samplesIn[readBuffNo][ADAT_RX_INDEX + 2]));
+ asm("ldw %0, dp[g_digData+20]":"=r"(samplesIn[readBuffNo][ADAT_RX_INDEX + 3]));
+ asm("ldw %0, dp[g_digData+24]":"=r"(samplesIn[readBuffNo][ADAT_RX_INDEX + 4]));
+ asm("ldw %0, dp[g_digData+28]":"=r"(samplesIn[readBuffNo][ADAT_RX_INDEX + 5]));
+ asm("ldw %0, dp[g_digData+32]":"=r"(samplesIn[readBuffNo][ADAT_RX_INDEX + 6]));
+ asm("ldw %0, dp[g_digData+36]":"=r"(samplesIn[readBuffNo][ADAT_RX_INDEX + 7]));
#endif
#if defined(SPDIF_RX) || defined(ADAT_RX)
@@ -707,10 +689,13 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
#if (NUM_PDM_MICS > 0)
/* 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_0[i];
+ c_pdm_pcm :> samplesIn[readBuffNo][i];
+ }
}
#endif
}
@@ -726,21 +711,9 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
unsigned sample;
asm volatile("in %0, res[%1]" : "=r"(sample) : "r"(p_i2s_adc[index++]));
- if(buffIndex)
- samplesIn_1[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 1, 3, 5.. on each line.
- else
- samplesIn_0[((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 1, 3, 5.. on each line.
+ samplesIn[buffIndex][((frameCount-1)&(I2S_CHANS_PER_FRAME-1))+i] = bitrev(sample); // channels 1, 3, 5.. on each line.
}
-
-#ifdef SU1_ADC_ENABLE
- {
- unsigned x;
- x = inuint(c_adc);
- inct(c_adc);
- asm volatile("stw %0, dp[g_adcVal]"::"r"(x));
- }
-#endif
#endif
#ifndef CODEC_MASTER
@@ -828,10 +801,9 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
/* The below looks a bit odd but forces the compiler to inline twice */
unsigned command;
if(readBuffNo)
- command = DoSampleTransfer(c_out, 1, underflowWord);
+ command = DoSampleTransfer(c_out, 1, underflowWord, i_audMan);
else
- command = DoSampleTransfer(c_out, 0, underflowWord);
-
+ command = DoSampleTransfer(c_out, 0, underflowWord, i_audMan);
if(command)
{
@@ -928,11 +900,6 @@ static void dummy_deliver(chanend c_out, unsigned &command)
}
}
}
-#define SAMPLE_RATE 200000
-#define NUMBER_CHANNELS 1
-#define NUMBER_SAMPLES 100
-#define NUMBER_WORDS ((NUMBER_SAMPLES * NUMBER_CHANNELS+1)/2)
-#define SAMPLES_PER_PRINT 1
void audio(chanend c_mix_out,
#if defined(SPDIF_TX) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
@@ -948,6 +915,7 @@ chanend ?c_config, chanend ?c
#if (NUM_PDM_MICS > 0)
, chanend c_pdm_in
#endif
+, client audManage_if i_audMan
)
{
#if defined (SPDIF_TX) && (SPDIF_TX_TILE == AUDIO_IO_TILE)
@@ -967,39 +935,6 @@ chanend ?c_config, chanend ?c
unsigned divide;
unsigned firstRun = 1;
-#ifdef SU1_ADC_ENABLE
- /* Setup galaxian ADC */
- unsigned data[1], channel;
- int r;
- unsigned int vals[NUMBER_WORDS];
- int cnt = 0;
- int div;
- unsigned val = 0;
- int val2 = 0;
- int adcOk = 0;
-
- /* Enable adc on channel */
- enable_xs1_su_adc_input(0, c);
-
- /* General ADC control (enabled, 1 samples per packet, 32 bits per sample) */
- data[0] = 0x10201;
- data[0] = 0x30101;
- r = write_periph_32(xs1_su, 2, 0x20, 1, data);
-
- /* ADC needs a few clocks before it starts pumping out samples */
- for(int i = 0; i< 10; i++)
- {
- p_lrclk <: val;
- val = ~val;
- {
- timer t;
- unsigned time;
- t :> time;
- t when timerafter(time+1000):> void;
- }
- }
-#endif
-
/* Clock master clock-block from master-clock port */
configure_clock_src(clk_audio_mclk, p_mclk_in);
@@ -1223,7 +1158,11 @@ chanend ?c_config, chanend ?c
#if (NUM_PDM_MICS > 0)
c_pdm_in,
#endif
- c);
+ null
+//#ifdef RUN_DSP_TASK
+ , i_audMan
+//#endif
+ );
if(command == SET_SAMPLE_FREQ)
{
diff --git a/module_usb_audio/audio_io/userbuffermanagement.c b/module_usb_audio/audio_io/userbuffermanagement.c
new file mode 100644
index 00000000..25cddcc7
--- /dev/null
+++ b/module_usb_audio/audio_io/userbuffermanagement.c
@@ -0,0 +1,14 @@
+
+#include "xccompat.h"
+#include "devicedefines.h"
+
+/* Default implentation for UserBufferManagement() */
+void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[]
+ , unsigned i_dsp
+ ) __attribute__ ((weak));
+void UserBufferManagement(unsigned sampsFromUsbToAudio[], unsigned sampsFromAudioToUsb[]
+ , unsigned i_dsp
+)
+{
+ /* Do nothing */
+}
diff --git a/module_usb_audio/audio.h b/module_usb_audio/audio_io/xua_audio.h
similarity index 67%
rename from module_usb_audio/audio.h
rename to module_usb_audio/audio_io/xua_audio.h
index 24622ca3..473dfe9a 100644
--- a/module_usb_audio/audio.h
+++ b/module_usb_audio/audio_io/xua_audio.h
@@ -1,8 +1,25 @@
#ifndef __audio_h__
#define __audio_h__
-#include "devicedefines.h"
+//#include "devicedefines.h"
#include "dfu_interface.h"
+//#include "xua_dsp.h"
+
+
+typedef interface audManage_if
+{
+ [[guarded]]
+ void transfer_buffers(int * unsafe in_aud_buf, int * unsafe in_usb_buf,
+ int * unsafe out_usb_buf, int * unsafe out_aud_buf);
+
+ [[guarded]]
+ void transfer_samples(int in_mic_buf[], int in_spk_buf[], int out_mic_buf[], int out_spk_buf[]);
+
+} audManage_if;
+
+
+
+
/** The audio driver thread.
*
* This function drives I2S ports and handles samples to/from other digital
@@ -29,6 +46,9 @@ 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 8bf0697c..b1269782 100644
--- a/module_usb_audio/devicedefines.h
+++ b/module_usb_audio/devicedefines.h
@@ -215,6 +215,16 @@
#define NUM_PDM_MICS (0)
#endif
+/**
+ * @brief PDM Microphone first channel index, defines which channels microphones will be input on.
+ * Note, indexed from 0.
+ *
+ * Default: 0 (i.e. channels [0:NUM_PDM_MICS-1])
+ * */
+#ifndef PDM_MIC_INDEX
+#define PDM_MIC_INDEX (0)
+#endif
+
/**
* @brief Enable MIDI functionality including buffering, descriptors etc. Default: DISABLED
*/
@@ -230,14 +240,14 @@
* @brief MIDI Rx port width (1 or 4bit). Default: 1
*/
#ifndef MIDI_RX_PORT_WIDTH
-#define MIDI_RX_PORT_WIDTH (1)
+#define MIDI_RX_PORT_WIDTH (1)
#endif
/**
* @brief Enables SPDIF Tx. Default: 0 (Disabled)
*/
#ifndef SPDIF_TX
-#define SPDIF_TX (0)
+#define SPDIF_TX (0)
#endif
/* Tidy up old SPDIF usage */
@@ -465,7 +475,7 @@
* @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 16
+#define BCD_DEVICE_M 19
#endif
/**
diff --git a/module_usb_audio/endpoint0/descriptors.h b/module_usb_audio/endpoint0/descriptors.h
index 6a925f7f..aa2d1037 100644
--- a/module_usb_audio/endpoint0/descriptors.h
+++ b/module_usb_audio/endpoint0/descriptors.h
@@ -391,7 +391,7 @@ USB_Descriptor_Device_t devDesc_Audio1 =
.idProduct = PID_AUDIO_1,
.bcdDevice = BCD_DEVICE,
.iManufacturer = offsetof(StringDescTable_t, vendorStr)/sizeof(char *),
- .iProduct = offsetof(StringDescTable_t, productStr_Audio2)/sizeof(char *),
+ .iProduct = offsetof(StringDescTable_t, productStr_Audio1)/sizeof(char *),
.iSerialNumber = 0,
.bNumConfigurations = 1
};
@@ -2244,17 +2244,25 @@ const unsigned num_freqs_a1 = MAX(3, (0
#endif
));
+#ifdef XVSM
+#define CONTROL_INTERFACE_BYTES 9
+#define NUM_CONTROL_INTERFACES 1
+#else
+#define CONTROL_INTERFACE_BYTES 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 STREAMING_INTERFACES (INPUT_INTERFACES_A1 + OUTPUT_INTERFACES_A1)
/* Number of interfaces for Audio 1.0 (+1 for control ) */
/* Note, this is different that INTERFACE_COUNT since we dont support items such as MIDI, iAP etc in UAC1 mode */
-#define NUM_INTERFACES_A1 (1+INPUT_INTERFACES_A1 + OUTPUT_INTERFACES_A1)
+#define NUM_INTERFACES_A1 (1+INPUT_INTERFACES_A1 + OUTPUT_INTERFACES_A1+NUM_CONTROL_INTERFACES)
#if (NUM_USB_CHAN_IN == 0) || defined(UAC_FORCE_FEEDBACK_EP)
-#define CFG_TOTAL_LENGTH_A1 (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES_A1 * 61) + (OUTPUT_INTERFACES_A1 * 70))
+#define CFG_TOTAL_LENGTH_A1 (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES_A1 * 61) + (OUTPUT_INTERFACES_A1 * 70) + CONTROL_INTERFACE_BYTES)
#else
-#define CFG_TOTAL_LENGTH_A1 (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES_A1 * 61) + (OUTPUT_INTERFACES_A1 * 61))
+#define CFG_TOTAL_LENGTH_A1 (18 + AC_TOTAL_LENGTH + (INPUT_INTERFACES_A1 * 61) + (OUTPUT_INTERFACES_A1 * 61) + CONTROL_INTERFACE_BYTES)
#endif
#define CHARIFY_SR(x) (x & 0xff),((x & 0xff00)>> 8),((x & 0xff0000)>> 16)
@@ -2454,7 +2462,7 @@ unsigned char cfgDesc_Audio1[] =
0x01, /* Interface class - AUDIO */
0x02, /* subclass - AUDIO_STREAMING */
0x00, /* Unused */
- 0x04, /* String table index */
+ 0x09, /* String table index */
/* Class-Specific AS Interface Descriptor (4.5.2) */
0x07,
@@ -2568,22 +2576,22 @@ unsigned char cfgDesc_Audio1[] =
0x04, /* INTERFACE */
(OUTPUT_INTERFACES_A1 + 1), /* bInterfaceNumber*/
0x00, /* AlternateSetting */
- 0x00, /* num endpoints */
+ 0x00, /* bNumEndpoints */
0x01, /* Interface class - AUDIO */
0x02, /* subclass - AUDIO_STREAMING */
0x00, /* Unused */
- 0x05, /* String table index */
+ 0x0A, /* iInterface */
/* Standard Interface Descriptor - Audio streaming IN */
0x09,
0x04, /* INTERFACE */
(OUTPUT_INTERFACES_A1 + 1), /* bInterfaceNumber */
0x01, /* AlternateSetting */
- 0x01, /* num endpoints */
+ 0x01, /* bNumEndpoints */
0x01, /* Interface class - AUDIO */
0x02, /* Subclass - AUDIO_STREAMING */
0x00, /* Unused */
- 0x0A, /* String table index */
+ 0x0A, /* iInterface*/
/* CS_Interface AC interface header descriptor */
0x07,
@@ -2677,6 +2685,20 @@ unsigned char cfgDesc_Audio1[] =
0x00, /* Unused */
0x00, 0x00, /* Unused */
#endif
+
+#ifdef XVSM
+ /* 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) */
+ (OUTPUT_INTERFACES_A1 + 2), /* bInterfaceNumber */
+ 0x00, /* 3 bAlternateSetting : Index of this setting. (field size 1 bytes) */
+ 0x00, /* 4 bNumEndpoints : 0 endpoints. (field size 1 bytes) */
+ 0xFF, /* 5 bInterfaceClass : DFU. (field size 1 bytes) */
+ 0xFF, /* 6 bInterfaceSubclass : (field size 1 bytes) */
+ 0xFF, /* 7 bInterfaceProtocol : Unused. (field size 1 bytes) */
+ 0x00, /* 8 iInterface */
+#endif
+
};
#endif
#endif
diff --git a/module_usb_audio/endpoint0/endpoint0.c b/module_usb_audio/endpoint0/endpoint0.c
index f3d4f51b..981fccd3 100755
--- a/module_usb_audio/endpoint0/endpoint0.c
+++ b/module_usb_audio/endpoint0/endpoint0.c
@@ -1,6 +1,4 @@
/**
- * g
- * @file endpoint0.xc
* @brief Implements endpoint zero for an USB Audio 1.0/2.0 device
* @author Ross Owen, XMOS Semiconductor
*/
@@ -15,7 +13,7 @@
#include "devicedefines.h"
#include "usb_device.h" /* Standard descriptor requests */
-#include "descriptors.h" /* This devices descriptors */
+#include "descriptors.h" /* This devices descriptors */
#include "commands.h"
#include "audiostream.h"
#include "hostactive.h"
@@ -31,7 +29,7 @@
#endif
#ifndef __XC__
-/* Support for C */
+/* Support for xCORE channels in C */
#define null 0
#define outuint(c, x) asm ("out res[%0], %1" :: "r" (c), "r" (x))
#define chkct(c, x) asm ("chkct res[%0], %1" :: "r" (c), "r" (x))
@@ -65,11 +63,9 @@ unsigned int DFU_mode_active = 0; // 0 - App active, 1 - DFU active
/* Global volume and mute tables */
int volsOut[NUM_USB_CHAN_OUT + 1];
unsigned int mutesOut[NUM_USB_CHAN_OUT + 1];
-//unsigned int multOut[NUM_USB_CHAN_OUT + 1];
int volsIn[NUM_USB_CHAN_IN + 1];
unsigned int mutesIn[NUM_USB_CHAN_IN + 1];
-//unsigned int multIn[NUM_USB_CHAN_IN + 1];
#ifdef MIXER
unsigned char mixer1Crossbar[18];
@@ -204,7 +200,7 @@ const unsigned g_chanCount_In_HS[INPUT_FORMAT_COUNT] = {HS_STREAM_FORMAT_I
/* Endpoint 0 function. Handles all requests to the device */
void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
- chanend c_mix_ctl, chanend c_clk_ctl, chanend c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, dfuInterface))
+ chanend c_mix_ctl, chanend c_clk_ctl, chanend c_EANativeTransport_ctrl, CLIENT_INTERFACE(i_dfu, dfuInterface) VENDOR_REQUESTS_PARAMS_DEC_)
{
USB_SetupPacket_t sp;
XUD_ep ep0_out = XUD_InitEp(c_ep0_out);
@@ -223,6 +219,8 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
mutesIn[i] = 0;
}
+ VendorRequests_Init(VENDOR_REQUESTS_PARAMS);
+
#ifdef MIXER
/* Set up mixer default state */
for (int i = 0; i < 18*8; i++)
@@ -271,10 +269,10 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
/* Init mixer inputs */
for(int j = 0; j < MAX_MIX_COUNT; j++)
- for(int i = 0; i < MIX_INPUTS; i++)
- {
- mixSel[j][i] = i;
- }
+ for(int i = 0; i < MIX_INPUTS; i++)
+ {
+ mixSel[j][i] = i;
+ }
#endif
#ifdef VENDOR_AUDIO_REQS
@@ -288,7 +286,7 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
/* Stop audio */
outuint(c_audioControl, SET_SAMPLE_FREQ);
outuint(c_audioControl, AUDIO_STOP_FOR_DFU);
- // No Handshake
+ /* No Handshake */
DFU_mode_active = 1;
}
#endif
@@ -608,7 +606,6 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
#endif
#ifdef VENDOR_AUDIO_REQS
-#error
/* If result is ERR at this point, then request to audio interface not handled - handle vendor audio reqs */
if(result == XUD_RES_ERR)
{
@@ -628,6 +625,16 @@ void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioControl,
} /* if(result == XUD_RES_OKAY) */
+ {
+ if(result == XUD_RES_ERR)
+ {
+ /* Run vendor defined parsing/processing */
+ /* Note, an interface might seem ideal here but this *must* be executed on the same
+ * core sure to shared memory depandancy */
+ result = VendorRequests(ep0_out, ep0_in, &sp VENDOR_REQUESTS_PARAMS_);
+ }
+ }
+
if(result == XUD_RES_ERR)
{
#ifdef DFU
diff --git a/module_usb_audio/endpoint0/endpoint0.h b/module_usb_audio/endpoint0/endpoint0.h
index ef3afaa8..b5303864 100644
--- a/module_usb_audio/endpoint0/endpoint0.h
+++ b/module_usb_audio/endpoint0/endpoint0.h
@@ -3,6 +3,8 @@
#define _ENDPOINT0_H_
#include "dfu_interface.h"
+#include "devicedefines.h"
+#include "vendorrequests.h"
/** Function implementing Endpoint 0 for enumeration, control and configuration
* of USB audio devices. It uses the descriptors defined in ``descriptors_2.h``.
@@ -21,6 +23,7 @@
* endpoint manager if present
*/
void Endpoint0(chanend c_ep0_out, chanend c_ep0_in, chanend c_audioCtrl,
- chanend ?c_mix_ctl,chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctr, client interface i_dfu dfuInterface);
+ chanend ?c_mix_ctl,chanend ?c_clk_ctl, chanend ?c_EANativeTransport_ctr, client interface i_dfu dfuInterface
+ VENDOR_REQUESTS_PARAMS_DEC_);
#endif
diff --git a/module_usb_audio/endpoint0/vendorrequests.c b/module_usb_audio/endpoint0/vendorrequests.c
new file mode 100644
index 00000000..e9361702
--- /dev/null
+++ b/module_usb_audio/endpoint0/vendorrequests.c
@@ -0,0 +1,33 @@
+
+
+#include "xud.h"
+#include "vendorrequests.h"
+
+int VendorAudioRequests(XUD_ep ep0_out, XUD_ep ep0_in, unsigned char bRequest, unsigned char cs, unsigned char cn,
+ unsigned short unitId, unsigned char direction, chanend c_audioControl,
+ NULLABLE_RESOURCE(chanend, c_mix_ctl),
+ NULLABLE_RESOURCE(chanend, c_clk_ctL)) __attribute__ ((weak));
+
+int VendorAudioRequests(XUD_ep ep0_out, XUD_ep ep0_in, unsigned char bRequest, unsigned char cs, unsigned char cn,
+ unsigned short unitId, unsigned char direction, chanend c_audioControl,
+ NULLABLE_RESOURCE(chanend, c_mix_ctl),
+ NULLABLE_RESOURCE(chanend, c_clk_ctL))
+{
+
+ return XUD_RES_ERR;
+}
+
+int VendorRequests(XUD_ep ep0_out, XUD_ep ep0_in, REFERENCE_PARAM(USB_SetupPacket_t, sp) VENDOR_REQUESTS_PARAMS_DEC_) __attribute__ ((weak));
+
+int VendorRequests(XUD_ep ep0_out, XUD_ep ep0_in, REFERENCE_PARAM(USB_SetupPacket_t, sp) VENDOR_REQUESTS_PARAMS_DEC_)
+{
+ return XUD_RES_ERR;
+}
+
+void VendorRequests_Init(VENDOR_REQUESTS_PARAMS_DEC) __attribute__ ((weak));
+
+void VendorRequests_Init(VENDOR_REQUESTS_PARAMS_DEC)
+{
+
+}
+
diff --git a/module_usb_audio/endpoint0/vendorrequests.h b/module_usb_audio/endpoint0/vendorrequests.h
index 99662fd1..7bb8052c 100644
--- a/module_usb_audio/endpoint0/vendorrequests.h
+++ b/module_usb_audio/endpoint0/vendorrequests.h
@@ -2,6 +2,9 @@
#define _VENDORREQUESTS_H_
#include
+#include "devicedefines.h"
+#include "xud.h"
+#include "usb_std_requests.h"
/* Functions that handle vustomer vendor requests.
*
@@ -11,10 +14,32 @@
*
* */
+#define PREPEND_COMMA(x) ,x
+
+#ifndef VENDOR_REQUESTS_PARAMS
+#define VENDOR_REQUESTS_PARAMS_
+#define VENDOR_REQUESTS_PARAMS_DEC_
+#else
+#define VENDOR_REQUESTS_PARAMS_ PREPEND_COMMA(VENDOR_REQUESTS_PARAMS)
+#define VENDOR_REQUESTS_PARAMS_DEC_ PREPEND_COMMA(VENDOR_REQUESTS_PARAMS_DEC)
+#endif
+
+#ifndef VENDOR_REQUESTS_PARAMS_DEC
+#define VENDOR_REQUESTS_PARAMS_DEC
+#endif
+#ifndef VENDOR_REQUESTS_PARAMS
+#define VENDOR_REQUESTS_PARAMS
+#endif
+
int VendorAudioRequests(XUD_ep ep0_out, XUD_ep ep0_in, unsigned char bRequest, unsigned char cs, unsigned char cn,
unsigned short unitId, unsigned char direction, chanend c_audioControl,
NULLABLE_RESOURCE(chanend, c_mix_ctl),
NULLABLE_RESOURCE(chanend, c_clk_ctL));
+
+int VendorRequests(XUD_ep ep0_out, XUD_ep ep0_in, REFERENCE_PARAM(USB_SetupPacket_t, sp) VENDOR_REQUESTS_PARAMS_DEC_);
+
+void VendorRequests_Init(VENDOR_REQUESTS_PARAMS_DEC);
+
#endif
diff --git a/module_usb_audio/main.xc b/module_usb_audio/main.xc
index ad4a4b06..ba5c232c 100755
--- a/module_usb_audio/main.xc
+++ b/module_usb_audio/main.xc
@@ -22,7 +22,8 @@
#ifdef MIDI
#include "usb_midi.h"
#endif
-#include "audio.h"
+
+#include "xua_audio.h"
#ifdef IAP
#include "i2c_shared.h"
@@ -44,7 +45,7 @@
#include "clocking.h"
#if (NUM_PDM_MICS > 0)
-#include "pcm_pdm_mic.h"
+#include "xua_pdm_mic.h"
#endif
[[distributable]]
@@ -144,18 +145,18 @@ on tile[AUDIO_IO_TILE] : out port p_pll_clk = PORT_PLL_REF;
#endif
#ifdef MIDI
-on tile[MIDI_TILE] : port p_midi_tx = PORT_MIDI_OUT;
+on tile[MIDI_TILE] : port p_midi_tx = PORT_MIDI_OUT;
#if(MIDI_RX_PORT_WIDTH == 4)
-on tile[MIDI_TILE] : buffered in port:4 p_midi_rx = PORT_MIDI_IN;
+on tile[MIDI_TILE] : buffered in port:4 p_midi_rx = PORT_MIDI_IN;
#elif(MIDI_RX_PORT_WIDTH == 1)
-on tile[MIDI_TILE] : buffered in port:1 p_midi_rx = PORT_MIDI_IN;
+on tile[MIDI_TILE] : buffered in port:1 p_midi_rx = PORT_MIDI_IN;
#endif
#endif
/* Clock blocks */
#ifdef MIDI
-on tile[MIDI_TILE] : clock clk_midi = CLKBLK_MIDI;
+on tile[MIDI_TILE] : clock clk_midi = CLKBLK_MIDI;
#endif
#if defined(SPDIF_TX) || defined(ADAT_TX)
@@ -286,6 +287,7 @@ void usb_audio_core(chanend c_mix_out
, chanend ?c_clk_int
, chanend ?c_clk_ctl
, client interface i_dfu ?dfuInterface
+VENDOR_REQUESTS_PARAMS_DEC_
)
{
chan c_sof;
@@ -380,7 +382,7 @@ void usb_audio_core(chanend c_mix_out
/* Endpoint 0 Core */
{
thread_speed();
- Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface);
+ Endpoint0( c_xud_out[0], c_xud_in[0], c_aud_ctl, c_mix_ctl, c_clk_ctl, c_EANativeTransport_ctrl, dfuInterface VENDOR_REQUESTS_PARAMS_);
}
/* Decoupling core */
@@ -414,6 +416,7 @@ void usb_audio_io(chanend c_aud_in, chanend ?c_adc,
#if (NUM_PDM_MICS > 0)
, chanend c_pdm_pcm
#endif
+ , client audManage_if i_audMan
)
{
#ifdef MIXER
@@ -457,6 +460,7 @@ void usb_audio_io(chanend c_aud_in, chanend ?c_adc,
#if (NUM_PDM_MICS > 0)
, c_pdm_pcm
#endif
+ , i_audMan
);
}
@@ -543,10 +547,15 @@ int main()
#if (NUM_PDM_MICS > 0)
chan c_pdm_pcm;
+ streaming chan c_ds_output[2];
+#ifdef MIC_PROCESSING_USE_INTERFACE
+ interface mic_process_if i_mic_process;
+#endif
#endif
- USER_MAIN_DECLARATIONS
+ interface audManage_if i_audMan;
+ USER_MAIN_DECLARATIONS
par
{
on tile[XUD_TILE]:
@@ -573,6 +582,7 @@ int main()
, c_mix_ctl
#endif
, c_clk_int, c_clk_ctl, dfuInterface
+ VENDOR_REQUESTS_PARAMS_
);
}
@@ -591,7 +601,7 @@ int main()
#if (NUM_PDM_MICS > 0)
, c_pdm_pcm
#endif
-
+ , i_audMan
);
#if defined(SPDIF_TX) && (SPDIF_TX_TILE != AUDIO_IO_TILE)
@@ -654,8 +664,14 @@ int main()
#endif
#if (NUM_PDM_MICS > 0)
- on stdcore[PDM_TILE]: pcm_pdm_mic(c_pdm_pcm);
+ on stdcore[PDM_TILE]: pdm_mic(c_ds_output);
+#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);
#endif
+#endif
+
USER_MAIN_CORES
}
diff --git a/module_usb_audio/pdm_mics/pcm_pdm_mic.h b/module_usb_audio/pdm_mics/pcm_pdm_mic.h
deleted file mode 100644
index dccd9ff1..00000000
--- a/module_usb_audio/pdm_mics/pcm_pdm_mic.h
+++ /dev/null
@@ -1,2 +0,0 @@
-
-void pcm_pdm_mic(chanend c_pcm_out);
diff --git a/module_usb_audio/pdm_mics/pcm_pdm_mic.xc b/module_usb_audio/pdm_mics/pcm_pdm_mic.xc
deleted file mode 100644
index 1e5295e1..00000000
--- a/module_usb_audio/pdm_mics/pcm_pdm_mic.xc
+++ /dev/null
@@ -1,112 +0,0 @@
-
-#include "devicedefines.h"
-
-#if (NUM_PDM_MICS > 0)
-
-/* This file includes an example integration of lib_array_mic into USB Audio */
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include "mic_array.h"
-
-#define MAX_DECIMATION_FACTOR 12
-
-/* Hardware resources */
-in port p_pdm_clk = PORT_PDM_CLK;
-in buffered port:32 p_pdm_mics = PORT_PDM_DATA;
-in port p_mclk = PORT_PDM_MCLK;
-clock pdmclk = on tile[PDM_TILE]: XS1_CLKBLK_3;
-
-/* User hooks */
-unsafe void user_pdm_process(mic_array_frame_time_domain * unsafe audio, int output[]);
-void user_pdm_init();
-
-int data_0[4*THIRD_STAGE_COEFS_PER_STAGE * MAX_DECIMATION_FACTOR] = {0};
-int data_1[4*THIRD_STAGE_COEFS_PER_STAGE * MAX_DECIMATION_FACTOR] = {0};
-
-mic_array_frame_time_domain mic_audio[2];
-
-void pdm_process(streaming chanend c_ds_output[2], chanend c_audio)
-{
- unsigned buffer = 1; // Buffer index
- int output[NUM_PDM_MICS];
-
- user_pdm_init();
-
- while(1)
- {
- unsigned samplerate;
-
- c_audio :> samplerate;
-
- unsigned decimationfactor = 96000/samplerate;
-
- unsafe
- {
- const int * unsafe fir_coefs[7] = {0, g_third_stage_div_2_fir, g_third_stage_div_4_fir, g_third_stage_div_6_fir, g_third_stage_div_8_fir, 0, g_third_stage_div_12_fir};
-
- mic_array_decimator_conf_common_t dcc = {MIC_ARRAY_MAX_FRAME_SIZE_LOG2, 1, 0, 0, decimationfactor, fir_coefs[decimationfactor/2], 0, 0, DECIMATOR_NO_FRAME_OVERLAP, 2};
- mic_array_decimator_config_t dc[2] = {{&dcc, data_0, {0, 0, 0, 0}, 4}, {&dcc, data_1, {0, 0, 0, 0}, 4}};
- mic_array_decimator_configure(c_ds_output, 2, dc);
-
- mic_array_init_time_domain_frame(c_ds_output, 2, buffer, mic_audio, dc);
-
- while(1)
- {
- mic_array_frame_time_domain * unsafe current = mic_array_get_next_time_domain_frame(c_ds_output, 2, buffer, mic_audio, dc);
-
- unsafe
- {
- int req;
- user_pdm_process(current, output);
-
- c_audio :> req;
-
- if(req)
- {
- for(int i = 0; i < NUM_PDM_MICS; i++)
- {
- c_audio <: output[i];
- }
- }
- else
- {
- break;
- }
- }
- }
- }
- }
-}
-
-#if MAX_FREQ > 48000
-#error MAX_FREQ > 48000 NOT CURRENTLY SUPPORTED
-#endif
-
-void pcm_pdm_mic(chanend c_pcm_out)
-{
- streaming chan c_4x_pdm_mic_0, c_4x_pdm_mic_1;
- streaming chan c_ds_output[2];
-
- /* Note, this divide should be based on master clock freq */
- configure_clock_src_divide(pdmclk, p_mclk, 2);
- configure_port_clock_output(p_pdm_clk, pdmclk);
- configure_in_port(p_pdm_mics, pdmclk);
- start_clock(pdmclk);
-
- par
- {
- 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_decimate_to_pcm_4ch(c_4x_pdm_mic_1, c_ds_output[1]);
- pdm_process(c_ds_output, c_pcm_out);
- }
-}
-
-#endif
diff --git a/module_usb_audio/pdm_mics/pdm_mic.h b/module_usb_audio/pdm_mics/pdm_mic.h
new file mode 100644
index 00000000..cf6f0e6d
--- /dev/null
+++ b/module_usb_audio/pdm_mics/pdm_mic.h
@@ -0,0 +1,37 @@
+
+#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
new file mode 100644
index 00000000..6bc4ab83
--- /dev/null
+++ b/module_usb_audio/pdm_mics/pdm_mic.xc
@@ -0,0 +1,201 @@
+
+#include "devicedefines.h"
+
+#if (NUM_PDM_MICS > 0)
+
+/* This file includes an example integration of lib_array_mic into USB Audio */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "mic_array.h"
+#include "xua_pdm_mic.h"
+
+#define MAX_DECIMATION_FACTOR 12
+
+/* Hardware resources */
+in port p_pdm_clk = PORT_PDM_CLK;
+in buffered port:32 p_pdm_mics = PORT_PDM_DATA;
+in port p_mclk = PORT_PDM_MCLK;
+clock pdmclk = on tile[PDM_TILE]: XS1_CLKBLK_3;
+
+int data_0[4*THIRD_STAGE_COEFS_PER_STAGE * MAX_DECIMATION_FACTOR] = {0};
+int data_1[4*THIRD_STAGE_COEFS_PER_STAGE * MAX_DECIMATION_FACTOR] = {0};
+
+mic_array_frame_time_domain mic_audio[2];
+
+#ifdef MIC_PROCESSING_USE_INTERFACE
+[[combinable]]
+#pragma unsafe arrays
+void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio, client mic_process_if i_mic_process)
+#else
+#pragma unsafe arrays
+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
+ i_mic_process.init();
+#else
+ user_pdm_init();
+#endif
+
+ mic_array_decimator_conf_common_t dcc;
+ const int * unsafe fir_coefs[7];
+ mic_array_frame_time_domain * unsafe current;
+ mic_array_decimator_config_t dc[2];
+
+ /* Get initial sample-rate and compute decimation factor */
+ c_audio :> samplerate;
+ unsigned decimationfactor = 96000/samplerate;
+
+ int fir_gain_compen[7];
+
+ unsafe
+ {
+ fir_gain_compen[0] = 0;
+ fir_gain_compen[1] = FIR_COMPENSATOR_DIV_2;
+ fir_gain_compen[2] = FIR_COMPENSATOR_DIV_4;
+ fir_gain_compen[3] = FIR_COMPENSATOR_DIV_6;
+ fir_gain_compen[4] = FIR_COMPENSATOR_DIV_6;
+ fir_gain_compen[5] = 0;
+ fir_gain_compen[6] = FIR_COMPENSATOR_DIV_12;
+
+ fir_coefs[0] = 0;
+ fir_coefs[1] = g_third_stage_div_2_fir;
+ fir_coefs[2] = g_third_stage_div_4_fir;
+ fir_coefs[3] = g_third_stage_div_6_fir;
+ fir_coefs[4] = g_third_stage_div_8_fir;
+ fir_coefs[5] = 0;
+ fir_coefs[6] = g_third_stage_div_12_fir;
+
+ //dcc = {MIC_ARRAY_MAX_FRAME_SIZE_LOG2, 1, 0, 0, decimationfactor, fir_coefs[decimationfactor/2], 0, 0, DECIMATOR_NO_FRAME_OVERLAP, 2};
+ dcc.frame_size_log2 = MIC_ARRAY_MAX_FRAME_SIZE_LOG2;
+ dcc.apply_dc_offset_removal = 1;
+ dcc.index_bit_reversal = 0;
+ dcc.windowing_function = null;
+ dcc.output_decimation_factor = decimationfactor;
+ dcc.coefs = fir_coefs[decimationfactor/2];
+ dcc.apply_mic_gain_compensation = 0;
+ dcc.fir_gain_compensation = fir_gain_compen[decimationfactor/2];
+ dcc.buffering_type = DECIMATOR_NO_FRAME_OVERLAP;
+ dcc.number_of_frame_buffers = 2;
+
+ //dc[2] = {{&dcc, data_0, {0, 0, 0, 0}, 4}, {&dcc, data_1, {0, 0, 0, 0}, 4}};
+ dc[0].dcc = &dcc;
+ dc[0].data = data_0;
+ dc[0].mic_gain_compensation[0]=0;
+ dc[0].mic_gain_compensation[1]=0;
+ dc[0].mic_gain_compensation[2]=0;
+ dc[0].mic_gain_compensation[3]=0;
+ dc[0].channel_count = 4;
+ dc[1].dcc = &dcc;
+ dc[1].data = data_1;
+ dc[1].mic_gain_compensation[0]=0;
+ dc[1].mic_gain_compensation[1]=0;
+ dc[1].mic_gain_compensation[2]=0;
+ dc[1].mic_gain_compensation[3]=0;
+ dc[1].channel_count = 4;
+
+ mic_array_decimator_configure(c_ds_output, 2, dc);
+
+ mic_array_init_time_domain_frame(c_ds_output, 2, 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);
+ }
+
+ /* Run user code */
+#ifdef MIC_PROCESSING_USE_INTERFACE
+ i_mic_process.transfer_buffers(current, output);
+#else
+ user_pdm_process(current, output);
+#endif
+ int req;
+ while(1)
+ {
+ select
+ {
+ case c_audio :> req:
+
+ /* Audio IO core requests samples */
+ if(req)
+ unsafe{
+ slave
+ {
+#pragma loop unroll
+ for(int i = 0; i < NUM_PDM_MICS; i++)
+ {
+ c_audio <: output[i];
+ }
+ }
+
+ /* 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);
+
+ /* Run user code */
+#ifdef MIC_PROCESSING_USE_INTERFACE
+ i_mic_process.transfer_buffers(current, output);
+#else
+ user_pdm_process(current, output);
+#endif
+ }
+ else
+ unsafe{
+ /* Sample rate change */
+ c_audio :> samplerate;
+
+ /* Re-config the mic decimators for the new sample-rate */
+ decimationfactor = 96000/samplerate;
+ 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);
+
+ /* 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);
+
+ /* Run user code */
+#ifdef MIC_PROCESSING_USE_INTERFACE
+ i_mic_process.transfer_buffers(current, output);
+#else
+ user_pdm_process(current, output);
+#endif
+ }
+ break;
+ } /* select */
+ } /* while(1) */
+}
+
+#if MAX_FREQ > 48000
+#error MAX_FREQ > 48000 NOT CURRENTLY SUPPORTED
+#endif
+
+void pdm_mic(streaming chanend c_ds_output[2])
+{
+ streaming chan c_4x_pdm_mic_0, c_4x_pdm_mic_1;
+
+ /* Note, this divide should be based on master clock freq */
+ configure_clock_src_divide(pdmclk, p_mclk, 2);
+ configure_port_clock_output(p_pdm_clk, pdmclk);
+ configure_in_port(p_pdm_mics, pdmclk);
+ start_clock(pdmclk);
+
+ par
+ {
+ 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_decimate_to_pcm_4ch(c_4x_pdm_mic_1, c_ds_output[1]);
+ }
+}
+#endif
diff --git a/module_usb_audio/pdm_mics/xua_pdm_mic.h b/module_usb_audio/pdm_mics/xua_pdm_mic.h
new file mode 100644
index 00000000..69e52d5c
--- /dev/null
+++ b/module_usb_audio/pdm_mics/xua_pdm_mic.h
@@ -0,0 +1,40 @@
+
+#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 */
+void user_pdm_process(mic_array_frame_time_domain * unsafe audio, int output[]);
+
+void user_pdm_init();
+
+/* PDM interface and decimation cores */
+void pdm_buffer(streaming chanend c_ds_output[2], chanend c_audio);
+
+/* PDM interface and decimation cores */
+void pdm_mic(streaming chanend c_ds_output[2]);
+
+#endif
+
diff --git a/module_usb_midi/.cproject b/module_usb_midi/.cproject
index be06e554..bd78753f 100644
--- a/module_usb_midi/.cproject
+++ b/module_usb_midi/.cproject
@@ -156,10 +156,8 @@
-
-
+
-
@@ -273,10 +271,8 @@
-
-
+
-
@@ -396,10 +392,8 @@
-
-
+
-
diff --git a/xpd.xml b/xpd.xml
index b201845d..266f4360 100644
--- a/xpd.xml
+++ b/xpd.xml
@@ -15,7 +15,7 @@
- module_queue
+ module_queue
MIDI
@@ -101,7 +101,10 @@
-
+
+
+
+
XM-004720-SM
XMOS