Question
STM32F4-Discovery Real-time microphone
Posted on April 30, 2013 at 11:53
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.
/* Includes ------------------------------------------------------------------*/
#include ''stm32f4xx.h''
#include ''stm32f4_discovery.h''
#include ''stm32f4_discovery_audio_codec.h''
#include ''stm32f4xx_it.h''
#include ''pdm_filter.h''
/* Private define ------------------------------------------------------------*/
#define SPI_SCK_PIN GPIO_Pin_10
#define SPI_SCK_GPIO_PORT GPIOB
#define SPI_SCK_GPIO_CLK RCC_AHB1Periph_GPIOB
#define SPI_SCK_SOURCE GPIO_PinSource10
#define SPI_SCK_AF GPIO_AF_SPI2
#define SPI_MOSI_PIN GPIO_Pin_3
#define SPI_MOSI_GPIO_PORT GPIOC
#define SPI_MOSI_GPIO_CLK RCC_AHB1Periph_GPIOC
#define SPI_MOSI_SOURCE GPIO_PinSource3
#define SPI_MOSI_AF GPIO_AF_SPI2
#define AUDIO_REC_SPI_IRQHANDLER SPI2_IRQHandler
#define INTERNAL_BUFF_SIZE 64
#define OUTPUT_BUFF_SIZE 16
#define SAMPLE_SIZE_IN_BYTES 32
//64
/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
uint32_t AudioRecInited = 0;
PDMFilter_InitStruct Filter;
uint32_t AudioRecBitRes = 16;
uint32_t AudioRecChnlNbr = 1;
uint16_t* pAudioRecBuf;
uint16_t OutputBuffer[OUTPUT_BUFF_SIZE];
uint16_t InternalBuffer[INTERNAL_BUFF_SIZE];
uint32_t InternalBufferSize = 0;
__IO uint8_t vol = 70;
uint16_t sample[] = {
};
uint16_t* sampleptr = &sample[0];
/* Private function prototypes -----------------------------------------------*/
uint32_t WavePlaybackInit(uint32_t AudioFreq);
void WavePlay(void);
uint32_t WaveRecorderInit(uint32_t AudioFreq);
uint8_t WaveRecorderStart(uint16_t* pbuf, uint32_t size);
uint32_t WaveRecorderStop(void);
void AUDIO_REC_SPI_IRQHANDLER(void);
void WaveRecorder_GPIO_Init(void);
void WaveRecorder_SPI_Init(uint32_t Freq);
void WaveRecorder_NVIC_Init(void);
void Delay(__IO uint32_t nCount);
/* Main ----------------------------------------------------------------------*/
int main(void)
{
//GPIO_InitTypeDef GPIO_InitStructure;
/* GPIOD Periph clock enable */
//RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD, ENABLE);
/* Configure PD12, PD13, PD14 and PD15 in output pushpull mode */
//GPIO_InitStructure.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13| GPIO_Pin_14| GPIO_Pin_15;
//GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
//GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
//GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
//GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
//GPIO_Init(GPIOD, &GPIO_InitStructure);
//STM_EVAL_PBInit(BUTTON_USER, BUTTON_MODE_EXTI);
WavePlaybackInit(I2S_AudioFreq_16k); //is it ok?
WaveRecorderInit(I2S_AudioFreq_16k); //why nonsense
WaveRecorderStart(OutputBuffer,OUTPUT_BUFF_SIZE);
WavePlay();
while (1)
{
//WavePlay();
/*
GPIO_SetBits(GPIOD, GPIO_Pin_12);
Delay(0x3FFFFF);
GPIO_SetBits(GPIOD, GPIO_Pin_13);
Delay(0x3FFFFF);
GPIO_SetBits(GPIOD, GPIO_Pin_14);
Delay(0x3FFFFF);
GPIO_SetBits(GPIOD, GPIO_Pin_15);
Delay(0x7FFFFF);
GPIO_ResetBits(GPIOD, GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15);
Delay(0xFFFFFF);
*/
}
}
uint32_t WavePlaybackInit(uint32_t AudioFreq)
{
EVAL_AUDIO_SetAudioInterface(AUDIO_INTERFACE_I2S);
if(EVAL_AUDIO_Init(OUTPUT_DEVICE_HEADPHONE, vol, AudioFreq)!=0)
{
return 1;
}
else
{
return 0;
}
}
void WavePlay(void)
{
EVAL_AUDIO_Play((uint16_t*)pAudioRecBuf, SAMPLE_SIZE_IN_BYTES);
//EVAL_AUDIO_Play((uint16_t*)sampleptr, 8000);
}
uint32_t WaveRecorderInit(uint32_t AudioFreq)
{
/* Check if the interface is already initialized */
if (AudioRecInited)
{
/* No need for initialization */
return 0;
}
else
{
/* Enable CRC module */
RCC->AHB1ENR |= RCC_AHB1ENR_CRCEN;
/* Filter LP & HP Init */
Filter.LP_HZ = 8000;
Filter.HP_HZ = 10;
Filter.Fs = 16000;
Filter.Out_MicChannels = 1;
Filter.In_MicChannels = 1;
PDM_Filter_Init((PDMFilter_InitStruct *)&Filter);
/* Configure the GPIOs */
WaveRecorder_GPIO_Init();
/* Configure the interrupts (for timer) */
WaveRecorder_NVIC_Init();
/* Configure the SPI */
WaveRecorder_SPI_Init(AudioFreq);
/* Set state of the audio recorder to initialized */
AudioRecInited = 1;
/* Return 0 if all operations are OK */
return 0;
}
}
uint8_t WaveRecorderStart(uint16_t* pbuf, uint32_t size)
{
/* Check if the interface has already been initialized */
if (AudioRecInited)
{
/* Store the location and size of the audio buffer */
pAudioRecBuf = pbuf;
/* Enable the Rx buffer not empty interrupt */
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
/* The Data transfer is performed in the SPI interrupt routine */
/* Enable the SPI peripheral */
I2S_Cmd(SPI2, ENABLE);
/* Return 0 if all operations are OK */
return 0;
}
else
{
/* Cannot perform operation */
return 1;
}
}
uint32_t WaveRecorderStop(void)
{
/* Check if the interface has already been initialized */
if (AudioRecInited)
{
/* Stop conversion */
I2S_Cmd(SPI2, DISABLE);
/* Return 0 if all operations are OK */
return 0;
}
else
{
/* Cannot perform operation */
return 1;
}
}
void AUDIO_REC_SPI_IRQHANDLER(void)
{
u16 volume;
u16 app;
/* 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);
/* Check to prevent overflow condition */
if (InternalBufferSize >= INTERNAL_BUFF_SIZE)
{
InternalBufferSize = 0;
volume = 50;
PDM_Filter_64_LSB((uint8_t *)InternalBuffer, (uint16_t *)pAudioRecBuf, volume , (PDMFilter_InitStruct *)&Filter);
}
}
}
void WaveRecorder_GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* Enable GPIO clocks */
RCC_AHB1PeriphClockCmd(SPI_SCK_GPIO_CLK | SPI_MOSI_GPIO_CLK, ENABLE);
/* Enable GPIO clocks */
RCC_AHB1PeriphClockCmd(SPI_SCK_GPIO_CLK | SPI_MOSI_GPIO_CLK, ENABLE);
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
/* SPI SCK pin configuration */
GPIO_InitStructure.GPIO_Pin = SPI_SCK_PIN;
GPIO_Init(SPI_SCK_GPIO_PORT, &GPIO_InitStructure);
/* Connect SPI pins to AF5 */
GPIO_PinAFConfig(SPI_SCK_GPIO_PORT, SPI_SCK_SOURCE, SPI_SCK_AF);
/* SPI MOSI pin configuration */
GPIO_InitStructure.GPIO_Pin = SPI_MOSI_PIN;
GPIO_Init(SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);
GPIO_PinAFConfig(SPI_MOSI_GPIO_PORT, SPI_MOSI_SOURCE, SPI_MOSI_AF);
}
void WaveRecorder_SPI_Init(uint32_t Freq)
{
I2S_InitTypeDef I2S_InitStructure;
/* Enable the SPI clock */
RCC_APB1PeriphClockCmd(RCC_APB1Periph_SPI2,ENABLE);
/* SPI configuration */
SPI_I2S_DeInit(SPI2);
I2S_InitStructure.I2S_AudioFreq = Freq;
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;
/* Initialize the I2S peripheral with the structure above */
I2S_Init(SPI2, &I2S_InitStructure);
/* Enable the Rx buffer not empty interrupt */
SPI_I2S_ITConfig(SPI2, SPI_I2S_IT_RXNE, ENABLE);
}
void WaveRecorder_NVIC_Init(void)
{
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);
}
void Delay(__IO uint32_t nCount)
{
while(nCount--)
{
}
}
void EVAL_AUDIO_TransferComplete_CallBack(uint32_t pBuffer, uint32_t Size)
{
EVAL_AUDIO_Play((uint16_t*)pAudioRecBuf, SAMPLE_SIZE_IN_BYTES);
//EVAL_AUDIO_Play((uint16_t*)sampleptr, 8000);
}
uint16_t EVAL_AUDIO_GetSampleCallBack(void)
{
return 0;
}
uint32_t Codec_TIMEOUT_UserCallback(void)
{
return 0;
}
#stm32f4-discovery-microphone #hll-delay-loop #audio