WROVER-B - PSRAM + SPI SD card Guru meditation

marmou
Posts: 3
Joined: Wed May 25, 2022 10:24 pm

WROVER-B - PSRAM + SPI SD card Guru meditation

Postby marmou » Wed May 25, 2022 11:25 pm

Good afternoon.
I'm starting work with PSRAM because I need lot of memory for program language modifications during the array of char arrays.
Examples on net are only few and don't right what I need, but at the end I made something which works/don't works.
For filling of array I use TextText.txt which is attached.
HARDWARE: LilyGo TTGO T-call & PMU (WROVER-B)
PROGRAMMING IDE: Arduino IDE and PROGRAMINO (https://programino.com/)
OS: Windows 10

Here is the code:

Code: Select all

#include <Arduino.h>
#include <SD.h>
#define PinMicroSDSS 12
File Soubor;
void setup() {
   pinMode(PinMicroSDSS, OUTPUT);
   SPI.begin(18, 39, 25, PinMicroSDSS); //sck, miso, mosi, ss : 18,19,25,12
   //#define SPI_CLOCK_DIV2    0x00101001 - 8 MHz //#define SPI_CLOCK_DIV4    0x00241001 - 4 MHz //#define SPI_CLOCK_DIV8    0x004c1001 - 2 MHz //#define SPI_CLOCK_DIV16   0x009c1001 - 1 MHz //#define SPI_CLOCK_DIV32   0x013c1001 - 500 KHz //#define SPI_CLOCK_DIV64   0x027c1001 - 250 KHz //#define SPI_CLOCK_DIV128  0x04fc1001 - 125 KHz
   SPI.setClockDivider(SPI_CLOCK_DIV2);
   SD.begin(PinMicroSDSS); //, SPI, 80000000);
   Serial.begin(115200);
   while (!Serial) {
      delay(200);
   }
   delay(1000);
   if (psramInit() == true) {
      int PocetRadku = 0, DelkaRadku = 0;
      String Cesta = "/TextText.txt";
      //PrevedTextNaCharArr(&NazevSiteZar, &NazevSiteZarChar[0], sizeof(NazevSiteZarChar));
      SDNactiParametryPromenne(&Cesta, &PocetRadku, &DelkaRadku);
      if (PocetRadku != 0 && DelkaRadku != 0) {
         Serial.println("Pocet radku: " + String(PocetRadku) + ", " + "Delka radku: " + String(DelkaRadku));
         char **SDC = (char **) ps_calloc(PocetRadku, sizeof(char));
         for (int i = 0; i != PocetRadku; i++) {
            SDC[i] = (char *) ps_calloc(DelkaRadku, sizeof(char));
         }
         SDNactiDoPromenne(&Cesta, SDC, &PocetRadku, &DelkaRadku);
      }
   }
}
void loop() {

}
void SDNactiDoPromenne(String *Cesta, char **Promenna, int *PocetRadku, int *DelkaRadku) {
   // Serial.println(&Promenna);
   Soubor = SD.open(*Cesta);
   if (!Soubor) {
      Serial.println("Nenalezeno");
   } else {
      int i = 0;
      while (Soubor.available()) {
         String Radek = Soubor.readStringUntil('\n');
         Radek.trim();
         // Serial.println("Radek: " + Radek);
         if (Radek.indexOf("PocetRadku") == -1 && Radek.indexOf("DelkaRadku") == -1) {
            //Serial.println("Adresa: " + String(&(&(Promenna[i]))));
            PrevedTextNaCharArr(&Radek, Promenna[i], *DelkaRadku);
            Serial.println("Promenna " + String(i) + ": " + Promenna[i]);
            i++;
         }
      }
      Soubor.close();
      Serial.println();
      Serial.println("Tady hotovo.");
   }
}
void SDNactiParametryPromenne(String *Cesta, int *PocetRadku, int *DelkaRadku) {
   Soubor = SD.open(*Cesta);
   if (!Soubor) {
      Serial.println("Nenalezeno");
   } else {
      while (Soubor.available()) {
         String Radek = Soubor.readStringUntil('\n');
         if (Radek.indexOf("PocetRadku") != -1) {
            String Hodnota = NajdiHodnotuParametru(&Radek, "PocetRadku", "=", true);
            if (Hodnota != "") {
               *PocetRadku = Hodnota.toInt();
            }
         } else if (Radek.indexOf("DelkaRadku") != -1) {
            String Hodnota = NajdiHodnotuParametru(&Radek, "DelkaRadku", "=", true);
            if (Hodnota != "") {
               *DelkaRadku = Hodnota.toInt();
            }
         }
         if(*DelkaRadku != 0 && *PocetRadku != 0) break;
      }
      Soubor.close();
   }
}
void PrevedTextNaCharArr(String *Text, char *AdresaChar0, int DelkaChar) {
   for (int i = 0; i < DelkaChar; i++) {
      if (i < (*Text).length()) {
         char Znak = (*Text).charAt(i);
         byte Bajt      = byte(Znak);
         *AdresaChar0 = Bajt;
      } else {
         *AdresaChar0 = '\0';
      }
      AdresaChar0++;
   }
}
String NajdiHodnotuParametru(String *Retezec, String *Parametr, String Oddelovac, bool MaBytCislo) {
   String HodnotaParametru = "";
   if (*Retezec != "" && *Parametr != "" && Oddelovac != "") {
      String Hledane = *Parametr + Oddelovac;
      if (Hledane.length() < (*Retezec).length()) {
         if (NajdiTextVTextu(&Hledane, Retezec, false) == 0) {
            HodnotaParametru = (*Retezec).substring(Hledane.length());
            HodnotaParametru.trim();
            if (HodnotaParametru != "") {
               if (MaBytCislo == true) {
                  HodnotaParametru = JeToCislo(&HodnotaParametru, false);
               }
            }
         }
      }
   }
   return HodnotaParametru;
}
String NajdiHodnotuParametru(String *Retezec, const String *Parametr, String Oddelovac, bool MaBytCislo) {
   String ParametrStr = *Parametr;
   return NajdiHodnotuParametru(Retezec, &ParametrStr, Oddelovac, MaBytCislo);
}
String NajdiHodnotuParametru(String *Retezec, String Parametr, String Oddelovac, bool MaBytCislo) {
   return NajdiHodnotuParametru(Retezec, &Parametr, Oddelovac, MaBytCislo);
}
int NajdiTextVTextu(String *CoHledat, String *KdeHledat, bool VelkaMala) {
   // Serial.println("String*");
   // Serial.println("Co hledat: " + *CoHledat);
   // Serial.println("Kde hledat: " + *KdeHledat);
   int Pozice = -1;
   if ((*CoHledat).length() <= (*KdeHledat).length()) {
      if (*CoHledat == *KdeHledat) {
         Pozice = 0;
      } else {
         if (VelkaMala == false) {
            String Co = *CoHledat;
            Co.toLowerCase();
            String Kde = *KdeHledat;
            Kde.toLowerCase();
            Pozice = Kde.indexOf(Co, 0);
         } else {
            Pozice = (*KdeHledat).indexOf(*CoHledat, 0);
         }
      }
   }
   return Pozice;
}
int NajdiTextVTextu(const String *CoHledat, String *KdeHledat, bool VelkaMala) {
   // Serial.println("const String*");
   String CoHledatStr = *CoHledat;
   return NajdiTextVTextu(&CoHledatStr, KdeHledat, VelkaMala);
}
int NajdiTextVTextu(String CoHledat, String *KdeHledat, bool VelkaMala) {
   // Serial.println("String");
   return NajdiTextVTextu(&CoHledat, KdeHledat, VelkaMala);
}
String JeToCislo(String *Retezec, bool NechatZnamenka) {
   byte p;
   char NovyText;
   String CisloString;
   bool Vysledek = false;
   CisloString   = *Retezec;
   CisloString.trim();
   CisloString.replace(" ", "");
   CisloString.replace(",", ".");
   if (NechatZnamenka == false) {
      CisloString.replace("+", "");
   }
   if (CisloString != "") {
      Vysledek = true;
      for (p = 0; p < CisloString.length() - 1; p++) {
         NovyText = CisloString.charAt(p);
         if (byte(NovyText) < 48 || byte(NovyText) > 57) { // Čísla
            if (byte(NovyText) < 43 && byte(NovyText) > 46) { // Znaménka +;,;-;.
               Vysledek = false;
               break;
            }
         }
      }
   }
   if (Vysledek == false) {
      CisloString = "";
   }
   return CisloString;
}
I got everytime in the same position result:
Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)
Core 1 register dump:
PC : 0x400882d4 PS : 0x00060034 A0 : 0x8008b598 A1 : 0x3ffb3dc0
A2 : 0x3ffb0058 A3 : 0x3f40ed84 A4 : 0x3ffb006c A5 : 0x3ffbec50
A6 : 0x3ffbec98 A7 : 0x00000001 A8 : 0x3ffb89b4 A9 : 0x3ffb3ee0
A10 : 0x00ff0000 A11 : 0xff000000 A12 : 0x8008c127 A13 : 0x3ffbec20
A14 : 0x00000008 A15 : 0x00000001 SAR : 0x0000001d EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x40088fc9 LEND : 0x40088fd9 LCOUNT : 0xfffffffd

