greiman / SdFat

Arduino FAT16/FAT32 exFAT Library
MIT License
1.07k stars 503 forks source link

esp32 - shared spi - lowering 'no card' initialisation timeout #438

Open DaLiV opened 1 year ago

DaLiV commented 1 year ago

is this possible somehow lower initialisation timeouts (so that will be below 100ms) used : SD_FAT_VERSION 20202

Explanation :

only as info : in "card connected" case init takes 20ms

ENABLE_DEDICATED_SPI=0
SPI_DRIVER_SELECT=1
const uint8_t SD_CS_PIN = 23;
const uint8_t SOFT_MISO_PIN = 15;
const uint8_t SOFT_MOSI_PIN = 4;
const uint8_t SOFT_SCK_PIN = 17;
#define SD_CONFIG SdSpiConfig(SD_CS_PIN, USER_SPI_BEGIN, SD_SCK_MHZ(20))

void testCard() {
 unsigned long timeb = millis();
 if (!sd.begin(SD_CONFIG)) {
  Serial.printf("%u:",millis()-timeb);
 }
}
DaLiV commented 1 year ago

found in SdCardInfo.h const uint16_t SD_INIT_TIMEOUT = 2000;

measured real timings for exact card - approximated that was

can close. but may consider also as point for improvement (add parameter passed to begin() function)

greiman commented 1 year ago

The SD standard states:

The busy bit in the OCR is used by the card to inform the host whether initialization of ACMD41 is completed. Setting the busy bit to 0 indicates that the card is still initializing. Setting the busy bit to 1 indicates completion of initialization. Card initialization shall be completed within 1 second from the first ACMD41. The host repeatedly issues ACMD41 for at least 1 second or until the busy bit are set to 1.

I have found that two seconds is about the minimal time to avoid problems with initialization. Card initialization depends on a number of factors including the size of the erased flash pool.

The SD Standard also state:

In order to be able to give feedback indication to the users, the SD Memory Card system shall implement detection of card insertion or removal. One method is that connector generate card detect signal.

I have also found that a card detect switch is the only practical way to implement hot card insertion and removal.

Many companies sell SD modules/sockets with a CD switch. In fact almost all SD sockets have a card detect switch but cheap breakout boards don't add a pin for it. Often it is possible to solder a wire to the pin on the socket.

Here is a socket that brings out CD and all SD pins.

Edit: Sorry but after 15 years of dealing with SD cards I no longer have an interest in flaky ways to support hot card insertion when the correct way is so easy.

greiman commented 1 year ago

At one point I tried to use a feature that was intended for card detect without a CD switch. The DATA3/CS pin has a 50K pull-up resistor enabled when the card is inserted. The idea was to have a weak pull-down resistor on CS and use digitalRead to detect the card.

This didn't work since 5V systems have level shifters and 3V3 breakout boards usually have 10K pull-ups.

Here is the text from an old SD standard:

At power up this line has a 50K Ohm pull up enabled in the card. This resistor serves two functions Card detection and Mode Selection. For Mode Selection, the host can drive the line high or let it be pulled high to select SD mode. If the host wants to select SPI mode it should drive the line low.

greiman commented 1 year ago

I tried the 50K feature on a 3.3V SAMD21 board. Seems very reliable with a 150K pull-down.

I can remove the breakout 10K pull-up with a fine solder tip.

Here is the test program.

// Uses a 150K resistor on CS pin of a Feather M0 Express
void setup() {
  Serial.begin(9600);
  while (!Serial) {}
  pinMode(SS, INPUT);
}
void loop() {
  Serial.println(digitalRead(SS) ? "HIGH" : "LOW");
  delay(500);
}

Typical output for card insertion:

LOW LOW LOW HIGH HIGH HIGH HIGH

Here is a photo of the modified breakout. There is no solder in the area where I removed the 10K pull-up - just glare from the board.

SD breakout

Still it's best to pick one of these high quality breakouts. I started working with Adafruit in 2008 on SD modules.

From Amazon, quick but with a premium price for shipping:

3.3 V boards

5 v boards