I wrote some code to read the Adafruit PDM Microphone Breakout board sensor output (ST MP34DT01-M microphone) with Zephyr and nRF Connect SDK into the Thingy 91.
I do this by connecting the microphone board to the externally available GPIO SPARE 1 (CLK) and 2 (DATA).
When I flash following code to the nRF52840 the PDM device intializes with NRFX_SUCCESS but the sensor reading is always -8. The microphone works at another microcontroller.
What might be wrong at the code for the initialization? Did I miss something in the KConfig file to correctly set up the PDM device?
/* Include ----------------------------------------------------------------- */
#include <stdio.h>
#include <stdint.h>
#include <zephyr.h>
#include <nrfx_power.h>
#include <nrfx_pdm.h>
#include <hal/nrf_pdm.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 6 /*<-- change for specific pin*/
#define DIN_PIN 5 /*<-- change for specific pin*/
int16_t pdm_buf[PDM_BUF_SIZE];
int16_t rms_buffer[RMS_BUFFER_SIZE];
uint16_t rms_buffer_cursor = 0;
double sqrt(double value)
{
int i;
double sqrt = value / 3;
if (value <= 0) {
return 0;
}
for (i = 0; i < 6; i++) {
sqrt = (sqrt + value / sqrt) / 2;
}
return sqrt;
}
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); // return sqrt(tosquirt)
}
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);
}
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);
}
}
static void pdm_init(void)
{
nrfx_pdm_config_t pdm_config = NRFX_PDM_DEFAULT_CONFIG(CLK_PIN, DIN_PIN);
//pdm_config.ratio = NRF_PDM_RATIO_64X; //NRF_PDM_RATIO_80X
//pdm_config.edge = NRF_PDM_EDGE_LEFTRISING;
//pdm_config.mode = NRF_PDM_MODE_STEREO;
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");
}
// ret = nrfx_pdm_stop();
// if (ret == NRFX_SUCCESS)
// {
// printk("Pdm stop was successfull\n");
// }
// else {
// printk("Pdm stop was NOT successfull\n");
// }
}

# Logging CONFIG_LOG=y CONFIG_CONSOLE=y CONFIG_RTT_CONSOLE=y CONFIG_USE_SEGGER_RTT=y CONFIG_LOG_BACKEND_RTT=y CONFIG_LOG_DEFAULT_LEVEL=4 # Event logs CONFIG_BRIDGE_LOG_MODULE_STATE_EVENT=n CONFIG_BRIDGE_LOG_UART_DATA_EVENT=n CONFIG_BRIDGE_LOG_CDC_DATA_EVENT=n CONFIG_BRIDGE_LOG_BLE_DATA_EVENT=n CONFIG_BRIDGE_LOG_BLE_CTRL_EVENT=n CONFIG_BRIDGE_LOG_PEER_CONN_EVENT=n CONFIG_BRIDGE_LOG_FS_EVENT=n CONFIG_BRIDGE_LOG_POWER_DOWN_EVENT=n # Microphone CONFIG_NRFX_PDM=y # Debugging CONFIG_DEBUG_OPTIMIZATIONS=y CONFIG_LOG_PRINTK=y CONFIG_CBPRINTF_FP_SUPPORT=y