GPIO conflicts with I2S interrupt

BuddyCasino
Posts: 263
Joined: Sun Jun 19, 2016 12:00 am

GPIO conflicts with I2S interrupt

Postby BuddyCasino » Thu Apr 13, 2017 8:19 pm

I have some code where I first setup a simple GPIO interrupt handler to react to GPIO_NUM_0.
Some time later I start the I2S driver via i2s_driver_install(). This results in a LoadProhibited exception, and I can't figure out why. When I remove the GPIO code the issue disappears. Heres the code for the GPIO and the I2S config:

Code: Select all

void controls_init()
{
    gpio_config_t io_conf;

    //interrupt of rising edge
    io_conf.intr_type = GPIO_PIN_INTR_POSEDGE;
    //bit mask of the pins, use GPIO0 here ("Boot" button)
    io_conf.pin_bit_mask = (1 << GPIO_NUM_0);
    //set as input mode
    io_conf.mode = GPIO_MODE_INPUT;
    //disable pull-down mode
    io_conf.pull_down_en = 0;
    //enable pull-up mode
    io_conf.pull_up_en = 1;
    gpio_config(&io_conf);

    //create a queue to handle gpio event from isr
    gpio_evt_queue = xQueueCreate(2, sizeof(uint32_t));

    //start gpio task
    xTaskCreatePinnedToCore(gpio_handler_task, "gpio_handler_task", 2048, NULL, 10, gpio_task, 0);

    //install gpio isr service
    gpio_install_isr_service(ESP_INTR_FLAG_DEFAULT);

    // remove existing handler that may be present
    gpio_isr_handler_remove(GPIO_NUM_0);

    //hook isr handler for specific gpio pin
    gpio_isr_handler_add(GPIO_NUM_0, gpio_isr_handler, (void*) GPIO_NUM_0);
}

Code: Select all

static void init_i2s(renderer_config_t *config)
{

    i2s_config_t i2s_config = {
            .mode = I2S_MODE_MASTER | I2S_MODE_TX,          // Only TX
            .sample_rate = config->sample_rate,
            .bits_per_sample = config->bit_depth,
            .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,   // 2-channels
            .communication_format = I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB,
            .dma_buf_count = 14,                            // number of buffers, 128 max.
            .dma_buf_len = 32 * 2,                          // size of each buffer
            .intr_alloc_flags = ESP_INTR_FLAG_LEVEL1        // Interrupt level 1
    };

    i2s_pin_config_t pin_config = {
            .bck_io_num = 26,
            .ws_io_num = 25,
            .data_out_num = 22,
            .data_in_num = I2S_PIN_NO_CHANGE    // Not used
    };

    i2s_driver_install(config->i2s_num, &i2s_config, 0, NULL);
    i2s_set_pin(config->i2s_num, &pin_config);
}

Code: Select all

Guru Meditation Error of type LoadProhibited occurred on core  0. Exception was unhandled.
Register dump:
PC      : 0x400811de  PS      : 0x00060733  A0      : 0x8010ea35  A1      : 0x3ffec030
A2      : 0x3ffb4b74  A3      : 0x00060720  A4      : 0x40082db4  A5      : 0x3ffd8594
A6      : 0x3ffd85b0  A7      : 0x3ffd7d28  A8      : 0x000e0b00  A9      : 0x3ffec010
A10     : 0x3ffb1360  A11     : 0x00060723  A12     : 0x00000000  A13     : 0x00000000
A14     : 0x40082db4  A15     : 0x3ffd8594  SAR     : 0x00000008  EXCCAUSE: 0x0000001c
EXCVADDR: 0x000e0b00  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xfffffffb

Backtrace: 0x400811de:0x3ffec030 0x4010ea35:0x3ffec050 0x4010ef9f:0x3ffec070 0x4010d078:0x3ffec0a0 0x4010d221:0x3ffec0f0 
0x4010d020:0x3ffec110 0x4010cce4:0x3ffec130 0x40111c50:0x3ffec150 0x4010cc41:0x3ffec180 0x401168dc:0x3ffec1a0 0x4011b3f2:0x3ffec200 0x4011b44c:0x3ffec420

