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?