This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

I2S pins are not outputting signals

Hello,

I've been trying to get the nrfx_i2s driver working with Zephyr, on the cpuapp core of the nRF5340. After configuring the driver, setting CONFIG_NRFX_I2S in prj.conf, setting my nRF5340 device as master, and registering the interrupt, I have noticed that no matter what pin configuration I use, I can not get any output on any of the i2s configured pins. However, the i2s interrupt is consistently being triggered, as I can toggle LED0 on the dk per couple of the interrupt triggers.

Current setup:

OS: macOS Mojave

Development environment: Visual Studio Code + CLI with west build -p auto -b nrf5340dk_nrf5340_cpuapp to build and west flash to flash

Logic analyzer: Logic Pro 16, Logic 2 software

Hardware: nRF5340_dk

To recreate the issue, I have attached my current files below. Please let me know if there's anything I need to try on my end!

 1106.prj.conf

#SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.13.1)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(wheezer)


include_directories(inc)
target_sources(app PRIVATE 
        src/main.c 
        src/buttonLed.c)
buttonLed.h
#include <zephyr.h>
#include <nrfx_gpiote.h>

#define SW0		DT_GPIO_PIN(DT_ALIAS(sw0), gpios)
#define SW1		DT_GPIO_PIN(DT_ALIAS(sw1), gpios)
#define SW2		DT_GPIO_PIN(DT_ALIAS(sw2), gpios)
#define SW3		DT_GPIO_PIN(DT_ALIAS(sw3), gpios)
#define LED0	DT_GPIO_PIN(DT_ALIAS(led0), gpios)
#define LED1	DT_GPIO_PIN(DT_ALIAS(led1), gpios)
#define LED2	DT_GPIO_PIN(DT_ALIAS(led2), gpios)
#define LED3	DT_GPIO_PIN(DT_ALIAS(led3), gpios)

static void sw0_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
	nrfx_gpiote_out_toggle(LED0);
}

static void sw1_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
	nrfx_gpiote_out_toggle(LED1);
}

static void sw2_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
	nrfx_gpiote_out_toggle(LED2);
}

static void sw3_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
{
	nrfx_gpiote_out_toggle(LED3);
}

void button_init(void){

	IRQ_CONNECT(DT_IRQN(DT_NODELABEL(gpiote)),
		    DT_IRQ(DT_NODELABEL(gpiote), priority),
		    nrfx_isr, nrfx_gpiote_irq_handler, 0);

	nrfx_gpiote_in_config_t const in_config = {
		.sense = NRF_GPIOTE_POLARITY_HITOLO,
		.pull = NRF_GPIO_PIN_PULLUP,
		.is_watcher = false,
		.hi_accuracy = true,
		.skip_gpio_setup = false,
	};

	nrfx_gpiote_in_init(SW0, &in_config, sw0_handler);
	nrfx_gpiote_in_init(SW1, &in_config, sw1_handler);
	nrfx_gpiote_in_init(SW2, &in_config, sw2_handler);
	nrfx_gpiote_in_init(SW3, &in_config, sw3_handler);

	nrfx_gpiote_in_event_enable(SW0, true);
	nrfx_gpiote_in_event_enable(SW1, true);
	nrfx_gpiote_in_event_enable(SW2, true);
	nrfx_gpiote_in_event_enable(SW3, true);

}

void led_init(void){

	nrfx_gpiote_init(0);

	nrfx_gpiote_out_config_t const out_config = {
		.action = NRF_GPIOTE_POLARITY_TOGGLE,
		.init_state = 1,
		.task_pin = true,
	};
	
	nrfx_gpiote_out_init(LED0, &out_config);
	nrfx_gpiote_out_init(LED1, &out_config);
	nrfx_gpiote_out_init(LED2, &out_config);
	nrfx_gpiote_out_init(LED3, &out_config);
	nrfx_gpiote_out_init(32, &out_config);

}

void led_toggle(int ledPin){

	nrfx_gpiote_out_toggle(ledPin);

}


void buttonLed_init(void){
	led_init();
	button_init();

}
#define NRFX_I2S_ENABLED 1

#include <zephyr.h>
#include "buttonLed.h"
#include <nrfx_i2s.h>


#define BUFFER_SIZE	200
#define PING_BUFFER_DATA_READY	0
#define PONG_BUFFER_DATA_READY	1

uint32_t rxBufferPing[BUFFER_SIZE] = {0};
uint32_t rxBufferPong[BUFFER_SIZE] = {0};
uint32_t txBufferDummy[BUFFER_SIZE] = {'d', 'e', 'a', 'd', 'b', 'e', 'e', 'f'};

nrfx_i2s_buffers_t rx_buffer_ping = {
	.p_rx_buffer = rxBufferPing,
	.p_tx_buffer = txBufferDummy
};

nrfx_i2s_buffers_t rx_buffer_pong = {
	.p_rx_buffer = rxBufferPong,
	.p_tx_buffer = txBufferDummy
};

volatile int whichBuffer = PING_BUFFER_DATA_READY;

volatile int i = 0;

static void i2s_data_handler(nrfx_i2s_buffers_t const* p_released, uint32_t status){
	
	// data corruption if p_released is null
	i++;

	if(i % 10000 == 0){
		led_toggle(LED0);
		i = 0;
	}
	nrfx_i2s_buffers_t* nextBuffer;
	if(p_released == &rx_buffer_ping){
		nextBuffer = &rx_buffer_pong;
		whichBuffer = PING_BUFFER_DATA_READY;
	}else{
		nextBuffer = &rx_buffer_ping;
		whichBuffer = PONG_BUFFER_DATA_READY;
	}



	nrfx_i2s_next_buffers_set(nextBuffer);
}

int main()
{
	// sanity check
	//buttonLed_init();

	led_init();

	IRQ_CONNECT(DT_IRQN(DT_NODELABEL(i2s0)),
		    DT_IRQ(DT_NODELABEL(i2s0), priority),
		    nrfx_isr, nrfx_i2s_irq_handler, 0);

	// i2s format is unaligned, but alignment param is mandatory
	// NOTE: change priority

	// LRCK = MCK/Ratio
	// SCK = LRCK * 2 * SWIDTH
	// Ratio >= 2 * SWIDTH
	// SWIDTH = 24
	// Ratio = 96
	// MCK = 761904.8
	// LRCK = 7936.5 (audio sampling rate)
	// SCK = 380952.4
	nrfx_i2s_config_t p_config = {
		.sck_pin = 10,
		.lrck_pin = 33,
		.mck_pin = 36,
		.sdout_pin = 37,
		.sdin_pin = 38,             
		.irq_priority = DT_IRQ(DT_NODELABEL(i2s0), priority),
		.mode = 0,
		.format = 0,
		.alignment = 0,
		.sample_width = 2,
		.channels = 2,
		.mck_setup = 16,
		.ratio = 3
	};

	volatile nrfx_err_t err0 = nrfx_i2s_init(&p_config, i2s_data_handler);
	irq_enable(DT_IRQN(DT_NODELABEL(i2s0)));

	while(1){

		int i_temp = i;
		volatile nrfx_err_t err1 = nrfx_i2s_start(&rx_buffer_ping, BUFFER_SIZE, 0);
		while(i_temp >= i){

		}
		nrfx_i2s_stop();
		
	}



	return 0;
}

 

Related