0x400811de: esp_intr_disable at /git/esp-idf/components/esp32/./intr_alloc.c:621
0x40082db4: i2s_intr_handler_default at /git/esp-idf/components/driver/./i2s.c:751
0x40082db4: i2s_intr_handler_default at /git/esp-idf/components/driver/./i2s.c:751
0x400811de: esp_intr_disable at /git/esp-idf/components/esp32/./intr_alloc.c:621
0x4010ea35: i2s_stop at /git/esp-idf/components/driver/./i2s.c:751
0x4010ef9f: i2s_driver_install at /git/esp-idf/components/driver/./i2s.c:751

BuddyCasino
Posts: 263
Joined: Sun Jun 19, 2016 12:00 am

Re: GPIO conflicts with I2S interrupt

Postby BuddyCasino » Thu Apr 20, 2017 9:28 pm

Not sure if there are no replies because I made a very obvious mistake or if it is hard to tell whats happening?

Forgot to include the ISR handler:

Code: Select all

static void IRAM_ATTR gpio_isr_handler(void* arg)
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;

    uint32_t gpio_num = (uint32_t) arg;
    xQueueSendToBackFromISR(gpio_evt_queue, &gpio_num, &xHigherPriorityTaskWoken);

    if(xHigherPriorityTaskWoken) {
        portYIELD_FROM_ISR();
    }
}

Hans Dorn
Posts: 62
Joined: Tue Feb 21, 2017 2:21 am

Re: GPIO conflicts with I2S interrupt

Postby Hans Dorn » Thu Apr 20, 2017 10:35 pm

You sent the address of gpio_num instead of it's value to the event queue.

I'm pretty sure that's not what you wanted ;)

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: GPIO conflicts with I2S interrupt

Postby ESP_Angus » Fri Apr 21, 2017 2:11 am

Hans Dorn wrote:You sent the address of gpio_num instead of it's value to the event queue.
This should be OK. Queues take a pointer to the data to send, in this case sending the address of gpio_num will cause the 4 bytes at that address to be copied into the queue. Presumably the other end of the queue does the same thing.
BuddyCasino wrote: Not sure if there are no replies because I made a very obvious mistake or if it is hard to tell whats happening?
I don't see any problems in the parts of you code you posted.

Do you get any other meaningful log output before the crash?

What version of IDF are you using? The line numbers in the decoded crash dump don't seem to line up with the IDF master branch or the V2.0 release.

Angus

BuddyCasino
Posts: 263
Joined: Sun Jun 19, 2016 12:00 am

Re: GPIO conflicts with I2S interrupt

Postby BuddyCasino » Fri Apr 21, 2017 6:35 am

Heres the traceback I get on the console with the current SDK:

Code: Select all

Guru Meditation Error of type LoadProhibited occurred on core  0. Exception was unhandled.
Register dump:
PC      : 0x40081236  PS      : 0x00060633  A0      : 0x8010ef99  A1      : 0x3ffdfa50
A2      : 0x3ffb4ccc  A3      : 0x00060620  A4      : 0x400833f0  A5      : 0x3ffcad94
A6      : 0x3ffcadb0  A7      : 0x3ffcae70  A8      : 0x000e0b00  A9      : 0x3ffdfa30
A10     : 0x3ffb1360  A11     : 0x00060623  A12     : 0x00000000  A13     : 0x00000000
A14     : 0x400833f0  A15     : 0x3ffcad94  SAR     : 0x00000004  EXCCAUSE: 0x0000001c
EXCVADDR: 0x000e0b00  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xfffffffb

Backtrace: 0x40081236:0x3ffdf8c0 0x4010efd1:0x3ffdf8e0 0x4010f53b:0x3ffdf900 0x4010d45c:0x3ffdf930 0x4010d625:0x3ffdf980 0x4010d404:0x3ffdf9a0 0x4010cf4c:0x3ffdf9c0 0x40112948:0x3ffdf9e0 0x4010cdf9:0x3ffdfa10 0x401186b4:0x3ffdfa30 0x4011d2cf:0x3ffdfa90 0x4010d2a9:0x3ffdfcb0 0x4010d304:0x3ffdfd20

