diff options
| author | Thales Fragoso <[email protected]> | 2021-06-23 19:22:53 -0300 |
|---|---|---|
| committer | Thales Fragoso <[email protected]> | 2021-06-24 20:42:43 -0300 |
| commit | efb3b3a0a8577059896100336f430c4eb45c544f (patch) | |
| tree | ef21daa36cca9245c2cc48919e603b0eadcd1042 | |
| parent | e1880a19df2f91757aa34a21b670da22ccb81440 (diff) | |
stm32: Allow for open drain configuration for output pin
| -rw-r--r-- | embassy-stm32/src/gpio.rs | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 873c73b4e..e562dcab7 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs | |||
| @@ -18,6 +18,31 @@ pub enum Pull { | |||
| 18 | Down, | 18 | Down, |
| 19 | } | 19 | } |
| 20 | 20 | ||
| 21 | /// Pull setting for an input. | ||
| 22 | #[derive(Debug)] | ||
| 23 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | ||
| 24 | pub enum Speed { | ||
| 25 | LowSpeed, | ||
| 26 | MediumSpeed, | ||
| 27 | #[cfg(not(syscfg_f0))] | ||
| 28 | HighSpeed, | ||
| 29 | VeryHighSpeed, | ||
| 30 | } | ||
| 31 | |||
| 32 | impl From<Speed> for vals::Ospeedr { | ||
| 33 | fn from(speed: Speed) -> Self { | ||
| 34 | use Speed::*; | ||
| 35 | |||
| 36 | match speed { | ||
| 37 | LowSpeed => vals::Ospeedr::LOWSPEED, | ||
| 38 | MediumSpeed => vals::Ospeedr::MEDIUMSPEED, | ||
| 39 | #[cfg(not(syscfg_f0))] | ||
| 40 | HighSpeed => vals::Ospeedr::HIGHSPEED, | ||
| 41 | VeryHighSpeed => vals::Ospeedr::VERYHIGHSPEED, | ||
| 42 | } | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 21 | /// GPIO input driver. | 46 | /// GPIO input driver. |
| 22 | pub struct Input<'d, T: Pin> { | 47 | pub struct Input<'d, T: Pin> { |
| 23 | pub(crate) pin: T, | 48 | pub(crate) pin: T, |
| @@ -86,7 +111,12 @@ pub struct Output<'d, T: Pin> { | |||
| 86 | } | 111 | } |
| 87 | 112 | ||
| 88 | impl<'d, T: Pin> Output<'d, T> { | 113 | impl<'d, T: Pin> Output<'d, T> { |
| 89 | pub fn new(pin: impl Unborrow<Target = T> + 'd, initial_output: Level) -> Self { | 114 | pub fn new( |
| 115 | pin: impl Unborrow<Target = T> + 'd, | ||
| 116 | initial_output: Level, | ||
| 117 | speed: Speed, | ||
| 118 | open_drain: bool, | ||
| 119 | ) -> Self { | ||
| 90 | unborrow!(pin); | 120 | unborrow!(pin); |
| 91 | 121 | ||
| 92 | match initial_output { | 122 | match initial_output { |
| @@ -99,6 +129,10 @@ impl<'d, T: Pin> Output<'d, T> { | |||
| 99 | let n = pin.pin() as usize; | 129 | let n = pin.pin() as usize; |
| 100 | r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING)); | 130 | r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING)); |
| 101 | r.moder().modify(|w| w.set_moder(n, vals::Moder::OUTPUT)); | 131 | r.moder().modify(|w| w.set_moder(n, vals::Moder::OUTPUT)); |
| 132 | if open_drain { | ||
| 133 | r.otyper().modify(|w| w.set_ot(n, vals::Ot::OPENDRAIN)); | ||
| 134 | } | ||
| 135 | pin.set_speed(speed); | ||
| 102 | }); | 136 | }); |
| 103 | 137 | ||
| 104 | Self { | 138 | Self { |
| @@ -115,6 +149,8 @@ impl<'d, T: Pin> Drop for Output<'d, T> { | |||
| 115 | let n = self.pin.pin() as usize; | 149 | let n = self.pin.pin() as usize; |
| 116 | r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING)); | 150 | r.pupdr().modify(|w| w.set_pupdr(n, vals::Pupdr::FLOATING)); |
| 117 | r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT)); | 151 | r.moder().modify(|w| w.set_moder(n, vals::Moder::INPUT)); |
| 152 | r.otyper().modify(|w| w.set_ot(n, vals::Ot::PUSHPULL)); | ||
| 153 | self.pin.set_speed(Speed::LowSpeed); | ||
| 118 | }); | 154 | }); |
| 119 | } | 155 | } |
| 120 | } | 156 | } |
| @@ -148,6 +184,18 @@ impl<'d, T: Pin> StatefulOutputPin for Output<'d, T> { | |||
| 148 | } | 184 | } |
| 149 | } | 185 | } |
| 150 | 186 | ||
| 187 | impl<'d, T: Pin> InputPin for Output<'d, T> { | ||
| 188 | type Error = Infallible; | ||
| 189 | |||
| 190 | fn is_high(&self) -> Result<bool, Self::Error> { | ||
| 191 | self.is_set_high() | ||
| 192 | } | ||
| 193 | |||
| 194 | fn is_low(&self) -> Result<bool, Self::Error> { | ||
| 195 | self.is_set_low() | ||
| 196 | } | ||
| 197 | } | ||
| 198 | |||
| 151 | impl<'d, T: Pin> toggleable::Default for Output<'d, T> {} | 199 | impl<'d, T: Pin> toggleable::Default for Output<'d, T> {} |
| 152 | 200 | ||
| 153 | pub(crate) mod sealed { | 201 | pub(crate) mod sealed { |
| @@ -206,6 +254,13 @@ pub(crate) mod sealed { | |||
| 206 | .moder() | 254 | .moder() |
| 207 | .modify(|w| w.set_moder(pin, vals::Moder::ANALOG)); | 255 | .modify(|w| w.set_moder(pin, vals::Moder::ANALOG)); |
| 208 | } | 256 | } |
| 257 | |||
| 258 | unsafe fn set_speed(&self, speed: Speed) { | ||
| 259 | let pin = self._pin() as usize; | ||
| 260 | self.block() | ||
| 261 | .ospeedr() | ||
| 262 | .modify(|w| w.set_ospeedr(pin, speed.into())); | ||
| 263 | } | ||
| 209 | } | 264 | } |
| 210 | 265 | ||
| 211 | pub trait OptionalPin {} | 266 | pub trait OptionalPin {} |
