diff --git a/module_usb_audio/.cproject b/module_usb_audio/.cproject
index cc782131..4e47aeca 100644
--- a/module_usb_audio/.cproject
+++ b/module_usb_audio/.cproject
@@ -1,3 +1,53 @@
+<<<<<<< HEAD
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ xmake
+ -f .makefile
+ all
+ true
+ true
+ true
+
+
+ xmake
+ -f .makefile
+ clean
+ true
+ true
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
@@ -395,21 +324,431 @@
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+<<<<<<< HEAD
+
+
+
+
+
+
+
+
+
+
+
+
+
+=======
@@ -424,107 +763,456 @@
+>>>>>>> master
-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+<<<<<<< HEAD
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+=======
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
+>>>>>>> master
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/module_usb_audio/.project b/module_usb_audio/.project
index cb42a172..80c9d6e8 100644
--- a/module_usb_audio/.project
+++ b/module_usb_audio/.project
@@ -1,76 +1,90 @@
- module_usb_audio
-
-
-
-
-
- org.eclipse.cdt.managedbuilder.core.genmakebuilder
- clean,full,incremental,
-
-
- ?children?
- ?name?=outputEntries\|?children?=?name?=entry\\\\|\\|\||
-
-
- ?name?
-
-
-
- org.eclipse.cdt.make.core.append_environment
- true
-
-
- org.eclipse.cdt.make.core.buildArguments
- CONFIG=Debug
-
-
- org.eclipse.cdt.make.core.buildCommand
- xmake
-
-
- org.eclipse.cdt.make.core.cleanBuildTarget
- clean
-
-
- org.eclipse.cdt.make.core.contents
- org.eclipse.cdt.make.core.activeConfigSettings
-
-
- org.eclipse.cdt.make.core.enableAutoBuild
- false
-
-
- org.eclipse.cdt.make.core.enableCleanBuild
- true
-
-
- org.eclipse.cdt.make.core.enableFullBuild
- true
-
-
- org.eclipse.cdt.make.core.stopOnError
- true
-
-
- org.eclipse.cdt.make.core.useDefaultBuildCmd
- false
-
-
-
-
- org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
- full,incremental,
-
-
-
-
-
- org.eclipse.cdt.core.cnature
- org.eclipse.cdt.managedbuilder.core.managedBuildNature
- org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
- com.xmos.cdt.core.XdeProjectNature
-
+ module_usb_audio
+
+
+
+
+
+ com.xmos.cdt.core.LegacyProjectCheckerBuilder
+
+
+
+
+ com.xmos.cdt.core.ProjectInfoSyncBuilder
+
+
+
+
+ com.xmos.cdt.core.ModulePathBuilder
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.genmakebuilder
+ clean,full,incremental,
+
+
+ ?children?
+ ?name?=outputEntries\|?children?=?name?=entry\\\\|\\|\||
+
+
+ ?name?
+
+
+
+ org.eclipse.cdt.make.core.append_environment
+ true
+
+
+ org.eclipse.cdt.make.core.buildArguments
+ CONFIG=Debug
+
+
+ org.eclipse.cdt.make.core.buildCommand
+ xmake
+
+
+ org.eclipse.cdt.make.core.cleanBuildTarget
+ clean
+
+
+ org.eclipse.cdt.make.core.contents
+ org.eclipse.cdt.make.core.activeConfigSettings
+
+
+ org.eclipse.cdt.make.core.enableAutoBuild
+ false
+
+
+ org.eclipse.cdt.make.core.enableCleanBuild
+ true
+
+
+ org.eclipse.cdt.make.core.enableFullBuild
+ true
+
+
+ org.eclipse.cdt.make.core.stopOnError
+ true
+
+
+ org.eclipse.cdt.make.core.useDefaultBuildCmd
+ false
+
+
+
+
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder
+ full,incremental,
+
+
+
+
+
+ org.eclipse.cdt.core.cnature
+ org.eclipse.cdt.managedbuilder.core.managedBuildNature
+ org.eclipse.cdt.managedbuilder.core.ScannerConfigNature
+ com.xmos.cdt.core.XdeProjectNature
+
-
diff --git a/module_usb_audio/audio.h b/module_usb_audio/audio.h
index 271def28..304656e8 100644
--- a/module_usb_audio/audio.h
+++ b/module_usb_audio/audio.h
@@ -26,6 +26,9 @@ void audio(chanend c_in,
#if (XUD_TILE != 0)
, server interface i_dfu dfuInterface
#endif
+#if (NUM_PDM_MICS > 0)
+ , chanend c_pdm_in
+#endif
);
void SpdifTxWrapper(chanend c_spdif_tx);
diff --git a/module_usb_audio/audio.xc b/module_usb_audio/audio.xc
index edadc756..5ec45615 100755
--- a/module_usb_audio/audio.xc
+++ b/module_usb_audio/audio.xc
@@ -224,7 +224,7 @@ static inline void TransferAdatTxSamples(chanend c_adat_out, const unsigned samp
#pragma unsafe arrays
-static inline unsigned DoSampleTransfer(chanend c_out, int readBuffNo, unsigned underflowWord)
+static inline unsigned DoSampleTransfer(chanend c_out, const int readBuffNo, const unsigned underflowWord)
{
outuint(c_out, underflowWord);
@@ -433,6 +433,10 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
#if(defined(SPDIF_RX) || defined(ADAT_RX))
chanend c_dig_rx,
#endif
+#if (NUM_PDM_MICS > 0)
+ chanend c_pdm_pcm,
+#endif
+
chanend ?c_adc)
{
@@ -684,7 +688,7 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
#endif
#if defined(SPDIF_RX) || defined(ADAT_RX)
- /* Request digital data (with prefill) */
+ /* Request digital data (with prefill) */
outuint(c_dig_rx, 0);
#endif
#if defined(SPDIF_TX) && (NUM_USB_CHAN_OUT > 0)
@@ -692,6 +696,15 @@ unsigned static deliver(chanend c_out, chanend ?c_spd_out,
unsigned sample = samplesOut[SPDIF_TX_INDEX + 1];
outuint(c_spd_out, sample); /* Forward sample to S/PDIF Tx thread */
#endif
+
+#if (NUM_PDM_MICS > 0)
+ /* Get samples from PDM->PCM comverter */
+#pragma loop unroll
+ for(int i = 0; i < NUM_PDM_MICS; i++)
+ {
+ c_pdm_pcm :> samplesIn_0[i];
+ }
+#endif
}
@@ -924,6 +937,9 @@ chanend ?c_config, chanend ?c
#if XUD_TILE != 0
, server interface i_dfu dfuInterface
#endif
+#if (NUM_PDM_MICS > 0)
+, chanend c_pdm_in
+#endif
)
{
#if defined (SPDIF_TX) && (SPDIF_TX_TILE == AUDIO_IO_TILE)
@@ -1164,6 +1180,7 @@ chanend ?c_config, chanend ?c
outuint(c_spdif_out, mClk);
#endif
+
#ifdef ADAT_TX
// Configure ADAT parameters ...
//
@@ -1190,6 +1207,9 @@ chanend ?c_config, chanend ?c
divide, curSamFreq,
#if defined (ADAT_RX) || defined (SPDIF_RX)
c_dig_rx,
+#endif
+#if (NUM_PDM_MICS > 0)
+ c_pdm_in,
#endif
c);
diff --git a/module_usb_audio/devicedefines.h b/module_usb_audio/devicedefines.h
index 1eb70cdd..c4d9a2aa 100644
--- a/module_usb_audio/devicedefines.h
+++ b/module_usb_audio/devicedefines.h
@@ -45,6 +45,13 @@
#define SPDIF_TX_TILE AUDIO_IO_TILE
#endif
+/**
+ * @brief Location (tile) of PDM Rx. Default: AUDIO_IO_TILE
+ */
+#ifndef PDM_TILE
+#define PDM_TILE AUDIO_IO_TILE
+#endif
+
/**
* @brief Number of input channels (device to host). Default: NONE (Must be defined by app)
*/
@@ -201,11 +208,18 @@
/* Feature defines */
+/**
+ * @brief Number of PDM microphones in the design. Default: None
+ */
+#ifndef NUM_PDM_MICS
+#define NUM_PDM_MICS (0)
+#endif
+
/**
* @brief Enable MIDI functionality including buffering, descriptors etc. Default: DISABLED
*/
#ifndef MIDI
-#define MIDI (0)
+#define MIDI (0)
#endif
#if defined(MIDI) && (MIDI == 0)
@@ -1088,6 +1102,8 @@
#endif
#endif
+
+
/* Endpoint addresses enums */
enum USBEndpointNumber_In
{
diff --git a/module_usb_audio/main.xc b/module_usb_audio/main.xc
index 63190444..93cef778 100755
--- a/module_usb_audio/main.xc
+++ b/module_usb_audio/main.xc
@@ -43,6 +43,12 @@
#include "clocking.h"
+#if (NUM_PDM_MICS > 0)
+#include "pcm_pdm_mic.h"
+#endif
+
+void genclock();
+
[[distributable]]
void DFUHandler(server interface i_dfu i, chanend ?c_user_cmd);
@@ -407,6 +413,9 @@ void usb_audio_io(chanend c_aud_in, chanend ?c_adc,
#if (XUD_TILE != 0)
, server interface i_dfu dfuInterface
#endif
+#if (NUM_PDM_MICS > 0)
+ , chanend c_pdm_pcm
+#endif
)
{
#ifdef MIXER
@@ -445,7 +454,10 @@ void usb_audio_io(chanend c_aud_in, chanend ?c_adc,
#endif
c_aud_cfg, c_adc
#if XUD_TILE != 0
- ,dfuInterface
+ , dfuInterface
+#endif
+#if (NUM_PDM_MICS > 0)
+ , c_pdm_pcm
#endif
);
}
@@ -458,6 +470,7 @@ void usb_audio_io(chanend c_aud_in, chanend ?c_adc,
}
#endif
+
//:
}
}
@@ -469,7 +482,6 @@ void usb_audio_io(chanend c_aud_in, chanend ?c_adc,
#ifndef USER_MAIN_CORES
#define USER_MAIN_CORES
#endif
-//::
/* Main for USB Audio Applications */
int main()
@@ -531,6 +543,9 @@ int main()
#define dfuInterface null
#endif
+#if (NUM_PDM_MICS > 0)
+ chan c_pdm_pcm;
+#endif
USER_MAIN_DECLARATIONS
@@ -560,6 +575,7 @@ int main()
, c_mix_ctl
#endif
, c_clk_int, c_clk_ctl, dfuInterface
+
);
}
@@ -574,6 +590,9 @@ int main()
#if XUD_TILE != 0
, dfuInterface
#endif
+#if (NUM_PDM_MICS > 0)
+ , c_pdm_pcm
+#endif
);
@@ -635,6 +654,10 @@ int main()
}
}
#endif
+
+#if (NUM_PDM_MICS > 0)
+ on stdcore[PDM_TILE]: pcm_pdm_mic(c_pdm_pcm);
+#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
new file mode 100644
index 00000000..dccd9ff1
--- /dev/null
+++ b/module_usb_audio/pdm_mics/pcm_pdm_mic.h
@@ -0,0 +1,2 @@
+
+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
new file mode 100644
index 00000000..3f959b47
--- /dev/null
+++ b/module_usb_audio/pdm_mics/pcm_pdm_mic.xc
@@ -0,0 +1,98 @@
+
+#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
+
+#include "fir_decimator.h"
+#include "mic_array.h"
+
+/* 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(frame_audio * unsafe audio, int output[]);
+void user_pdm_init();
+
+void pdm_process(streaming chanend c_ds_output_0, streaming chanend c_ds_output_1, chanend c_audio)
+{
+ unsigned buffer = 1; // Buffer index
+ frame_audio audio[2]; // Double buffered
+ memset(audio, sizeof(frame_audio), 0);
+ int output[NUM_PDM_MICS];
+
+ user_pdm_init();
+
+ decimator_init_audio_frame(c_ds_output_0, c_ds_output_1, buffer, audio);
+
+ while(1)
+ {
+ frame_audio * unsafe current = decimator_get_next_audio_frame(c_ds_output_0, c_ds_output_1, buffer, audio);
+
+ unsafe
+ {
+ user_pdm_process(current, output);
+
+ for(int i = 0; i < NUM_PDM_MICS; i++)
+ {
+ c_audio <: output[i];
+ }
+ }
+ }
+}
+
+#define DF 1
+
+#define OUTPUT_SAMPLE_RATE (48000/DF)
+
+#if MAX_FREQ != 48000
+#error NOT CURRENTLY SUPPORTED
+#endif
+#if MIN_FREQ != 48000
+#error NOT CURRENTLY SUPPORTED
+#endif
+
+//TODO make these not global
+int data_0[4*COEFS_PER_PHASE*DF] = {0};
+int data_1[4*COEFS_PER_PHASE*DF] = {0};
+
+void pcm_pdm_mic(chanend c_pcm_out)
+{
+ streaming chan c_multi_channel_pdm, c_sync, c_4x_pdm_mic_0, c_4x_pdm_mic_1;
+ streaming chan c_ds_output_0, c_ds_output_1;
+ streaming chan c_buffer_mic0, c_buffer_mic1;
+
+ 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);
+
+ unsafe
+ {
+ decimator_config dc0 = {FRAME_SIZE_LOG2, 1, 0, 0, DF, FIR_LUT(DF), data_0, 0, {0,0, 0, 0}};
+ decimator_config dc1 = {FRAME_SIZE_LOG2, 1, 0, 0, DF, FIR_LUT(DF), data_1, 0, {0,0, 0, 0}};
+
+ par
+ {
+ pdm_rx(p_pdm_mics, c_4x_pdm_mic_0, c_4x_pdm_mic_1);
+ decimate_to_pcm_4ch(c_4x_pdm_mic_0, c_ds_output_0, dc0);
+ decimate_to_pcm_4ch(c_4x_pdm_mic_1, c_ds_output_1, dc1);
+ pdm_process(c_ds_output_0, c_ds_output_1, c_pcm_out);
+ }
+ }
+}
+
+#endif