Reputation: 9
this is my first post here.
I'm having the following problem. I have some code that transfers a gif file from SD card to flash memory and then uses a TFT display to show it.
The following code works as expected:
#include <Memoria.h>
#include <Pantalla.h>
#include <FS.h>
#include <LittleFS.h>
#include <SD_MMC.h>
// ************************* PINES SD *************************
#define ONE_BIT_MODE false // Indica si la SD trabajará con MMC de 1 bit (si no, trabaja con 4 bits)
int d2 = 4;
int d3 = 5; // GPIO 34 is not broken-out on ESP32-S3-DevKitC-1 v1.1
int cmd = 6;
int clk = 7;
int d0 = 15;
int d1 = 16;
Pantalla *Pantalla::inst_ = NULL; // Se instancia el punturo al singleton
Pantalla* pantalla = Pantalla::getInstance(); // Se obtiene una copia del singleton
Memoria memoria = Memoria(clk, cmd, d0, d1, d2, d3); // Se instancia la memoria
const char *filename = "/sparkle_simple.gif"; // Change to load other gif files in images/GIF
void inicializarSD(void);
void inicializarLittleFS(void);
void cargarArchivo(const char *filename);
void setup()
{
Serial.begin(115200);
/*
memoria.begin();
memoria.transferir(filename);
*/
inicializarSD();
inicializarLittleFS();
cargarArchivo(filename);
pantalla->begin(); // Se inicializa la pantalla
// Initialize the GIF
pantalla->mostrar(filename);
}
void loop()
{
}
void inicializarSD(void) {
// Configuracion de resistencias pull-up
// Se siguio la indicacion del README de la librería SD_MMC
pinMode(clk, INPUT_PULLUP);
pinMode(cmd, INPUT_PULLUP);
pinMode(d0, INPUT_PULLUP);
pinMode(d1, INPUT_PULLUP);
pinMode(d2, INPUT_PULLUP);
pinMode(d3, INPUT_PULLUP);
// Seteo de pines de la SD
if(! SD_MMC.setPins(clk, cmd, d0, d1, d2, d3)) {
Serial.println("Pin change failed!");
return;
}
Serial.println("SD card initialization...");
if (!SD_MMC.begin("/sdcard", ONE_BIT_MODE)) {
Serial.println("SD card initialization failed!");
return;
}
}
void inicializarLittleFS(void) {
// Inicialización LittleFS
Serial.println("Initialize LittleFS...");
if (!LittleFS.begin(true))
{
Serial.println("LittleFS initialization failed!");
}
// Reformmating the LittleFS to have space if a large GIF is loaded
// You could run out of LittleFS storage space if you load more than one image or a large GIF
// You can also increase the LittleFS storage space by changing the partition of the ESP32
//
Serial.println("Formatting LittleFS...");
LittleFS.format(); // This will erase all the files, change as needed, LittleFS is non-volatile memory
Serial.println("LittleFS formatted successfully.");
}
void cargarArchivo(const char *filename) {
// Open GIF file from SD card
Serial.println("Openning GIF file from SD card...");
File sdFile = SD_MMC.open(filename);
if (!sdFile) {
Serial.println("Failed to open GIF file from SD card!");
return;
}
// Create a file in LittleFS to store the GIF )
File LittleFSFile = LittleFS.open(filename, FILE_WRITE, true);
if (!LittleFSFile) {
Serial.println("Failed to copy GIF in LittleFS!");
return;
}
// Read the GIF from SD card and write to LittleFS
Serial.println("Copy GIF in LittleFS...");
byte buffer[512];
while (sdFile.available())
{
int bytesRead = sdFile.read(buffer, sizeof(buffer));
LittleFSFile.write(buffer, bytesRead);
}
LittleFSFile.close();
sdFile.close();
}
I wanted to create a Memory class to handle SD card and flash memory. This is what I wrote:
Memoria.h
#pragma once
#include "Arduino.h"
#include <FS.h>
#include <LittleFS.h>
#include <SD_MMC.h>
#include "StatusTools.h"
class Memoria {
using Status = SimpleStatus;
public: // These are the "functions" exposed to the consumer of this library
Memoria(int clk, int cmd, int d0, int d1, int d2, int d3); // Constructor
Status begin(void); // Inicializar la SD
Status transferir(const char *filename); // Transferir el archivo "filename" desde la SD a la flash
private: // Only visible from within this class
// Registro de los pines
int clk_;
int cmd_;
int d0_;
int d1_;
int d2_;
int d3_;
protected: // Not exposed publicly. Can be used within this class AND used in inherited classes
// Hmm Nothing springs to mind that should go here instead of one of the above sections
};
Memoria.cpp
#include "Memoria.h"
#include "Arduino.h"
#include <FS.h>
#include <LittleFS.h>
#include <SD_MMC.h>
#include "StatusTools.h"
using Status = SimpleStatus;
Memoria::Memoria(int clk, int cmd, int d0, int d1, int d2, int d3) {
// Registro pines SD
clk_ = clk;
cmd_ = cmd;
d0_ = d0;
d1_ = d1;
d2_ = d2;
d3_ = d3;
// Configuracion de resistencias pull-up
// Se siguio la indicacion del README de la librería SD_MMC
pinMode(clk_, INPUT_PULLUP);
pinMode(cmd_, INPUT_PULLUP);
pinMode(d0_, INPUT_PULLUP);
pinMode(d1_, INPUT_PULLUP);
pinMode(d2_, INPUT_PULLUP);
pinMode(d3_, INPUT_PULLUP);
}
Status Memoria::begin(void) {
// Seteo de pines de la SD
if(!SD_MMC.setPins(clk_, cmd_, d0_, d1_, d2_, d3_)) {
Serial.println("Pin change failed!");
return Status::Error;
}
// Inicialización SD
Serial.println("SD card initialization...");
if (!SD_MMC.begin()) { // MMC 4-bit
Serial.println("SD card initialization failed!");
return Status::Error;
}
// Inicialización LittleFS
Serial.println("Initialize LittleFS...");
if (!LittleFS.begin(true)) {
Serial.println("LittleFS initialization failed!");
}
// Formateo de LittleFS
Serial.println("Formatting LittleFS...");
LittleFS.format(); // This will erase all the files, change as needed, LittleFS is non-volatile memory
Serial.println("LittleFS formatted successfully.");
return Status::Success;
}
Status Memoria::transferir(const char *filename) {
// Open GIF file from SD card
Serial.println("Openning GIF file from SD card...");
File sdFile = SD_MMC.open(filename);
if (!sdFile) {
Serial.println("Failed to open GIF file from SD card!");
return Status::Error;
}
// Create a file in LittleFS to store the GIF
File LittleFSFile = LittleFS.open(filename, FILE_WRITE, true);
if (!LittleFSFile) {
Serial.println("Failed to copy GIF in LittleFS!");
return Status::Error;
}
// Read the GIF from SD card and write to LittleFS
Serial.println("Copy GIF in LittleFS...");
byte buffer[512];
while (sdFile.available()) {
int bytesRead = sdFile.read(buffer, sizeof(buffer));
LittleFSFile.write(buffer, bytesRead);
}
LittleFSFile.close();
sdFile.close();
}
I implemented this in my main program file by commenting the following lines...
inicializarSD();
inicializarLittleFS();
cargarArchivo(filename);
...and uncommenting the two code lines above them.
I get the following log while running the program:
load:0x3fce3808,len:0x4bc
load:0x403c9700,len:0xbd8
load:0x403cc700,len:0x2a0c
entry 0x403c98d0
[ 348][I][esp32-hal-psram.c:96] psramInit(): PSRAM enabled
[ 358][V][esp32-hal-uart.c:330] uartBegin(): UART0 baud(115200) Mode(800001c) rxPin(44) txPin(43)
[ 367][V][esp32-hal-uart.c:416] uartBegin(): UART0 not installed. Starting installation
[ 376][V][esp32-hal-uart.c:463] uartBegin(): UART0 initialization done.
SD card initialization...
Initialize LittleFS...
Formatting LittleFS...
LittleFS formatted successfully.
Openning GIF file from SD card...
Copy GIF in LittleFS...
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
Core 0 register dump:
PC : 0x42002960 PS : 0x00060a30 A0 : 0x8200269b A1 : 0x3fceba00
A2 : 0x00000000 A3 : 0x3c050120 A4 : 0x0000e100 A5 : 0x00000000
A6 : 0x0000002b A7 : 0x0001c200 A8 : 0x82002930 A9 : 0x00000004
A10 : 0x42002db0 A11 : 0x3fced200 A12 : 0x000000b6 A13 : 0x3c050264
A14 : 0x00000001 A15 : 0x00000000 SAR : 0x0000001e EXCCAUSE: 0x0000001c
EXCVADDR: 0x00000004 LBEG : 0x400570a4 LEND : 0x400570a9 LCOUNT : 0x00000000
Backtrace: 0x4200295d:0x3fceba00 0x42002698:0x3fcebc60 0x4200d7f3:0x3fcebc90
ELF file SHA256: 690274674a15b2f5
Rebooting...
And this repeats forever until I power of the device.
I tried changing SD frequency to 20 MHz using the following line
SD_MMC.begin("\sdcard", false, false, 20000, 5)
I had the same problem
I also put a print statement here...
// Read the GIF from SD card and write to LittleFS
Serial.println("Copy GIF in LittleFS...");
byte buffer[512];
while (sdFile.available()) {
int bytesRead = sdFile.read(buffer, sizeof(buffer));
Serial.println(bytesRead); // TEST
LittleFSFile.write(buffer, bytesRead);
}
...this leads to the following log...
(Same as before...)
Copy GIF in LittleFS...
512
512
512
512
512
512
512
512
512
512
512
182
Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled.
(Same as before...)
And this repeats forever.
Upvotes: 1
Views: 134
Reputation: 9
After testing a lot of things, I realized the problem was that I forgot to put a return statement at the end of Memoria::transferir function implementation.
I thought that the problem was somehow related to the specific implementation of the SD_MMC library because that was what the log lead me to. How silly.
I also implemented a whole class SimpleStatus for debugging purposes and I didn't use it. If I'd used it then I'd probably found that error using the log.
Upvotes: 0