I2S on Thingy91 not working with Adafruit SPH0645LM4H or InvenSense INMP441 Microphone

Hi

I am working on implementing I2S Communcation for the Thingy91 prototyping board using the common Adafruit SPH0645LM4H and InvenSense INMP441 Microphone:

I got some first code implementation running by following the Echo and Litex sample given by the Zephyr OS.

I use following code for flashing to the nRF52840 using J-Link:

#include <zephyr.h>
#include <drivers/i2s.h>
#include <stdlib.h>
#include <string.h>

#define I2S_RX_NODE DT_NODELABEL(i2s_rx)
#define I2S_RX_TIMEOUT 1000
#define AUDIO_SAMPLE_FREQ 44100
#define AUDIO_SAMPLES_PER_CH_PER_BUF 128
#define AUDIO_NUM_CHANNELS 2
#define AUDIO_SAMPLES_PER_BUF (AUDIO_SAMPLES_PER_CH_PER_BUF * AUDIO_NUM_CHANNELS)
#define AUDIO_SAMPLE_BIT_WIDTH 24
#define AUDIO_BUF_BYTES (AUDIO_SAMPLES_PER_BUF * AUDIO_SAMPLE_BIT_WIDTH / 8)
#define AUDIO_BUF_COUNT 64
#define AUDIO_BUF_BYTES_ALIGN 4
K_MEM_SLAB_DEFINE(i2s_rx_mem_slab, AUDIO_BUF_BYTES, AUDIO_BUF_COUNT, AUDIO_BUF_BYTES_ALIGN);
static const struct device *host_i2s_rx_dev;
static struct i2s_config i2s_rx_cfg;
static int ret;

static void audio_init(void)
{
	/*configure rx device*/
	host_i2s_rx_dev = DEVICE_DT_GET(I2S_RX_NODE);
	if (!host_i2s_rx_dev) {
		LOG_ERR("unable to find i2s_rx device\n");
	}

	/* configure i2s for audio playback */
	i2s_rx_cfg.word_size = AUDIO_SAMPLE_BIT_WIDTH;
	i2s_rx_cfg.channels = AUDIO_NUM_CHANNELS;
	i2s_rx_cfg.format = I2S_FMT_DATA_FORMAT_I2S;
	i2s_rx_cfg.options = I2S_OPT_BIT_CLK_MASTER | I2S_OPT_FRAME_CLK_MASTER;
	i2s_rx_cfg.frame_clk_freq = AUDIO_SAMPLE_FREQ;
	i2s_rx_cfg.mem_slab = &i2s_rx_mem_slab;
	i2s_rx_cfg.block_size = AUDIO_BUF_BYTES;
	i2s_rx_cfg.timeout = I2S_RX_TIMEOUT;
	ret = i2s_configure(host_i2s_rx_dev, I2S_DIR_RX, &i2s_rx_cfg);
	if (ret != 0) {
		LOG_ERR("i2s_configure failed with %d error\n", ret);
	}
}

void main(void)
{
	audio_init();

	/* start i2s rx driver */
	ret = i2s_trigger(host_i2s_rx_dev, I2S_DIR_RX, I2S_TRIGGER_START);
	if (ret != 0) {
	    LOG_ERR("i2s_trigger failed with %d error\n", ret);
	}

    void *rx_mem_block;
    rx_mem_block = k_malloc(AUDIO_BUF_BYTES);
    size_t size;
    int16_t sample;
	while (true) {
        	/* receive data */
		    ret = i2s_buf_read(host_i2s_rx_dev, rx_mem_block, &size);
        	if (ret != 0) {
        		LOG_ERR("i2s_read failed with %d error\n", ret);
        	}
                for (int i = 0; i < AUDIO_SAMPLES_PER_BUF; ++i) {
                        sample = ((int16_t *)rx_mem_block)[i] >> 16;
                }
	}
    k_free(rx_mem_block);

}

with following overlay to adress the SPARE GPIO Pins of the Thingy91.

i2s_rx: &i2s0 {
	status = "okay"; // Thingy91, InvenSense INMP441, Adafruit SPH0645LM4H
	sck-pin = <6>; // SPARE1, sck, BCLK
	lrck-pin = <5>; // SPARE2, ws, LRCL
	sdin-pin = <26>; // SPARE3, sd, DOUT
};

The code run's the functions i2s_configure(), i2s_trigger() and i2s_buf_read() with return code = 0, showing no errors.

However, the memory buffer rx_mem_block does not update at i2s_buf_read() from the recorded I2S microphone data. It is constantly showing -1 in each loop iteration:

Any ideas why this happens, does the code look ok to you and any tips how to further debug the issue?

Thanks in advance.

Parents Reply Children
Related