0x40082e90: i2s_intr_handler_default at /Users/michaelboeckling/git/esp-idf/components/driver/./i2s.c:751
0x40082e90: i2s_intr_handler_default at /Users/michaelboeckling/git/esp-idf/components/driver/./i2s.c:751
0x40081236: esp_intr_disable at /Users/michaelboeckling/git/esp-idf/components/esp32/./intr_alloc.c:621
0x4010efd1: i2s_stop at /Users/michaelboeckling/git/esp-idf/components/driver/./i2s.c:751
0x4010f53b: i2s_driver_install at /Users/michaelboeckling/git/esp-idf/components/driver/./i2s.c:751
0x4010d45c: init_i2s at /Users/michaelboeckling/Documents/eclipse/esp8266/ESP32_Alexa/components/audio_renderer/./audio_renderer.c:74
The line numbers aren't correct though. Here is the same via JTAG debugger, with more reasonable line numbers:

Code: Select all

Thread #1 1073522864 (_handler_ta : Running) (Suspended : Signal : SIGTRAP:Trace/breakpoint trap)	
	esp_intr_disable() at intr_alloc.c:668 0x40081236	
	i2s_stop() at i2s.c:353 0x4010ef99	
	i2s_driver_install() at i2s.c:612 0x4010f503	
	init_i2s() at audio_renderer.c:73 0x4010d424	
	audio_renderer_init() at audio_renderer.c:218 0x4010d5ed	
	audio_player_init() at audio_player.c:70 0x4010d3cc	
	on_header_value() at alexa.c:190 0x4010cf14	
	multipart_parser_execute() at multipart_parser.c:200 0x40112910	
	recv_callback() at alexa.c:530 0x4010cdc1	
	nghttp2_session_mem_recv() at nghttp2_session.c:6.459 0x4011867c	
	read_write_loop() at nghttp2_client.c:732 0x4011d297	
	send_speech() at alexa.c:751 0x4010d271	
	alexa_gpio_handler_task() at alexa.c:769 0x4010d2cc	
Variables:

Code: Select all

handle	intr_handle_t	0x3ffb4ccc	
	vector_desc	vector_desc_t *	0x0	
		flags	int	0	
		cpu	unsigned int	0	
		intno	unsigned int	0	
		source	int	0	
		shared_vec_info	shared_vector_desc_t *	0x0	
		next	vector_desc_t *	0x0	
	shared_vector_desc	shared_vector_desc_t *	0x0	
		disabled	int	0	
		source	int	0	
		statusreg	volatile uint32_t *	0x0	
		statusmask	uint32_t	0	
		isr	intr_handler_t	0x0	
		arg	void *	0x0	
		next	shared_vector_desc_t *	0x0	
source	int	<optimized out>	
Registers:

Code: Select all

