cancel
Showing results for 
Search instead for 
Did you mean: 

Unable to convert PDM data to PCM data using pdm2pcm

EEnco.1
Associate III

I'm using a stm32wb55RG. I'm trying to get data from a MEMS PDM microphone and convert it into PCM data. I'm using SAI PDM interface and DMA. So far, I think I manage to receive the PDM data (I get some values from the SAI interface) :

0693W00000KbvY4QAJ.pngI don't know if these values make a sense or not. But when I try to convert these data into PCM using PDM_Filter, I can't get any value in the output buffer.

I provide the code :

#include "main.h"
#include "pdm2pcm_glo.h"
#include "stdio.h"
 
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
 
/* USER CODE END Includes */
 
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */
 
/* USER CODE END PTD */
 
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
 
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
 
/* USER CODE END PM */
 
/* Private variables ---------------------------------------------------------*/
 SAI_HandleTypeDef hsai_BlockA1;
DMA_HandleTypeDef hdma_sai1_a;
 
UART_HandleTypeDef huart1;
 
PCD_HandleTypeDef hpcd_USB_FS;
 
/* USER CODE BEGIN PV */
 
/* USER CODE END PV */
 
/* 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);
/* USER CODE BEGIN PFP */
 
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
uint8_t rxstate = 0;
uint8_t PDM_Buffer[1024];
 
 
 
 
/* PDM-PCM conversion configuration */
PDM_Filter_Handler_t PDM_FilterHandler;
PDM_Filter_Config_t  PDM_FilterConfig;
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
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_MSB;
  PDM_FilterHandler.endianness = PDM_FILTER_ENDIANNESS_BE;
  PDM_FilterHandler.high_pass_tap = 2104533974;
  PDM_FilterHandler.out_ptr_channels = 1;
  PDM_FilterHandler.in_ptr_channels  = 1;
 
  PDM_FilterConfig.output_samples_number = 16;
  PDM_FilterConfig.mic_gain = 24;
 
  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 pcm_data[4096];
  uint16_t mid_Buffer[16];
 
  uint16_t pcm_index = 0;
 
  HAL_SAI_Receive_DMA(&hsai_BlockA1, &PDM_Buffer[0], 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;
}
 
void SystemClock_Config(void)
{
  ...
}
 
void PeriphCommonClock_Config(void)
{
  RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
 
  /** Initializes the peripherals clock
  */
  PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SMPS;
  PeriphClkInitStruct.SmpsClockSelection = RCC_SMPSCLKSOURCE_HSI;
  PeriphClkInitStruct.SmpsDivSelection = RCC_SMPSCLKDIV_RANGE0;
 
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN Smps */
 
  /* USER CODE END Smps */
}
 
/**
  * @brief SAI1 Initialization Function
  * @param None
  * @retval None
  */
static void MX_SAI1_Init(void)
{
 
  /* USER CODE BEGIN SAI1_Init 0 */
 
  /* USER CODE END SAI1_Init 0 */
 
  /* USER CODE BEGIN SAI1_Init 1 */
 
  /* USER CODE END SAI1_Init 1 */
  hsai_BlockA1.Instance = SAI1_Block_A;
  hsai_BlockA1.Init.Protocol = SAI_FREE_PROTOCOL;
  hsai_BlockA1.Init.AudioMode = SAI_MODEMASTER_RX;
  hsai_BlockA1.Init.DataSize = SAI_DATASIZE_16;
  hsai_BlockA1.Init.FirstBit = SAI_FIRSTBIT_LSB;
  hsai_BlockA1.Init.ClockStrobing = SAI_CLOCKSTROBING_FALLINGEDGE;
  hsai_BlockA1.Init.Synchro = SAI_ASYNCHRONOUS;
  hsai_BlockA1.Init.OutputDrive = SAI_OUTPUTDRIVE_DISABLE;
  hsai_BlockA1.Init.NoDivider = SAI_MASTERDIVIDER_DISABLE;
  hsai_BlockA1.Init.MckOverSampling = SAI_MCK_OVERSAMPLING_DISABLE;
  hsai_BlockA1.Init.FIFOThreshold = SAI_FIFOTHRESHOLD_EMPTY;
  hsai_BlockA1.Init.AudioFrequency = SAI_AUDIO_FREQUENCY_48K;
  hsai_BlockA1.Init.MonoStereoMode = SAI_STEREOMODE;
  hsai_BlockA1.Init.CompandingMode = SAI_NOCOMPANDING;
  hsai_BlockA1.Init.PdmInit.Activation = ENABLE;
  hsai_BlockA1.Init.PdmInit.MicPairsNbr = 1;
  hsai_BlockA1.Init.PdmInit.ClockEnable = SAI_PDM_CLOCK1_ENABLE;
  hsai_BlockA1.FrameInit.FrameLength = 16;
  hsai_BlockA1.FrameInit.ActiveFrameLength = 1;
  hsai_BlockA1.FrameInit.FSDefinition = SAI_FS_STARTFRAME;
  hsai_BlockA1.FrameInit.FSPolarity = SAI_FS_ACTIVE_HIGH;
  hsai_BlockA1.FrameInit.FSOffset = SAI_FS_FIRSTBIT;
  hsai_BlockA1.SlotInit.FirstBitOffset = 0;
  hsai_BlockA1.SlotInit.SlotSize = SAI_SLOTSIZE_DATASIZE;
  hsai_BlockA1.SlotInit.SlotNumber = 1;
  hsai_BlockA1.SlotInit.SlotActive = 0x0000FFFF;
  if (HAL_SAI_Init(&hsai_BlockA1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN SAI1_Init 2 */
 
  /* USER CODE END SAI1_Init 2 */
 
}

TL DR : Using this : PDM_Filter(&PDM_Buffer[0], &mid_Buffer[0], &PDM_FilterHandler); mid_buffer is stuck to 0 and I don't understand where the problem comes from

1 ACCEPTED SOLUTION

Accepted Solutions

Yes, you can remove all the posts in this page as I managed to fix the issue

View solution in original post

3 REPLIES 3
EEnco.1
Associate III

To be removed

Eleon BORLINI
ST Employee

Hi @EEnco.1​ ,

should I remove this post?

-Eleon

Yes, you can remove all the posts in this page as I managed to fix the issue