2018-08-29 09:19 AM
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?
Solved! Go to Solution.
2019-01-25 06:17 AM
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);
2018-09-26 06:38 AM
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.
2018-09-26 08:09 AM
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.
2018-10-01 11:45 AM
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?
2018-10-01 11:50 AM
We use a card detect circuit so to avoid attempting comm. if there's no card present.
2018-10-02 07:40 AM
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.
2018-10-02 08:05 AM
>>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.
2018-10-02 11:51 AM
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())?
2018-10-02 01:33 PM
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.
2018-10-03 01:19 AM
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.