digital MEMS MIC (MP34DT05) issue on STMH747I-DISCO
- April 22, 2026
- 1 reply
- 89 views
Hi Community,
I am working on STM32H747I-DISCO Board and trying to bringup digital MEMS Mic (MP34DT05) which is integrated on STM32H7-DISCO Board.
I am trying to record random voice for 5 seconds and need to play back via audio jack out which is connected to codec also it is integrated on the board. I am sharing you schematic of the board as below:

MP34DT05 is connected to MCU directly with SAI4 Interface and Solder Brifdges are provided to connect via codec
Here I developed the application code to interface and record via MIC and playback via Audio Jack out.
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stm32h747i_discovery_audio.h"
#include <math.h>
#include"log.h"
#include<string.h>
#include "pdm_config.h"
#include "pdm2pcm_glo.h"
#include <stdio.h>
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
/* USER CODE END PTD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define AUDIO_MIC_INIT
//#define AUDIO_JACK_INIT
//#define AUDIO_BUFFER_SIZE 2048
/************** AUDIO CONFIG *************************/
#define SAMPLE_RATE 16000
#define RECORD_TIME_SEC 4
#define PCM_CHUNK (SAMPLE_RATE / 1000) // 16
#define PDM_CHUNK (PCM_CHUNK * 64) // 1024
#define PCM_TOTAL_SAMPLES (SAMPLE_RATE * RECORD_TIME_SEC) //16000*4
#define PCM_BUFFER_SIZE (PCM_TOTAL_SAMPLES)
#define PDM_BUFFER_SIZE 1024
#define AUDIO_OUT_SAMPLES (PCM_TOTAL_SAMPLES * 2)
#define AUDIO_INSTANCE 0
/* DUAL_CORE_BOOT_SYNC_SEQUENCE: Define for dual core boot synchronization */
/* demonstration code based on hardware semaphore */
/* This define is present in both CM7/CM4 projects */
/* To comment when developping/debugging on a single core */
//#define DUAL_CORE_BOOT_SYNC_SEQUENCE
#if defined(DUAL_CORE_BOOT_SYNC_SEQUENCE)
#ifndef HSEM_ID_0
#define HSEM_ID_0 (0U) /* HW semaphore 0*/
#endif
#endif /* DUAL_CORE_BOOT_SYNC_SEQUENCE */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
I2C_HandleTypeDef hi2c4;
SAI_HandleTypeDef hsai_BlockA1;
SAI_HandleTypeDef hsai_BlockB1;
SAI_HandleTypeDef hsai_BlockA4;
UART_HandleTypeDef huart1;
SDRAM_HandleTypeDef hsdram1;
/* USER CODE BEGIN PV */
/* ================= SDRAM BUFFER ================= */
__attribute__((section(".sdram")))
uint16_t pcm_sdram_buffer[PCM_TOTAL_SAMPLES];
uint16_t audio_out_buffer[AUDIO_OUT_SAMPLES];
/****************Buffers *******************/
uint16_t pdm_buffer[PDM_CHUNK];
uint16_t pcm_chunk[PCM_CHUNK];
int16_t stereo_buffer[PCM_BUFFER_SIZE * 2];
//int16_t audio_buffer[AUDIO_BUFFER_SIZE];
PDM_Filter_Handler_t PDM_FilterHandler; // Handler (internal memory)
PDM_Filter_Config_t PDM_FilterConfig; // Configuration
/* Global variables */
volatile uint32_t pcm_index = 0;
volatile uint8_t recording_done = 0;
BSP_AUDIO_Init_t MicInit;
BSP_AUDIO_Init_t AudioOutInit;
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
void PeriphCommonClock_Config(void);
static void MPU_Config(void);
static void MX_GPIO_Init(void);
static void MX_I2C4_Init(void);
static void MX_SAI1_Init(void);
static void MX_USART1_UART_Init(void);
static void MX_SAI4_Init(void);
static void MX_FMC_Init(void);
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
int32_t BSP_AUDIO_IN_PDMToPCM_Init(uint32_t Instance, uint32_t AudioFreq, uint32_t ChnlNbrIn, uint32_t ChnlNbrOut)
{
PDM_FilterHandler.bit_order = PDM_FILTER_BIT_ORDER_LSB;
PDM_FilterHandler.endianness = PDM_FILTER_ENDIANNESS_LE;
PDM_FilterHandler.high_pass_tap = 2104533974;
PDM_FilterHandler.out_ptr_channels = ChnlNbrOut;
PDM_FilterHandler.in_ptr_channels = ChnlNbrIn;
if(PDM_Filter_Init(&PDM_FilterHandler) != 0)
Error_Handler();
PDM_FilterConfig.decimation_factor = PDM_FILTER_DEC_FACTOR_64;
PDM_FilterConfig.output_samples_number = PCM_CHUNK; // 16
PDM_FilterConfig.mic_gain = 24;
if(PDM_Filter_setConfig(&PDM_FilterHandler, &PDM_FilterConfig) != 0)
Error_Handler();
return 0;
}
void PDM_To_PCM(uint16_t *pdm, uint16_t *pcm)
{
PDM_Filter((uint8_t*)pdm, pcm, &PDM_FilterHandler);
}
void Convert_Mono_To_Stereo(void)
{
for(uint32_t i = 0, j = 0; i < PCM_TOTAL_SAMPLES; i++, j += 2)
{
audio_out_buffer[j] = pcm_sdram_buffer[i]; // Left
audio_out_buffer[j + 1] = pcm_sdram_buffer[i]; // Right
}
}
//void GenerateSineWave(void)
//{
// for(int i = 0; i < AUDIO_BUFFER_SIZE; i++)
// {
// audio_buffer[i] = (uint16_t)(20000 * sin(2 * 3.14159 * i / 100));
// }
//}
#if defined(AUDIO_MIC_INIT)
void BSP_AUDIO_IN_HalfTransfer_CallBack(uint32_t Instance)
{
if(recording_done) return;
PDM_To_PCM(&pdm_buffer[0], pcm_chunk);
for(int i = 0; i < PCM_CHUNK/2; i++) // 8 samples
{
if(pcm_index < PCM_TOTAL_SAMPLES)
pcm_sdram_buffer[pcm_index++] = pcm_chunk[i];
else
{
recording_done = 1;
BSP_AUDIO_IN_Stop(1);
break;
}
}
}
void BSP_AUDIO_IN_TransferComplete_CallBack(uint32_t Instance)
{
if(recording_done) return;
PDM_To_PCM(&pdm_buffer[PDM_CHUNK/2], pcm_chunk);
for(int i = 0; i < PCM_CHUNK/2; i++) // 8 samples
{
if(pcm_index < PCM_TOTAL_SAMPLES)
pcm_sdram_buffer[pcm_index++] = pcm_chunk[i];
else
{
recording_done = 1;
BSP_AUDIO_IN_Stop(1);
break;
}
}
}
#endif
/* USER CODE END 0 */
/**
* @brief The application entry point.
* @retval int
*/
int main(void)
{
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/* USER CODE BEGIN Boot_Mode_Sequence_0 */
#if defined(DUAL_CORE_BOOT_SYNC_SEQUENCE)
int32_t timeout;
#endif /* DUAL_CORE_BOOT_SYNC_SEQUENCE */
/* USER CODE END Boot_Mode_Sequence_0 */
/* MPU Configuration--------------------------------------------------------*/
MPU_Config();
/* USER CODE BEGIN Boot_Mode_Sequence_1 */
#if defined(DUAL_CORE_BOOT_SYNC_SEQUENCE)
/* Wait until CPU2 boots and enters in stop mode or timeout*/
timeout = 0xFFFF;
while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) != RESET) && (timeout-- > 0));
if ( timeout < 0 )
{
Error_Handler();
}
#endif /* DUAL_CORE_BOOT_SYNC_SEQUENCE */
/* USER CODE END Boot_Mode_Sequence_1 */
/* MCU Configuration--------------------------------------------------------*/
/* Reset of all peripherals, Initializes the Flash interface and the Systick. */
HAL_Init();
/* USER CODE BEGIN Init */
/* USER CODE END Init */
/* Configure the system clock */
SystemClock_Config();
/* Configure the peripherals common clocks */
PeriphCommonClock_Config();
/* USER CODE BEGIN Boot_Mode_Sequence_2 */
#if defined(DUAL_CORE_BOOT_SYNC_SEQUENCE)
/* When system initialization is finished, Cortex-M7 will release Cortex-M4 by means of
HSEM notification */
/*HW semaphore Clock enable*/
__HAL_RCC_HSEM_CLK_ENABLE();
/*Take HSEM */
HAL_HSEM_FastTake(HSEM_ID_0);
/*Release HSEM in order to notify the CPU2(CM4)*/
HAL_HSEM_Release(HSEM_ID_0,0);
/* wait until CPU2 wakes up from stop mode */
timeout = 0xFFFF;
while((__HAL_RCC_GET_FLAG(RCC_FLAG_D2CKRDY) == RESET) && (timeout-- > 0));
if ( timeout < 0 )
{
Error_Handler();
}
#endif /* DUAL_CORE_BOOT_SYNC_SEQUENCE */
/* USER CODE END Boot_Mode_Sequence_2 */
/* USER CODE BEGIN SysInit */
/* USER CODE END SysInit */
/* Initialize all configured peripherals */
MX_GPIO_Init();
MX_I2C4_Init();
MX_SAI1_Init();
MX_USART1_UART_Init();
MX_SAI4_Init();
MX_FMC_Init();
/* USER CODE BEGIN 2 */
#if defined(AUDIO_MIC_INIT)
/* === AUDIO IN (digital mic - Instance 1) === */
MicInit.Device = AUDIO_IN_DEVICE_DIGITAL_MIC;
MicInit.SampleRate = AUDIO_FREQUENCY_16K;
MicInit.BitsPerSample = AUDIO_RESOLUTION_16B;
MicInit.ChannelsNbr = 1;
MicInit.Volume = 100;
if (BSP_AUDIO_IN_Init(0, &MicInit) != BSP_ERROR_NONE) {
Error_Handler();
}else{
LOG("Audio In Successfully Configured....\r\n");
}
/* PDM → PCM conversion setup (1 mic in → stereo PCM out for easy playback) */
BSP_AUDIO_IN_PDMToPCM_Init(AUDIO_INSTANCE, AUDIO_FREQUENCY_16K, 1, 1);
/* -------- START RECORDING -------- */
BSP_AUDIO_IN_RecordPDM(0, (uint8_t*)pdm_buffer, PDM_BUFFER_SIZE);
printf("Recording started...\r\n");
while(!recording_done);
/* -------- MONO → STEREO -------- */
Convert_Mono_To_Stereo();
printf("Recording DONE: %lu samples\r\n", pcm_index);
#endif
#if defined(AUDIO_JACK_INIT)
AudioOutInit.Device=AUDIO_OUT_DEVICE_HEADPHONE;//Output device Headphone
AudioOutInit.SampleRate=AUDIO_FREQUENCY_48K;//48Khz
AudioOutInit.BitsPerSample=AUDIO_RESOLUTION_16B;//16bit resolution
AudioOutInit.ChannelsNbr=2;//1 for MONO and 2 for Stereo
AudioOutInit.Volume=50;
if(BSP_AUDIO_OUT_Init(AUDIO_INSTANCE, &AudioOutInit)!= BSP_ERROR_NONE){
LOG("BSP_AUDIO_OUT is fail to initialize");
}else{
LOG("BSP_AUDIO_OUT is initialize...\r\n");
}
LOG("Playing Audio...\r\n");
BSP_AUDIO_OUT_Play(0,(uint8_t*)audio_out_buffer,AUDIO_OUT_SAMPLES * 2);
// GenerateSineWave();
#endif
/* USER CODE END 2 */
/* Infinite loop */
/* USER CODE BEGIN WHILE */
while (1)
{
/* USER CODE END WHILE */
/* USER CODE BEGIN 3 */
}
/* USER CODE END 3 */
}
When I run this code i am facing issue at BSP_AUDIO_IN_PDMToPCM_Init();
Code is stuck at that function and not moving forward.
I need your suggestion/modifications of the code to work properly and what changes i need to do for BSP_AUDIO_IN_PDMToPCM_Init() function to work correctly
Note : I added required driver files(discovery files) for codec config and mic config.
Added : pdm2pcm_glo.h file ,
lib: libPDMFilter_CM7_GCC_wc32.a
I am sharing you reference project. for better understanding
Working On:
CubeIDE: Version 1.19.0
FW Package: STM32H7 1.12.1
If issue is solved, share the updated file.
Clear me below questions:
1.MIC is shared by SAI4(MCU) and SAI1(codec). So to get PDM data which Interface I need to prefer?
2.How to do this PDM to PCM convertion?
Edited to apply source code formatting - please see How to insert source code for future reference.
