PDMMIC integtarion

Hi,

I am working on pdm mic integration in zephyr RTOS. I used INMP441 mic sensor. I got SPL in dB by using nrfx. I want to create a driver for this mic. Please help me how to create driver.

I attached the working code of nrfx pdm mic.

Thank you.

/*
 * Copyright (c) 2021 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */
#include <math.h>
#include <stdio.h>
#include <stdint.h>
#include <zephyr.h>
#include <nrfx_power.h>
#include <nrfx_pdm.h>
#include <hal/nrf_pdm.h>
#include <nrfx_log.h>
#define RMS_BUFFER_SIZE 4096
#define MAX_SOUND_PRESSURE_LEVEL 120 /*<-- change for specific mic*/

#define PDM_BUF_ADDRESS 0x20000000 // buffer address in RAM
#define PDM_BUF_SIZE 512
#define CLK_PIN 30 /*<-- change for specific pin*/
#define DIN_PIN 31 /*<-- change for specific pin*/

int16_t pdm_buf[PDM_BUF_SIZE];
int16_t rms_buffer[RMS_BUFFER_SIZE];
double rms_normalized = 0.0;
double rms_db_spl = 0.0;   
uint16_t rms_buffer_cursor = 0;


double calculate_rms(int16_t *buffer, uint16_t num_samples) {
  	uint64_t sum = 0;

  	for (uint16_t j = 0; j < num_samples; j++) {
    	rms_buffer[rms_buffer_cursor] = buffer[j];
  		rms_buffer_cursor = (rms_buffer_cursor + 1) % RMS_BUFFER_SIZE;
  	}

  	for (uint16_t j = 0; j < RMS_BUFFER_SIZE; j++) {
    	sum += rms_buffer[j] * rms_buffer[j];
  	}
	double tosquirt = sum / RMS_BUFFER_SIZE;
  	
	return sqrt(tosquirt);
}

double calculate_dbfs_from_normalized(double rms_normalized) {

	double fabsRmsNormalised = fabs(rms_normalized);	
  	return log10(fabsRmsNormalised) * 20;
}



double get_db_spl(double normalized_rms) {
  	const uint8_t db_spl_offset = MAX_SOUND_PRESSURE_LEVEL;
  	double out = calculate_dbfs_from_normalized(normalized_rms) + db_spl_offset;
	
  	// printk("RMS out: %f\n", out);
	return out;
}

void audio_callback(int16_t *buffer, uint16_t size) { 

  	// Calculate RMS of last 250 ms 
  	double rms = calculate_rms(buffer, size); 
	// printk("RMS value: %f\n", rms);
  
  	// Convert int16_t to double 
  	rms_normalized = rms / (double) 32768.0; 

  	// Convert rms to dB value 
  	rms_db_spl = get_db_spl(rms_normalized);
	printk("dB value %f\n", rms_db_spl);
}



void nrfx_pdm_event_handler(nrfx_pdm_evt_t const *const p_evt)
{
	if (p_evt->buffer_requested) {
		nrfx_pdm_buffer_set(pdm_buf, PDM_BUF_SIZE);						
	}
	if (p_evt->buffer_released != 0) {
		
		audio_callback(pdm_buf, PDM_BUF_SIZE);
		//k_sleep(K_MSEC(1000));
		
	}
}

static void pdm_init(void)
{
    nrfx_pdm_config_t pdm_config = NRFX_PDM_DEFAULT_CONFIG(CLK_PIN, DIN_PIN);
    nrfx_pdm_init(&pdm_config, nrfx_pdm_event_handler);
   
}

void main(void)
{
	nrfx_err_t ret;
	printk("Starting PDM program!\n");
	printk("PDM Buffer size: %d\n", (PDM_BUF_SIZE * 4));
	printk("PDM Starting Address: %x\n", PDM_BUF_ADDRESS);
	pdm_init();

	ret = nrfx_pdm_start();
	if (ret == NRFX_SUCCESS)
	{
		printk("Pdm start was successfull\n");
	}
	else {
		printk("Pdm start was NOT successfull\n");
	}

}

Parents Reply Children
Related