Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crashes on ESP32 when using interrupts #45

Closed
danclarke opened this issue May 3, 2018 · 19 comments
Closed

Crashes on ESP32 when using interrupts #45

danclarke opened this issue May 3, 2018 · 19 comments

Comments

@danclarke
Copy link

  • Arduino board: WeMos (not really) ESP32 R2, basically generic ESP32
  • Arduino IDE version: 1.8.5

The interrupt-based playback does not work on ESP32, calling the SD library from within an interrupt handler seems to cause an almost immediate crash. The exception stack trace is as follows:

0x400812f5: lock_acquire_generic at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/newlib/./locks.c line 141
0x40087754: invoke_abort at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/esp32/./panic.c line 648
0x4008792f: abort at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/esp32/./panic.c line 648
0x400812f5: lock_acquire_generic at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/newlib/./locks.c line 141
0x40081415: _lock_acquire_recursive at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/newlib/./locks.c line 169
0x400da302: _fread_r at /Users/ivan/e/newlib_xtensa-2.2.0-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/stdio/../../../.././newlib/libc/stdio/fread.c line 194 (discriminator 2)
0x400da3c9: fread at /Users/ivan/e/newlib_xtensa-2.2.0-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/stdio/../../../.././newlib/libc/stdio/fread.c line 301
0x400d280b: VFSFileImpl::read(unsigned char*, unsigned int) at c:\users\dancl\documents\arduino\hardware\espressif\esp32\tools\xtensa-esp32-elf\xtensa-esp32-elf\include\c++\5.2.0\bits/shared_ptr_base.h line 127 (discriminator 1)
0x400ec6e7: fs::File::read(unsigned char*, unsigned int) at C:\Users\dancl\Documents\Arduino\hardware\espressif\esp32\libraries\FS\src/FS.cpp line 258
0x400d1314: Adafruit_VS1053_FilePlayer::feedBuffer_noLock() at C:\Users\dancl\Documents\Arduino\libraries\Adafruit_VS1053_Library/Adafruit_VS1053.cpp line 737 (discriminator 1)
0x400d1355: Adafruit_VS1053_FilePlayer::feedBuffer() at C:\Users\dancl\Documents\Arduino\libraries\Adafruit_VS1053_Library/Adafruit_VS1053.cpp line 737 (discriminator 1)
0x400d1368: feeder() at C:\Users\dancl\Documents\Arduino\libraries\Adafruit_VS1053_Library/Adafruit_VS1053.cpp line 737 (discriminator 1)
0x40080ddd: __onPinInterrupt at C:\Users\dancl\Documents\Arduino\hardware\espressif\esp32\cores\esp32/esp32-hal-gpio.c line 211
0x400817d9: _xt_lowint1 at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/./xtensa_vectors.S line 1105
0x400dbc63: esp_vApplicationIdleHook at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/esp32/./freertos_hooks.c line 85

I've done a quick test where the interrupt handler sets a flag, letting the main loop know to populate the buffer and that works fine. I'm pretty sure I can set up a solution using a separate task to just feed the buffer as and when with maybe a larger memory buffer to cater for the extra latency. Of course this will be super ESP32 specific and couldn't be integrated back into the library.

@danclarke
Copy link
Author

Small update - I got it working with some very small amends to the library, the task can be created transparently within the library itself. I'll continue testing and create a PR if I'm happy with how it works.

@brandondixon
Copy link

@danclarke I was about to dive into this problem. Do you have any working code? I would love to help test/debug.

@danclarke
Copy link
Author

@brandondixon I do, I've put a fork up here: https://github.com/danclarke/Adafruit_VS1053_Library

In my specific application I was getting some odd behaviour, but it could be power related. I've tried with some much more advanced workarounds and changes, and they seem to get progressively worse than the simple code I've uploaded. Sadly I haven't had the time to fully investigate.

@TheNitek
Copy link
Contributor

TheNitek commented May 9, 2018

