ESP32-S3 Multiple I2s Instances exhausts interrupt resources

JP5654
Posts: 17
Joined: Fri Jul 07, 2023 11:50 pm

ESP32-S3 Multiple I2s Instances exhausts interrupt resources

Postby JP5654 » Sat Jul 08, 2023 4:34 pm

I'm currently using ESP-IDF v5.1. My application is running on ESP32-S3. When registering two instances of i2s_tdm, it cannot allocate the interrupt for the second rx_event. The error message is as follows:

Code: Select all

E (508) gdma: gdma_install_rx_interrupt(776): alloc interrupt failed
E (508) gdma: gdma_register_rx_event_callbacks(436): install interrupt service failed

My application is pretty simple so far. I am using 2 i2c interfaces, 2 i2s interfaces, gptimer and gpio isr. Maybe I am exhausting all of the available interrupts but why is there not an option in the i2s driver to initialize shared interrupts? I have noticed that the i2s driver calls i2s_init_dma_intr(handle, I2S_INTR_ALLOC_FLAGS) where I2S_INTR_ALLOC_FLAGS defines ESP_INTR_FLAG_SHARED but these flags are not used when calling this api with the esp32-s3 because on the s3 platform SOC_GDMA_SUPPORTED is defines. This results in a call to gdma_install_rx_interrupt() to configure the gdma interrupts but this does not use the ESP_INTR_FLAG_SHARED flag.

What can I do to get around this problem without modifying the esp-idf?

A sample project exhibiting the problem is attached. Thank you.
Attachments
i2s_tdm.zip
(48.95 KiB) Downloaded 4919 times

ESP_Sprite
Posts: 9764
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32-S3 Multiple I2s Instances exhausts interrupt resources

Postby ESP_Sprite » Sun Jul 09, 2023 1:42 am

Could be interrupt exhaustion, indeed. I think it's a bug the interrupt flags aren't used; I'll see if I can file an issue for that. In the mean time, can you add the ESP_INTR_FLAG_SHARED flag to other peripherals, e.g. the two I2C interfaces? This should free op an interrupt for the I2S to use.

JP5654
Posts: 17
Joined: Fri Jul 07, 2023 11:50 pm

Re: ESP32-S3 Multiple I2s Instances exhausts interrupt resources

Postby JP5654 » Sun Jul 09, 2023 3:34 pm

Thank you for the quick response. In the meantime I will run the other peripherals with ESP_INTR_FLAG_SHARED, that does fix the issue for now. Please let me know when you file an issue so I can follow along with it's progress. Thanks!

JP5654
Posts: 17
Joined: Fri Jul 07, 2023 11:50 pm

Re: ESP32-S3 Multiple I2s Instances exhausts interrupt resources

Postby JP5654 » Mon Jul 10, 2023 6:47 pm

I guess one follow on question, how could I be exhausting all interrupts already? I enabled DEBUG_INT_ALLOC_DECISIONS to take a look at the allocations. At startup there are already only 12 level interrupts available, is that really correct? Why are so many of the interrupts listed as "reserved"? I haven't found any documentation that describes any of these reserved interrupts. Is there something I could configure to get access to more of these interrupts?

Below is the output from DEBUG_INT_ALLOC_DECISIONS before app_main runs:

Code: Select all

D (272) intr_alloc: get_available_int: try to find existing. Cpu: 0, Source: 39

D (272) intr_alloc: get_free_int: start looking. Current cpu: 0

D (272) intr_alloc: Int 0 reserved 2 priority 1 LEVEL hasIsr 0

D (273) intr_alloc: ....Unusable: reserved

D (273) intr_alloc: Int 1 reserved 2 priority 1 LEVEL hasIsr 0

D (273) intr_alloc: ....Unusable: reserved

D (273) intr_alloc: Int 2 reserved 0 priority 1 LEVEL hasIsr 0

D (274) intr_alloc: Int 3 reserved 0 priority 1 LEVEL hasIsr 0

D (274) intr_alloc: ...worse than int 2

D (274) intr_alloc: Int 4 reserved 2 priority 1 LEVEL hasIsr 0

D (274) intr_alloc: ....Unusable: reserved

D (274) intr_alloc: Int 5 reserved 2 priority 1 LEVEL hasIsr 0

D (275) intr_alloc: ....Unusable: reserved

D (275) intr_alloc: Int 6 reserved 0 priority 1 EDGE hasIsr 0

D (275) intr_alloc: ....Unusable: special-purpose int

D (275) intr_alloc: Int 7 reserved 0 priority 1 EDGE hasIsr 0

D (276) intr_alloc: ....Unusable: special-purpose int

D (276) intr_alloc: Int 8 reserved 2 priority 1 LEVEL hasIsr 0

D (276) intr_alloc: ....Unusable: reserved

D (276) intr_alloc: Int 9 reserved 0 priority 1 LEVEL hasIsr 0

D (276) intr_alloc: ...worse than int 2

D (277) intr_alloc: Int 10 reserved 0 priority 1 EDGE hasIsr 0

D (277) intr_alloc: ....Unusable: incompatible trigger type

D (277) intr_alloc: Int 11 reserved 0 priority 3 EDGE hasIsr 0

D (277) intr_alloc: ....Unusable: special-purpose int

