642: stm32: centralize gpio reg access in the gpio module. r=Dirbaio a=Dirbaio



Co-authored-by: Dario Nieuwenhuis <dirbaio@dirbaio.net>
This commit is contained in:
bors[bot] 2022-02-24 01:49:54 +00:00 committed by GitHub
commit cb8a7d00d5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 115 additions and 288 deletions

View file

@ -11,9 +11,7 @@ use embassy_hal_common::unborrow;
use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU}; use embassy_net::{Device, DeviceCapabilities, LinkState, PacketBuf, MTU};
use crate::gpio::sealed::Pin as __GpioPin; use crate::gpio::sealed::Pin as __GpioPin;
use crate::gpio::Pin as GpioPin;
use crate::gpio::{sealed::AFType, AnyPin, Speed}; use crate::gpio::{sealed::AFType, AnyPin, Speed};
use crate::pac::gpio::vals::Ospeedr;
use crate::pac::{ETH, RCC, SYSCFG}; use crate::pac::{ETH, RCC, SYSCFG};
mod descriptors; mod descriptors;
@ -308,15 +306,12 @@ impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Drop
dma.dmaomr().modify(|w| w.set_sr(DmaomrSr::STOPPED)); dma.dmaomr().modify(|w| w.set_sr(DmaomrSr::STOPPED));
} }
for pin in self.pins.iter_mut() { // NOTE(unsafe) Exclusive access to the regs
// NOTE(unsafe) Exclusive access to the regs critical_section::with(|_| unsafe {
critical_section::with(|_| unsafe { for pin in self.pins.iter_mut() {
pin.set_as_analog(); pin.set_as_disconnected();
pin.block() }
.ospeedr() })
.modify(|w| w.set_ospeedr(pin.pin() as usize, Ospeedr::LOWSPEED));
})
}
} }
} }

View file

@ -304,13 +304,12 @@ impl<'d, T: Instance, P: PHY, const TX: usize, const RX: usize> Drop
dma.dmacrx_cr().modify(|w| w.set_sr(false)); dma.dmacrx_cr().modify(|w| w.set_sr(false));
} }
for pin in self.pins.iter_mut() { // NOTE(unsafe) Exclusive access to the regs
// NOTE(unsafe) Exclusive access to the regs critical_section::with(|_| unsafe {
critical_section::with(|_| unsafe { for pin in self.pins.iter_mut() {
pin.set_as_analog(); pin.set_as_disconnected();
pin.set_speed(Speed::Low); }
}) })
}
} }
} }

View file

@ -2,9 +2,8 @@ use core::marker::PhantomData;
use embassy::util::Unborrow; use embassy::util::Unborrow;
use embassy_hal_common::unborrow; use embassy_hal_common::unborrow;
use crate::gpio::sealed::AFType::OutputPushPull; use crate::gpio::sealed::AFType;
use crate::gpio::Speed; use crate::gpio::{Pull, Speed};
use crate::pac::gpio::vals::Pupdr;
mod pins; mod pins;
pub use pins::*; pub use pins::*;
@ -41,9 +40,8 @@ macro_rules! config_pins {
($($pin:ident),*) => { ($($pin:ident),*) => {
unborrow!($($pin),*); unborrow!($($pin),*);
$( $(
$pin.set_as_af($pin.af_num(), OutputPushPull); $pin.set_as_af_pull($pin.af_num(), AFType::OutputPushPull, Pull::Up);
$pin.set_speed(Speed::VeryHigh); $pin.set_speed(Speed::VeryHigh);
$pin.block().pupdr().modify(|w| w.set_pupdr($pin.pin() as usize, Pupdr::PULLUP));
)* )*
}; };
} }

View file

