This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Issues interfacing I2S MP34DT05 with nRF52840

Hello,

I am currently interfacing MP34DT05 with nRF52840 using I2S protocol. I have tried using nrfx I2S drivers but it gives me initialization error. I have used the sample code given as the solution in the following link as reference, but cant make it work for my DK.

  https://devzone.nordicsemi.com/f/nordic-q-a/63708/i2s-loopback-example-missing-in-installation-folder

Below is my main.c file for nRF52840. I have only defined 3 pins because i just want to read the data from sensor.

#include <zephyr.h>
#include <string.h>

#include "nrfx_i2s.h"

//#error Remember to define these pins before you run! // This assume you only have these 3 pins for I2S.
#define I2S_WS_PIN 20
#define I2S_SD_PIN 21
#define I2S_SCK_PIN 22

#define I2S_DATA_BLOCK_WORDS 512 //How many numbers do we want. time reorded = DATA_BLOCK_WORDS / freq

static uint32_t m_buffer_rx32u[I2S_DATA_BLOCK_WORDS];
static int32_t tmp[I2S_DATA_BLOCK_WORDS];
static nrfx_i2s_buffers_t initial_buffers;
static bool data_ready_flag = false;

ISR_DIRECT_DECLARE(i2s_isr_handler)
{
	data_ready_flag = false;
	nrfx_i2s_irq_handler();
	ISR_DIRECT_PM(); /* PM done after servicing interrupt for best latency
			  */
	return 1;		 /* We should check if scheduling decision should be made */
}

static void data_handler(nrfx_i2s_buffers_t const *p_released, uint32_t status)
{
	if (NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED == status)
	{
		nrfx_err_t err = nrfx_i2s_next_buffers_set(&initial_buffers);
		if (err != NRFX_SUCCESS)
		{
			printk("Error!, continuing running as if nothing happened, but you should probably investigate.\n");
		}
	}
	if (p_released)
	{
		if (p_released->p_rx_buffer != NULL)
		{
			data_ready_flag = true; //This is used in print_sound()
		}
	}
}

void print_sound()
{
	while (!data_ready_flag)
	{
		k_sleep(K_MSEC(1));
		//Wait for data. Since we do not want I2S_DATA_BLOCK_WORDS amount of prints inside the interrupt.
	}
	nrfx_i2s_stop();
	data_ready_flag = false;


	int64_t sum = 0;
	int64_t words = I2S_DATA_BLOCK_WORDS;

	for (int i = 0; i < I2S_DATA_BLOCK_WORDS; i++)
	{
		memcpy(tmp + i, m_buffer_rx32u + i, sizeof(uint32_t));
		tmp[i] >>= 8;
		sum += tmp[i];
	}

	int64_t mean = sum / words;
	for (int i = 0; i < I2S_DATA_BLOCK_WORDS; i++)
	{
		tmp[i] -= mean;
		printk("%d, ", tmp[i]);
		k_sleep(K_MSEC(16));
	}
	printk("\n\n");
	/**  End of formatted data print*/
}

nrfx_err_t get_sound_init()
{
	IRQ_DIRECT_CONNECT(I2S_IRQn, 0, i2s_isr_handler, 0);
	memset(&m_buffer_rx32u, 0x00, sizeof(m_buffer_rx32u));
	initial_buffers.p_rx_buffer = m_buffer_rx32u;

	//YOu should probably change this config to fit your I2S microphone and audio preferences.
	nrfx_i2s_config_t config =
		NRFX_I2S_DEFAULT_CONFIG(I2S_SCK_PIN, I2S_WS_PIN,
								NRFX_I2S_PIN_NOT_USED,
								NRFX_I2S_PIN_NOT_USED, I2S_SD_PIN);

	config.mode = NRF_I2S_MODE_MASTER;			//Microphone requirement
	config.ratio = NRF_I2S_RATIO_64X;			//Microphone requirement
	config.sample_width = NRF_I2S_SWIDTH_24BIT; //Microphone requirement
	config.mck_setup = NRF_I2S_MCK_32MDIV31;	//Preference     freq = (MCKfreq/ratio) =16.129 KHz.
	config.channels = NRF_I2S_CHANNELS_LEFT;	//Preference

	nrfx_err_t err_code = nrfx_i2s_init(&config, data_handler);
	if (err_code != NRFX_SUCCESS)
	{
		printk("I2S init error\n");
		return err_code;
	}
	err_code = nrfx_i2s_start(&initial_buffers, I2S_DATA_BLOCK_WORDS, 0); //start recording
	if (err_code != NRFX_SUCCESS)
	{
		printk("I2S start error\n");
		return err_code;
	}
	//nrfx_i2s_stop() //stop recording

	k_sleep(K_SECONDS(2));
	return err_code;
}

void main()
{
	nrfx_err_t err;
	err = get_sound_init();
	if (err != NRFX_SUCCESS)
	{
		return;
	}
	while (1)
	{
		k_sleep(K_SECONDS(5));
		print_sound();
	}
}

Here is my project.conf file.

#I2S
CONFIG_NRFX_I2S=y
CONFIG_SPM_NRF_I2S0_NS=y

#LOG
CONFIG_LOG=y
CONFIG_LOG_PRINTK=y
CONFIG_LOG_BACKEND_SHOW_COLOR=n

I have also enabled I2S to be used in the non-secure area by following this post devzone.nordicsemi.com/.../adafruit-i2s-mems-microphone-breakout-with-the-nrf9160-dk

Can anyone suggest what else i have to do for initializing and reading data via I2S on nRF52840.

Related