Interfacing PDM Mic with NRF52832

I am trying to interface the PDM mic (Link : https://www.adafruit.com/product/3492) with NRF52832 Devkit. I am using PIN 27 and 26 for Clock and Data Respectively. 
I can see the PCM Data in the log. However, when I play the Audio, it generates only the chirping sound. Why so?

Code:-

#include "stdio.h"
#include <stdbool.h>
#include <stdint.h>
#include "nrf_drv_pdm.h"
#include "nrf_delay.h"
#include "app_error.h"
#include "boards.h"
#include "nrf_log.h"
#include "nrf_log_ctrl.h"
#include "nrf_log_default_backends.h"
#include "app_error.h"
#include <stdint.h>


#define PDM_CLK_PIN 27
#define PDM_DIN_PIN 26

#define BUFFER_SIZE 1024
static int16_t pdm_buffer[BUFFER_SIZE];

float calculate_volume_level(int16_t *buffer, size_t length) {
uint32_t sum = 0;
for (size_t i = 0; i < length; i++) {
sum += abs(buffer[i]);
}

float avg = (float)sum / length;
return avg;
}

void pdm_event_handler(nrfx_pdm_evt_t const *p_evt)
{
if (p_evt->buffer_requested)
{
APP_ERROR_CHECK(nrf_drv_pdm_buffer_set(pdm_buffer, BUFFER_SIZE));

}
if (p_evt->buffer_released != NULL)
{
for (int i = 0; i < BUFFER_SIZE; i++)
{
printf("%d\n", p_evt->buffer_released[i]);
}
}

}

void pdm_init(void)
{
nrf_drv_pdm_config_t pdm_cfg = NRF_DRV_PDM_DEFAULT_CONFIG(PDM_CLK_PIN, PDM_DIN_PIN);
pdm_cfg.mode = NRF_PDM_MODE_MONO;
pdm_cfg.edge = NRF_PDM_EDGE_LEFTFALLING;
pdm_cfg.clock_freq = NRF_PDM_FREQ_1032K;
pdm_cfg.gain_l = 10;
pdm_cfg.gain_r = 10;

APP_ERROR_CHECK(nrf_drv_pdm_init(&pdm_cfg, pdm_event_handler));
APP_ERROR_CHECK(nrf_drv_pdm_start());
}

int main(void)
{
bsp_board_init(BSP_INIT_LEDS);
APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
NRF_LOG_DEFAULT_BACKENDS_INIT();

NRF_LOG_INFO("PDM mic example started.");
pdm_init();

while (true)
{
NRF_LOG_FLUSH();
nrf_delay_ms(100);
}
}

Please help me out!!

Parents
  • Actually, I am receiving the data and I can see it over the Serial terminal. Today, I checked the clock frequency that my controller is generating. PDM Mic needs 1Mhz to 3Mhz of clock frequency. I am setting it by pdm_cfg.clock_freq = NRF_PDM_FREQ_1032K;

    However, the clock is not generating properly. I have observed that when I set the 
    pdm_cfg.clock_freq = NRF_PDM_FREQ_DEFAULT;   it is generating the 5Khz
    pdm_cfg.clock_freq = NRF_PDM_FREQ_1032K;   it is generating the 30Khz
    pdm_cfg.clock_freq = NRF_PDM_FREQ_1067K;   it is generating the 70Khz


    which is incorrect. 
    I would really appreciate the help to enable the High Frequency Clock to generate at least 1MHz of frequency. 

    My code to generate the clock:-

    #include "nrf.h"
    #include "nrf_delay.h"

    // PDM CLK and DIN pin selection
    #define PDM_CLK_PIN 23
    #define PDM_DIN_PIN 25

    // Dummy buffer for PDM DMA (required)
    static int16_t dummy_buf[64];

    // Start High Frequency Clock (16 MHz crystal)
    void hfclk_start(void) {
    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART = 1;
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
    }

    void pdm_init(void) {
    // Route CLK and DIN pins
    NRF_PDM->PSEL.CLK = PDM_CLK_PIN;
    NRF_PDM->PSEL.DIN = PDM_DIN_PIN;

    // Use 16x PDM clock ratio → ~1.067 MHz
    NRF_PDM->PDMCLKCTRL = PDM_PDMCLKCTRL_FREQ_1067K; // 16 MHz / 15 = 1.067 MHz

    // Configure for Mono input, Left channel, falling edge
    NRF_PDM->MODE = (PDM_MODE_OPERATION_Mono << PDM_MODE_OPERATION_Pos) |
    (PDM_MODE_EDGE_LeftFalling << PDM_MODE_EDGE_Pos);

    // Dummy buffer for DMA, 64 samples
    NRF_PDM->SAMPLE.PTR = (uint32_t)dummy_buf;
    NRF_PDM->SAMPLE.MAXCNT = 64;

    // Enable the PDM peripheral
    NRF_PDM->ENABLE = PDM_ENABLE_ENABLE_Enabled << PDM_ENABLE_ENABLE_Pos;

    // Start the PDM clock and sampling
    NRF_PDM->TASKS_START = 1;
    }

    int main(void) {
    hfclk_start(); // Ensure the external 16 MHz oscillator is started
    pdm_init(); // Setup and start PDM

    while (1) {
    nrf_delay_ms(1000); // Do nothing, just keep the system running
    }
    }


    Thank You!!!

Reply
  • Actually, I am receiving the data and I can see it over the Serial terminal. Today, I checked the clock frequency that my controller is generating. PDM Mic needs 1Mhz to 3Mhz of clock frequency. I am setting it by pdm_cfg.clock_freq = NRF_PDM_FREQ_1032K;

    However, the clock is not generating properly. I have observed that when I set the 
    pdm_cfg.clock_freq = NRF_PDM_FREQ_DEFAULT;   it is generating the 5Khz
    pdm_cfg.clock_freq = NRF_PDM_FREQ_1032K;   it is generating the 30Khz
    pdm_cfg.clock_freq = NRF_PDM_FREQ_1067K;   it is generating the 70Khz


    which is incorrect. 
    I would really appreciate the help to enable the High Frequency Clock to generate at least 1MHz of frequency. 

    My code to generate the clock:-

    #include "nrf.h"
    #include "nrf_delay.h"

    // PDM CLK and DIN pin selection
    #define PDM_CLK_PIN 23
    #define PDM_DIN_PIN 25

    // Dummy buffer for PDM DMA (required)
    static int16_t dummy_buf[64];

    // Start High Frequency Clock (16 MHz crystal)
    void hfclk_start(void) {
    NRF_CLOCK->EVENTS_HFCLKSTARTED = 0;
    NRF_CLOCK->TASKS_HFCLKSTART = 1;
    while (NRF_CLOCK->EVENTS_HFCLKSTARTED == 0);
    }

    void pdm_init(void) {
    // Route CLK and DIN pins
    NRF_PDM->PSEL.CLK = PDM_CLK_PIN;
    NRF_PDM->PSEL.DIN = PDM_DIN_PIN;

    // Use 16x PDM clock ratio → ~1.067 MHz
    NRF_PDM->PDMCLKCTRL = PDM_PDMCLKCTRL_FREQ_1067K; // 16 MHz / 15 = 1.067 MHz

    // Configure for Mono input, Left channel, falling edge
    NRF_PDM->MODE = (PDM_MODE_OPERATION_Mono << PDM_MODE_OPERATION_Pos) |
    (PDM_MODE_EDGE_LeftFalling << PDM_MODE_EDGE_Pos);

    // Dummy buffer for DMA, 64 samples
    NRF_PDM->SAMPLE.PTR = (uint32_t)dummy_buf;
    NRF_PDM->SAMPLE.MAXCNT = 64;

    // Enable the PDM peripheral
    NRF_PDM->ENABLE = PDM_ENABLE_ENABLE_Enabled << PDM_ENABLE_ENABLE_Pos;

    // Start the PDM clock and sampling
    NRF_PDM->TASKS_START = 1;
    }

    int main(void) {
    hfclk_start(); // Ensure the external 16 MHz oscillator is started
    pdm_init(); // Setup and start PDM

    while (1) {
    nrf_delay_ms(1000); // Do nothing, just keep the system running
    }
    }


    Thank You!!!

Children
Related