cancel
Showing results for 
Search instead for 
Did you mean: 

Question about my code to get data from PDM microphone and convert it to PCM

EEnco.1
Associate III

I'm trying to get data from PDM microphone and convert it to PCM data. This is my first project on stm32 and I'm starting to debug the project. Could you take a quick look at my code and say if you notice something wrong ? Some part of the code come from other project that have been shared here.

#include "main.h"
 
#include "pdm2pcm_glo.h"
 
#include "stdio.h"
 
 
 
/* Private variables ---------------------------------------------------------*/
 
 SAI_HandleTypeDef hsai_BlockA1;
 
DMA_HandleTypeDef hdma_sai1_a;
 
 
 
UART_HandleTypeDef huart1;
 
 
 
PCD_HandleTypeDef hpcd_USB_FS;
 
 
 
/* Private function prototypes -----------------------------------------------*/
 
void SystemClock_Config(void);
 
void PeriphCommonClock_Config(void);
 
static void MX_GPIO_Init(void);
 
static void MX_USART1_UART_Init(void);
 
static void MX_DMA_Init(void);
 
static void MX_USB_PCD_Init(void);
 
static void MX_SAI1_Init(void);
 
 
 
/* Private user code ---------------------------------------------------------*/
 
/* USER CODE BEGIN 0 */
 
uint8_t rxstate = 0;
 
 
 
/* PDM-PCM conversion configuration */
 
PDM_Filter_Handler_t PDM_FilterHandler;
 
PDM_Filter_Config_t  PDM_FilterConfig;
 
 
 
int main(void)
 
{
 
 /* MCU Configuration--------------------------------------------------------*/
 
 
 
 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 
 HAL_Init();
 
 
 
 /* Configure the system clock */
 
 SystemClock_Config();
 
 
 
/* Configure the peripherals common clocks */
 
 PeriphCommonClock_Config();
 
 
 
 /* Initialize all configured peripherals */
 
 MX_GPIO_Init();
 
 MX_USART1_UART_Init();
 
 MX_USB_PCD_Init();
 
 MX_DMA_Init();
 
 MX_SAI1_Init();
 
 
 
 PDM_FilterHandler.bit_order = PDM_FILTER_BIT_ORDER_LSB;
 
 PDM_FilterHandler.endianness = PDM_FILTER_ENDIANNESS_BE;
 
 PDM_FilterHandler.high_pass_tap = 2122358088;
 
 PDM_FilterHandler.out_ptr_channels = 1;
 
 PDM_FilterHandler.in_ptr_channels = 1;
 
 
 
 PDM_FilterConfig.output_samples_number = 64;
 
 PDM_FilterConfig.mic_gain = 1;
 
 
 
 PDM_FilterConfig.decimation_factor = PDM_FILTER_DEC_FACTOR_64;
 
 
 
 PDM_Filter_Init((PDM_Filter_Handler_t *)(&PDM_FilterHandler));
 
 PDM_Filter_setConfig((PDM_Filter_Handler_t *)&PDM_FilterHandler, &PDM_FilterConfig);
 
 
 
 uint16_t PDM_Buffer[128];
 
 uint16_t pcm_data[4096];
 
 uint16_t mid_Buffer[64];
 
 //pcm_index = 0;
 
 uint8_t pcm_index = 0;
 
 
 
 HAL_SAI_DMAResume(&hsai_BlockA1);
 
 HAL_SAI_Receive_DMA(&hsai_BlockA1, PDM_Buffer, 64);
 
 
 
 while (1)
 
 {
 
         if (rxstate==1){
 
                        PDM_Filter(&PDM_Buffer[0], &mid_Buffer[0], &PDM_FilterHandler);
 
                        for(uint8_t i = 0; i < 64 ; i++){
 
                                        pcm_data[pcm_index] = mid_Buffer[i];
 
                                        pcm_index++;
 
                                }
 
                        rxstate=0;
 
                }
 
 
 
                if (rxstate==2){
 
                                PDM_Filter(&PDM_Buffer[64], &mid_Buffer[0], &PDM_FilterHandler);
 
                                for(uint8_t i = 0; i < 64 ; i++){
 
                                                pcm_data[pcm_index] = mid_Buffer[i];
 
                                                pcm_index++;
 
                                        }
 
                                rxstate=0;
 
                        }
 
 
 
                if(pcm_index==4096){
 
                        HAL_SAI_DMAPause(&hsai_BlockA1);
 
                        pcm_index = 0;
 
                }
 
 }
 
 
 
}
 
 
 
void HAL_SAI_RxHalfCpltCallback(SAI_HandleTypeDef *hsai_BlockA1){
 
        rxstate = 1;
 
}
 
 
 
void HAL_SAI_RxCpltCallback(SAI_HandleTypeDef *hsai_BlockA1){
 
        rxstate = 2;
 
}

Update : Some parts of the code work not like I was expecting. About PDM_Buffer, only PDM_Buffer[0] gets a moving value : most of the time 0, sometime 7, sometime 64. All the other cases are stuck to 0. I don't know why this is happening.

1 ACCEPTED SOLUTION

Accepted Solutions

Yes you can close the current topic as well. For the code, I took one from this link https://github.com/YetAnotherElectronicsChannel/STM32_PDM_Microphone/blob/master/code/Src/main.c#L200 and modified so it works as I intended.

View solution in original post

3 REPLIES 3
EEnco.1
Associate III

I'm testing this code and so far, I can't get the PDM data into PDM_Buffer.

Eleon BORLINI
ST Employee

Hi @EEnco.1​ ,

Can we close also the current topic, referring to this other thread?

Could you share here on the Community the solution you found to this issue?

-Eleon

Yes you can close the current topic as well. For the code, I took one from this link https://github.com/YetAnotherElectronicsChannel/STM32_PDM_Microphone/blob/master/code/Src/main.c#L200 and modified so it works as I intended.