mirror of
https://github.com/embassy-rs/embassy.git
synced 2024-11-22 14:53:03 +00:00
stm32: Allow for open drain configuration for output pin
This commit is contained in:
parent
e1880a19df
commit
efb3b3a0a8
@ -18,6 +18,31 @@ pub enum Pull {
|
||||
Down,
|
||||
}
|
||||
|
||||
/// Pull setting for an input.
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
pub enum Speed {
|
||||
LowSpeed,
|
||||
MediumSpeed,
|
||||
#[cfg(not(syscfg_f0))]
|
||||
HighSpeed,
|
||||
VeryHighSpeed,
|
||||
}
|
||||
|
||||
impl From<Speed> for vals::Ospeedr {
|
||||
fn from(speed: Speed) -> Self {
|
||||
use Speed::*;
|
||||
|
||||
match speed {
|
||||
LowSpeed => vals::Ospeedr::LOWSPEED,
|
||||
MediumSpeed => vals::Ospeedr::MEDIUMSPEED,
|
||||
#[cfg(not(syscfg_f0))]
|
||||
HighSpeed => vals::Ospeedr::HIGHSPEED,
|
||||
VeryHighSpeed => vals::Ospeedr::VERYHIGHSPEED,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// GPIO input driver.
|
||||
pub struct Input<'d, T: Pin> {
|
||||
pub(crate) pin: T,
|
||||
@ -86,7 +111,12 @@ pub struct Output<'d, T: Pin> {
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> Output<'d, T> {
|
||||
pub fn new(pin: impl Unborrow<Target = T> + 'd, initial_output: Level) -> Self {
|
||||
pub fn new(
|
||||
pin: impl Unborrow<Target = T> + 'd,
|
||||
initial_output: Level,
|
||||
speed: Speed,
|
||||
open_drain: bool,
|
||||
) -> Self {
|
||||
unborrow!(pin);
|
||||
|
||||
match initial_output {
|
||||
@ -99,6 +129,10 @@ impl<'d, T: Pin> Output<'d, T> {
|
||||
let n = pin.pin() as usize;
|
||||
r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING));
|
||||
r.moder().modify(|w| w.set_moder(n, vals::Moder::OUTPUT));
|
||||
if open_drain {
|
||||
r.otyper().modify(|w| w.set_ot(n, vals::Ot::OPENDRAIN));
|
||||
}
|
||||
pin.set_speed(speed);
|
||||
});
|
||||
|
||||
Self {
|
||||
@ -115,6 +149,8 @@ impl<'d, T: Pin> Drop for Output<'d, T> {
|
||||
let n = self.pin.pin() as usize;
|
||||
r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING));
|
||||
r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT));
|
||||
r.otyper().modify(|w| w.set_ot(n, vals::Ot::PUSHPULL));
|
||||
self.pin.set_speed(Speed::LowSpeed);
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -148,6 +184,18 @@ impl<'d, T: Pin> StatefulOutputPin for Output<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> InputPin for Output<'d, T> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||
self.is_set_high()
|
||||
}
|
||||
|
||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||
self.is_set_low()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> toggleable::Default for Output<'d, T> {}
|
||||
|
||||
pub(crate) mod sealed {
|
||||
@ -206,6 +254,13 @@ pub(crate) mod sealed {
|
||||
.moder()
|
||||
.modify(|w| w.set_moder(pin, vals::Moder::ANALOG));
|
||||
}
|
||||
|
||||
unsafe fn set_speed(&self, speed: Speed) {
|
||||
let pin = self._pin() as usize;
|
||||
self.block()
|
||||
.ospeedr()
|
||||
.modify(|w| w.set_ospeedr(pin, speed.into()));
|
||||
}
|
||||
}
|
||||
|
||||
pub trait OptionalPin {}
|
||||
|
Loading…
Reference in New Issue
Block a user