AnsweredAssumed Answered

STM32F4-Discovery Real-time microphone

Question asked by krmp8 on Apr 30, 2013
Latest reply on Feb 6, 2014 by fm
Hello,

I would like to use the internal microphone built in the board to hear the sound from headphone jack in real time. After that I 'll be implementing filter to the sound but thats not so important at the moment.

The problem is static. Firstly i used a simple very short 16bit 16khz wave to test the headphone but I hear static no matter what I did. Also I tried with microphone but I realized that by adding a breakpoint at the spi interrupt, the code runs continously without entering interrupt routine.

What am I missing? Any help will be appreciated.

Note: I deleted the sound file in the sample array below because it is taking up much space.

001./* Includes ------------------------------------------------------------------*/
002.#include "stm32f4xx.h"
003.#include "stm32f4_discovery.h"
004.#include "stm32f4_discovery_audio_codec.h"
005.#include "stm32f4xx_it.h"
006.#include "pdm_filter.h"
007. 
008./* Private define ------------------------------------------------------------*/
009.#define SPI_SCK_PIN                       GPIO_Pin_10
010.#define SPI_SCK_GPIO_PORT                 GPIOB
011.#define SPI_SCK_GPIO_CLK                  RCC_AHB1Periph_GPIOB
012.#define SPI_SCK_SOURCE                    GPIO_PinSource10
013.#define SPI_SCK_AF                        GPIO_AF_SPI2
014.#define SPI_MOSI_PIN                      GPIO_Pin_3
015.#define SPI_MOSI_GPIO_PORT                GPIOC
016.#define SPI_MOSI_GPIO_CLK                 RCC_AHB1Periph_GPIOC
017.#define SPI_MOSI_SOURCE                   GPIO_PinSource3
018.#define SPI_MOSI_AF                       GPIO_AF_SPI2
019.#define AUDIO_REC_SPI_IRQHANDLER          SPI2_IRQHandler
020.#define INTERNAL_BUFF_SIZE                64
021.#define OUTPUT_BUFF_SIZE                  16
022.#define SAMPLE_SIZE_IN_BYTES              32
023.//64
024. 
025./* Private macro -------------------------------------------------------------*/
026./* Private variables ---------------------------------------------------------*/
027.uint32_t AudioRecInited = 0;
028.PDMFilter_InitStruct Filter;
029.uint32_t AudioRecBitRes = 16;
030.uint32_t AudioRecChnlNbr = 1;
031.uint16_t* pAudioRecBuf;
032.uint16_t OutputBuffer[OUTPUT_BUFF_SIZE];
033.uint16_t InternalBuffer[INTERNAL_BUFF_SIZE];
034.uint32_t InternalBufferSize = 0;
035.__IO uint8_t vol = 70;
036. 
037.uint16_t sample[] = {
038.         
039.};
040. 
041.uint16_t* sampleptr = &sample[0];
042. 
043./* Private function prototypes -----------------------------------------------*/
044.uint32_t WavePlaybackInit(uint32_t AudioFreq);
045.void WavePlay(void);
046.uint32_t WaveRecorderInit(uint32_t AudioFreq);
047.uint8_t WaveRecorderStart(uint16_t* pbuf, uint32_t size);
048.uint32_t WaveRecorderStop(void);
049.void AUDIO_REC_SPI_IRQHANDLER(void);
050.void WaveRecorder_GPIO_Init(void);
051.void WaveRecorder_SPI_Init(uint32_t Freq);
052.void WaveRecorder_NVIC_Init(void);
053.void Delay(__IO uint32_t nCount);
054. 
055./* Main ----------------------------------------------------------------------*/
056. 
057.int main(void)
058.{
059.  //GPIO_InitTypeDef  GPIO_InitStructure;
060. 
061.  /* GPIOD Periph clock enable */
062.  //RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
063. 
064.  /* Configure PD12, PD13, PD14 and PD15 in output pushpull mode */
065.  //GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
066.  //GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
067.  //GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
068.  //GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
069.  //GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
070.  //GPIO_Init(GPIOD, &GPIO_InitStructure);
071. 
072.  //STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_EXTI);
073. 
074.  WavePlaybackInit(I2S_AudioFreq_16k); //is it ok?
075.  WaveRecorderInit(I2S_AudioFreq_16k); //why nonsense
076.  WaveRecorderStart(OutputBuffer,OUTPUT_BUFF_SIZE);
077. 
078.  WavePlay();
079. 
080.  while (1)
081.  {
082.    //WavePlay();
083./*
084.    GPIO_SetBits(GPIOD, GPIO_Pin_12);
085.    Delay(0x3FFFFF);
086.    GPIO_SetBits(GPIOD, GPIO_Pin_13);
087.    Delay(0x3FFFFF);
088.    GPIO_SetBits(GPIOD, GPIO_Pin_14);
089.    Delay(0x3FFFFF);
090.    GPIO_SetBits(GPIOD, GPIO_Pin_15);
091.    Delay(0x7FFFFF);
092.    GPIO_ResetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
093.    Delay(0xFFFFFF);
094.    */
095.  }
096.}
097. 
098.uint32_t WavePlaybackInit(uint32_t AudioFreq)
099.{
100.  EVAL_AUDIO_SetAudioInterface(AUDIO_INTERFACE_I2S);
101.  if(EVAL_AUDIO_Init(OUTPUT_DEVICE_HEADPHONE, vol, AudioFreq)!=0)
102.  {
103.      return 1;
104.  }
105.  else
106.  {
107.      return 0;
108.  }
109.}
110. 
111.void WavePlay(void)
112.{
113.  EVAL_AUDIO_Play((uint16_t*)pAudioRecBuf, SAMPLE_SIZE_IN_BYTES);
114.  //EVAL_AUDIO_Play((uint16_t*)sampleptr, 8000);
115.}
116. 
117.uint32_t WaveRecorderInit(uint32_t AudioFreq)
118.{
119.  /* Check if the interface is already initialized */
120.  if (AudioRecInited)
121.  {
122.    /* No need for initialization */
123.    return 0;
124.  }
125.  else
126.  {
127.    /* Enable CRC module */
128.    RCC->AHB1ENR |= RCC_AHB1ENR_CRCEN;
129. 
130.    /* Filter LP & HP Init */
131.    Filter.LP_HZ = 8000;
132.    Filter.HP_HZ = 10;
133.    Filter.Fs = 16000;
134.    Filter.Out_MicChannels = 1;
135.    Filter.In_MicChannels = 1;
136. 
137.    PDM_Filter_Init((PDMFilter_InitStruct *)&Filter);
138. 
139.    /* Configure the GPIOs */
140.    WaveRecorder_GPIO_Init();
141. 
142.    /* Configure the interrupts (for timer) */
143.    WaveRecorder_NVIC_Init();
144. 
145.    /* Configure the SPI */
146.    WaveRecorder_SPI_Init(AudioFreq);
147. 
148.    /* Set state of the audio recorder to initialized */
149.    AudioRecInited = 1;
150. 
151.    /* Return 0 if all operations are OK */
152.    return 0;
153.  }
154.}
155. 
156.uint8_t WaveRecorderStart(uint16_t* pbuf, uint32_t size)
157.{
158./* Check if the interface has already been initialized */
159.  if (AudioRecInited)
160.  {
161.    /* Store the location and size of the audio buffer */
162.    pAudioRecBuf = pbuf;
163. 
164.    /* Enable the Rx buffer not empty interrupt */
165.    SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
166.    /* The Data transfer is performed in the SPI interrupt routine */
167.    /* Enable the SPI peripheral */
168.    I2S_Cmd(SPI2, ENABLE);
169. 
170.    /* Return 0 if all operations are OK */
171.    return 0;
172.  }
173.  else
174.  {
175.    /* Cannot perform operation */
176.    return 1;
177.  }
178.}
179. 
180.uint32_t WaveRecorderStop(void)
181.{
182.  /* Check if the interface has already been initialized */
183.  if (AudioRecInited)
184.  {
185. 
186.    /* Stop conversion */
187.    I2S_Cmd(SPI2, DISABLE);
188. 
189.    /* Return 0 if all operations are OK */
190.    return 0;
191.  }
192.  else
193.  {
194.    /* Cannot perform operation */
195.    return 1;
196.  }
197.}
198. 
199.void AUDIO_REC_SPI_IRQHANDLER(void)
200.{
201.   u16 volume;
202.   u16 app;
203. 
204.  /* Check if data are available in SPI Data register */
205.  if (SPI_GetITStatus(SPI2, SPI_I2S_IT_RXNE) != RESET)
206.  {
207.    app = SPI_I2S_ReceiveData(SPI2);
208.    InternalBuffer[InternalBufferSize++] = HTONS(app);
209. 
210.    /* Check to prevent overflow condition */
211.    if (InternalBufferSize >= INTERNAL_BUFF_SIZE)
212.    {
213.      InternalBufferSize = 0;
214. 
215.      volume = 50;
216. 
217.      PDM_Filter_64_LSB((uint8_t *)InternalBuffer, (uint16_t *)pAudioRecBuf, volume , (PDMFilter_InitStruct *)&Filter);
218.    }
219.  }
220.}
221. 
222.void WaveRecorder_GPIO_Init(void)
223.{
224.  GPIO_InitTypeDef GPIO_InitStructure;
225. 
226.  /* Enable GPIO clocks */
227.  RCC_AHB1PeriphClockCmd(SPI_SCK_GPIO_CLK | SPI_MOSI_GPIO_CLK, ENABLE);
228. 
229.  /* Enable GPIO clocks */
230.  RCC_AHB1PeriphClockCmd(SPI_SCK_GPIO_CLK | SPI_MOSI_GPIO_CLK, ENABLE);
231. 
232.  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
233.  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
234.  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_NOPULL;
235.  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
236. 
237.  /* SPI SCK pin configuration */
238.  GPIO_InitStructure.GPIO_Pin = SPI_SCK_PIN;
239.  GPIO_Init(SPI_SCK_GPIO_PORT, &GPIO_InitStructure);
240. 
241.  /* Connect SPI pins to AF5 */
242.  GPIO_PinAFConfig(SPI_SCK_GPIO_PORT, SPI_SCK_SOURCE, SPI_SCK_AF);
243. 
244.  /* SPI MOSI pin configuration */
245.  GPIO_InitStructure.GPIO_Pin =  SPI_MOSI_PIN;
246.  GPIO_Init(SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);
247.  GPIO_PinAFConfig(SPI_MOSI_GPIO_PORT, SPI_MOSI_SOURCE, SPI_MOSI_AF);
248.}
249. 
250.void WaveRecorder_SPI_Init(uint32_t Freq)
251.{
252.  I2S_InitTypeDef I2S_InitStructure;
253. 
254.  /* Enable the SPI clock */
255.  RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
256. 
257.  /* SPI configuration */
258.  SPI_I2S_DeInit(SPI2);
259.  I2S_InitStructure.I2S_AudioFreq = Freq;
260.  I2S_InitStructure.I2S_Standard = I2S_Standard_LSB;
261.  I2S_InitStructure.I2S_DataFormat = I2S_DataFormat_16b;
262.  I2S_InitStructure.I2S_CPOL = I2S_CPOL_High;
263.  I2S_InitStructure.I2S_Mode = I2S_Mode_MasterRx;
264.  I2S_InitStructure.I2S_MCLKOutput = I2S_MCLKOutput_Disable;
265.  /* Initialize the I2S peripheral with the structure above */
266.  I2S_Init(SPI2, &I2S_InitStructure);
267. 
268.  /* Enable the Rx buffer not empty interrupt */
269.  SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
270.}
271. 
272.void WaveRecorder_NVIC_Init(void)
273.{
274.  NVIC_InitTypeDef NVIC_InitStructure;
275. 
276.  NVIC_PriorityGroupConfig(NVIC_PriorityGroup_3);
277.  /* Configure the SPI interrupt priority */
278.  NVIC_InitStructure.NVIC_IRQChannel = SPI2_IRQn;
279.  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
280.  NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
281.  NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
282.  NVIC_Init(&NVIC_InitStructure);
283.}
284. 
285.void Delay(__IO uint32_t nCount)
286.{
287.  while(nCount--)
288.  {
289.  }
290.}
291. 
292.void EVAL_AUDIO_TransferComplete_CallBack(uint32_t pBuffer, uint32_t Size)
293.{
294.    EVAL_AUDIO_Play((uint16_t*)pAudioRecBuf, SAMPLE_SIZE_IN_BYTES);
295.    //EVAL_AUDIO_Play((uint16_t*)sampleptr, 8000);
296.}
297. 
298.uint16_t EVAL_AUDIO_GetSampleCallBack(void)
299.{
300.    return 0;
301.}
302. 
303.uint32_t Codec_TIMEOUT_UserCallback(void)
304.{
305.    return 0;
306.}

  

Outcomes