General Registers	General Purpose and FPU Register Group	
	pc	0x40081236 <esp_intr_disable+18>	
	ar0	-2146942294	
	ar1	1073609312	
	ar2	3	
	ar3	395299	
	ar4	1072955392	
	ar5	125	
	ar6	470958080	
	ar7	0	
	ar8	-2146950280	
	ar9	1073609216	
	ar10	1073523712	
	ar11	396835	
	ar12	396835	
	ar13	-2130706433	
	ar14	1073608800	
	ar15	2	
	ar16	-2146928304	
	ar17	1073609184	
	ar18	128	
	ar19	1073523704	
	ar20	1073421388	
	ar21	0	
	ar22	10	
	ar23	1073609472	
	ar24	-2146380764	
	ar25	1073609456	
	ar26	0	
	ar27	1073609504	
	ar28	0	
	ar29	0	
	ar30	2	
	ar31	1073609424	
	ar32	-2146372349	
	ar33	1073609424	
	ar34	0	
	ar35	1073442004	
	ar36	1073421604	
	ar37	1073523756	
	ar38	0	
	ar39	0	
	ar40	-2146373735	
	ar41	1073609392	
	ar42	1073433804	
	ar43	395296	
	ar44	1074279408	
	ar45	1073523756	
	ar46	1073523784	
	ar47	1073524288	
	ar48	920320	
	ar49	1073609360	
	ar50	1073419104	
	ar51	395299	
	ar52	0	
	ar53	0	
	ar54	1074279408	
	ar55	1073523756	
	ar56	1	
	ar57	1073439064	
	ar58	1073419104	
	ar59	395299	
	ar60	1073427278	
	ar61	1073609104	
	ar62	0	
	ar63	1	
	lbeg	1073747197	
	lend	1073747213	
	lcount	4294967291	
	sar	4	
	windowbase	10	
	windowstart	1024	
	configid0	3267166206	
	configid1	482737814	
	ps	395299	
	threadptr	0	
	br	0	
	scompare1	3007315967	
	acclo	0	
	acchi	0	
	m0	0	
	m1	0	
	m2	0	
	m3	0	
	expstate	0	
	f64r_lo	0	
	f64r_hi	0	
	f64s	0	
	f0	0	
	f1	0	
	f2	0	
	f3	0	
	f4	0	
	f5	0	
	f6	0	
	f7	0	
	f8	0	
	f9	0	
	f10	0	
	f11	0	
	f12	0	
	f13	0	
	f14	0	
	f15	0	
	fcr	0	
	fsr	0	
	mmid	0	
	ibreakenable	0	
	memctl	0	
	atomctl	0	
	ddr	0	
	ibreaka0	0	
	ibreaka1	0	
	dbreaka0	0	
	dbreaka1	0	
	dbreakc0	0	
	dbreakc1	0	
	epc1	0	
	epc2	0	
	epc3	0	
	epc4	0	
	epc5	0	
	epc6	0	
	epc7	0	
	depc	0	
	eps2	0	
	eps3	0	
	eps4	0	
	eps5	0	
	eps6	0	
	eps7	0	
	excsave1	0	
	excsave2	0	
	excsave3	0	
	excsave4	0	
	excsave5	0	
	excsave6	0	
	excsave7	0	
	cpenable	0	
	interrupt	0	
	intset	0	
	intclear	0	
	intenable	0	
	vecbase	0	
	exccause	0	
	debugcause	0	
	ccount	0	
	prid	0	
	icount	0	
	icountlevel	0	
	excvaddr	0	
	ccompare0	0	
	ccompare1	0	
	ccompare2	0	
	misc0	0	
	misc1	0	
	misc2	0	
	misc3	0	
	a0	-2146373735	
	a1	1073609392	
	a2	1073433804	
	a3	395296	
	a4	1074279408	
	a5	1073523756	
	a6	1073523784	
	a7	1073524288	
	a8	920320	
	a9	1073609360	
	a10	1073419104	
	a11	395299	
	a12	0	
	a13	0	
	a14	1074279408	
	a15	1073523756	
	b0	0	
	b1	0	
	b2	0	
	b3	0	
	b4	0	
	b5	0	
	b6	0	
	b7	0	
	b8	0	
	b9	0	
	b10	0	
	b11	0	
	b12	0	
	b13	0	
	b14	0	
	b15	0	
	psintlevel	3	
	psum	1	
	pswoe	1	
	psexcm	0	
	pscallinc	2	
	psowb	8	
	acc	0	
	dbnum	0	
	f64r	0	
	roundmode	0	
	invalidenable	0	
	divzeroenable	0	
	overflowenable	0	
	underflowenable	0	
	inexactenable	0	
	invalidflag	0	
	divzeroflag	0	
	overflowflag	0	
	underflowflag	0	
	inexactflag	0	
	fpreserved20	0	
	fpreserved20a	0	
	fpreserved5	0	
The error only happens when the action is triggered by the GPIO button, it works fine when run of the main thread.

Who is online

Users browsing this forum: Baidu [Spider] and 250 guests