D (278) intr_alloc: Int 12 reserved 0 priority 1 LEVEL hasIsr 0

D (278) intr_alloc: ...worse than int 2

D (278) intr_alloc: Int 13 reserved 0 priority 1 LEVEL hasIsr 0

D (278) intr_alloc: ...worse than int 2

D (278) intr_alloc: Int 14 reserved 2 priority 7 LEVEL hasIsr 0

D (279) intr_alloc: ....Unusable: reserved

D (279) intr_alloc: Int 15 reserved 0 priority 3 EDGE hasIsr 0

D (279) intr_alloc: ....Unusable: special-purpose int

D (279) intr_alloc: Int 16 reserved 0 priority 5 EDGE hasIsr 0

D (280) intr_alloc: ....Unusable: special-purpose int

D (280) intr_alloc: Int 17 reserved 0 priority 1 LEVEL hasIsr 0

D (280) intr_alloc: ...worse than int 2

D (280) intr_alloc: Int 18 reserved 0 priority 1 LEVEL hasIsr 0

D (280) intr_alloc: ...worse than int 2

D (281) intr_alloc: Int 19 reserved 0 priority 2 LEVEL hasIsr 0

D (281) intr_alloc: ...worse than int 2

D (281) intr_alloc: Int 20 reserved 0 priority 2 LEVEL hasIsr 0

D (281) intr_alloc: ...worse than int 2

D (281) intr_alloc: Int 21 reserved 0 priority 2 LEVEL hasIsr 0

D (282) intr_alloc: ...worse than int 2

D (282) intr_alloc: Int 22 reserved 2 priority 3 EDGE hasIsr 0

D (282) intr_alloc: ....Unusable: reserved

D (282) intr_alloc: Int 23 reserved 0 priority 3 LEVEL hasIsr 0

D (282) intr_alloc: ...worse than int 2

D (283) intr_alloc: Int 24 reserved 2 priority 4 LEVEL hasIsr 0

D (283) intr_alloc: ....Unusable: reserved

D (283) intr_alloc: Int 25 reserved 2 priority 4 LEVEL hasIsr 0

D (283) intr_alloc: ....Unusable: reserved

D (283) intr_alloc: Int 26 reserved 0 priority 5 LEVEL hasIsr 0

D (284) intr_alloc: ....Unusable: incompatible priority

D (284) intr_alloc: Int 27 reserved 2 priority 3 LEVEL hasIsr 0

D (284) intr_alloc: ....Unusable: reserved

D (284) intr_alloc: Int 28 reserved 0 priority 4 EDGE hasIsr 0

D (285) intr_alloc: ....Unusable: incompatible priority

D (285) intr_alloc: Int 29 reserved 0 priority 3 EDGE hasIsr 0

D (285) intr_alloc: ....Unusable: special-purpose int

D (285) intr_alloc: Int 30 reserved 2 priority 4 EDGE hasIsr 0

D (285) intr_alloc: ....Unusable: reserved

D (285) intr_alloc: Int 31 reserved 2 priority 5 LEVEL hasIsr 0

D (286) intr_alloc: ....Unusable: reserved

ESP_Sprite
Posts: 9764
Joined: Thu Nov 26, 2015 4:08 am

Re: ESP32-S3 Multiple I2s Instances exhausts interrupt resources

Postby ESP_Sprite » Tue Jul 11, 2023 2:24 am

That is a very good question and I'm raising some internal issues about this. Seems for devs it's easier to mark an interrupt as 'reserved' than figure out if interrupts still need to be reserved and un-reserve it if it's not needed anymore; I'm decently sure a fair amount of them can be freed up but I unfortunately can't tell you which ones at this point. Thank you for pointing this out.

chriscckan
Posts: 6
Joined: Tue Sep 05, 2023 8:51 am

Re: ESP32-S3 Multiple I2s Instances exhausts interrupt resources

Postby chriscckan » Fri Jan 19, 2024 3:07 pm

I have exactly the same problem about running out of interrupt on ESP32S3. But there is no such example about sharing interrupt in the example folder of ESP IDF. The online ESP IDF document "Interrupt allocation" chapter is far not sufficient to clarify the use of share interrupt.
I look into some driver code it is calling some low level API to setup/share interrupt. But just no example to clearly show how we can resolve this problem by sharing interrupt. Pls help.

JP5654
Posts: 17
Joined: Fri Jul 07, 2023 11:50 pm

Re: ESP32-S3 Multiple I2s Instances exhausts interrupt resources

Postby JP5654 » Fri Jan 19, 2024 5:46 pm

If you are setting up your own interrupt and want it to be a shared interrupt you can just pass ESP_INTR_FLAG_SHARED for flags to:

Code: Select all

esp_intr_alloc(int source, int flags, intr_handler_t handler, void *arg, intr_handle_t *ret_handle)
If you are using a driver and want it to setup its interrupts as shared, most (but not all) drivers provide an api that allows you to specify the interrupts it sets up as shared. In most drivers it's done by passing ESP_INTR_FLAG_SHARED for intr_alloc_flags. For example, i2c driver:

Code: Select all

i2c_driver_install(i2c_hw_instance, I2C_MODE_MASTER, 0, 0,ESP_INTR_FLAG_SHARED);

Who is online

Users browsing this forum: No registered users and 6 guests