ELF file SHA256: 0000000000000000

Backtrace: 0x400882d4:0x3ffb3dc0 0x4008b595:0x3ffb3de0 0x4008cf10:0x3ffb3e00 0x4008cec6:0x00000001

Core 0 register dump:
PC : 0x400f57da PS : 0x00060d34 A0 : 0x800eb51e A1 : 0x3ffbc130
A2 : 0x00000000 A3 : 0x00000001 A4 : 0x00000000 A5 : 0x00000001
A6 : 0x00060f20 A7 : 0x00000000 A8 : 0x800eb212 A9 : 0x3ffbc100
A10 : 0x00000000 A11 : 0x40085910 A12 : 0x00060f20 A13 : 0x3ffbb800
A14 : 0x00000002 A15 : 0x3ffbbca8 SAR : 0x00000000 EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000

ELF file SHA256: 0000000000000000

Backtrace: 0x400f57da:0x3ffbc130 0x400eb51b:0x3ffbc150 0x4008c116:0x3ffbc170 0x4008ac85:0x3ffbc190

Rebooting...
ets Jun 8 2016 00:22:57
Here is full Serial report:
Pocet radku: 107, Delka radku: 100
Promenna 0: 037Ov⸮⸮uji existenci slo⸮ky:
Promenna 1: 038existuje
Promenna 2: 039Objekt
Promenna 3: 040nen⸮ slozka
Promenna 4: 041Slo⸮ka
Promenna 5: 042neexistuje
Promenna 6: 043Ov⸮⸮uji existenci souboru:
Promenna 7: 044Soubor
Promenna 8: 045Objekt
Promenna 9: 046nen⸮ soubor
Promenna 10: 047Soubor
Promenna 11: 048⸮tu soubor:
Promenna 12: 049Chyba p⸮i ⸮ten⸮ souboru
Promenna 13: 050Vytv⸮⸮⸮m soubor
Promenna 14: 051Chyba p⸮i vytvo⸮en⸮ souboru
Promenna 15: 052Soubor
Promenna 16: 053vytvo⸮en
Promenna 17: 054P⸮id⸮v⸮m data do souboru
Promenna 18: 055Chyba p⸮i otev⸮en⸮ souboru
Promenna 19: 056Obsah do souboru
Promenna 20: 057Chyba p⸮i z⸮pisu do souboru
Promenna 21: 058P⸮ejmenov⸮v⸮m soubor
Promenna 22: 059Soubor
Promenna 23: 060p⸮ejmenov⸮n na
Promenna 24: 061P⸮ejmenov⸮n⸮ souboru
Promenna 25: 062selhalo
Promenna 26: 063Ma⸮u soubor
Promenna 27: 064smaz⸮n
Promenna 28: 065Maz⸮n⸮ souboru
Promenna 29: 066Zji⸮⸮uji zapln⸮n⸮ karty
Promenna 30: 067Velikost odd⸮lu:
Promenna 31: ⸮
Promenna 32:
Promenna 33:
Promenna 34: ⸮
Promenna 35:
Promenna 36:
Promenna 37:
Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)
Core 1 register dump:
PC : 0x400882d4 PS : 0x00060034 A0 : 0x8008b598 A1 : 0x3ffb3dc0
A2 : 0x3ffb0058 A3 : 0x3f40ed84 A4 : 0x3ffb006c A5 : 0x3ffbec50
A6 : 0x3ffbec98 A7 : 0x00000001 A8 : 0x3ffb89b4 A9 : 0x3ffb3ee0
A10 : 0x00ff0000 A11 : 0xff000000 A12 : 0x8008c127 A13 : 0x3ffbec20
A14 : 0x00000008 A15 : 0x00000001 SAR : 0x0000001d EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x40088fc9 LEND : 0x40088fd9 LCOUNT : 0xfffffffd

