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?