cancel
Showing results for 
Search instead for 
Did you mean: 

Mic on Discovery

gitarpista
Associate II
Posted on May 01, 2012 at 12:37

Hi.

I want to simply read the PCM data coming from the microphone(MP45DT02), which is on the stm32f4 discovery board. I configured the I2S2_CK and I2S2_SD pins, the I2S communication, and enabled the SPI_I2S_IT_RXNE interrupt request. In the IRQHandler when i call the SPI_I2S_ReceiveData(SPI2) function, it looks like i always read ZEROS. What's the problem? Is something else is missing?

I read similiar examples, and documents but it didnt help me a lot. Please help me.

Thanx.
10 REPLIES 10
Posted on May 01, 2012 at 13:39

Post the code if you want it reviewed. I'd guess you've misconfigured the pins, or AF assignments.

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
gitarpista
Associate II
Posted on May 01, 2012 at 14:58

GPIO config:

    GPIO_InitTypeDef GPIO_InitStructure;

 

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOB, ENABLE);

    RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;

    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;

    GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;

    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_SPI2); /* I2S2_CK    */

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;

    GPIO_Init(GPIOC, &GPIO_InitStructure);

    GPIO_PinAFConfig(GPIOC, GPIO_PinSource3, GPIO_AF_SPI2); /* I2S2_SD    */

I2S config:

    I2S_InitTypeDef I2S_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2, ENABLE);

    SPI_I2S_DeInit(SPI2);

    I2S_InitStructure.I2S_AudioFreq = 32000;

    I2S_InitStructure.I2S_Standard = I2S_Standard_LSB;

    I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;

    I2S_InitStructure.I2S_CPOL = I2S_CPOL_High;

    I2S_InitStructure.I2S_Mode = I2S_Mode_MasterRx;

    I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;

    RCC_I2SCLKConfig(RCC_I2S2CLKSource_PLLI2S);

    RCC_PLLI2SCmd(ENABLE);

    while(RCC_GetFlagStatus(RCC_FLAG_PLLI2SRDY)==RESET);

    I2S_Init(SPI2, &I2S_InitStructure);

    SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);

    I2S_Cmd(SPI2, ENABLE);

NVIC Config:

    NVIC_InitTypeDef NVIC_InitStructure;

    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);

    /* Configure the SPI interrupt priority */

    NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;

    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;

    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;

    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;

    NVIC_Init(&NVIC_InitStructure);

SPI2_IRQHandler:

   u16 volume=0;

   u16 app=0;

    

  if (SPI_GetITStatus(SPI2, SPI_I2S_IT_RXNE) != RESET)

  {

    app = SPI_I2S_ReceiveData(SPI2);

    InternalBuffer[InternalBufferSize++] = HTONS(app);

        

    if (InternalBufferSize >= INTERNAL_BUFF_SIZE)

    {

      InternalBufferSize = 0;

      volume = 10;

      PDM_Filter_64_LSB((uint8_t *)InternalBuffer, pAudioRecBuf, volume , &Filter);

            Data_Status = 1;

     }

   }

I copied most of it from an example project. I also implemented the Filter, but it is not relevant now, so i havent posted it. My  problem is: when i exam the 'app' variable at debugging, the value is always ''<not in scope>'', so the InternalBuffer[] remains full of zeros.
frankmeyer9
Associate II
Posted on May 01, 2012 at 19:40

It might helpful to declare your '

app

' variable as

volatile

, so it's not optimized out.

gitarpista
Associate II
Posted on May 01, 2012 at 20:15

Thanx. 'volatile' helped a bit, because 'app' isnt  'not in scope' anymore after the statement app = SPI_I2S_ReceiveData(SPI2). But of course it's always zero.

It looks like the microphone doesnt send anything towards the microcontroller. Maybe i forgot to call a clock enable function or there's a strange way of turning on the microphone.

frankmeyer9
Associate II
Posted on May 02, 2012 at 16:02

