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

  • Hello,

    What pins were you origninally use when the SDOUT didn't work? I know you say you have tried multiple pins, but perhaps you were unlucky. 

    Have you tried printing the tx_mem_block before you pass it on in i2s_write? Is it properly populated? Are you sure you need the "&" on "&buf" when buf is an array? Try without. 

    How did you check the TXD.PTR register and decide that it was empty?

    Best regards,

    Edvin

  • 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

  • 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

Related