Your new topic does not fit any of the above??? Check first. Then post here. Thanks.

Moderator: igrr

User avatar
By Vicne
#50846 Me-no-dev, one more question if I may:

Your slave setup code sets the following bit:
Code: Select all    SPI1P = (1 << 19);

I can't find any reference to that bit in the include files nor anywhere else.
Could you tell me what it is about and why set it ? Do you have another reference that explains it ?

Kind regards,

Vicne
User avatar
By Vicne
#51162 Hi,
Integration of the HSPI slave is progressing but I'm now getting crashes when I try to access SPIFFS while HSPI slave is active. I would say 10-30% of the SPIFFS calls crash the ESP.
I'm trying to see what could be the conflicting code and I'm coming across this code in the _hspi_slave_isr_handler() function:
Code: Select all    else if(istatus & (1 << SPII0)) { //SPI0 ISR
        SPI0S &= ~(0x3ff);//clear SPI ISR
    }

So it seems we fiddle with SPI0 interrupt while we should only work on SPI1, right ?
I tried to comment out the line that clears the interrupt flag but it's even worse. Now each HSPI message crashes the ESP.

But is the interrupt handler really the same for both SPI0 and SPI1 ? in this case, shouldn't we pass control to the original SPI0 handler after handling HSPI-specific flags ?

Edit:
The typical dump I get is this:
Code: Select allFatal exception 0(IllegalInstructionCause):
epc1=0x402095f8, epc2=0x00000000, epc3=0x00000000, excvaddr=0x00000000, depc=0x00000000

Exception (0):
epc1=0x402095f8 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000

ctx: cont
sp: 3fff3110 end: 3fff3720 offset: 01a0

