NeoCat / ESP32-P3RGB64x32MatrixPanel

ESP32 Arduino library for the P3 64x32 RGB matrix panels
MIT License
136 stars 30 forks source link

Guru Meditation Error: Core 1 panic'ed (Cache disabled but cached memory region accessed) #4

Closed mrcodetastic closed 5 years ago

mrcodetastic commented 5 years ago

Hi NeoCat,

Fantastic work with your RGB library. It is very smart and clean in its implementation.

I was having all sorts of issues with an equivalent library https://github.com/2dom/PxMatrix/ in that it would cause a Core 1 panic whenever I had a project that either needed to use WiFi extensively, such as httpWebserver. However, the same thing would happen with your library as well!

Essentially, it seems it is impossible to use any of these interrupt-based implementations for pumping out data to the RGB panels, when you need to use WiFi or read anything from the flash at the same time. FYI - @2dom

Usual crash is something like:

Guru Meditation Error: Core  1 panic'ed (Cache disabled but cached memory region accessed)
Core 1 register dump:
PC      : 0x400e2c14  PS      : 0x00060034  A0      : 0x800816ac  A1      : 0x3ffc0bc0  
A2      : 0x00000000  A3      : 0x20000000  A4      : 0x00000400  A5      : 0x00060a20  
A6      : 0x00000001  A7      : 0x00000000  A8      : 0x80080f96  A9      : 0x3ffc0b90  
A10     : 0x3ffc50e8  A11     : 0x3ffb2034  A12     : 0x00000001  A13     : 0x00000001  
A14     : 0x00060021  A15     : 0x00000000  SAR     : 0x00000016  EXCCAUSE: 0x00000007  
EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xfffffffc  
Core 1 was running in ISR context:
EPC1    : 0x400825da  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x400e2c14

Backtrace: 0x400e2c14:0x3ffc0bc0 0x400816a9:0x3ffc0bf0 0x40081ba1:0x3ffc0c10 0x400825d7:0x00000000

Which using the ESP Exception Decoder, results in:

PC: 0x400e2c14: P3RGB64x32MatrixPanel::draw() at C:\Users\user\Documents\Arduino\libraries\ESP32-P3RGB64x32MatrixPanel-master\P3RGB64x32MatrixPanel.cpp line 82
EXCVADDR: 0x00000000

Decoding stack results
0x400e2c14: P3RGB64x32MatrixPanel::draw() at C:\Users\user\Documents\Arduino\libraries\ESP32-P3RGB64x32MatrixPanel-master\P3RGB64x32MatrixPanel.cpp line 82
0x400816a9: __timerISR at C:\Users\user\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.0\cores\esp32\esp32-hal-timer.c line 88
0x400825d7: spi_flash_disable_cache at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/soc/esp32/include/soc/dport_access.h line 172

After much fooling around. I fixed the issue by changing in P3RGB64x32MatrixPanel.cpp:

void P3RGB64x32MatrixPanel::draw() {

to

void IRAM_ATTR P3RGB64x32MatrixPanel::draw() {

and also adding the 'IRAM_ATTR' attribute to the corresponding shell in the .h file.

It appears it is not sufficient to only add the IRAM_ATTR flag to the onTimer() function.

NeoCat commented 5 years ago

Thank you very much for shooting this issue. It is known that this library hangs if the LED matrix is enabled during WiFI is establishing connection, but I haven't detected why this happens. I think you are totally right; IRAM_ATTR must be added to P3RGB64x32MatrixPanel::draw() since it is called in the interrupt handler.

If you are going to open a pull request for this, I will test and merge it. (Or I will modify the code by myself as you suggested if you don't care.)

mrcodetastic commented 5 years ago

Hello! Please feel free to make the change.

I'm confident this will resolve the issue. It's not just when using WiFi where things would break - Any time the flash needed to be accessed whilst the ISR is occurring (which is pretty often given it occurs a million times a second fr the RGB panel), it would crash.

My sketch used a combination of WiFiManager and Webserver, and for example, if I ever accessed by ESP32 via HTTP (which results in it reading a file of the SPIFFS Flash or even PROGMEM-based hard-coded string), there would be an immediate crash.

SDK seems to imply any ISR code must be stored in the IRAM using via the IRAM_ATTR flag. Ref: https://dl.espressif.com/doc/esp-idf/latest/api-reference/system/intr_alloc.html

Good thing I figured this one out otherwise the ESP32 would be useless for any of my projects... and any other methods of pumping out the pixels (even using a software timer), led to poor/flickery results.

On another note, can I request a feature? A crud 'brightness' setting/function whereby one can globally set/change the brightness? I suspect the easiest routine is to do some magic in the drawPixel function. I would like to be able to crudely dim the display without having to change all the colours.

NeoCat commented 5 years ago

OK, I will add the change, thanks.

About brightness.. I need some testing to realize that without losing color scale. Of course you can simply make a child class and overload drawPixel to multiply 1/2, but it will lose gradation scale by half.

mrcodetastic commented 5 years ago

Would something like this be of any use:

https://github.com/pixelmatix/esp32_I2sParallelDmaLedMatrix/blob/row-based-refresh/main/val2pwm.c

?