cancel
Showing results for 
Search instead for 
Did you mean: 

mp45dt02 mic passthru to DAC

davejun
Associate
Posted on December 15, 2012 at 02:25

On the discovery board, the digital MEMs mic data is accessed by providing a clock from i2s_2. In the Audio_playback_record example, i2s is set up to acquire data in 16b blocks, and an interrupt (AUDIO_REC_SPI_IRQHANDLER) is called when this data is ready to be filtered.

My question is, what is the ''correct'' way to set up a DAC to stream out this data? Is there a way to drive the DAC based on the i2s clock?

6 REPLIES 6
raptorhal2
Lead
Posted on December 15, 2012 at 15:32

I believe all you need to do is DAC each filtered result in the interrupt handler.

Cheers, Hal

davejun
Associate
Posted on December 16, 2012 at 00:18

Thanks for the reply, I got it working. I'll leave some tips and code here for anyone that wants to stream data from the PDM Mic:

1. use WaveRecorderInit() and WaveRecorderStart() from the audio_playback_record example project to setup the MIC. 2. for DAC, setup GPIO clk, pins, and settings. For DAC triggering, use DAC_Trigger_None. 3. modify the IRQ handler in waverecorder.c:

void AUDIO_REC_SPI_IRQHANDLER(void)
{ 
u16 volume;
u16 app;
u16 tmp;
/* Check if data are available in SPI Data register */
if (SPI_GetITStatus(SPI2, SPI_I2S_IT_RXNE) != RESET)
{
app = SPI_I2S_ReceiveData(SPI2);
InternalBuffer[InternalBufferSize++] = HTONS(app);
outputcnt++;
if (outputcnt >= 4) 
{
outputcnt = 0;
// convert data from 2sC to unsigned int
tmp = *(pAudioRecBuf+bufcntr);
tmp = (tmp>=32768) ? tmp - 32768 : tmp + 32768;
// load DAC. trigger is set to none, so data will immediately be transferred out
DAC_SetChannel2Data((uint32_t)DAC_Align_12b_L, tmp);
bufcntr++;
}
/* Check to prevent overflow condition */
if (InternalBufferSize >= INTERNAL_BUFF_SIZE)
{
// reset output-buffer counter
bufcntr = 0;
// reset internal-buffer counter
InternalBufferSize = 0;
volume = 50;
PDM_Filter_64_LSB((uint8_t *)InternalBuffer, (uint16_t *)pAudioRecBuf, volume, (PDMFilter_InitStruct *)&Filter);
Data_Status = 1;
}
}
}

In the code, outputcnt controls how often the DAC outputs data, which is depends on the PDM decimation factor and the fact that every time the interrupt is called, 16 bits are generated from the mic. In my case, I chose a decimation factor of 64, so we output to the DAC once every 64/16=4 calls to the interrupt. Finally, it looks like the PDM filter output is in 2s complement format. The DAC requires unsigned int, so we make the conversion. If you don't, the DAC output sounds very noisy and clipped. Cheers! David
emb_zb
Associate
Posted on August 16, 2013 at 16:28

emb_zb
Associate
Posted on August 16, 2013 at 16:28

what did you connect after the DAC? Need a amp and a speaker?

How can I use the cs43l22 to implement the record and play at the same time? thanks

sevketkahya
Associate II
Posted on February 06, 2014 at 09:04

Hi, i am new at embedded programming, and i am trying to learn but I couldn't find source which is appropriate for beginners. 

Can you upload your project that you mentioned?

Posted on February 06, 2014 at 17:39

Can you upload your project that you mentioned?

The code in question comes from the STM32F4-Discovery firmware library

STM32F4-Discovery_FW_V1.1.0\Project\Audio_playback_and_record\src\waverecorder.c

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..