I2S Zephyr SDOUT not working

I am trying to get I2S communication up and running but am unable to produce a signal on my SDOUT pin. MCLK, LRCLK and SCLK work as intended but trying to send any data does not work. I did notice that the TXD.PTR register is empty. I have tried multiple pins for my SDOUT and have nrf SDK 1.8.0 installed, using VScode. Any help would be appreciated.

#include <zephyr.h>
#include <drivers/gpio.h>
#include <init.h>
#include <nrf.h>
#include <nrfx.h>
#include <nrfx_gpiote.h>
#include <drivers/i2s.h>
#include "nrfx_i2s.h"
#include <errno.h>
#include <string.h>
#include <logging/log.h>

LOG_MODULE_REGISTER(Main);

#define AUDIO_SAMPLE_FREQ (44100)
#define AUDIO_NUM_CHANNELS (1)
#define AUDIO_SAMPLE_BIT_WIDTH (16)
#define AUDIO_SAMPLES_PER_CH_PER_FRAME (128)
#define AUDIO_SAMPLES_PER_FRAME (AUDIO_SAMPLES_PER_CH_PER_FRAME * AUDIO_NUM_CHANNELS)
#define AUDIO_SAMPLE_BYTES (sizeof(uint16_t))
#define AUDIO_FRAME_BUF_BYTES (AUDIO_SAMPLES_PER_FRAME * AUDIO_SAMPLE_BYTES)
#define I2S_PLAY_BUF_COUNT (500)

static const struct device *host_i2s_tx_dev;
static struct k_mem_slab i2s_tx_mem_slab;
static char tx_buffer[AUDIO_FRAME_BUF_BYTES * I2S_PLAY_BUF_COUNT];
static struct i2s_config config;
volatile int ret;

static void init(void)
{
	/*configure tx device*/
	host_i2s_tx_dev = device_get_binding("I2S_0");

	k_mem_slab_init(&i2s_tx_mem_slab, tx_buffer, AUDIO_FRAME_BUF_BYTES, I2S_PLAY_BUF_COUNT);

	/* configure i2s for audio playback */
	config.word_size = AUDIO_SAMPLE_BIT_WIDTH;
	config.channels = AUDIO_NUM_CHANNELS;
	config.format = I2S_FMT_DATA_FORMAT_I2S;
	config.options = (I2S_OPT_BIT_CLK_MASTER | I2S_OPT_FRAME_CLK_MASTER);
	config.frame_clk_freq = AUDIO_SAMPLE_FREQ;
	config.block_size = AUDIO_FRAME_BUF_BYTES;
	config.mem_slab = &i2s_tx_mem_slab;
	config.timeout = -1;
	ret = i2s_configure(host_i2s_tx_dev, I2S_DIR_TX, &config);
	if (ret < 0)
	{
		LOG_INF("tx config:%d", ret);
	}
}

void main(void)
{
	init();

	uint16_t buf[128];
	volatile size_t size = sizeof(buf);

	int i = 0;
	for (i = 0; i < size; i++)
	{
		if (i <= size / 4)
		{
			buf[i] = i;
		}
		else if (i > size / 4)
		{
			buf[i] = size / 2 - i;
		}
	}

	void *tx_mem_block;

	ret = i2s_trigger(host_i2s_tx_dev, I2S_DIR_TX, I2S_TRIGGER_START);

	while (1)
	{
		ret = k_mem_slab_alloc(&i2s_tx_mem_slab, &tx_mem_block, K_NO_WAIT);
		memcpy(tx_mem_block, &buf, size);
		ret = i2s_write(host_i2s_tx_dev, tx_mem_block, size);
		k_mem_slab_free(&i2s_tx_mem_slab, &tx_mem_block);
	}
}
# CONFIG_MULTITHREADING=n
# CONFIG_KERNEL_MEM_POOL=n
# CONFIG_NUM_PREEMPT_PRIORITIES=0
# CONFIG_SYS_CLOCK_EXISTS=n
# CONFIG_ARM_MPU=n
# CONFIG_SIZE_OPTIMIZATIONS=y
CONFIG_I2S=y
CONFIG_NRFX_I2S=y
# CONFIG_WATCHDOG=n
CONFIG_GPIO=y
# CONFIG_PINMUX=n
# CONFIG_SPI=n
# CONFIG_SERIAL=n
# CONFIG_FLASH=n
# CONFIG_PM=n
# CONFIG_DYNAMIC_INTERRUPTS=n
# CONFIG_IRQ_OFFLOAD=n
# CONFIG_THREAD_STACK_INFO=n
# CONFIG_THREAD_CUSTOM_DATA=n
# CONFIG_BOOT_BANNER=n
# CONFIG_BOOT_DELAY=0
# CONFIG_CONSOLE=n
# CONFIG_UART_CONSOLE=n
# CONFIG_STDOUT_CONSOLE=n
# CONFIG_EARLY_CONSOLE=n
CONFIG_BOARD_ENABLE_CPUNET=n
CONFIG_NRF_RTC_TIMER=n
CONFIG_CORTEX_M_SYSTICK=y
CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=64000000
CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000000
CONFIG_LOG=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_LOG_BACKEND_RTT=y

