Update embassy-stm32

This commit is contained in:
Dario Nieuwenhuis
2022-07-23 01:29:35 +02:00
parent e0521ea249
commit 8a9d2f59af
26 changed files with 433 additions and 361 deletions

View File

@ -1,18 +1,17 @@
#![macro_use]
use core::default::Default;
use core::marker::PhantomData;
use core::task::Poll;
use embassy::waitqueue::AtomicWaker;
use embassy_hal_common::drop::OnDrop;
use embassy_hal_common::unborrow;
use embassy_hal_common::{unborrow, Unborrowed};
use futures::future::poll_fn;
use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR};
use crate::dma::NoDma;
use crate::gpio::sealed::AFType;
use crate::gpio::{Pull, Speed};
use crate::gpio::sealed::{AFType, Pin};
use crate::gpio::{AnyPin, Pull, Speed};
use crate::interrupt::{Interrupt, InterruptExt};
use crate::pac::sdmmc::Sdmmc as RegBlock;
use crate::rcc::RccPeripheral;
@ -176,12 +175,19 @@ impl Default for Config {
}
/// Sdmmc device
pub struct Sdmmc<'d, T: Instance, P: Pins<T>, Dma = NoDma> {
sdmmc: PhantomData<&'d mut T>,
pins: P,
irq: T::Interrupt,
pub struct Sdmmc<'d, T: Instance, Dma = NoDma> {
_peri: Unborrowed<'d, T>,
irq: Unborrowed<'d, T::Interrupt>,
dma: Unborrowed<'d, Dma>,
clk: Unborrowed<'d, AnyPin>,
cmd: Unborrowed<'d, AnyPin>,
d0: Unborrowed<'d, AnyPin>,
d1: Option<Unborrowed<'d, AnyPin>>,
d2: Option<Unborrowed<'d, AnyPin>>,
d3: Option<Unborrowed<'d, AnyPin>>,
config: Config,
dma: Dma,
/// Current clock to card
clock: Hertz,
/// Current signalling scheme to card
@ -191,16 +197,99 @@ pub struct Sdmmc<'d, T: Instance, P: Pins<T>, Dma = NoDma> {
}
#[cfg(sdmmc_v1)]
impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
pub fn new(
_peripheral: impl Unborrow<Target = T> + 'd,
pins: impl Unborrow<Target = P> + 'd,
impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> {
pub fn new_1bit(
sdmmc: impl Unborrow<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd,
config: Config,
dma: impl Unborrow<Target = Dma> + 'd,
clk: impl Unborrow<Target = impl CkPin<T>> + 'd,
cmd: impl Unborrow<Target = impl CmdPin<T>> + 'd,
d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
config: Config,
) -> Self {
unborrow!(irq, pins, dma);
pins.configure();
unborrow!(clk, cmd, d0);
critical_section::with(|_| unsafe {
clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None);
cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up);
d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up);
clk.set_speed(Speed::VeryHigh);
cmd.set_speed(Speed::VeryHigh);
d0.set_speed(Speed::VeryHigh);
});
Self::new_inner(
sdmmc,
irq,
dma,
clk.map_into(),
cmd.map_into(),
d0.map_into(),
None,
None,
None,
config,
)
}
pub fn new_4bit(
sdmmc: impl Unborrow<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd,
dma: impl Unborrow<Target = Dma> + 'd,
clk: impl Unborrow<Target = impl CkPin<T>> + 'd,
cmd: impl Unborrow<Target = impl CmdPin<T>> + 'd,
d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
config: Config,
) -> Self {
unborrow!(clk, cmd, d0, d1, d2, d3);
critical_section::with(|_| unsafe {
clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None);
cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up);
d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up);
d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::Up);
d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::Up);
d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::Up);
clk.set_speed(Speed::VeryHigh);
cmd.set_speed(Speed::VeryHigh);
d0.set_speed(Speed::VeryHigh);
d1.set_speed(Speed::VeryHigh);
d2.set_speed(Speed::VeryHigh);
d3.set_speed(Speed::VeryHigh);
});
Self::new_inner(
sdmmc,
irq,
dma,
clk.map_into(),
cmd.map_into(),
d0.map_into(),
Some(d1.map_into()),
Some(d2.map_into()),
Some(d3.map_into()),
config,
)
}
fn new_inner(
sdmmc: impl Unborrow<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd,
dma: impl Unborrow<Target = Dma> + 'd,
clk: Unborrowed<'d, AnyPin>,
cmd: Unborrowed<'d, AnyPin>,
d0: Unborrowed<'d, AnyPin>,
d1: Option<Unborrowed<'d, AnyPin>>,
d2: Option<Unborrowed<'d, AnyPin>>,
d3: Option<Unborrowed<'d, AnyPin>>,
config: Config,
) -> Self {
unborrow!(sdmmc, irq, dma);
T::enable();
T::reset();
@ -213,11 +302,18 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
irq.enable();
Self {
sdmmc: PhantomData,
pins,
_peri: sdmmc,
irq,
config,
dma,
clk,
cmd,
d0,
d1,
d2,
d3,
config,
clock,
signalling: Default::default(),
card: None,
@ -226,15 +322,94 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
}
#[cfg(sdmmc_v2)]
impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P, NoDma> {
pub fn new(
_peripheral: impl Unborrow<Target = T> + 'd,
pins: impl Unborrow<Target = P> + 'd,
impl<'d, T: Instance> Sdmmc<'d, T, NoDma> {
pub fn new_1bit(
sdmmc: impl Unborrow<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd,
clk: impl Unborrow<Target = impl CkPin<T>> + 'd,
cmd: impl Unborrow<Target = impl CmdPin<T>> + 'd,
d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
config: Config,
) -> Self {
unborrow!(irq, pins);
pins.configure();
unborrow!(clk, cmd, d0);
critical_section::with(|_| unsafe {
clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None);
cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up);
d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up);
clk.set_speed(Speed::VeryHigh);
cmd.set_speed(Speed::VeryHigh);
d0.set_speed(Speed::VeryHigh);
});
Self::new_inner(
sdmmc,
irq,
clk.map_into(),
cmd.map_into(),
d0.map_into(),
None,
None,
None,
config,
)
}
pub fn new_4bit(
sdmmc: impl Unborrow<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd,
clk: impl Unborrow<Target = impl CkPin<T>> + 'd,
cmd: impl Unborrow<Target = impl CmdPin<T>> + 'd,
d0: impl Unborrow<Target = impl D0Pin<T>> + 'd,
d1: impl Unborrow<Target = impl D1Pin<T>> + 'd,
d2: impl Unborrow<Target = impl D2Pin<T>> + 'd,
d3: impl Unborrow<Target = impl D3Pin<T>> + 'd,
config: Config,
) -> Self {
unborrow!(clk, cmd, d0, d1, d2, d3);
critical_section::with(|_| unsafe {
clk.set_as_af_pull(clk.af_num(), AFType::OutputPushPull, Pull::None);
cmd.set_as_af_pull(cmd.af_num(), AFType::OutputPushPull, Pull::Up);
d0.set_as_af_pull(d0.af_num(), AFType::OutputPushPull, Pull::Up);
d1.set_as_af_pull(d1.af_num(), AFType::OutputPushPull, Pull::Up);
d2.set_as_af_pull(d2.af_num(), AFType::OutputPushPull, Pull::Up);
d3.set_as_af_pull(d3.af_num(), AFType::OutputPushPull, Pull::Up);
clk.set_speed(Speed::VeryHigh);
cmd.set_speed(Speed::VeryHigh);
d0.set_speed(Speed::VeryHigh);
d1.set_speed(Speed::VeryHigh);
d2.set_speed(Speed::VeryHigh);
d3.set_speed(Speed::VeryHigh);
});
Self::new_inner(
sdmmc,
irq,
clk.map_into(),
cmd.map_into(),
d0.map_into(),
Some(d1.map_into()),
Some(d2.map_into()),
Some(d3.map_into()),
config,
)
}
fn new_inner(
sdmmc: impl Unborrow<Target = T> + 'd,
irq: impl Unborrow<Target = T::Interrupt> + 'd,
clk: Unborrowed<'d, AnyPin>,
cmd: Unborrowed<'d, AnyPin>,
d0: Unborrowed<'d, AnyPin>,
d1: Option<Unborrowed<'d, AnyPin>>,
d2: Option<Unborrowed<'d, AnyPin>>,
d3: Option<Unborrowed<'d, AnyPin>>,
config: Config,
) -> Self {
unborrow!(sdmmc, irq);
T::enable();
T::reset();
@ -247,11 +422,18 @@ impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P, NoDma> {
irq.enable();
Self {
sdmmc: PhantomData,
pins,
_peri: sdmmc,
irq,
dma: NoDma.unborrow(),
clk,
cmd,
d0,
d1,
d2,
d3,
config,
dma: NoDma,
clock,
signalling: Default::default(),
card: None,
@ -259,23 +441,28 @@ impl<'d, T: Instance, P: Pins<T>> Sdmmc<'d, T, P, NoDma> {
}
}
impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
impl<'d, T: Instance, Dma: SdmmcDma<T>> Sdmmc<'d, T, Dma> {
#[inline(always)]
pub async fn init_card(&mut self, freq: Hertz) -> Result<(), Error> {
let inner = T::inner();
let freq = freq.into();
let bus_width = match self.d3.is_some() {
true => BusWidth::Four,
false => BusWidth::One,
};
inner
.init_card(
freq,
P::BUSWIDTH,
bus_width,
&mut self.card,
&mut self.signalling,
T::frequency(),
&mut self.clock,
T::state(),
self.config.data_transfer_timeout,
&mut self.dma,
&mut *self.dma,
)
.await
}
@ -295,7 +482,7 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
card_capacity,
state,
self.config.data_transfer_timeout,
&mut self.dma,
&mut *self.dma,
)
.await
}
@ -314,7 +501,7 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
card,
state,
self.config.data_transfer_timeout,
&mut self.dma,
&mut *self.dma,
)
.await
}
@ -345,12 +532,26 @@ impl<'d, T: Instance, P: Pins<T>, Dma: SdmmcDma<T>> Sdmmc<'d, T, P, Dma> {
}
}
impl<'d, T: Instance, P: Pins<T>, Dma> Drop for Sdmmc<'d, T, P, Dma> {
impl<'d, T: Instance, Dma> Drop for Sdmmc<'d, T, Dma> {
fn drop(&mut self) {
self.irq.disable();
let inner = T::inner();
unsafe { inner.on_drop() };
self.pins.deconfigure();
critical_section::with(|_| unsafe {
self.clk.set_as_disconnected();
self.cmd.set_as_disconnected();
self.d0.set_as_disconnected();
if let Some(x) = &mut self.d1 {
x.set_as_disconnected();
}
if let Some(x) = &mut self.d2 {
x.set_as_disconnected();
}
if let Some(x) = &mut self.d3 {
x.set_as_disconnected();
}
});
}
}
@ -1296,114 +1497,6 @@ cfg_if::cfg_if! {
}
}
pub trait Pins<T: Instance>: sealed::Pins<T> + 'static {
const BUSWIDTH: BusWidth;
fn configure(&mut self);
fn deconfigure(&mut self);
}
impl<T, CLK, CMD, D0, D1, D2, D3> sealed::Pins<T> for (CLK, CMD, D0, D1, D2, D3)
where
T: Instance,
CLK: CkPin<T>,
CMD: CmdPin<T>,
D0: D0Pin<T>,
D1: D1Pin<T>,
D2: D2Pin<T>,
D3: D3Pin<T>,
{
}
impl<T, CLK, CMD, D0> sealed::Pins<T> for (CLK, CMD, D0)
where
T: Instance,
CLK: CkPin<T>,
CMD: CmdPin<T>,
D0: D0Pin<T>,
{
}
impl<T, CLK, CMD, D0, D1, D2, D3> Pins<T> for (CLK, CMD, D0, D1, D2, D3)
where
T: Instance,
CLK: CkPin<T>,
CMD: CmdPin<T>,
D0: D0Pin<T>,
D1: D1Pin<T>,
D2: D2Pin<T>,
D3: D3Pin<T>,
{
const BUSWIDTH: BusWidth = BusWidth::Four;
fn configure(&mut self) {
let (clk_pin, cmd_pin, d0_pin, d1_pin, d2_pin, d3_pin) = self;
critical_section::with(|_| unsafe {
clk_pin.set_as_af_pull(clk_pin.af_num(), AFType::OutputPushPull, Pull::None);
cmd_pin.set_as_af_pull(cmd_pin.af_num(), AFType::OutputPushPull, Pull::Up);
d0_pin.set_as_af_pull(d0_pin.af_num(), AFType::OutputPushPull, Pull::Up);
d1_pin.set_as_af_pull(d1_pin.af_num(), AFType::OutputPushPull, Pull::Up);
d2_pin.set_as_af_pull(d2_pin.af_num(), AFType::OutputPushPull, Pull::Up);
d3_pin.set_as_af_pull(d3_pin.af_num(), AFType::OutputPushPull, Pull::Up);
clk_pin.set_speed(Speed::VeryHigh);
cmd_pin.set_speed(Speed::VeryHigh);
d0_pin.set_speed(Speed::VeryHigh);
d1_pin.set_speed(Speed::VeryHigh);
d2_pin.set_speed(Speed::VeryHigh);
d3_pin.set_speed(Speed::VeryHigh);
});
}
fn deconfigure(&mut self) {
let (clk_pin, cmd_pin, d0_pin, d1_pin, d2_pin, d3_pin) = self;
critical_section::with(|_| unsafe {
clk_pin.set_as_disconnected();
cmd_pin.set_as_disconnected();
d0_pin.set_as_disconnected();
d1_pin.set_as_disconnected();
d2_pin.set_as_disconnected();
d3_pin.set_as_disconnected();
});
}
}
impl<T, CLK, CMD, D0> Pins<T> for (CLK, CMD, D0)
where
T: Instance,
CLK: CkPin<T>,
CMD: CmdPin<T>,
D0: D0Pin<T>,
{
const BUSWIDTH: BusWidth = BusWidth::One;
fn configure(&mut self) {
let (clk_pin, cmd_pin, d0_pin) = self;
critical_section::with(|_| unsafe {
clk_pin.set_as_af_pull(clk_pin.af_num(), AFType::OutputPushPull, Pull::None);
cmd_pin.set_as_af_pull(cmd_pin.af_num(), AFType::OutputPushPull, Pull::Up);
d0_pin.set_as_af_pull(d0_pin.af_num(), AFType::OutputPushPull, Pull::Up);
clk_pin.set_speed(Speed::VeryHigh);
cmd_pin.set_speed(Speed::VeryHigh);
d0_pin.set_speed(Speed::VeryHigh);
});
}
fn deconfigure(&mut self) {
let (clk_pin, cmd_pin, d0_pin) = self;
critical_section::with(|_| unsafe {
clk_pin.set_as_disconnected();
cmd_pin.set_as_disconnected();
d0_pin.set_as_disconnected();
});
}
}
foreach_peripheral!(
(sdmmc, $inst:ident) => {
impl sealed::Instance for peripherals::$inst {