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.