Why do you want to use interrupts when you have to feed the buffer in the main loop anyway?

Something like

void loop() {
  if (musicPlayer.playingMusic) {
    musicPlayer.feedBuffer();
  }
}

will do fine without any interrupts.

The main Problem is that the ESP8266 and ESP32 do not support this function: https://www.arduino.cc/en/Reference/SPIusingInterrupt
This makes SPI communication and interrupts a hassle.

@brandondixon
Copy link

I'm stuck using an ESP32 :(

@TheNitek
Copy link
Contributor

TheNitek commented May 9, 2018

There's nothing wrong using an ESP32, IMHO it's just easier not to use this library with interrupts on it, but with manual buffer feeding as shown in my previous post

@danclarke
Copy link
Author

@TheNitek It's so that you can play audio in the background while performing other tasks without having to worry about keeping the buffer fed manually.

Interestingly I created a task where the sole purpose is to call the feed method, and I still get the same audio corruption in the same place. I'm thinking it's due to how I'm using the audio files specifically so more investigation required. On the plus side, it behaved in an identical manner to my interrupt workaround.

@danclarke
Copy link
Author

Well I found the source of the audio corruption, seems my SD card was slowly getting more and more corrupted. Also I found wav files I was using to play very slightly less reliably than mp3. I don't think it's due to insufficient feeding of the buffer, but I don't know enought to say for certain. It was a slight lack of dynamic range rather than static.

Anyway if the workaround for the interrupt / SPI access works OK for others, I'll submit a PR.

@NitramLegov
Copy link

It works for me using the devkit1 board.
I would love to see this in the official library!

@paulmand3l
Copy link

Works for me on the Huzzah Esp32 feather. Thanks!

@eziya
Copy link

eziya commented Jun 16, 2019

Hello, I'm adding my modification link for who might run into same issue like me
https://github.com/eziya/ESP32_ADAFRUIT_VS1053

@bentwookie
Copy link

Is this going to be addressed? The stock sample code fails for me on a stock HUZZAH32 without the forked library.

@caternuson
Copy link
Contributor

The base issue here is in the ESP32 BSP. See here:
espressif/arduino-esp32#7211

The lack of ability to disable interrupts, combined with the DREQ pin behavior of the VS1053, ends up causing grief when trying to use interrupt based playback. The DREQ pin toggles for other reasons and fires the ISR when not expected. This eventually leads to a WDT reset or other behavior.

The approach in the @eziya fork is to essentially not use interrupts and rely on feeding the buffer in the sketch's loop().

@MarcHagen
Copy link

Yes @eziya fork works fine, but the main loop freezes at feedBuffer() .
So in my example button inputs are not working until the song is done playing (using startPlayingFile).

Also the sounds seems to pop from time to time :(

Anyone suggestions?

@caternuson
Copy link
Contributor

Try updating to the 2.0.5 release of the ESP32 BSP:
https://github.com/espressif/arduino-esp32/releases

The addition of support for noInterrupt() and interrupt() fixed interrupt based playback on ESP32 in our testing using this library and the feather_player example.

@MarcHagen
Copy link

MarcHagen commented Sep 21, 2022

@caternuson it seems im unable to get a stable output from the HUZZAH32 + VS1053 feather, nor the HUZZAH + VS1053 feather. It jitters and pops.
Both instances give me jitter sounds. File is a WAV 44100Hz at 16bit PCM.
Even with the feather_player example

@caternuson
Copy link
Contributor

Is that happening if the WAV file is played back with both playFullFile() and startPlayingFile()? Or is it just with startPlayingFile()?

@MarcHagen
Copy link

It seems to be both do the same. You almost say it the module or something but I’ve 3 audio feathers all with the same issue 😅

@caternuson
Copy link
Contributor

If it is also happening with playFullFile(), then it is unrelated to interrupt playback. Please open a new issue.

Closing this one for now since interrupt playback with startPlayingFile() is working in local testing with on ESP32.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

9 participants