SdFat
SdFat copied to clipboard
Failure in FatPartition::init after editing file on PC
Version 2.1.0 MCU - Custom ATMEGA2560
I should start by saying that I have been working through your library to de-Arduino it for execution on a custom AVR ATMEGA2560.
All is working quite well ... except ...
If I take the SD card from the MCU, load it into my PC, edit the file that I am using as a configuration file for my application, EJECT the card, then load back into the MCU - I encounter an error in FatPartition::init.
Error code 0x1D Error data 0xFF
The section of code that suffers the error is:
if (!mbr || mp->type == 0 || (mp->boot != 0 && mp->boot != 0X80)) {
asm volatile("nop"); // for breakpoint
DBG_FAIL_MACRO;
goto fail;
}
I stress the word EJECT above, as I initially thought that simply removing the card from the PC without ejecting might be leaving something in an odd state. So I started EJECTing intentionally.
Yet strangely - if I reset the AVR - everything starts working satisfactorily again (until the next edit of course).
I should also state the card in question is FAT16 (not that I suspect it should make any difference).
Edit - #define SPI_CLOCK SD_SCK_HZ(1000UL * 16) & #define SPI_CLOCK SD_SCK_HZ(1000UL * 4)
attempted ... results same.
Any ideas ?
The error:
Error code 0x1D Error data 0xFF
Is a read timeout error. So the first read of the SD fails. This has nothing to do with the format of the card, just a read of sector zero.
This is the call that fails:
mbr = reinterpret_cast<MbrSector_t*>
(dataCachePrepare(0, FsCache::CACHE_FOR_READ));
I should do the test for a return of null after this call. I will add the mod in a future version.
I have no idea why this is happening. I regularly remove SD cards and insert new ones during tests with examples like bench.
It's best to close all files and call sd.end() before removing a card. Call sd.begin() after the new card is inserted.
It was a problem of my own making (which I kind of expected ... but couldn't nail down).
Seems in the process of "de-Arduino'ing" - It hadn't registered you had typdef'ed SdMillis_t down to 16 bits - so I was comparing a 32bit return from millis() to a 16 bit "t0" timestamp.
So isTimedOut was triggering early.
I suspect that after ejecting the SD card from the PC - something remains in a busy state (returning 0xff) - and the isTimedOut was prematurely generating timed out conditions.
The 16 bit time dates back to the first version of SdFat in 2009 when I made it run on a 16K flash1KB RAM ATMEGA168. I avoided 32-bit when ever possible.
Did you get the call to end() to work?
#include "SdFat.h"
SdFat sd;
void setup() {
// Close all files then call end like this.
sd.end();
}
void loop() {}
2.1.0 doesn’t have any of the end() functions, so I lifted them from the current GitHub master and inserted them into my 2.1.0-with mods.
I’m not sure they have great effect as my SD processes are all in a function - so the objects should get torn down at the conclusion of the function.
On Wed, 13 Apr 2022 at 10:46 pm, Bill Greiman @.***> wrote:
The 16 bit time dates back to the first version of SdFat in 2009 when I made it run on a 16K flash1KB RAM ATMEGA168. I avoided 32-bit when ever possible.
Did you get the call to end() to work?
#include "SdFat.h" SdFat sd; void setup() { // Close all files then call end like this. sd.end(); } void loop() {}
— Reply to this email directly, view it on GitHub https://github.com/greiman/SdFat/issues/368#issuecomment-1098008758, or unsubscribe https://github.com/notifications/unsubscribe-auth/AMY4VAXXA3QAPSM46L322BDVE2635ANCNFSM5TFKYMRA . You are receiving this because you authored the thread.Message ID: @.***>
A key part of sd.end() is a call to SPI.end().
You also need to make sure all files are closed if you use dedicated SPI since you may get unbalanced SPI.beginTransaction() SPI.endTransaction().
Unfortunately not enough state is included in the classes to insure cleanup for all classes in destructors.
Ah yes - good point
On Thu, 14 Apr 2022 at 12:39 am, Bill Greiman @.***> wrote:
A key part of sd.end() is a call to SPI.end().
You also need to make sure all files are closed if you use dedicated SPI since you may get unbalanced SPI.beginTransaction() SPI.endTransaction().
— Reply to this email directly, view it on GitHub https://github.com/greiman/SdFat/issues/368#issuecomment-1098133410, or unsubscribe https://github.com/notifications/unsubscribe-auth/AMY4VAX3XJBV3NGNFXTFHO3VE3MCBANCNFSM5TFKYMRA . You are receiving this because you authored the thread.Message ID: @.***>
Hmmm ... with that in mind - would one make a call to sd.end() in the event that cardBegin failed ? I would assume yes as we must have done a SPI.beginTransaction() ... ?
If you have failures initializing an SD there is probably a hardware problem.
I generally test a new version of SdFat with about 10-15 SD cards. I start the test program and when it pauses, I swap cards and have no problems with sd.begin().
If you have any other SPI devices you must disable them by setting their CS pin high.