Description
Board
ESP32 NodeMCU
Device Description
(irrelevant for issue)
Hardware Configuration
(irrelevant for issue)
Version
v2.0.4
IDE Name
Arduino IDE
Operating System
Windows 10
Flash frequency
80MHz
PSRAM enabled
no
Upload speed
921600
Description
When going to this part of the code
arduino-esp32/libraries/I2S/src/I2S.cpp
Line 156 in 3cb73dc
then it causes the value of
_bitsPerSample
to change to 0.
This later causes this assertion to fail:
https://github.com/espressif/esp-idf/blob/1b16ef6cfc2479a08136782f9dc57effefa86f66/components/esp_ringbuf/ringbuf.c#L874
That part of the code is called from here:
arduino-esp32/libraries/I2S/src/I2S.cpp
Lines 297 to 298 in 3cb73dc
I attached a debugger (Segger J-Link via steps defined here, basically using USBDriverTool to change J-Link driver to WinUSB, then using openocd -f interface/jlink.cfg -c "adapter_khz 1000" -f board/esp-wroom-32.cfg
, then connecting using gdb supplied in esp-idf 4.4.2) to get to the root of this, and got so far as to find out that the actual change seems to happen in this function:
https://github.com/espressif/esp-idf/blob/1b16ef6cfc2479a08136782f9dc57effefa86f66/components/hal/esp32/include/hal/i2s_ll.h#L920-L930
(gdb) p/x &_bitsPerSample
$2 = 0x3ffc14f4
(gdb) watch *0x3ffc14f4
Hardware watchpoint 2: *0x3ffc14f4
(gdb) display *((int32_t *)0x3ffc14f4)
3: *((int32_t *)0x3ffc14f4) = 24
(gdb) c
Thread 1 received signal SIGTRAP, Trace/breakpoint trap.
0x400de3b0 in i2s_ll_enable_builtin_adc (enable=false, hw=<optimized out>) at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/hal/esp32/include/hal/i2s_ll.h:929
929 /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/hal/esp32/include/hal/i2s_ll.h: No such file or directory.
3: *((int32_t *)0x3ffc14f4) = 24
(gdb) s
i2s_hal_config_param (hal=0x3ffb9998, hal_cfg=0x3ffb99a4) at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/hal/i2s_hal.c:299
299 /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/hal/i2s_hal.c: No such file or directory.
3: *((int32_t *)0x3ffc14f4) = 0
(this shows L929 as offender, but that's strange to me, setting to 0 seems incorrect for this? https://github.com/espressif/esp-idf/blob/1b16ef6cfc2479a08136782f9dc57effefa86f66/components/hal/esp32/include/hal/i2s_ll.h#L929)
Sketch
~~~c++
#include <I2S.h>
I2SClass I2S1(1 /*I2S1*/, 0 /*as in I2S.c*/, PIN_I2S1_SD, PIN_I2S1_SCK, PIN_I2S1_FS); // global variable
// in setup
I2S1.begin(I2S_PHILIPS_MODE, 16000, 24);
~~~
Debug Message
(None, Hard Reset)
Other Steps to Reproduce
No response
I have checked existing issues, online documentation and the Troubleshooting Guide
- I confirm I have checked existing issues, online documentation and Troubleshooting guide.
Metadata
Metadata
Assignees
Type
Projects
Status
Activity
musteresel commentedon Aug 10, 2022
edit: The parameters of the function call only become valid after stepping once into the function, so what we see here is a GDB usage error on my side
Adding to this, I just looked up how the call stack looks like whenI2S
(the "default" one on I2S0) has itsbegin
called, breaking atxRingbufferCreate
where the assertion with the other instance fails.Backtrace:
What I find strange is that there's the call
xRingbufferCreate (xBufferSize=1073485104, xBufferType=RINGBUF_TYPE_ALLOWSPLIT)
... but (first parameter)_buffer_byte_size == 1536
and the second parameter also does not match with what we see in the source (at tag 2.0.4):arduino-esp32/libraries/I2S/src/I2S.cpp
Line 298 in c93bf11
To me this looks like a garbled stack.musteresel commentedon Aug 10, 2022
From the linker map:
From a backtrack:
Note that
hal=0x3ffb9998
is outside of the heap!But ...
https://github.com/espressif/esp-idf/blob/1b16ef6cfc2479a08136782f9dc57effefa86f66/components/driver/i2s.c#L1972
i2s_hal_config_param(&(pre_alloc_i2s_obj->hal), &pre_alloc_i2s_obj->hal_cfg);
... and ...
... therefore
pre_alloc_i2s_obj
and its memberhal
are heap allocated, but outside of the heap memory region.But they're inside ...
the data section ...
musteresel commentedon Aug 11, 2022
Short note ... renaming
I2SClass I2S1
toI2SClass I2S1_
to avoid (potentially?) wrong linkage (withI2S1
being the actual hardware; memory mapped) surprisingly helps; setting up the second I2S this way "works" .. but the input queue never fills, meaning the DMA tx done is never called. No idea why.Not using I2S0 at the same time doesn't help, either.
PilnyTomas commentedon Aug 12, 2022
I think I might have a lead:
I2S._onTransferComplete();
I will fix that as soon as possible.
But that solves only 2nd half of the problem - still getting
bitsPerSample == 0
after callingi2s_driver_install
- this one seems more like IDF bug.musteresel commentedon Aug 12, 2022
Ah yes, that makes sense as to why the input queue doesn't fill.
Did you have the issue with
bitsPerSample
being written from within IDF code also after renaming (or not using the name)I2S1
(which is the same name as the peripheral) ? I honestly did not check this, but assumed that fixed it (because I then got past the assertion mentioned above).PilnyTomas commentedon Aug 12, 2022
No, different name seems to work.
PilnyTomas commentedon Nov 9, 2022
Please try out the changes in the mentioned PR #7117 I have renamed the second I2S to
I2S_1
The PR will be merged after testing.
2 remaining items