cancel
Showing results for 
Search instead for 
Did you mean: 

How do you install PDM library ?

EEnco.1
Associate III

I struggle to use PDM Filter library.

This is the message error I get :

0693W00000KbhBQQAZ.pngWhat I have done so far are : - in project properties, C/C++ general, Paths and syombols, in "Includes" I added the path to pdm2pcm_glo.h ; in "Library Paths" I added the path to a folder with all the libPDM_FIlter_CM3_GCC_wc16.A ... files.- Wrote #include "pdm2pcm_glo.h" in the main.

It's still not working :\

In "Paths and Symbols", in libraries, I think I can add a library but I don't know which one to use (all the files were included in mems1 folder). I tried randomly picking but I had another error message;

0693W00000KbhEyQAJ.pngI am new to cubeIDE so it's very possible Im doing a beginner mistake here

1 ACCEPTED SOLUTION

Accepted Solutions

Thanks for you answer. I managed to fix the issue, it was a mistake with how I confugired the C/C++ Build settings. Thanks for taking your time to help me !

View solution in original post

10 REPLIES 10
Imen.D
ST Employee

Hello @EEnco.1​ ,

Could you please confirm which library and IDE tool versions are used?

Please make sure to use the latest release of CubeMX/CubeIDE and keep me informed if you have the same issue.

Imen

When your question is answered, please close this topic by clicking "Accept as Solution".
Thanks
Imen
EEnco.1
Associate III

I'm using STM32CubeIde 1.8.0 and for the library I took one from memsmic1_v5.6.0.

Maybe I'm doing something wrong with the library because when I do this :

0693W00000KbjlQQAR.png 

I get this message error :

c:\st\stm32cubeide_1.8.0\stm32cubeide\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.9-2020-q2-update.win32_2.0.0.202105311346\tools\arm-none-eabi\bin\ld.exe: cannot find -lC:/Users/username/STM32CubeIDE/workspace_1.8.0/MEMS/PDM/Lib/libPDMFilter_CM4_Keil_wc16.lib

EEnco.1
Associate III

Update : I have managed to solve the issue, It was a problem with how I configured C/C++ Build settings

mattias norlander
ST Employee

The error message suggests that there is no problem with include of header files. Pre-processing seem to work. The error is finding the PDM_Filter_Init function in the linked arhive file.

Did you have a look at the CubeIDE User Guide and specifically the chapter 2.5.8 Include libraries?

It shows quite hands-on how to add a library. I think you could validate this first.

Which library is the right one? Not sure... There seem to be dedicated archives for GCC, choose the one matching your fpu setting.

Thanks for you answer. I managed to fix the issue, it was a mistake with how I confugired the C/C++ Build settings. Thanks for taking your time to help me !

khashayar
Associate

Hi
where can i download "pdm2pcm_glo.h" library?

 

Hello @khashayar

The "pdm2pcm_glo.h" file is part of PDM2PCM library. You have to download the full zipped STM32CubeWB package from ST.com and then extract the content of the library Middlewares/ST/STM32_Audio.

With regards,

FShah.1
Associate III

Hi, I am trying to use the pdm2pcm code to get the audio from MEMS I2S interface mics SPH0645LM4H.

I am getting this error during build. 