>>>stack>>>
3fff32b0:  00000000 00000000 0000001f 401057fd 
3fff32c0:  4000050c 00000019 7fffffff 4000050c 
3fff32d0:  400043a3 00000030 00000013 ffffffff 
3fff32e0:  60000200 00000004 ffffffff 80000000 
3fff32f0:  20000000 3fff5430 80000000 203e8040 
3fff3300:  00000000 ffffff80 00001a3b 3fff5434 
3fff3310:  000000c0 003e8040 003e8100 00000030 
3fff3320:  40203446 00000030 0000001b ffffffff 
3fff3330:  40203435 00000000 00000000 00000001 
3fff3340:  00007fff 00002e40 00000000 402033f0 
3fff3350:  0000000c 0000000c 00000000 3fff4568 
3fff3360:  00000100 3fff4da4 00002e4c 00000030 
3fff3370:  4000050c 3fff33b0 00000004 4000050c 
3fff3380:  40107061 00000030 0000001b ffffffff 
3fff3390:  402039d1 00000002 00001000 00000004 
3fff33a0:  00000012 00000000 00000000 00000080 
3fff33b0:  00000007 00000007 00000000 00000165 
3fff33c0:  00000000 400042db 3fff509a 00000030 
3fff33d0:  40004b31 3fff53e4 00000100 003e8000 
3fff33e0:  40105d62 3fff5194 00002710 402132b4 
3fff33f0:  40211a36 003e8000 00000100 3fff53e4 
3fff3400:  003e8100 003e8000 003e8000 40213f44 
3fff3410:  3fff4da4 00081000 3fff4568 40203468 
3fff3420:  3fff53e4 00000100 00001128 74732f01 
3fff3430:  3fff4568 3fff5194 003e8000 3fff53d0 
3fff3440:  3fff4568 3fff5194 003e8000 40205cd9 
3fff3450:  00000100 3fff508c 00000000 00000100 
3fff3460:  3fff53e4 00000100 3fff4cd4 00000100 
3fff3470:  3fff4568 002e8000 00000174 40203911 
3fff3480:  00000000 00000080 00000000 00000172 
3fff3490:  00000000 00000171 402033f0 00000000 
3fff34a0:  3fff508c 00000000 00000020 00000100 
3fff34b0:  0000001f 00000000 00000000 40202409 
3fff34c0:  00008046 643c00f8 00000552 3ffe8a74 
3fff34d0:  3fff3530 3fff3550 3fff4568 4020517a 
3fff34e0:  3fff4da4 00000000 3fff34f4 3fff34f0 
3fff34f0:  0000001e 00000173 0000001e 00100000 
3fff3500:  00002000 0000001d 3ffee2e0 3fff2618 
3fff3510:  00000010 3fff35e4 00000000 3ffe8a74 
3fff3520:  00000001 3fff3550 3fff4568 40202ecf 
3fff3530:  0000005e 3fff35d8 00000000 4010053d 
3fff3540:  00000010 3fff3744 3fff4564 40213936 
3fff3550:  3ffe0046 00000552 005e3501 646e692f 
3fff3560:  682e7865 00006d74 00000000 00000000 
3fff3570:  00000000 00000000 00000000 402124f3 
3fff3580:  3fff4da4 000003a0 000003a0 4010020c 
3fff3590:  00000001 00000000 3fff3610 40214885 
3fff35a0:  3ffe8a74 00000000 3fff3610 40211b10 
3fff35b0:  00000001 00000000 3fff3610 40208651 
3fff35c0:  00000000 00000000 00000000 402124f3 
3fff35d0:  00000010 3fff3660 3fff4da4 0000000f 
3fff35e0:  0000000d 3fff4d8c 0000000f 00000009 
3fff35f0:  3ffe8cdc 00000001 3fff3640 4020c148 
3fff3600:  00000001 00000001 3fff44dc 40208696 
3fff3610:  3fff3fe4 0000000f 0000000a 4010068c 
3fff3620:  00000000 00000030 3fff44dc 4020c13e 
3fff3630:  3fff44dc 3fff1b1c 3fff44dc 4020c17a 
3fff3640:  00000000 00000000 00000000 40212654 
3fff3650:  3fff44dc 3fff1b1c 3fff1adc 4020c209 
3fff3660:  3fff48fc 0000000f 00000001 3fff0080 
3fff3670:  3fff1b1c 0000009c 4021323c 00000001 
3fff3680:  00000001 4020b234 0000000f 4020118f 
3fff3690:  00000000 3fff0080 3fff03c4 3fff26f8 
3fff36a0:  00000001 3fff1b00 3fff1adc 4020c5c3 
3fff36b0:  3ffe9148 00000000 000003e8 3fff26f8 
3fff36c0:  3fffdad0 3fff03e4 3fff0080 4020fa14 
3fff36d0:  3fffdad0 3fff03e4 3fff23cc 40207ff7 
3fff36e0:  40207648 3fff4d8c 3fff3fdc feefeffe 
3fff36f0:  00000000 00000000 00000001 4021325d 
3fff3700:  3fffdad0 00000000 3fff26f1 40213288 
3fff3710:  feefeffe feefeffe 3fff2700 40100718 
<<<stack<<<

 ets Jan  8 2013,rst cause:2, boot mode:(3,6)

