Consistent EIO errors on i2s_write

Hi all,

I'm using an nRF5340 DK and I want to build a simple project that plays a sinewave to an i2s DAC (MAX 98357A, perfectly working on other development boards I have).

Being new to the nRF platform, I used the i2s_echo sample and some code found on the Internet, and I think all the information match. However, I always get stuck with a code that runs but returns -5 (EIO) at the i2s_write command

This is the code I'm using

#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <soc.h>
#include <string.h>
#include <nrf.h>
#include <zephyr/drivers/i2s.h>

/* Prepare for 32 sample values */
#define NUM_SAMPLES 32

/* Sine Wave Sample */
static int16_t data_frame[NUM_SAMPLES] = {
	  6392,  12539,  18204,  23169,  27244,  30272,  32137,  32767,  32137,
	 30272,  27244,  23169,  18204,  12539,   6392,      0,  -6393, -12540,
	-18205, -23170, -27245, -30273, -32138, -32767, -32138, -30273, -27245,
	-23170, -18205, -12540,  -6393,     -1,
};

/* The size of the memory block should be a multiple of data_frame size */
#define BLOCK_SIZE (2 * sizeof(data_frame))

/* The number of memory blocks in a slab has to be at least 2 per queue */
#define NUM_BLOCKS 5

/* Define a new Memory Slab which consistes of NUM_BLOCKS blocks
   __________________________________________________________________________
  |    Block 0   |    Block 1   |    Block 2   |    Block 3   |    Block 4   |
  |    0...31    |    0...31    |    0...31    |    0...31    |    0...31    |
  |______________|______________|______________|______________|______________|
*/
static K_MEM_SLAB_DEFINE(mem_slab, BLOCK_SIZE, NUM_BLOCKS, NUM_SAMPLES);

void main(void) {
	/* Get I2S device from the devicetree */
	const struct device *i2s_dev = DEVICE_DT_GET(DT_NODELABEL(i2s_rxtx));
	printk("Allocating i2s device \n");
	if (!device_is_ready(i2s_dev)) {
		printk("%s is not ready\n", i2s_dev->name);
		return;
	}

	/* Configure the I2S device */
	struct i2s_config i2s_cfg;
	i2s_cfg.word_size = 16; // due to int16_t in data_frame declaration
	i2s_cfg.channels = 2; // L + R channel
	i2s_cfg.format = I2S_FMT_DATA_FORMAT_I2S;
	i2s_cfg.options = I2S_OPT_BIT_CLK_MASTER | I2S_OPT_FRAME_CLK_MASTER;
	i2s_cfg.frame_clk_freq = 44100;
	i2s_cfg.mem_slab = &mem_slab;
	i2s_cfg.block_size = BLOCK_SIZE;
	i2s_cfg.timeout = 1000;
	int ret = i2s_configure(i2s_dev, I2S_DIR_TX, &i2s_cfg);
	if (ret < 0) {
		printk("Failed to configure the I2S stream: (%d)\n", ret);
		return;
	}

	/* Allocate the memory blocks (tx buffer) from the slab and
	   set everything to 0 */
	void *mem_blocks;
	ret = k_mem_slab_alloc(&mem_slab, &mem_blocks, K_NO_WAIT);
	if (ret < 0) {
		printk("Failed to allocate the memory blocks: %d\n", ret);
		return;
	}
	memset((uint16_t*)mem_blocks, 0, NUM_SAMPLES * NUM_BLOCKS);

	/* Start the transmission of data */
	printk("Starting transmission \n");
	ret = i2s_trigger(i2s_dev, I2S_DIR_TX, I2S_TRIGGER_START);
	if (ret < 0) {
		printk("Failed to start the transmission: %d\n", ret);
		return;
	}
	
	for(;;) {
		/*for (int i=0; i < 10; i++) {*/
			int ret;
			
			/* Put data into the tx buffer */
			for (int i = 0; i < NUM_SAMPLES * NUM_BLOCKS; i++) {
				((uint16_t*)mem_blocks)[i] = data_frame[i % NUM_SAMPLES];
			}

			/* Write Data */
			printk("Playing.. \n");
			ret = i2s_write(i2s_dev, mem_blocks, BLOCK_SIZE);
			if (ret < 0) {
				printk("Error: i2s_write failed with %d\n", ret);
				return; 
			}
			ret = i2s_trigger(i2s_dev, I2S_DIR_TX, I2S_TRIGGER_STOP);
			if (ret < 0) {
				printk("Failed to stop the transmission: %d\n", ret);
				return;
			}
		/*}*/
		
	}
}

This is my overlay:

&pinctrl {
	compatible = "nordic,nrf-pinctrl";
	i2c0_default_alt: i2c0_default_alt {
		group1 {
			psels = <NRF_PSEL(TWIM_SDA, 0, 25)>,
				<NRF_PSEL(TWIM_SCL, 0, 26)>;
		};
	};

	i2c0_sleep_alt: i2c0_sleep_alt {
		group1 {
			psels = <NRF_PSEL(TWIM_SDA, 0, 25)>,
				<NRF_PSEL(TWIM_SCL, 0, 26)>;
			low-power-enable;
		};
	};

	i2s0_default_alt: i2s0_default_alt {
		group1 {
			psels = <NRF_PSEL(I2S_SCK_M, 1, 15)>,
				<NRF_PSEL(I2S_LRCK_M, 1, 12)>,
				<NRF_PSEL(I2S_SDOUT, 1, 13)>,
				<NRF_PSEL(I2S_SDIN, 1, 14)>;
		};
	};
};


&clock {
	hfclkaudio-frequency = <11289600>;
};

spi: &spi4 {
	status = "disabled";
};


i2s_rxtx: &i2s0 {
	status = "okay";
	pinctrl-0 = <&i2s0_default_alt>;
	pinctrl-names = "default";
	clock-source = "ACLK";
};

i2s in the generated zephyr.dts checks fine (status is "okay")

How can I get past this error?

Thanks in advance

Parents Reply Children
Related