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