SDMMC: Cannot init_card() after card is removed and inserted
Using the code at https://github.com/mattico/miscomp-repro extracted and simplified from my firmware.
Trying to run init_card() a second time after the card is removed and re-inserted always returns an error here: https://github.com/stm32-rs/stm32h7xx-hal/blob/e6da7dc7bf9cd9f85e4f84a980a94e8cbf18be34/src/sdmmc.rs#L520
Since there's no way to free() and re-initialize the SDMMC it seems like this should work?
Actually the error doesn't happen at sdmmc.rs:520, that was a debuginfo bug? It seems that get_scr returns Error::Timeout.
More precisely: the card can be inserted at runtime but it only works the first time it's inserted.
Looking at 55.6.7 Reset and card cycle power in the RM, there are a number of steps that need to occur to reset the card, which includes completely resetting the SDMMC peripheral (the PWRCTRL bits can't be written after being set to ON). Perhaps the card is getting spurious data when inserted due to the peripheral still being enabled after the first insertion.
I tried adding a deinit_card function which would be called after the card disconnects but that didn't help.
https://github.com/mattico/stm32h7xx-hal/commit/4588673a177a3675407bfead94fd601c3534caf7
pub fn deinit_card(&mut self) {
let prec = unsafe { core::mem::transmute::<(), rec::$Rec>(()) };
let clkr = self.sdmmc.clkcr.read().bits();
prec.reset();
self.sdmmc.clkcr.write(|w| unsafe { w.bits(clkr) });
self.card = None;
self.signalling = Default::default();
self.sdmmc.power.modify(|_, w| unsafe { w.pwrctrl().bits(PowerCtrl::Reset as u8)})
}
@mattico Did you get this working?
Nope!