@ -48,9 +48,9 @@ impl From<Speed> for vals::Mode {
use Speed::*; use Speed::*;
match speed { match speed {
Low => vals::Mode::OUTPUT2, Low => vals::Mode::OUTPUT2MHZ,
Medium => vals::Mode::OUTPUT, Medium => vals::Mode::OUTPUT10MHZ,
VeryHigh => vals::Mode::OUTPUT50, VeryHigh => vals::Mode::OUTPUT50MHZ,
} }
} }
} }
@ -85,20 +85,23 @@ impl<'d, T: Pin> Input<'d, T> {
let n = pin.pin() as usize; let n = pin.pin() as usize;
#[cfg(gpio_v1)] #[cfg(gpio_v1)]
{ {
let cnf = match pull {
Pull::Up => {
r.bsrr().write(|w| w.set_bs(n, true));
vals::CnfIn::PULL
}
Pull::Down => {
r.bsrr().write(|w| w.set_br(n, true));
vals::CnfIn::PULL
}
Pull::None => vals::CnfIn::FLOATING,
};
let crlh = if n < 8 { 0 } else { 1 }; let crlh = if n < 8 { 0 } else { 1 };
match pull { r.cr(crlh).modify(|w| {
Pull::Up => r.bsrr().write(|w| w.set_bs(n, true)), w.set_mode(n % 8, vals::Mode::INPUT);
Pull::Down => r.bsrr().write(|w| w.set_br(n, true)), w.set_cnf_in(n % 8, cnf);
Pull::None => {} });
}
if pull == Pull::None {
r.cr(crlh)
.modify(|w| w.set_cnf(n % 8, vals::Cnf::OPENDRAIN));
} else {
r.cr(crlh)
.modify(|w| w.set_cnf(n % 8, vals::Cnf::ALTPUSHPULL));
}
r.cr(crlh).modify(|w| w.set_mode(n % 8, vals::Mode::INPUT));
} }
#[cfg(gpio_v2)] #[cfg(gpio_v2)]
{ {
@ -133,7 +136,7 @@ impl<'d, T: Pin> Drop for Input<'d, T> {
{ {
let crlh = if n < 8 { 0 } else { 1 }; let crlh = if n < 8 { 0 } else { 1 };
r.cr(crlh) r.cr(crlh)
.modify(|w| w.set_cnf(n % 8, vals::Cnf::OPENDRAIN)); .modify(|w| w.set_cnf_in(n % 8, vals::CnfIn::FLOATING));
} }
#[cfg(gpio_v2)] #[cfg(gpio_v2)]
r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING)); r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING));
@ -170,8 +173,10 @@ impl<'d, T: Pin> Output<'d, T> {
#[cfg(gpio_v1)] #[cfg(gpio_v1)]
{ {
let crlh = if n < 8 { 0 } else { 1 }; let crlh = if n < 8 { 0 } else { 1 };
r.cr(crlh).modify(|w| w.set_cnf(n % 8, vals::Cnf::PUSHPULL)); r.cr(crlh).modify(|w| {
r.cr(crlh).modify(|w| w.set_mode(n % 8, speed.into())); w.set_mode(n % 8, speed.into());
w.set_cnf_out(n % 8, vals::CnfOut::PUSHPULL);
});
} }
#[cfg(gpio_v2)] #[cfg(gpio_v2)]
{ {
@ -227,9 +232,10 @@ impl<'d, T: Pin> Drop for Output<'d, T> {
#[cfg(gpio_v1)] #[cfg(gpio_v1)]
{ {
let crlh = if n < 8 { 0 } else { 1 }; let crlh = if n < 8 { 0 } else { 1 };
r.cr(crlh) r.cr(crlh).modify(|w| {
.modify(|w| w.set_cnf(n % 8, vals::Cnf::OPENDRAIN)); w.set_mode(n % 8, vals::Mode::INPUT);
r.cr(crlh).modify(|w| w.set_mode(n % 8, vals::Mode::INPUT)); w.set_cnf_in(n % 8, vals::CnfIn::FLOATING);
});
} }
#[cfg(gpio_v2)] #[cfg(gpio_v2)]
{ {
@ -273,7 +279,7 @@ impl<'d, T: Pin> OutputOpenDrain<'d, T> {
} }
r.cr(crlh).modify(|w| w.set_mode(n % 8, speed.into())); r.cr(crlh).modify(|w| w.set_mode(n % 8, speed.into()));
r.cr(crlh) r.cr(crlh)
.modify(|w| w.set_cnf(n % 8, vals::Cnf::OPENDRAIN)); .modify(|w| w.set_cnf_out(n % 8, vals::CnfOut::OPENDRAIN));
} }
#[cfg(gpio_v2)] #[cfg(gpio_v2)]
{ {
@ -338,9 +344,10 @@ impl<'d, T: Pin> Drop for OutputOpenDrain<'d, T> {
#[cfg(gpio_v1)] #[cfg(gpio_v1)]
{ {
let crlh = if n < 8 { 0 } else { 1 }; let crlh = if n < 8 { 0 } else { 1 };
r.cr(crlh) r.cr(crlh).modify(|w| {
.modify(|w| w.set_cnf(n % 8, vals::Cnf::OPENDRAIN)); w.set_mode(n % 8, vals::Mode::INPUT);
r.cr(crlh).modify(|w| w.set_mode(n % 8, vals::Mode::INPUT)); w.set_cnf_in(n % 8, vals::CnfIn::FLOATING);
});
} }
#[cfg(gpio_v2)] #[cfg(gpio_v2)]
{ {
@ -410,30 +417,34 @@ pub(crate) mod sealed {
AFType::Input => { AFType::Input => {
r.cr(crlh).modify(|w| { r.cr(crlh).modify(|w| {
w.set_mode(n % 8, vals::Mode::INPUT); w.set_mode(n % 8, vals::Mode::INPUT);
w.set_cnf(n % 8, vals::Cnf::OPENDRAIN); w.set_cnf_in(n % 8, vals::CnfIn::FLOATING);
}); });
} }
AFType::OutputPushPull => { AFType::OutputPushPull => {
r.cr(crlh).modify(|w| { r.cr(crlh).modify(|w| {
w.set_mode(n % 8, vals::Mode::OUTPUT50); w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ);
w.set_cnf(n % 8, vals::Cnf::ALTPUSHPULL); w.set_cnf_out(n % 8, vals::CnfOut::ALTPUSHPULL);
}); });
} }
AFType::OutputOpenDrain => { AFType::OutputOpenDrain => {
r.cr(crlh).modify(|w| { r.cr(crlh).modify(|w| {
w.set_mode(n % 8, vals::Mode::OUTPUT50); w.set_mode(n % 8, vals::Mode::OUTPUT50MHZ);
w.set_cnf(n % 8, vals::Cnf::ALTOPENDRAIN); w.set_cnf_out(n % 8, vals::CnfOut::ALTOPENDRAIN);
}); });
} }
} }
} }
#[cfg(gpio_v2)] #[cfg(gpio_v2)]
unsafe fn set_as_af(&self, af_num: u8, af_type: AFType) { unsafe fn set_as_af(&self, af_num: u8, af_type: AFType) {
self.set_as_af_pull(af_num, af_type, Pull::None);
}
#[cfg(gpio_v2)]
unsafe fn set_as_af_pull(&self, af_num: u8, af_type: AFType, pull: Pull) {
let pin = self._pin() as usize; let pin = self._pin() as usize;
let block = self.block(); let block = self.block();
block block.afr(pin / 8).modify(|w| w.set_afr(pin % 8, af_num));
.afr(pin / 8)
.modify(|w| w.set_afr(pin % 8, vals::Afr(af_num)));
match af_type { match af_type {
AFType::Input => {} AFType::Input => {}
AFType::OutputPushPull => { AFType::OutputPushPull => {
@ -443,9 +454,7 @@ pub(crate) mod sealed {
.otyper() .otyper()
.modify(|w| w.set_ot(pin, vals::Ot::OPENDRAIN)), .modify(|w| w.set_ot(pin, vals::Ot::OPENDRAIN)),
} }
block block.pupdr().modify(|w| w.set_pupdr(pin, pull.into()));
.pupdr()
.modify(|w| w.set_pupdr(pin, vals::Pupdr::FLOATING));
block block
.moder() .moder()
@ -458,12 +467,10 @@ pub(crate) mod sealed {
#[cfg(gpio_v1)] #[cfg(gpio_v1)]
{ {
let crlh = if pin < 8 { 0 } else { 1 }; let crlh = if pin < 8 { 0 } else { 1 };
block block.cr(crlh).modify(|w| {
.cr(crlh) w.set_mode(pin % 8, vals::Mode::INPUT);
.modify(|w| w.set_cnf(pin % 8, vals::Cnf::PUSHPULL)); w.set_cnf_in(pin % 8, vals::CnfIn::ANALOG);
block });
.cr(crlh)
.modify(|w| w.set_mode(pin % 8, vals::Mode::INPUT));
} }
#[cfg(gpio_v2)] #[cfg(gpio_v2)]
block block
@ -471,6 +478,15 @@ pub(crate) mod sealed {
.modify(|w| w.set_moder(pin, vals::Moder::ANALOG)); .modify(|w| w.set_moder(pin, vals::Moder::ANALOG));
} }
/// Set the pin as "disconnected", ie doing nothing and consuming the lowest
/// amount of power possible.
///
/// This is currently the same as set_as_analog but is semantically different really.
/// Drivers should set_as_disconnected pins when dropped.
unsafe fn set_as_disconnected(&self) {
self.set_as_analog();
}
#[cfg(gpio_v2)] #[cfg(gpio_v2)]
unsafe fn set_speed(&self, speed: Speed) { unsafe fn set_speed(&self, speed: Speed) {
let pin = self._pin() as usize; let pin = self._pin() as usize;

View file

@ -1,12 +1,11 @@
use crate::i2c::{Error, Instance, SclPin, SdaPin};
use crate::time::Hertz;
use core::marker::PhantomData; use core::marker::PhantomData;
use embassy::util::Unborrow; use embassy::util::Unborrow;
use embassy_hal_common::unborrow; use embassy_hal_common::unborrow;
use crate::gpio::sealed::AFType;
use crate::i2c::{Error, Instance, SclPin, SdaPin};
use crate::pac::i2c; use crate::pac::i2c;
use crate::time::Hertz;
use crate::gpio::sealed::AFType::OutputOpenDrain;
pub struct I2c<'d, T: Instance> { pub struct I2c<'d, T: Instance> {
phantom: PhantomData<&'d mut T>, phantom: PhantomData<&'d mut T>,
@ -27,8 +26,8 @@ impl<'d, T: Instance> I2c<'d, T> {
T::enable(); T::enable();
unsafe { unsafe {
scl.set_as_af(scl.af_num(), OutputOpenDrain); scl.set_as_af(scl.af_num(), AFType::OutputOpenDrain);
sda.set_as_af(sda.af_num(), OutputOpenDrain); sda.set_as_af(sda.af_num(), AFType::OutputOpenDrain);
} }
unsafe { unsafe {

View file

@ -11,10 +11,9 @@ use embassy_hal_common::unborrow;
use futures::future::poll_fn; use futures::future::poll_fn;
use crate::dma::NoDma; use crate::dma::NoDma;
use crate::gpio::sealed::AFType;
use crate::i2c::{Error, Instance, SclPin, SdaPin}; use crate::i2c::{Error, Instance, SclPin, SdaPin};
use crate::pac; use crate::pac;
use crate::pac::gpio::vals::{Afr, Moder, Ot};
use crate::pac::gpio::Gpio;
use crate::pac::i2c; use crate::pac::i2c;
use crate::time::Hertz; use crate::time::Hertz;
@ -64,8 +63,8 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
T::enable(); T::enable();
unsafe { unsafe {
Self::configure_pin(scl.block(), scl.pin() as _, scl.af_num()); scl.set_as_af(scl.af_num(), AFType::OutputOpenDrain);
Self::configure_pin(sda.block(), sda.pin() as _, sda.af_num()); sda.set_as_af(sda.af_num(), AFType::OutputOpenDrain);
} }
unsafe { unsafe {
@ -120,16 +119,6 @@ impl<'d, T: Instance, TXDMA, RXDMA> I2c<'d, T, TXDMA, RXDMA> {
}); });
} }
unsafe fn configure_pin(block: Gpio, pin: usize, af_num: u8) {
let (afr, n_af) = if pin < 8 { (0, pin) } else { (1, pin - 8) };
block.moder().modify(|w| w.set_moder(pin, Moder::ALTERNATE));
block.afr(afr).modify(|w| w.set_afr(n_af, Afr(af_num)));
block.otyper().modify(|w| w.set_ot(pin, Ot::OPENDRAIN));
//block
//.ospeedr()
//.modify(|w| w.set_ospeedr(pin, crate::pac::gpio::vals::Ospeedr::VERYHIGHSPEED));
}
fn master_stop(&mut self) { fn master_stop(&mut self) {
unsafe { unsafe {
T::regs().cr2().write(|w| w.set_stop(true)); T::regs().cr2().write(|w| w.set_stop(true));

View file

@ -12,9 +12,9 @@ use embassy_hal_common::unborrow;
use futures::future::poll_fn; use futures::future::poll_fn;
use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR}; use sdio_host::{BusWidth, CardCapacity, CardStatus, CurrentState, SDStatus, CID, CSD, OCR, SCR};
use crate::gpio::sealed::AFType;
use crate::gpio::{Pull, Speed};
use crate::interrupt::Interrupt; use crate::interrupt::Interrupt;
use crate::pac;
use crate::pac::gpio::Gpio;
use crate::pac::sdmmc::Sdmmc as RegBlock; use crate::pac::sdmmc::Sdmmc as RegBlock;
use crate::peripherals; use crate::peripherals;
use crate::time::Hertz; use crate::time::Hertz;
@ -1191,23 +1191,6 @@ where
{ {
} }
/// # Safety
///
/// Access to `block` registers should be exclusive
unsafe fn configure_pin(block: Gpio, n: usize, afr_num: u8, pup: bool) {
use pac::gpio::vals::{Afr, Moder, Ospeedr, Pupdr};
let (afr, n_af) = if n < 8 { (0, n) } else { (1, n - 8) };
block.afr(afr).modify(|w| w.set_afr(n_af, Afr(afr_num)));
block.moder().modify(|w| w.set_moder(n, Moder::ALTERNATE));
if pup {
block.pupdr().modify(|w| w.set_pupdr(n, Pupdr::PULLUP));
}
block
.ospeedr()
.modify(|w| w.set_ospeedr(n, Ospeedr::VERYHIGHSPEED));
}
impl<T, CLK, CMD, D0, D1, D2, D3> Pins<T> for (CLK, CMD, D0, D1, D2, D3) impl<T, CLK, CMD, D0, D1, D2, D3> Pins<T> for (CLK, CMD, D0, D1, D2, D3)
where where
T: Instance, T: Instance,
@ -1224,135 +1207,32 @@ where
let (clk_pin, cmd_pin, d0_pin, d1_pin, d2_pin, d3_pin) = self; let (clk_pin, cmd_pin, d0_pin, d1_pin, d2_pin, d3_pin) = self;
critical_section::with(|_| unsafe { critical_section::with(|_| unsafe {
// clk clk_pin.set_as_af_pull(clk_pin.af_num(), AFType::OutputPushPull, Pull::None);
let block = clk_pin.block(); cmd_pin.set_as_af_pull(cmd_pin.af_num(), AFType::OutputPushPull, Pull::Up);
let n = clk_pin.pin() as usize; d0_pin.set_as_af_pull(d0_pin.af_num(), AFType::OutputPushPull, Pull::Up);
let afr_num = clk_pin.af_num(); d1_pin.set_as_af_pull(d1_pin.af_num(), AFType::OutputPushPull, Pull::Up);
configure_pin(block, n, afr_num, false); 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);
// cmd clk_pin.set_speed(Speed::VeryHigh);
let block = cmd_pin.block(); cmd_pin.set_speed(Speed::VeryHigh);
let n = cmd_pin.pin() as usize; d0_pin.set_speed(Speed::VeryHigh);
let afr_num = cmd_pin.af_num(); d1_pin.set_speed(Speed::VeryHigh);
configure_pin(block, n, afr_num, true); d2_pin.set_speed(Speed::VeryHigh);
d3_pin.set_speed(Speed::VeryHigh);
// d0
let block = d0_pin.block();
let n = d0_pin.pin() as usize;
let afr_num = d0_pin.af_num();
configure_pin(block, n, afr_num, true);
// d1
let block = d1_pin.block();
let n = d1_pin.pin() as usize;
let afr_num = d1_pin.af_num();
configure_pin(block, n, afr_num, true);
// d2
let block = d2_pin.block();
let n = d2_pin.pin() as usize;
let afr_num = d2_pin.af_num();
configure_pin(block, n, afr_num, true);
// d3
let block = d3_pin.block();
let n = d3_pin.pin() as usize;
let afr_num = d3_pin.af_num();
configure_pin(block, n, afr_num, true);
}); });
} }
fn deconfigure(&mut self) { fn deconfigure(&mut self) {
use pac::gpio::vals::{Moder, Ospeedr, Pupdr};
let (clk_pin, cmd_pin, d0_pin, d1_pin, d2_pin, d3_pin) = self; let (clk_pin, cmd_pin, d0_pin, d1_pin, d2_pin, d3_pin) = self;
critical_section::with(|_| unsafe { critical_section::with(|_| unsafe {
// clk clk_pin.set_as_disconnected();
let n = clk_pin.pin().into(); cmd_pin.set_as_disconnected();
clk_pin d0_pin.set_as_disconnected();
.block() d1_pin.set_as_disconnected();
.moder() d2_pin.set_as_disconnected();
.modify(|w| w.set_moder(n, Moder::ANALOG)); d3_pin.set_as_disconnected();
clk_pin
.block()
.ospeedr()
.modify(|w| w.set_ospeedr(n, Ospeedr::LOWSPEED));
// cmd
let n = cmd_pin.pin().into();
cmd_pin
.block()
.moder()
.modify(|w| w.set_moder(n, Moder::ANALOG));
cmd_pin
.block()
.ospeedr()
.modify(|w| w.set_ospeedr(n, Ospeedr::LOWSPEED));
cmd_pin
.block()
.pupdr()
.modify(|w| w.set_pupdr(n, Pupdr::FLOATING));
// d0
let n = d0_pin.pin().into();
d0_pin
.block()
.moder()
.modify(|w| w.set_moder(n, Moder::ANALOG));
d0_pin
.block()
.ospeedr()
.modify(|w| w.set_ospeedr(n, Ospeedr::LOWSPEED));
d0_pin
.block()
.pupdr()
.modify(|w| w.set_pupdr(n, Pupdr::FLOATING));
// d1
let n = d1_pin.pin().into();
d1_pin
.block()
.moder()
.modify(|w| w.set_moder(n, Moder::ANALOG));
d1_pin
.block()
.ospeedr()
.modify(|w| w.set_ospeedr(n, Ospeedr::LOWSPEED));
d1_pin
.block()
.pupdr()
.modify(|w| w.set_pupdr(n, Pupdr::FLOATING));
// d2
let n = d2_pin.pin().into();
d2_pin
.block()
.moder()
.modify(|w| w.set_moder(n, Moder::ANALOG));
d2_pin
.block()
.ospeedr()
.modify(|w| w.set_ospeedr(n, Ospeedr::LOWSPEED));
d2_pin
.block()
.pupdr()
.modify(|w| w.set_pupdr(n, Pupdr::FLOATING));
// d3
let n = d3_pin.pin().into();
d3_pin
.block()
.moder()
.modify(|w| w.set_moder(n, Moder::ANALOG));
d3_pin
.block()
.ospeedr()
.modify(|w| w.set_ospeedr(n, Ospeedr::LOWSPEED));
d3_pin
.block()
.pupdr()
.modify(|w| w.set_pupdr(n, Pupdr::FLOATING));
}); });
} }
} }
@ -1370,72 +1250,23 @@ where
let (clk_pin, cmd_pin, d0_pin) = self; let (clk_pin, cmd_pin, d0_pin) = self;
critical_section::with(|_| unsafe { critical_section::with(|_| unsafe {
// clk clk_pin.set_as_af_pull(clk_pin.af_num(), AFType::OutputPushPull, Pull::None);
let block = clk_pin.block(); cmd_pin.set_as_af_pull(cmd_pin.af_num(), AFType::OutputPushPull, Pull::Up);
let n = clk_pin.pin() as usize; d0_pin.set_as_af_pull(d0_pin.af_num(), AFType::OutputPushPull, Pull::Up);
let afr_num = clk_pin.af_num();
configure_pin(block, n, afr_num, false);
// cmd clk_pin.set_speed(Speed::VeryHigh);
let block = cmd_pin.block(); cmd_pin.set_speed(Speed::VeryHigh);
let n = cmd_pin.pin() as usize; d0_pin.set_speed(Speed::VeryHigh);
let afr_num = cmd_pin.af_num();
configure_pin(block, n, afr_num, true);
// d0
let block = d0_pin.block();
let n = d0_pin.pin() as usize;
let afr_num = d0_pin.af_num();
configure_pin(block, n, afr_num, true);
}); });
} }
fn deconfigure(&mut self) { fn deconfigure(&mut self) {
use pac::gpio::vals::{Moder, Ospeedr, Pupdr};
let (clk_pin, cmd_pin, d0_pin) = self; let (clk_pin, cmd_pin, d0_pin) = self;
critical_section::with(|_| unsafe { critical_section::with(|_| unsafe {
// clk clk_pin.set_as_disconnected();
let n = clk_pin.pin().into(); cmd_pin.set_as_disconnected();
clk_pin d0_pin.set_as_disconnected();
.block()
.moder()
.modify(|w| w.set_moder(n, Moder::ANALOG));
clk_pin
.block()
.ospeedr()
.modify(|w| w.set_ospeedr(n, Ospeedr::LOWSPEED));
// cmd
let n = cmd_pin.pin().into();
cmd_pin
.block()
.moder()
.modify(|w| w.set_moder(n, Moder::ANALOG));
cmd_pin
.block()
.ospeedr()
.modify(|w| w.set_ospeedr(n, Ospeedr::LOWSPEED));
cmd_pin
.block()
.pupdr()
.modify(|w| w.set_pupdr(n, Pupdr::FLOATING));
// d0
let n = d0_pin.pin().into();
d0_pin
.block()
.moder()
.modify(|w| w.set_moder(n, Moder::ANALOG));
d0_pin
.block()
.ospeedr()
.modify(|w| w.set_ospeedr(n, Ospeedr::LOWSPEED));
d0_pin
.block()
.pupdr()
.modify(|w| w.set_pupdr(n, Pupdr::FLOATING));
}); });
} }
} }

View file

@ -458,9 +458,9 @@ impl<'d, T: Instance, Tx, Rx> Spi<'d, T, Tx, Rx> {
impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> { impl<'d, T: Instance, Tx, Rx> Drop for Spi<'d, T, Tx, Rx> {
fn drop(&mut self) { fn drop(&mut self) {
unsafe { unsafe {
self.sck.as_ref().map(|x| x.set_as_analog()); self.sck.as_ref().map(|x| x.set_as_disconnected());
self.mosi.as_ref().map(|x| x.set_as_analog()); self.mosi.as_ref().map(|x| x.set_as_disconnected());
self.miso.as_ref().map(|x| x.set_as_analog()); self.miso.as_ref().map(|x| x.set_as_disconnected());
} }
} }
} }

@ -1 +1 @@
Subproject commit dbb0ad74f2a4612f0ca168da38e1c443a838a607 Subproject commit 608581a8960b95c4d472f59d0b028b47053d5873