mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-28 04:40:39 +00:00
support 8 lane data bus
This commit is contained in:
parent
b92eb948b5
commit
0a231505d8
@ -145,6 +145,8 @@ pub enum Error {
|
||||
Crc,
|
||||
/// No card inserted.
|
||||
NoCard,
|
||||
/// 8-lane buses are not supported for SD cards.
|
||||
BusWidth,
|
||||
/// Bad clock supplied to the SDMMC peripheral.
|
||||
BadClock,
|
||||
/// Signaling switch failed.
|
||||
@ -365,6 +367,10 @@ pub struct Sdmmc<'d, T: Instance> {
|
||||
d1: Option<Peri<'d, AnyPin>>,
|
||||
d2: Option<Peri<'d, AnyPin>>,
|
||||
d3: Option<Peri<'d, AnyPin>>,
|
||||
d4: Option<Peri<'d, AnyPin>>,
|
||||
d5: Option<Peri<'d, AnyPin>>,
|
||||
d6: Option<Peri<'d, AnyPin>>,
|
||||
d7: Option<Peri<'d, AnyPin>>,
|
||||
|
||||
config: Config,
|
||||
/// Current clock to card
|
||||
@ -413,6 +419,10 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
config,
|
||||
)
|
||||
}
|
||||
@ -448,6 +458,60 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
|
||||
Some(d1.into()),
|
||||
Some(d2.into()),
|
||||
Some(d3.into()),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
config,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(sdmmc_v1)]
|
||||
impl<'d, T: Instance> Sdmmc<'d, T> {
|
||||
/// Create a new SDMMC driver, with 8 data lanes.
|
||||
pub fn new_8bit(
|
||||
sdmmc: Peri<'d, T>,
|
||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||
dma: Peri<'d, impl SdmmcDma<T>>,
|
||||
clk: Peri<'d, impl CkPin<T>>,
|
||||
cmd: Peri<'d, impl CmdPin<T>>,
|
||||
d0: Peri<'d, impl D0Pin<T>>,
|
||||
d1: Peri<'d, impl D1Pin<T>>,
|
||||
d2: Peri<'d, impl D2Pin<T>>,
|
||||
d3: Peri<'d, impl D3Pin<T>>,
|
||||
d4: Peri<'d, impl D4Pin<T>>,
|
||||
d5: Peri<'d, impl D5Pin<T>>,
|
||||
d6: Peri<'d, impl D6Pin<T>>,
|
||||
d7: Peri<'d, impl D7Pin<T>>,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
critical_section::with(|_| {
|
||||
clk.set_as_af(clk.af_num(), CLK_AF);
|
||||
cmd.set_as_af(cmd.af_num(), CMD_AF);
|
||||
d0.set_as_af(d0.af_num(), DATA_AF);
|
||||
d1.set_as_af(d1.af_num(), DATA_AF);
|
||||
d2.set_as_af(d2.af_num(), DATA_AF);
|
||||
d3.set_as_af(d3.af_num(), DATA_AF);
|
||||
d4.set_as_af(d4.af_num(), DATA_AF);
|
||||
d5.set_as_af(d5.af_num(), DATA_AF);
|
||||
d6.set_as_af(d6.af_num(), DATA_AF);
|
||||
d7.set_as_af(d7.af_num(), DATA_AF);
|
||||
});
|
||||
|
||||
Self::new_inner(
|
||||
sdmmc,
|
||||
new_dma_nonopt!(dma),
|
||||
clk.into(),
|
||||
cmd.into(),
|
||||
d0.into(),
|
||||
Some(d1.into()),
|
||||
Some(d2.into()),
|
||||
Some(d3.into()),
|
||||
Some(d4.into()),
|
||||
Some(d5.into()),
|
||||
Some(d6.into()),
|
||||
Some(d7.into()),
|
||||
config,
|
||||
)
|
||||
}
|
||||
@ -470,7 +534,20 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
|
||||
d0.set_as_af(d0.af_num(), DATA_AF);
|
||||
});
|
||||
|
||||
Self::new_inner(sdmmc, clk.into(), cmd.into(), d0.into(), None, None, None, config)
|
||||
Self::new_inner(
|
||||
sdmmc,
|
||||
clk.into(),
|
||||
cmd.into(),
|
||||
d0.into(),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
config,
|
||||
)
|
||||
}
|
||||
|
||||
/// Create a new SDMMC driver, with 4 data lanes.
|
||||
@ -502,6 +579,58 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
|
||||
Some(d1.into()),
|
||||
Some(d2.into()),
|
||||
Some(d3.into()),
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
config,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(sdmmc_v2)]
|
||||
impl<'d, T: Instance> Sdmmc<'d, T> {
|
||||
/// Create a new SDMMC driver, with 8 data lanes.
|
||||
pub fn new_8bit(
|
||||
sdmmc: Peri<'d, T>,
|
||||
_irq: impl interrupt::typelevel::Binding<T::Interrupt, InterruptHandler<T>> + 'd,
|
||||
clk: Peri<'d, impl CkPin<T>>,
|
||||
cmd: Peri<'d, impl CmdPin<T>>,
|
||||
d0: Peri<'d, impl D0Pin<T>>,
|
||||
d1: Peri<'d, impl D1Pin<T>>,
|
||||
d2: Peri<'d, impl D2Pin<T>>,
|
||||
d3: Peri<'d, impl D3Pin<T>>,
|
||||
d4: Peri<'d, impl D4Pin<T>>,
|
||||
d5: Peri<'d, impl D5Pin<T>>,
|
||||
d6: Peri<'d, impl D6Pin<T>>,
|
||||
d7: Peri<'d, impl D7Pin<T>>,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
critical_section::with(|_| {
|
||||
clk.set_as_af(clk.af_num(), CLK_AF);
|
||||
cmd.set_as_af(cmd.af_num(), CMD_AF);
|
||||
d0.set_as_af(d0.af_num(), DATA_AF);
|
||||
d1.set_as_af(d1.af_num(), DATA_AF);
|
||||
d2.set_as_af(d2.af_num(), DATA_AF);
|
||||
d3.set_as_af(d3.af_num(), DATA_AF);
|
||||
d4.set_as_af(d4.af_num(), DATA_AF);
|
||||
d5.set_as_af(d5.af_num(), DATA_AF);
|
||||
d6.set_as_af(d6.af_num(), DATA_AF);
|
||||
d7.set_as_af(d7.af_num(), DATA_AF);
|
||||
});
|
||||
|
||||
Self::new_inner(
|
||||
sdmmc,
|
||||
clk.into(),
|
||||
cmd.into(),
|
||||
d0.into(),
|
||||
Some(d1.into()),
|
||||
Some(d2.into()),
|
||||
Some(d3.into()),
|
||||
Some(d4.into()),
|
||||
Some(d5.into()),
|
||||
Some(d6.into()),
|
||||
Some(d7.into()),
|
||||
config,
|
||||
)
|
||||
}
|
||||
@ -517,6 +646,10 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
|
||||
d1: Option<Peri<'d, AnyPin>>,
|
||||
d2: Option<Peri<'d, AnyPin>>,
|
||||
d3: Option<Peri<'d, AnyPin>>,
|
||||
d4: Option<Peri<'d, AnyPin>>,
|
||||
d5: Option<Peri<'d, AnyPin>>,
|
||||
d6: Option<Peri<'d, AnyPin>>,
|
||||
d7: Option<Peri<'d, AnyPin>>,
|
||||
config: Config,
|
||||
) -> Self {
|
||||
rcc::enable_and_reset::<T>();
|
||||
@ -555,6 +688,10 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
|
||||
d1,
|
||||
d2,
|
||||
d3,
|
||||
d4,
|
||||
d5,
|
||||
d6,
|
||||
d7,
|
||||
|
||||
config,
|
||||
clock: SD_INIT_FREQ,
|
||||
@ -1039,6 +1176,10 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
|
||||
impl<'d, T: Instance> Sdmmc<'d, T> {
|
||||
/// Initializes card (if present) and sets the bus at the specified frequency.
|
||||
pub async fn init_card(&mut self, freq: Hertz) -> Result<(), Error> {
|
||||
if self.d7.is_some() {
|
||||
return Err(Error::BusWidth);
|
||||
}
|
||||
|
||||
let regs = T::regs();
|
||||
let ker_ck = T::frequency();
|
||||
|
||||
@ -1419,9 +1560,10 @@ impl<'d, T: Instance> Sdmmc<'d, T> {
|
||||
let regs = T::regs();
|
||||
let ker_ck = T::frequency();
|
||||
|
||||
let bus_width = match self.d3.is_some() {
|
||||
true => BusWidth::Four,
|
||||
false => BusWidth::One,
|
||||
let bus_width = match (self.d3.is_some(), self.d7.is_some()) {
|
||||
(true, true) => BusWidth::Eight,
|
||||
(true, false) => BusWidth::Four,
|
||||
_ => BusWidth::One,
|
||||
};
|
||||
|
||||
// While the SD/SDIO card or eMMC is in identification mode,
|
||||
@ -1613,6 +1755,18 @@ impl<'d, T: Instance> Drop for Sdmmc<'d, T> {
|
||||
if let Some(x) = &mut self.d3 {
|
||||
x.set_as_disconnected();
|
||||
}
|
||||
if let Some(x) = &mut self.d4 {
|
||||
x.set_as_disconnected();
|
||||
}
|
||||
if let Some(x) = &mut self.d5 {
|
||||
x.set_as_disconnected();
|
||||
}
|
||||
if let Some(x) = &mut self.d6 {
|
||||
x.set_as_disconnected();
|
||||
}
|
||||
if let Some(x) = &mut self.d7 {
|
||||
x.set_as_disconnected();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user