Skip to main content
Visitor II
March 8, 2022
Solved

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

  • March 8, 2022
  • 2 replies
  • 1719 views

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.

    This topic has been closed for replies.
    Best answer by EEnco.1

    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.

    2 replies

    EEnco.1Author
    Visitor II
    March 8, 2022

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

    ST Employee
    March 10, 2022

    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

    EEnco.1AuthorAnswer
    Visitor II
    March 10, 2022

    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.