ELF file SHA256: 0000000000000000

Backtrace: 0x400882d4:0x3ffb3dc0 0x4008b595:0x3ffb3de0 0x4008cf10:0x3ffb3e00 0x4008cec6:0x00000001

Core 0 register dump:
PC : 0x400f57da PS : 0x00060d34 A0 : 0x800eb51e A1 : 0x3ffbc130
A2 : 0x00000000 A3 : 0x00000001 A4 : 0x00000000 A5 : 0x00000001
A6 : 0x00060f20 A7 : 0x00000000 A8 : 0x800eb212 A9 : 0x3ffbc100
A10 : 0x00000000 A11 : 0x40085910 A12 : 0x00060f20 A13 : 0x3ffbb800
A14 : 0x00000002 A15 : 0x3ffbbca8 SAR : 0x00000000 EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x00000000 LEND : 0x00000000 LCOUNT : 0x00000000

ELF file SHA256: 0000000000000000

Backtrace: 0x400f57da:0x3ffbc130 0x400eb51b:0x3ffbc150 0x4008c116:0x3ffbc170 0x4008ac85:0x3ffbc190

Rebooting...
ets Jun 8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1216
ho 0 tail 12 room 4
load:0x40078000,len:10944
load:0x40080400,len:6388
entry 0x400806b4
Do You have please any idea what can be the reason of these errors ?
Thank You.
Attachments
TextText.txt
(1.58 KiB) Downloaded 146 times

