touch: SD mount ladders renegotiate the clock upward after a slow-rung init (#194)

A card whose power-up handshake only completed at 400 kHz kept 400 kHz as its
SESSION clock — SD.begin's frequency is the operating clock, and neither the
boot ladder (main.cpp) nor the runtime ladder (fmSdTryMount) ever raised it
after a slow success. With the SD as the T-Deck's primary store that meant
loading contacts + history at ~25 KB/s: the reported ~3-minute boot, f_getfree
timeouts making an inserted card show as 0 KB/empty in the file manager, and
backups wedging. Launcher installs hit it most (the Launcher's own SD use
leaves the card needing the slow wake path more often).

Standard SD bring-up is init-slow-then-raise: after any sub-4MHz success both
ladders now re-begin at 4 MHz, falling back to the clock that just worked if
the fast re-begin fails. A healthy card is unaffected (mounts at 4 MHz on the
first rung). T-Deck + V4-R8 + M9 (the shared-SPI SD boards) build.

Likely also behind the long-standing Launcher-mode weirdness cluster together
with the torn-prefs fix (#195/#196): slow-clock sessions made every write
window enormous.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Kaj SchittecatandClaude Opus 4.8 committed 2026-08-01 11:36:24 +02:00
1 parent 67b863d93e
commit 51617b404e
2 files changed
+39 -1

No files matched your search

+24 -1
View File
@@ -519,11 +519,34 @@ void setup() {
{ 300, 1000000 }, { 450, 1000000 }, { 650, 400000 }, { 900, 400000 },
};
int tries = want_full_sd ? 7 : 3;
uint32_t mounted_hz = 0;
for (int a = 0; a < tries && !sd_mounted; ++a) {
SD.end();
delay(kBootMount[a].settle_ms);
if (SD.begin(PIN_SD_CS, *_spi, kBootMount[a].hz, "/sd", 6) && SD.cardType() != CARD_NONE)
if (SD.begin(PIN_SD_CS, *_spi, kBootMount[a].hz, "/sd", 6) && SD.cardType() != CARD_NONE) {
sd_mounted = true;
mounted_hz = kBootMount[a].hz;
}
}
// RENEGOTIATE UPWARD after a slow-rung success (GH #194). Standard SD bring-up is
// "initialise at a conservative clock, then raise it" — but SD.begin's clock is the
// operating clock for the whole session, so a card that only WOKE at 400 kHz then ran
// its entire life at 400 kHz (~25 KB/s). With the card as the primary store that was a
// ~3-minute boot (contacts + history at modem speed), runtime f_getfree timeouts (the
// file manager showing an inserted card as 0 KB/empty), and wedged backups. An
// initialised card almost always sustains 4 MHz even when its power-up handshake needed
// 400 kHz; if the fast re-begin fails, fall back to the clock that just worked.
if (sd_mounted && mounted_hz < 4000000) {
SD.end();
delay(60);
if (SD.begin(PIN_SD_CS, *_spi, 4000000, "/sd", 6) && SD.cardType() != CARD_NONE) {
Serial.printf("[BOOT] SD renegotiated %lu -> 4000000 Hz\n", (unsigned long)mounted_hz);
} else {
SD.end();
delay(120);
sd_mounted = SD.begin(PIN_SD_CS, *_spi, mounted_hz, "/sd", 6) && SD.cardType() != CARD_NONE;
if (sd_mounted) Serial.printf("[BOOT] SD stays at %lu Hz (4 MHz renegotiation failed)\n", (unsigned long)mounted_hz);
}
}
}
if (sd_mounted) {