Skip to main content
Visitor II
March 7, 2022
Solved

How do you install PDM library ?

  • March 7, 2022
  • 7 replies
  • 5288 views

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

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

    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 !

    7 replies

    Technical Moderator
    March 7, 2022

    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

    EEnco.1Author
    Visitor II
    March 7, 2022

    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.1Author
    Visitor II
    March 8, 2022

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

    ST Employee
    March 8, 2022

    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.

    EEnco.1AuthorAnswer
    Visitor II
    March 8, 2022

    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 !

    Visitor II
    April 17, 2024

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

     

    ST Employee
    May 2, 2024

    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,

    Explorer II
    May 15, 2024

    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

     

     

    ST Employee
    May 16, 2024

    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

     

    Explorer II
    May 16, 2024

    Thanks @ghrairim the problem has solved.