SD card error handling

I’m trying to add more error handling to my project. Right now I’m looking at the SDMMC interface.

I’d like to recover from the case when the SD card is removed while mounted. I’m trying to detect this state by querying the free space on the card. If that operation fails, then I assume the card has been removed.

At that point I try to reinitialize the SDMMC interface and FatFS. However, I’m not able to access the SD card after attempting to reinitialize. I get an FR_NOT_READY error.

This is my initialization code:

FatFileSystem::FatFileSystem()
{
    m_curPath[0] = '\0';
    m_available  = false;
}

bool FatFileSystem::initialize()
{
    // Initialize the SDMMC interface and the FAT file system
    m_sdConfig.Defaults();
    m_sdConfig.speed = daisy::SdmmcHandler::Speed::FAST;
    m_sdHandler.Init(m_sdConfig);
    m_fsi.Init(daisy::FatFSInterface::Config::MEDIA_SD);

    // Try to mount the SD card
    strcpy(m_curPath,  m_fsi.GetSDPath());
    strcpy(m_rootPath, m_fsi.GetSDPath());
    FRESULT res = f_mount(&m_fsi.GetSDFileSystem(), m_curPath, 1);
    infoPrint("f_mount( %s ), result: %s\r\n", m_curPath, getFatFSErrorCode(res));
    m_available = (res == FR_OK);
    return m_available;
}

void FatFileSystem::deinitialize()
{
    m_fsi.DeInit();
    new (this) FatFileSystem;
}

This runs in a loop about once every second:

    uint32_t totalKB, freeKB;
    if(fileSystem.getFreeSpace(totalKB, freeKB))
    {
        debugPrint("Total: %u, Free: %u\r\n", totalKB, freeKB);
    }
    else
    {
        debugPrint("SD not available, attempting to reinitialize\n");
        fileSystem.deinitialize();
        appState.fsOkay = fileSystem.initialize();
    }

If I perform the de-init/re-init sequence without removing the SD card then things continue to work properly. But removing the SD card and then attempting to access it puts something in a bad state that I’m not sure how to recover from.

Any ideas?

Hey miminashi!

I think using the CD pin on your SDMMC inteface could be a simpler solution here.
The pin needs to be pulled up but you can initialize the GPIO to do so. Then, when the SD card is not inserted, the CD pin will be a high level and vice versa.

CD is an efficient way to detect the card, but doesn’t address the second question - how to reinitialize the SDMMC interface and FatFS.

Thanks, Takumi. I’m using the same circuit from the Daisy Patch, with the 47K pull-up resistors on the data lines. Is it possible to use the CD pin while also using the 4-bit interface? I tried reading the pin, but it always reads HIGH, even when the card is not inserted.

Does the microSD socket have a switch to detect the card?

No, there’s no switch unfortunately: https://www.mouser.com/ProductDetail/Yamaichi-Electronics/PJS008U-3000-0?qs=nO3wRANIIvnp3f0XwG2X3A%3D%3D

I’m sorry for misunderstanding the point of your question.

This thread could be of help as it mentions using f_close() and f_mount(0) as part of deinit.
https://community.st.com/s/question/0D50X00009fFWPSSA4/what-is-the-proper-method-to-reinitialize-sd-card-interface-to-support-removalreinsertion-of-sd-card
And you will have to dig into the SD card code in libDaisy as well as the HAL probably.
It will most likely get complex so make sure that you have a debug probe as you embark on this journey.

And if you have any questions along the way, please do reach out and we’ll have a deeper look into this.

Thanks. I had seen that thread and many others like it. It looks like I will need to completely re-initialized the SDMMC for it to work after it gets into the bad state.

Apparently the low-level initialization is handled by the bootloader. Is the source for the bootloader available so I can see what needs to be done?

The source for the bootloader has not been opensourced yet. (according to an
2/27/2023 email from Electrosmith).

Why the delay?. It was promised during the Kickstarter funding campain, that:

"All firmware that we develop will be released for free under a permissive open source license(MIT). "
source

1 Like

libDaisy/src/per/sdmmc.cpp has some HAL init/deinit functions that may be of interest.

Cheers

Thanks for the replies. I did try calling those HAL init/denit functions, but I must have been missing something. I’ll take another look.

Hi Jens,

From my understanding, we still want to polish it more. And there seems to be other steps/processes involved before it can be shared.
We hope to update you all on this soon! I appreciate your waiting.