Skip to main content
Tim Russell
Associate II
August 29, 2018
Solved

What is the proper method to re-initialize SD card interface to support removal/reinsertion of SD card?

  • August 29, 2018
  • 14 replies
  • 5071 views

My SD card interface (using SDMMC1) stops working after the SD card has been removed/re-inserted.

I have tried un-mounting using f_mount(0, &SDPath, 0) and then re-mounting with no success.

As a test, I executed the following for each transaction:

f_mount(&SDFatFs, &SDPath, 0);

f_open(&SDFile,.....);

f_write(&SDFile, .....);

f_close(&SDFile);

f_mount(0, &SDPath, 0);

If I remove/re-insert the SD card after the 1st transaction, I get an FR_DISK_ERR error on the f_open() on the second transaction (following the reinsertion of the SD card). I have traced this error down into the HAL_SD_ReadBlocks_DMA() functions which gets a timeout on the call to SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE).

Any suggestions?

This topic has been closed for replies.
Best answer by Tim Russell

Lctasca,

My SD code is functioning properly now.

The code I am using is as follows,

FATFS_UnLinkDriver(SDPath);

FATFS_LinkDriver(&SD_Driver, SDPath);

f_mount(&SDFatFs, &SDPath, 0);

f_open(&SDFile,.....);

f_write(&SDFile, .....);

--- if write error, go back to top to re-init ---

f_sync(&SDFile);

14 replies

Tim Russell
Associate II
September 26, 2018

Still looking for suggestions on how to re-initialize (i.e. re-mount) an SD card after it has been ejected and re-inserted.

The following sequence is an update to the (5) step sequence I documented in my original post.

f_mount(&SDFatFs, &SDPath, 0);

f_open(&SDFile,.....);

f_write(&SDFile, .....);

<---- SD card is removed and re-inserted

f_write(&SDFile, .....);

<---- Error is detected on f_write(), so I close, unmount, and re-init

f_close(&SDFile);

f_mount(0, &SDPath, 0);

f_mount(&SDFatFs, &SDPath, 0);

f_open(&SDFile,.....);

                                       <---- Error is detected on f_open() [FR_DISK_ERR]

Is there a different recommended re-initialization method?

Thanks.

Tesla DeLorean
Guru
September 26, 2018

The lower level code must reinitialize the interface and the card.

memset() the SDFatFs structure to zero so it is clean.

Have an interrupt on the card removal/insertion so the subsystem doesn't have to figure the card is not initialized before sending commands to it.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Tim Russell
Associate II
October 1, 2018

Thanks Clive.

I like the idea of using the interrupt (I should have thought of that).

After detecting that the SD card has been removed/reinserted, are the f_close() and f_mount(0) required or is the memset(SDFatFS) sufficient?

Matthew Staben
Associate
October 1, 2018

We use a card detect circuit so to avoid attempting comm. if there's no card present.

Tim Russell
Associate II
October 2, 2018

Still getting an error after SD card is re-inserted.

I implemented an interrupt to detect only the insertion of the SD card. None were available for detecting the ejection of the SD card. Therefore, on detection of SD card being re-inserted, the SD card initialize looks like this:

f_close(&SDFile); //close previously opened file (if any)

f_mount(0, &SDPath, 0); //un-mount

memset(&SDFatFs,0,sizeofSDFatFs));

f_mount(&SDFatFs, &SDPath, 0);

f_open(&SDFile,.....); <---- Error is detected [FR_DISK_ERR]

This code works on initial startup (when SD card has not been previously initialized), but fails on the f_open() when re-executed after re-insertion is detected.

Tesla DeLorean
Guru
October 2, 2018

>>f_close() and f_mount(0)

I'd be very wary of that, there is no guarantee you are even talking to the same card, so flushing structures to it seems very ill advised, and likely to cause corruption at some point.

The DISKIO layer really just wants to be throwing errors and rejecting reads/writes until a disk_initialize has occured, and that should manage the underlying SDIO/SDMMC interface and reinitialization.

The example code really doesn't get that involved, significant effort would be required to harden it for card removal/replacement, and high level application code should be aware of and account for the possibility of this occurring. Most code I see ploughs on regardless rather than unwind gracefully.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Tim Russell
Associate II
October 2, 2018

Clive, not clear what exactly your "disk_initialize" refers to.

Are you stating that accessing the SD card after re-insertion is not possible without a power-cycle/reboot?

I believe I am missing some command.

Is a FATFS_LinkDriver() required after re-insertion (before the f_mout())?

Tesla DeLorean
Guru
October 2, 2018

http://elm-chan.org/fsw/ff/doc/dinit.html

I'm saying that at a DISKIO subsystem level you should probably fail ALL read/write requests once a disk removal is detected so it drills it home to the app level code that nothing it has open or working on is viable, and you can break out of that code to the point you can attempt to recover. The app level code needs to watch for errors on f_open, f_read, f_write, etc so that it aborts/exits cleanly.

Pretty sure the HAL_SD_Init() and HAL_SD_InitCard() reset the peripheral and re-establish communication with the card at 400 KHz. Most implementations can't power cycle/reset the card itself. You'll have to chase the rabbit down the HAL abstractions. FATFS_LinkDriver() should flag the subsystem for reinitialization, but I've seen ST examples where the SD/MMC are initialized outside their own abstraction. Also haven't torn down the FatFs implementation recently.

These are all areas one could bury man-days of effort to get to a commercial grade solution, and not something I can deal with in a two-minute forum response.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
SNama
Visitor II
October 3, 2018

To my knowledge, If you are using SDIO interface then whenever you remove the SD card the state of the SDIO is lost and it requires reinitialization process. If you go with the SPI interface for SD card then I am sure you can insert and remove as many times you need and hoping that you are not removing it while SPI communication is in progress.

Tesla DeLorean
Guru
January 18, 2019

If you remove power from the card, whether it is interfaced via SPI or SDIO, you're going to want to reinitialize thing to ensure you are talking to the same card, or that it is configured for optimal rates.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..
Lctasca
Visitor II
January 18, 2019

Hello

Have the same problem here, managed to solve the issue Tim?