I have developed a device that uses Teensy 4.1 and enables the user to read and write data onto the internal SD card.
There are some cases where SD.begin() returns false.
I just finished the first 30 units and use the same type of FAT32-formatted SD-cards in all of them (Intenso microSDHC Class 4, 4GB: LINK). In about 5/30 units i have problems with the SD-card.
When initializing the SD-card, sometimes SD.begin(BUILTIN_SDCARD) returns false, like 3/10 of access attempts. This seems to be dependent on the SD-card inserted, some cards do not produce any errors while others do. For this first release i made some sort of brute-force workaround by simply trying SD.begin a few times after each other. In most cases, if the first attempt fails the second attempt is successful.
I dug deeper into the library and found out, that in the function
SdioCard::begin(SdioConfig sdioConfig) --> cardCMD6()
there are two kinds of errors produced:
SD_CARD_ERROR_CMD6 "Switch card function"<-- more often
SD_CARD_ERROR_DMA "DMA transfer failed" <-- rarely
If no errors occur, the SD clock frequency kHzSdClk is set to 50000.
I also have a bunch of low quality 64MB SD-cards from alibaba here with FAT16 formatting which used to work well on a very old version of the SD library (I don't remember which one...) but now produce the error code on most attempts of SD.begin(). They also work find on a computer.
ACMD41, "Activate card initialization"
My goal is to get my code as robust as possible for any kind of FAT-formatted SD-card that any user might insert. All of the above cards work well on a computer. Write and read speed are not so important as my files have only a few kByte.
I am also using:
- I2S audio codec
- OpenAudio library (32bit version of the regular Audio lib, but relies on the same principles)
- ADC with interrupt timer, priority 208 and 224
- WS2812Serial library
- Adafruit SSD1306 library (I2C display)
- Encoder library
- external PSRAM chip APS6404
I am actually writing my code in VScode and PlatformIO. But as their version of Teensy core and libraries usually are far behind, i also installed Teensyduino 1.56 and use the Teensyduino /cores/ and /libraries/ folder instead of the PlatformIO bundled versions.
Here is my caller code:
In SdioTeensy.cpp i enabled USE_DEBUG_MODE and added some debug output in SdFat.h
Debug output for an attempt where the first try of SD.begin fails and the second one succeeds:
Thank you for any hint!
There are some cases where SD.begin() returns false.
I just finished the first 30 units and use the same type of FAT32-formatted SD-cards in all of them (Intenso microSDHC Class 4, 4GB: LINK). In about 5/30 units i have problems with the SD-card.
When initializing the SD-card, sometimes SD.begin(BUILTIN_SDCARD) returns false, like 3/10 of access attempts. This seems to be dependent on the SD-card inserted, some cards do not produce any errors while others do. For this first release i made some sort of brute-force workaround by simply trying SD.begin a few times after each other. In most cases, if the first attempt fails the second attempt is successful.
I dug deeper into the library and found out, that in the function
SdioCard::begin(SdioConfig sdioConfig) --> cardCMD6()
there are two kinds of errors produced:
SD_CARD_ERROR_CMD6 "Switch card function"<-- more often
SD_CARD_ERROR_DMA "DMA transfer failed" <-- rarely
If no errors occur, the SD clock frequency kHzSdClk is set to 50000.
I also have a bunch of low quality 64MB SD-cards from alibaba here with FAT16 formatting which used to work well on a very old version of the SD library (I don't remember which one...) but now produce the error code on most attempts of SD.begin(). They also work find on a computer.
ACMD41, "Activate card initialization"
My goal is to get my code as robust as possible for any kind of FAT-formatted SD-card that any user might insert. All of the above cards work well on a computer. Write and read speed are not so important as my files have only a few kByte.
I am also using:
- I2S audio codec
- OpenAudio library (32bit version of the regular Audio lib, but relies on the same principles)
- ADC with interrupt timer, priority 208 and 224
- WS2812Serial library
- Adafruit SSD1306 library (I2C display)
- Encoder library
- external PSRAM chip APS6404
I am actually writing my code in VScode and PlatformIO. But as their version of Teensy core and libraries usually are far behind, i also installed Teensyduino 1.56 and use the Teensyduino /cores/ and /libraries/ folder instead of the PlatformIO bundled versions.
Here is my caller code:
Code:
#define NR_OF_SD_TRIES_MAX 4U
SDClass SD;
// Workaround to give the SD-card begin a few more tries. Each try causes a delay of 1 second, probably from BUSY_TIMEOUT_MICROS = 1000000 in SdioTeensy.cpp
uint8_t ct=0;
bool success = false;
while(ct < NR_OF_SD_TRIES_MAX && !success) {
if(SD.begin((uint8_t)(BUILTIN_SDCARD))) {
success = true;
break;
}
ct++;
}
if(!success) {
Serial.println("MenuHandler::readGlobalDataFromSdCard(): initialization failed!");
return 2;
}
if(ct > 0) {
Serial.printf("MenuHandler::readGlobalDataFromSdCard(): Needed more tries to open SD-card: %i\n", ct);
}
In SdioTeensy.cpp i enabled USE_DEBUG_MODE and added some debug output in SdFat.h
Debug output for an attempt where the first try of SD.begin fails and the second one succeeds:
Code:
LINE: 420
BLKATTR 10040
XFERTYP 63A0000 CMD6 TYP0 DPSEL
PRSSTAT FF888088 SDOFF SDSTB
PROCTL 8800022 EMODE2 DWT1
IRQSTAT 0
m_irqstat B
SdioCard::begin(): kHzSdClk = 25000
SdFat.h SdBase::cardBegin(SdioConfig): m_card->errorCode() = 4
SdFat.h SdBase::begin(): cardBegin success: 0, Vol::begin success: 1
SdioCard::begin(): kHzSdClk = 50000
SdFat.h SdBase::cardBegin(SdioConfig): m_card->errorCode() = 0
SdFat.h SdBase::begin(): cardBegin success: 1, Vol::begin success: 1
MenuHandler::readGlobalDataFromSdCard(): Needed more tries to open SD-card: 1
Thank you for any hint!