Which gets decoded as
Code: Select all0x402095f8: SPISlaveClass::_s_trans(void*, unsigned int) at C:\Users\Lab7\AppData\Local\Temp\build7764f69c4aedd653a2a4563ad0e03a44.tmp\sketch/SPISlave.cpp line 42
0x402095f8: SPISlaveClass::_s_trans(void*, unsigned int) at C:\Users\Lab7\AppData\Local\Temp\build7764f69c4aedd653a2a4563ad0e03a44.tmp\sketch/SPISlave.cpp line 42
0x401057fd: ets_timer_disarm at ?? line ?
0x40203446: spiffs_object_find_object_index_header_by_name_v at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\spiffs/spiffs_nucleus.c line 941
0x40203435: spiffs_object_find_object_index_header_by_name_v at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\spiffs/spiffs_nucleus.c line 941
0x402033f0: spiffs_object_find_object_index_header_by_name_v at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\spiffs/spiffs_nucleus.c line 941
0x40107061: __udivsi3 at d:\ivan\projects\arduinoesp\toolchain\dl\gcc-xtensa\build-2\xtensa-lx106-elf\libgcc/../../../libgcc/config/xtensa/lib1funcs.S line 536
0x402039d1: spiffs_obj_lu_find_entry_visitor at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\spiffs/spiffs_nucleus.c line 941
0x40105d62: spi_flash_read at ?? line ?
0x402132b4: __yield at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/core_esp8266_main.cpp line 56
0x40211a36: EspClass::flashRead(unsigned int, unsigned int*, unsigned int) at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/Esp.cpp line 519
0x40213f44: spiffs_hal_read(unsigned int, unsigned int, unsigned char*) at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/spiffs_hal.cpp line 67
0x40203468: spiffs_object_find_object_index_header_by_name_v at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\spiffs/spiffs_nucleus.c line 941
0x40205cd9: spiffs_phys_rd at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\spiffs/spiffs_cache.c line 145
0x40203911: spiffs_obj_lu_find_entry_visitor at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\spiffs/spiffs_nucleus.c line 941
0x402033f0: spiffs_object_find_object_index_header_by_name_v at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\spiffs/spiffs_nucleus.c line 941
0x40202409: spiffs_stat_pix at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\spiffs/spiffs_hydrogen.c line 980
0x4020517a: spiffs_object_find_object_index_header_by_name at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\spiffs/spiffs_nucleus.c line 1465
0x40202ecf: SPIFFS_stat at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\spiffs/spiffs_hydrogen.c line 980
0x4010053d: _umm_realloc at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1491
:  (inlined by) realloc at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1709
0x40213936: SPIFFSImpl::exists(char const*) at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/spiffs_api.cpp line 63
0x402124f3: String::reserve(unsigned int) at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/WString.cpp line 519
0x4010020c: _umm_free at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1287
0x40214885: fs::FS::exists(char const*) at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/FS.cpp line 214
0x40211b10: fs::FS::exists(String const&) at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/FS.cpp line 188
0x40208651: handleFileRead(String) at D:\Dropbox\Misc\electronique\Voocorder_hack\ESP_WebApiCombo_v10/ESP_WebApiCombo_v10.ino line 148
0x402124f3: String::reserve(unsigned int) at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/WString.cpp line 519
0x4020c148: FunctionRequestHandler::handle(ESP8266WebServer&, HTTPMethod, String) at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WebServer\src/ESP8266WebServer.cpp line 299
0x40208696: operator() at D:\Dropbox\Misc\electronique\Voocorder_hack\ESP_WebApiCombo_v10/ESP_WebApiCombo_v10.ino line 148
:  (inlined by) _M_invoke at c:\users\lab7\appdata\local\arduino15\packages\esp8266\tools\xtensa-lx106-elf-gcc\1.20.0-26-gb404fb9-2\xtensa-lx106-elf\include\c++\4.8.2/functional line 2071
0x4010068c: free at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266\umm_malloc/umm_malloc.c line 1733
0x4020c13e: std::function ::operator()() const at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WebServer\src/ESP8266WebServer.cpp line 299
0x4020c17a: FunctionRequestHandler::handle(ESP8266WebServer&, HTTPMethod, String) at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WebServer\src/ESP8266WebServer.cpp line 299
0x40212654: String::String(String const&) at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/WString.cpp line 519
0x4020c209: ESP8266WebServer::_handleRequest() at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WebServer\src/ESP8266WebServer.cpp line 299
0x4021323c: esp_yield at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/core_esp8266_main.cpp line 56
0x4020b234: FunctionRequestHandler::canHandle(HTTPMethod, String) at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WebServer\src/ESP8266WebServer.cpp line 299
0x4020118f: delay at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/core_esp8266_wiring.c line 50
0x4020c5c3: ESP8266WebServer::handleClient() at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\libraries\ESP8266WebServer\src/ESP8266WebServer.cpp line 299
0x4020fa14: WebSocketsServer::loop() at C:\Users\Lab7\Documents\Arduino\libraries\arduinoWebSockets-master\src/WebSocketsServer.cpp line 118
0x40207ff7: loop at D:\Dropbox\Misc\electronique\Voocorder_hack\ESP_WebApiCombo_v10/ESP_WebApiCombo_v10.ino line 148
0x40207648: _M_invoke at D:\Dropbox\Misc\electronique\Voocorder_hack\ESP_WebApiCombo_v10/ESP_WebApiCombo_v10.ino line 148
0x4021325d: esp_schedule at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/core_esp8266_main.cpp line 56
0x40213288: loop_wrapper at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/core_esp8266_main.cpp line 56
0x40100718: cont_norm at C:\Users\Lab7\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\2.3.0\cores\esp8266/cont.S line 109


