From 3ee57eb8781bc3fb3da72e2effa6d0e09104cb48 Mon Sep 17 00:00:00 2001 From: Andy Aragon Date: Fri, 29 May 2026 11:22:25 -0700 Subject: [PATCH] fix(firmware): load STACKCHAN.RON via long-filename lookup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "STACKCHAN" is a 9-char base name, which is not a valid FAT 8.3 short name, so embedded-sdmmc's open_file_in_dir rejected "STACKCHAN.RON" with NameTooLong — masked as FileNotFound — and the boot config never loaded even though the file was on the card (short name STACKC~1.RON + an LFN entry). Resolve the short name by matching the long name via iterate_dir_lfn, then open by that. --- crates/stackchan-firmware/src/storage.rs | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/crates/stackchan-firmware/src/storage.rs b/crates/stackchan-firmware/src/storage.rs index 14d284e..22a28bc 100644 --- a/crates/stackchan-firmware/src/storage.rs +++ b/crates/stackchan-firmware/src/storage.rs @@ -24,7 +24,7 @@ use embassy_sync::mutex::Mutex; use embassy_time::Delay; use embedded_hal::digital::OutputPin; use embedded_hal::spi::SpiBus; -use embedded_sdmmc::{Mode, SdCard, TimeSource, Timestamp, VolumeIdx, VolumeManager}; +use embedded_sdmmc::{LfnBuffer, Mode, SdCard, TimeSource, Timestamp, VolumeIdx, VolumeManager}; use esp_hal::Blocking; use esp_hal::gpio::Output; use esp_hal::spi::Mode as SpiMode; @@ -365,8 +365,23 @@ where .open_volume(VolumeIdx(0)) .map_err(|_| StorageError::Volume)?; let root = volume.open_root_dir().map_err(|_| StorageError::Volume)?; + // CONFIG_FILE ("STACKCHAN.RON") has a 9-char base name, which is not a + // valid FAT 8.3 short name — `open_file_in_dir` rejects it outright with + // `NameTooLong`. The card stores it with a long-filename entry and a + // mangled short name (e.g. `STACKC~1.RON`), so resolve the short name by + // matching the long name, then open by that. + let mut lfn_storage = [0u8; 64]; + let mut lfn = LfnBuffer::new(&mut lfn_storage); + let mut short = None; + root.iterate_dir_lfn(&mut lfn, |entry, long| { + if short.is_none() && long.is_some_and(|l| l.eq_ignore_ascii_case(CONFIG_FILE)) { + short = Some(entry.name.clone()); + } + }) + .map_err(|_| StorageError::Volume)?; + let short = short.ok_or(StorageError::FileNotFound)?; let file = root - .open_file_in_dir(CONFIG_FILE, Mode::ReadOnly) + .open_file_in_dir(&short, Mode::ReadOnly) .map_err(|_| StorageError::FileNotFound)?; let len = file.length();