Description Resource Path Location Type
C:/Users/mylaptop/STM32CubeIDE/workspace_1.14.0/audio_mic_I2S/Debug/../Middlewares/ST/STM32_Audio/Addons/PDM/Inc/pdm2pcm_glo.c:31: undefined reference to `PDM_Filter_setConfig' audio_mic_I2S C/C++ Problem

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * @file           : main.c
  * @brief          : Main program body
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024 STMicroelectronics.
  * All rights reserved.
  *
  * This software is licensed under terms that can be found in the LICENSE file
  * in the root directory of this software component.
  * If no LICENSE file comes with this software, it is provided AS-IS.
  *
  ******************************************************************************
  */
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
 
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include "stdio.h"
#include "pdm2pcm_glo.h"
 
/* 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 ---------------------------------------------------------*/
I2S_HandleTypeDef hi2s1;
DMA_HandleTypeDef hdma_spi1_rx;
 
/* USER CODE BEGIN PV */
int16_t data_i2s[100];
volatile int16_t sample_i2s;
/* USER CODE END PV */
 
/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_DMA_Init(void);
static void MX_I2S1_Init(void);
/* USER CODE BEGIN PFP */
static void MX_PDM2PCM_Init(void);
/* USER CODE END PFP */
 
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
 
/* USER CODE END 0 */
 
/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */
 
  /* USER CODE END 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();
 
  /* USER CODE BEGIN SysInit */
 
  /* USER CODE END SysInit */
 
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_DMA_Init();
  MX_I2S1_Init();
  MX_PDM2PCM_Init();
  /* USER CODE BEGIN 2 */
HAL_I2S_Receive_DMA(&hi2s1, (uint16_t *)data_i2s , sizeof(data_i2s)/2);
  /* USER CODE END 2 */
 
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
 
    /* USER CODE BEGIN 3 */
//   printf("Hello World!\r\n");
  HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_3);
  HAL_Delay(1000);
  }
  /* USER CODE END 3 */
}
 
/**
  * @brief System Clock Configuration
  * @retval None
  */
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
 
  /** Configure the main internal regulator output voltage
  */
  __HAL_RCC_PWR_CLK_ENABLE();
  __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);
 
  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  RCC_OscInitStruct.PLL.PLLM = 8;
  RCC_OscInitStruct.PLL.PLLN = 100;
  RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;
  RCC_OscInitStruct.PLL.PLLQ = 2;
  RCC_OscInitStruct.PLL.PLLR = 2;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
 
  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
  {
    Error_Handler();
  }
}
 
/**
  * @brief I2S1 Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_I2S1_Init(void)
{
 
  /* USER CODE BEGIN I2S1_Init 0 */
 
  /* USER CODE END I2S1_Init 0 */
 
  /* USER CODE BEGIN I2S1_Init 1 */
 
  /* USER CODE END I2S1_Init 1 */
  hi2s1.Instance = SPI1;
  hi2s1.Init.Mode = I2S_MODE_MASTER_RX;
  hi2s1.Init.Standard = I2S_STANDARD_PHILIPS;
  hi2s1.Init.DataFormat = I2S_DATAFORMAT_16B_EXTENDED;
  hi2s1.Init.MCLKOutput = I2S_MCLKOUTPUT_DISABLE;
  hi2s1.Init.AudioFreq = I2S_AUDIOFREQ_32K;
  hi2s1.Init.CPOL = I2S_CPOL_LOW;
  hi2s1.Init.ClockSource = I2S_CLOCK_PLL;
  hi2s1.Init.FullDuplexMode = I2S_FULLDUPLEXMODE_DISABLE;
  if (HAL_I2S_Init(&hi2s1) != HAL_OK)
  {
    Error_Handler();
  }
  /* USER CODE BEGIN I2S1_Init 2 */
 
  /* USER CODE END I2S1_Init 2 */
 
}
 
/**
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void)
{
 
  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();
 
  /* DMA interrupt init */
  /* DMA2_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
 
}
 
/**
  * @brief GPIO Initialization Function
  * @PAram None
  * @retval None
  */
static void MX_GPIO_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStruct = {0};
/* USER CODE BEGIN MX_GPIO_Init_1 */
/* USER CODE END MX_GPIO_Init_1 */
 
  /* GPIO Ports Clock Enable */
  __HAL_RCC_GPIOC_CLK_ENABLE();
  __HAL_RCC_GPIOA_CLK_ENABLE();
 
  /*Configure GPIO pin Output Level */
  HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
 
  /*Configure GPIO pin : PA3 */
  GPIO_InitStruct.Pin = GPIO_PIN_3;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Pull = GPIO_NOPULL;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
 
/* USER CODE BEGIN MX_GPIO_Init_2 */
/* USER CODE END MX_GPIO_Init_2 */
}
 
/* USER CODE BEGIN 4 */
PDM_Filter_Handler_t PDM_Filter_Handler[4];
PDM_Filter_Config_t PDM_Filter_Config[4];
 
static void MX_PDM2PCM_Init(void)
{
/*Enables and resets CRC-32 from STM32 HW */
__HAL_RCC_CRC_CLK_ENABLE();
CRC->CR = CRC_CR_RESET;
 
for (uint8_t index = 0; index < 4; index++)
{
PDM_Filter_Handler[index].bit_order = PDM_FILTER_BIT_ORDER_LSB;
PDM_Filter_Handler[index].endianness = PDM_FILTER_ENDIANNESS_BE;
PDM_Filter_Handler[index].high_pass_tap = 2122358088;
PDM_Filter_Handler[index].out_ptr_channels = 1;
PDM_Filter_Handler[index].in_ptr_channels = 1;
PDM_Filter_Init((PDM_Filter_Handler_t *)(&PDM_Filter_Handler[index]));
 
PDM_Filter_Config[index].output_samples_number = 16;
PDM_Filter_Config[index].mic_gain = 24;
PDM_Filter_Config[index].decimation_factor = PDM_FILTER_DEC_FACTOR_64;
PDM_Filter_setConfig((PDM_Filter_Handler_t *)&PDM_Filter_Handler[index], &PDM_Filter_Config[index]);
}
}
 
 
 
 
void HAL_I2S_RxCpltCallback(I2S_HandleTypeDef *hi2s)
{
sample_i2s = data_i2s[0];
}
 
/* USER CODE END 4 */
 
/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */
  __disable_irq();
  while (1)
  {
  }
  /* USER CODE END Error_Handler_Debug */
}
 
#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @PAram  file: pointer to the source file name
  * @PAram  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */

 

FShah1_0-1715809113045.png

FShah1_1-1715809160633.pngFShah1_2-1715809494565.png

 

 

Hello @FShah.1 

I suggest you in: C/C++ General/ Include paths and Symbols to Edit the format :  Middlewares/ST/STM32_Audio/Addons/PDM/Inc and Middlewares/ST/STM32_Audio/Addons/PDM 

And in C/C++ Build / Settings / MCU GCC Compiler / Include Paths :    ../Middlewares/ST/STM32_Audio/Addons/PDM/Inc  and  ../Middlewares/ST/STM32_Audio/Addons/PDM