First, I guess "IllegalInstructionCause" means that PC has jumped to an address that is not code (or not aligned).
Then is seems to indicate error occurs in "SPISlaveClass::_s_trans(void*, unsigned int)" which is my handler (note: I'm now hooked on the "TRANS" interrupt because I'm not using the "command/address/data + separate status" protocol, so "trans" seems a good "catch-all" and performs remarkably well when SPIFFS is not in use.
The next few lines don't give much information because "SPISlave.cpp line 42" is in the "begin" function, but then we get into "spiffs_nucleus.c line 941" which seems to confirm that interleaved SPI and HSPI handling is occurring...

I tried reducing the number of interrupts (only if status SPISRSIS is set for example) and the crashes occur less often.
I also tired reducing the number of instructions in the handler and it also occurs less often.
But in the end, even just incrementing a counter in the handler, it ends up crashing if I do many SPIFFS calls.
I really believe there's a race condition in there, which shouldn't happen if interrupt handling is performed correctly by the code.

Any idea ?

All comments are welcome of course.

Kind regards,

Vicne
User avatar
By Me-no-dev
#51181 Interesting... I don't thing that SPI0 uses interrupts or just enabling the slave would kill the esp all together.
There seems to be just one ISR callback for both SPIs and I2S :)
I wonder if this happens when you get slave spi transmission interrupt while reading SPIFFS...?
User avatar
By Vicne
#51223
Me-no-dev wrote:Interesting... I don't thing that SPI0 uses interrupts or just enabling the slave would kill the esp all together.
There seems to be just one ISR callback for both SPIs and I2S :)
I wonder if this happens when you get slave spi transmission interrupt while reading SPIFFS...?

Yes, clearly:
- I had a sketch with an HTTP web server with dynamically generated pages including static resources (images, js, css) and it worked perfectly.
- I also had a sketch doing SPI Slave using mostly your sample code and library (thanks again) and dumping on the console the info I'm "spying" on.
Both worked reliably for hours.
Now I'm in the process of merging the two, so that the info I'm spying on is displayed in a web page, but that's what is causing crashes.
If I unplug the SPI source (no interrupt gets generated), I can browse files on the SPIFFS without any issue.
If I replug the SPI source but don't browse pages, no issue either.
But as soon as I do both at the same time (getting SPI interrupts while reading files via SPIFFS), the ESP starts crashing, and the more I'm getting interrupts or the more files I'm reading, the more the crashes happen.

I noticed that cleaning up SPI0 interrupt flags when processing SPI1 is also what the samples in the Espressif Technical Reference does (at page 26 for example):
Code: Select all...
if(READ_PERI_REG(0x3ff00020)&BIT4){
  //following 3 lines is to close spi isr enable
  regvalue=READ_PERI_REG(SPI_FLASH_SLAVE(SPI));
  regvalue&=~(0x3ff);
  WRITE_PERI_REG(SPI_FLASH_SLAVE(SPI),regvalue);
  //os_printf("SPI ISR is trigged\n"); //debug code
  } else if(READ_PERI_REG(0x3ff00020)&BIT7){ //bit7 is for hspi isr,
...


But I still don't understand why. And moreover it does't work if I remove it (seems the watchdog timer gets triggered).
I also tried putting SPI0 handling first and HSPI second (inverting the if's in your sample code, to have the same logic as in the Espressif reference above), to no avail.

Is there any way to know if there is code already attached to the SPI ISR before calling "attach" ? How can we be sure we don't break the code that is already in place to handle SPI0 (or I2S by the way) interrupts ?

Kind regards,

Vicne