lbernstone
Posts: 636
Joined: Mon Jul 22, 2019 3:20 pm

Re: WROVER-B - PSRAM + SPI SD card Guru meditation

Postby lbernstone » Thu May 26, 2022 3:28 am

If you decode the backtrace (https://github.com/me-no-dev/EspExceptionDecoder) it will show you exactly where the watchdog timer is getting stuck. I can see that you have 2 tight while loops reading from flash. Put a delay(1) at the end of each of those loops and it should keep the watchdog happy.
I would also recommend you read the data in chunks of 512 bytes (or the sector size if it is larger) to maximize the transfer rate.

marmou
Posts: 3
Joined: Wed May 25, 2022 10:24 pm

Re: WROVER-B - PSRAM + SPI SD card Guru meditation

Postby marmou » Thu May 26, 2022 8:07 am

Good mornng.
I tried put to each cycle of while delay(1); and also at the end of while loop delay(10);. Still the same issue at the same place.

Decoder give mi this feedback:
0x400882d4: memcmp at /home/mak/e/p/newlib_old/newlib_xtensa-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/string/../../../.././newlib/libc/string/memcmp.c line 64
0x40088fc9: strlen at /home/mak/e/p/newlib_old/newlib_xtensa-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/machine/xtensa/../../../../.././newlib/libc/machine/xtensa/strlen.S line 84
0x40088fd9: strlen at /home/mak/e/p/newlib_old/newlib_xtensa-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/machine/xtensa/../../../../.././newlib/libc/machine/xtensa/strlen.S line 96
0x400882d4: memcmp at /home/mak/e/p/newlib_old/newlib_xtensa-bin/newlib_xtensa-2.2.0/xtensa-esp32-elf/newlib/libc/string/../../../.././newlib/libc/string/memcmp.c line 64
0x4008b595: vTaskSwitchContext at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c line 4560
0x4008cf10: _frxt_dispatch at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/portasm.S line 406
0x4008cec6: _frxt_int_exit at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/portasm.S line 206
0x400f57ea: esp_pm_impl_waiti at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/pm_esp32.c line 492
0x40085910: _free_r at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/newlib/syscalls.c line 41
0x400f57ea: esp_pm_impl_waiti at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/pm_esp32.c line 492
0x400eb52b: esp_vApplicationIdleHook at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/esp32/freertos_hooks.c line 86
0x4008c116: prvIdleTask at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/tasks.c line 4560
0x4008ac85: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 355 (discriminator 1)
Unfortunately, I do not understand this. :-(

Is there any cache, which must be cleared ? Is necessary close file and open it again ? Or switch off SD card and mount again ? I don't know how it works inside.

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

Re: WROVER-B - PSRAM + SPI SD card Guru meditation

Postby ESP_Sprite » Thu May 26, 2022 9:09 am

I'm 80% sure you're overflowing a buffer somewhere, but the foreign-language functions and variables throw me off enough that I can't decode what your program is doing.

marmou
Posts: 3
Joined: Wed May 25, 2022 10:24 pm

Re: WROVER-B - PSRAM + SPI SD card Guru meditation

Postby marmou » Thu May 26, 2022 10:06 am

SOLVED, WORKS !
Like a size must be used size of char pointer, not char, because it is array of char type pointers.
How I read this again and again...
ps_calloc(PocetRadku, sizeof(char*));
ps_calloc(DelkaRadku, sizeof(char*));

Who is online

Users browsing this forum: No registered users and 57 guests