I don't know what toolchain you use. But 'not in scope' usually means that variable is simply not known in this scope. This happens for instance if you add a local ('automatic') variable to the debug watch. As soon as you step out of this function, the variable is out of scope for the debugger. This is not really a problem.

I have not been working with the microphone chip - do you see anything on the bus ?

I guess not, the datasheet says:

CLK  :  Synchronization input clock

That suggests to me that you need to initialize the STM32F4 as master, with clock output enabled.

gitarpista
Associate II
Posted on May 02, 2012 at 20:47

gitarpista
Associate II
Posted on May 02, 2012 at 20:49

I dont understand exactly what you mean, but if i configure the SPI communication this way, it works perfectly(obviously not the mic, but everything else).

If i change to I2S_MCLKOutput_Enable it doest work either, if your idea was that. 

frankmeyer9
Associate II
Posted on May 02, 2012 at 21:11

I was checking the Mic chip data sheet, which stated exactly this. I interpret it in this way, i.e. the MP45DT02 needs a clock at the CLK pin.

With an oscilloscope on CLK and DOUT, you should see the bus traffic. If not, there is something missing. There might be more necessary to configure the STM I2S peripheral to Master mode than setting

I2S_InitStructure.I2S_MCLKOutput

to

I2S_MCLKOutput_Enable

. I did not yet study this part of the Ref. Manual in detail. The ST firmware library has an (more complex) example, that initializes the I2S unit with MCLK enabled: (from stm32f4_discovery_audio_codec.h)

#define I2S_STANDARD_PHILLIPS

#define CODEC_MCLK_ENABLED

(from stm32f4_discovery_audio_codec.c)

static void Codec_GPIO_DeInit(void)

{

 GPIO_InitTypeDef GPIO_InitStructure;

 /* Deinitialize all the GPIOs used by the driver */

 GPIO_InitStructure.GPIO_Pin = CODEC_I2S_SCK_PIN | CODEC_I2S_SD_PIN;

 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;

 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;

 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;

 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;

 GPIO_Init(CODEC_I2S_GPIO, &GPIO_InitStructure); 

 

 GPIO_InitStructure.GPIO_Pin = CODEC_I2S_WS_PIN ;

 GPIO_Init(CODEC_I2S_WS_GPIO, &GPIO_InitStructure); 

 

 /* Disconnect pins from I2S peripheral */

 GPIO_PinAFConfig(CODEC_I2S_WS_GPIO, CODEC_I2S_WS_PINSRC, 0x00); 

 GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_SCK_PINSRC, 0x00);

 GPIO_PinAFConfig(CODEC_I2S_GPIO, CODEC_I2S_SD_PINSRC, 0x00); 

 

#ifdef CODEC_MCLK_ENABLED

 /* CODEC_I2S pins deinitialization: MCK pin */

 GPIO_InitStructure.GPIO_Pin = CODEC_I2S_MCK_PIN; 

 GPIO_Init(CODEC_I2S_MCK_GPIO, &GPIO_InitStructure); 

 /* Disconnect pins from I2S peripheral */

 GPIO_PinAFConfig(CODEC_I2S_MCK_GPIO, CODEC_I2S_MCK_PINSRC, CODEC_I2S_GPIO_AF); 

#endif /* CODEC_MCLK_ENABLED */ 

}

From: sodenberg.kristian Posted: Wednesday, May 02, 2012 8:52 PM Subject: Mic on Discovery

I dont understand exactly what you mean, but if i configure the SPI communication this way, it works perfectly(obviously not the mic, but everything else).

If i change to I2S_MCLKOutput_Enable it doest work either, if your idea was that.

gitarpista
Associate II
Posted on May 05, 2012 at 00:25

With an oscilloscope i could measure the I2S_SCK

clock but there's no data on the I2S_DOUT.  I also tried to call the functions above, but nothing happens. Maybe my mic is the problem. I dont have any idea, but truly thank you for your effort.