Parents
  • Hi thank you for your response,

    I tried on GPIO 36, 26, 0, 2 ,3. Removing "&" gives the same result unfortunately, and yes the data is properly populated within tx_mem_block before i2s_write() is called. To view the TXD.PTR I use "Cortex-Debug: View Memory" then set the address to 0x5002850C since 0x50028000 is the base address. I used this method to check the other registers and they all seem to be set correctly.

  • Hello,

    Would it be possible for me to reproduce this on a DK? Are you able to replicate this without any external I2C devices? If so, can you please send the project here? (Or if you can't share, please strip the project down to something smaller that is able to replicate the issue).

    Best regards,

    Edvin

Reply Children
  • Yes I forgot to mention I am using a DK, and yes this happens with no other peripherals attached to it.

    nRF5340_i2s_test.zip

  • Hello,

    How do you build your project? Do you use nRF Connect for VS Code? If so, can you please try to unzip it to an unmodified SDK and see if you can compile it? (I tried both this and using West from the command line, but in both cases, I get a ZEPHYR_FATAL_ERROR:

    00> [00:00:00.281,000] <err> fatal_error: Resetting system
    00> [00:00:00.004,000] <err> os: ***** BUS FAULT *****
    00> [00:00:00.004,000] <err> os:   Instruction bus error
    00> 
    00> [00:00:00.004,000] <err> os: r0/a1:  0x00000000  r1/a2:  0x00000001  r2/a3:  0x200002f8
    00> [00:00:00.004,000] <err> os: r3/a4:  0x2ef7fbb5 r12/ip:  0xffffffff r14/lr:  0x000004a5
    00> [00:00:00.004,000] <err> os:  xpsr:  0x69000000
    00> [00:00:00.004,000] <err> os: Faulting instruction address (r15/pc): 0x2ef7fbb4
    00> [00:00:00.004,000] <err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
    00> [00:00:00.004,000] <err> os: Current thread: 0x20000270 (unknown)
    00> [00:00:00.281,000] <err> fatal_error: Resetting system
    00> [00:00:00.004,000] <err> os: ***** BUS FAULT *****
    00> [00:00:00.004,000] <err> os:   Instruction bus error
    00> [00:00:00.004,000] <err> os: r0/a1:  0x00000000  r1/a2:  0x00000001  r2/a3:  0x200002f8
    00> [00:00:00.004,000] <err> os: r3/a4:  0x2ef7fbb5 r12/ip:  0xffffffff r14/lr:  0x000004a5[0m
    00> [00:00:00.004,000] <err> os:  xpsr:  0x69000000
    00> [00:00:00.004,000] <err> os: Faulting instruction address (r15/pc): 0x2ef7fbb4
    00> [00:00:00.004,000] <err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
    00> [00:00:00.004,000] <err> os: Current thread: 0x20000270 (unknown)
    00> [00:00:00.281,000] <err> fatal_error: Resetting system
    00> [00:00:00.004,000] <err> os: ***** BUS FAULT *****
    00> [00:00:00.004,000] <err> os:   Instruction bus error
    00> [00:00:00.004,000] <err> os: r0/a1:  0x00000000  r1/a2:  0x00000001  r2/a3:  0x200002f8
    00> [00:00:00.004,000] <err> os: r3/a4:  0x2ef7fbb5 r12/ip:  0xffffffff r14/lr:  0x000004a5
    00> [00:00:00.004,000] <err> os:  xpsr:  0x69000000
    00> [00:00:00.004,000] <err> os: Faulting instruction address (r15/pc): 0x2ef7fbb4
    00> [00:00:00.004,000] <err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0

    I didn't look into what it points to, but I want to check whether you get the same when you are using the DK?

    Best regards,

    Edvin

  • Yes I use nrf connect for VS code, and I just recently tried it in an unmodified SDK. It runs without any errors for me but the DOUT line remains low while the clocks function.

  • Hello,

    So I was able to change the project so that I was able to compile without your custom files, and so that it ran on my nRF53DK "without errors". 

    Did you check the return value from i2s_write()? (It didn't print until I added "k_sleep(K_SECONDS(1))" to the end of your while loop (for the log to be processed), but in my case it returns -5 and prints "Cannot write in state: 4",  where 4 refers to I2S_STATE_ERROR.

    I haven't gotten to play around with I2S in NCS that much. Did you test the sample found in NCS\zephyr\samples\drivers\i2s?
    Best regards,
    Edvin
  • Hi, 

    Yes I did take a look at the sample projects there but unfortunately they did not work on my board. Not sure if something is being configured incorrectly or where the issue is stemming from. I had a delay at first but then it gave me the I2S_STATE_ERROR until I removed it. The state that I sent my code in ran for me with all returns of 0.

Related