i2s_trigger failing while setting up - nRF5340 Audio DK

Hey, I'm trying to setup i2s buffers and other related stuff for mic communication, this is my code for i2s

#include <zephyr/kernel.h>
#include <zephyr/drivers/i2s.h>
#include <zephyr/logging/log.h>


/* Audio I2S Configuration Definitions */
#define AUDIO_WORD_SIZE (32) // Number of bits representing one data word.
#define AUDIO_NUM_CHANNELS (2) // Number of words per frame.
#define AUDIO_FORMAT I2S_FMT_DATA_FORMAT_I2S // Data stream format as defined by I2S_FMT_* constants.
#define AUDIO_OPTIONS I2S_OPT_FRAME_CLK_MASTER // Configuration options as defined by I2S_OPT_* constants.
#define AUDIO_SAMPLE_FREQ (44100) // Frame clock (WS) frequency, this is the sampling rate.
#define AUDIO_SAMPLES_PER_CH_PER_FRAME (128) // Samples per channel per frame
#define AUDIO_SAMPLES_PER_FRAME \
    (AUDIO_NUM_CHANNELS * AUDIO_SAMPLES_PER_CH_PER_FRAME) // Samples per frame
#define AUDIO_SAMPLE_BYTES (3) // Sample bytes
#define AUDIO_FRAME_BUF_BYTES \
    (AUDIO_SAMPLES_PER_FRAME * AUDIO_SAMPLE_BYTES) // Size of one RX/TX memory block (buffer) in bytes.
#define I2S_PLAY_BUF_COUNT (50) // I2S buffer count

#define I2S_DEV DT_NODELABEL(i2s0)

// LOG_MODULE_REGISTER(i2s_custom, CONFIG_I2S_LOG_LEVEL);
LOG_MODULE_REGISTER(i2s_custom, LOG_LEVEL_DBG);


/* Device definitions */
static const struct device *host_i2s_rx_dev = DEVICE_DT_GET(DT_NODELABEL(i2s0));
static const struct device *host_i2s_tx_dev = DEVICE_DT_GET(DT_NODELABEL(i2s0));

/* Memory slab definitions */
static struct k_mem_slab i2s_rx_mem_slab;
static struct k_mem_slab i2s_tx_mem_slab;

/* tx and rx buffers */
static char rx_buffers[AUDIO_FRAME_BUF_BYTES * I2S_PLAY_BUF_COUNT];
static char tx_buffer[AUDIO_FRAME_BUF_BYTES * I2S_PLAY_BUF_COUNT];

/* Config definitions */
static struct i2s_config i2s_rx_cfg;
static struct i2s_config i2s_tx_cfg;

const struct device* get_rx_dev(void) {
    return host_i2s_rx_dev;
}

int configure_rx(void) {
    int ret;

    if (!device_is_ready(host_i2s_rx_dev)) {
        LOG_ERR("I2S RX device not ready.");
        return -1;
    }

    LOG_DBG("I2S Device: %s", host_i2s_rx_dev->name);

    /* Allocate memory slab */
    ret = k_mem_slab_init(&i2s_rx_mem_slab, rx_buffers, AUDIO_FRAME_BUF_BYTES, I2S_PLAY_BUF_COUNT);
    if (ret != 0) {
		LOG_ERR("k_mem_slab_init failed with %d error", ret);
        return ret;
	}

    /* Setting up config */
    i2s_rx_cfg.word_size = AUDIO_WORD_SIZE;
	i2s_rx_cfg.channels = AUDIO_NUM_CHANNELS;
	i2s_rx_cfg.format = I2S_FMT_DATA_FORMAT_I2S;
	i2s_rx_cfg.options = AUDIO_OPTIONS;
	i2s_rx_cfg.frame_clk_freq = AUDIO_SAMPLE_FREQ;
	i2s_rx_cfg.block_size = AUDIO_FRAME_BUF_BYTES;
	i2s_rx_cfg.mem_slab = &i2s_rx_mem_slab;
	i2s_rx_cfg.timeout = -1;

    ret = i2s_configure(host_i2s_rx_dev, I2S_DIR_RX, &i2s_rx_cfg);

    if (ret != 0) {
		LOG_ERR("i2s_configure failed with %d error", ret);
        return ret;
	}

    LOG_DBG("Successfully configured RX I2S.");
    return 0;
}

int configure_tx(void) {
    int ret;

    if (!device_is_ready(host_i2s_tx_dev)) {
        LOG_ERR("I2S TX device not ready.");
        return -1;
    }

    LOG_DBG("I2S Device: %s", host_i2s_tx_dev->name);

    /* Allocate memory slab */
    ret = k_mem_slab_init(&i2s_tx_mem_slab, tx_buffer, AUDIO_FRAME_BUF_BYTES, I2S_PLAY_BUF_COUNT);
    if (ret != 0) {
		LOG_ERR("k_mem_slab_init failed with %d error", ret);
        return ret;
	}

    /* Setting up config */
    i2s_tx_cfg.word_size = AUDIO_WORD_SIZE;
	i2s_tx_cfg.channels = AUDIO_NUM_CHANNELS;
	i2s_tx_cfg.format = I2S_FMT_DATA_FORMAT_I2S;
	i2s_tx_cfg.options = AUDIO_OPTIONS;
	i2s_tx_cfg.frame_clk_freq = AUDIO_SAMPLE_FREQ;
	i2s_tx_cfg.block_size = AUDIO_FRAME_BUF_BYTES;
	i2s_tx_cfg.mem_slab = &i2s_tx_mem_slab;
	i2s_tx_cfg.timeout = -1;

    ret = i2s_configure(host_i2s_tx_dev, I2S_DIR_TX, &i2s_tx_cfg);

    if (ret != 0) {
		LOG_ERR("i2s_configure failed with %d error", ret);
        return ret;
	}

    LOG_DBG("Successfully configured TX I2S.");
    return 0;
}

int audio_i2s_setup(void) {
    int err;

	LOG_INF("Setting up I2S...");

    err = configure_rx();
    if (err != 0) {
		LOG_ERR("Failed to setup rx i2s: err %d", err);
        return err;
	}

    err = configure_tx();
    if (err != 0) {
		LOG_ERR("Failed to setup tx i2s: err %d", err);
        return err;
	}

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

	/* start i2s tx driver */
	err = i2s_trigger(host_i2s_tx_dev, I2S_DIR_TX, I2S_TRIGGER_START);
	if (err != 0) {
		LOG_ERR("i2s_trigger failed with %d error\n", err);
		return err;
	}

    /* receive data */
	void *rx_mem_block, *tx_mem_block;
	size_t size;

	while (true) {
		k_mem_slab_alloc(&i2s_tx_mem_slab, &tx_mem_block, K_NO_WAIT);
		i2s_read(host_i2s_rx_dev, &rx_mem_block, &size);
		memcpy(tx_mem_block, rx_mem_block, size);
		i2s_write(host_i2s_tx_dev, tx_mem_block, size);
		k_mem_slab_free(&i2s_rx_mem_slab, rx_mem_block);
	}

	LOG_INF("I2S configured successfully");


    return 0;

}

There are no errors while building or flashing, however while running i2s_trigger, I'm getting this error

<err> i2s_custom: i2s_trigger failed with -5 error

This supposedly means that  The trigger cannot be executed in the current state or a DMA channel cannot be allocated.

What could be the possible reason for this, even tho the rx and tx i2s instances are being configured properly?

Parents Reply Children
No Data
Related