Error reading file from SD card

I’m trying to read WAV header info from the SD card on my Daisy Patch. I’ve pored over the FatFS docs, read multiple examples, and even referenced other projects. Best I can tell I’m using the SDMMC/FatFS libraries correctly.

I can list files in directories and even stat files, but any time I try to read a file I get an error. I’ve tried multiple SD cards to no avail. Does anyone know what’s going on here? I’ve managed to pare down the code to something simple. Program and output below.

sdissue

#include <cstring>
#include "daisy_patch.h"
#include "daisysp.h"
#include "hid/wavplayer.h"
#include "util/wav_format.h"
#include "ff.h"

using namespace daisy;
using namespace daisysp;

DaisyPatch hw;

SdmmcHandler    sdcard;
FatFSInterface  fsi;

int main(void)
{
	hw.Init();
	hw.display.Fill(false);
	hw.display.Update();

    SdmmcHandler::Config sd_cfg;
    sd_cfg.Defaults();
	//sd_cfg.speed = daisy::SdmmcHandler::Speed::FAST;
    sdcard.Init(sd_cfg);
    fsi.Init(FatFSInterface::Config::MEDIA_SD);
    f_mount(&fsi.GetSDFileSystem(), fsi.GetSDPath(), 1);

	FIL file;
	FILINFO fileInfo;
	size_t bytesRead;
	WAV_FormatTypeDef header;
	char error[256];
	char info[256];
	sprintf(error, "ok");
	if(f_stat("0.wav", &fileInfo)) {
		sprintf(info, "file info error");
	} else {
		sprintf(info, "%s %d", fileInfo.fname, fileInfo.fsize);
	}
	if(f_open(&file, "0.wav", (FA_OPEN_EXISTING | FA_READ)))
		sprintf(error, "error opening file");
	if(f_read(&file, (void*)&header, sizeof(WAV_FormatTypeDef), &bytesRead))
		sprintf(error, "error reading file");

	hw.display.SetCursor(0, 0);
	hw.display.WriteString(error, Font_7x10, true);
	hw.display.SetCursor(0, 10);
	hw.display.WriteString(info, Font_7x10, true);
	hw.display.Update();
}
1 Like

Referencing the WavPlayer code, I noticed that it concatenates the file name to fsi.GetSDPath(). I’ve just tried this updated code and still no luck. Really stumped. I tested the WavPlayer code and it compiles and runs for me just fine, so clearly this is a me issue but I can’t for the life of me figure out what I’m doing wrong/differently.

#include <cstring>
#include "daisy_patch.h"
#include "daisysp.h"
#include "hid/wavplayer.h"

using namespace daisy;
using namespace daisysp;

DaisyPatch hw;

SdmmcHandler    sdcard;
FatFSInterface  fsi;

int main(void)
{
	hw.Init();
	hw.display.Fill(false);
	hw.display.Update();

    SdmmcHandler::Config sd_cfg;
    sd_cfg.Defaults();
    sdcard.Init(sd_cfg);
    fsi.Init(FatFSInterface::Config::MEDIA_SD);
    f_mount(&fsi.GetSDFileSystem(), "/", 1);
	
	// DIR dir;
	// f_opendir(&dir, fsi.GetSDPath());

	FIL file;
	FILINFO fileInfo;
	size_t bytesRead;
	WAV_FormatTypeDef header;
	char filename[256];
	char error[256];
	char info[256];
	sprintf(error, "ok");
	if(f_stat("0.wav", &fileInfo)) {
		sprintf(info, "file info error");
	} else {
		sprintf(info, "%s %d", fileInfo.fname, fileInfo.fsize);
		strcpy(filename, fsi.GetSDPath());
		strcat(filename, fileInfo.fname);
	}
	if(f_open(&file, filename, (FA_OPEN_EXISTING | FA_READ)))
		sprintf(error, "error opening file");
	if(f_read(&file, (void*)&header, sizeof(WAV_FormatTypeDef), &bytesRead))
		sprintf(error, "error reading file");

	hw.display.SetCursor(0, 0);
	hw.display.WriteString(filename, Font_7x10, true);
	hw.display.SetCursor(0, 10);
	hw.display.WriteString(info, Font_7x10, true);
	hw.display.SetCursor(0, 20);
	hw.display.WriteString(error, Font_7x10, true);
	hw.display.Update();
}
1 Like

Hi,

Take a look at this thread FatFS f_read returns FR_DISK_ERR - Software Development - Daisy Forums (electro-smith.com)

Basically you need to move the FIL file; declaration out of your main function to avoid it being allocated on the stack. If you declare it a global by adding it just under the place where you define FatFSInterface fsi; you should be able to get it to work.

Cheers

3 Likes

Thank you so much! I moved all the filesystem-related variables to the global namespace and it immediately worked.

2 Likes