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 + + + + + + + + + + + + + + + - - + + + + + - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + - - - +>>>>>>> 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