diff options
| author | Dario Nieuwenhuis <[email protected]> | 2022-01-14 22:02:00 +0100 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2022-01-19 17:59:55 +0100 |
| commit | 58fc64722c65bbdc209ae0fd1700f03702bbcd08 (patch) | |
| tree | 77f9412b47259cd4cf4170b0a257b371398d4f2c /embassy-stm32/src | |
| parent | 52e156b429417bde59d0ea67d11256866f1dcec9 (diff) | |
stm32/gpio: expose all functionality as inherent methods.
Diffstat (limited to 'embassy-stm32/src')
| -rw-r--r-- | embassy-stm32/src/exti.rs | 12 | ||||
| -rw-r--r-- | embassy-stm32/src/gpio.rs | 230 |
2 files changed, 165 insertions, 77 deletions
diff --git a/embassy-stm32/src/exti.rs b/embassy-stm32/src/exti.rs index 552433b87..eded6ba71 100644 --- a/embassy-stm32/src/exti.rs +++ b/embassy-stm32/src/exti.rs | |||
| @@ -94,17 +94,25 @@ impl<'d, T: GpioPin> ExtiInput<'d, T> { | |||
| 94 | pub fn new(pin: Input<'d, T>, _ch: impl Unborrow<Target = T::ExtiChannel> + 'd) -> Self { | 94 | pub fn new(pin: Input<'d, T>, _ch: impl Unborrow<Target = T::ExtiChannel> + 'd) -> Self { |
| 95 | Self { pin } | 95 | Self { pin } |
| 96 | } | 96 | } |
| 97 | |||
| 98 | pub fn is_high(&self) -> bool { | ||
| 99 | self.pin.is_high() | ||
| 100 | } | ||
| 101 | |||
| 102 | pub fn is_low(&self) -> bool { | ||
| 103 | self.pin.is_low() | ||
| 104 | } | ||
| 97 | } | 105 | } |
| 98 | 106 | ||
| 99 | impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> { | 107 | impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> { |
| 100 | type Error = Infallible; | 108 | type Error = Infallible; |
| 101 | 109 | ||
| 102 | fn is_high(&self) -> Result<bool, Self::Error> { | 110 | fn is_high(&self) -> Result<bool, Self::Error> { |
| 103 | self.pin.is_high() | 111 | Ok(self.is_high()) |
| 104 | } | 112 | } |
| 105 | 113 | ||
| 106 | fn is_low(&self) -> Result<bool, Self::Error> { | 114 | fn is_low(&self) -> Result<bool, Self::Error> { |
| 107 | self.pin.is_low() | 115 | Ok(self.is_low()) |
| 108 | } | 116 | } |
| 109 | } | 117 | } |
| 110 | 118 | ||
diff --git a/embassy-stm32/src/gpio.rs b/embassy-stm32/src/gpio.rs index 6b4a9285f..57b9ba6b7 100644 --- a/embassy-stm32/src/gpio.rs +++ b/embassy-stm32/src/gpio.rs | |||
| @@ -3,7 +3,7 @@ use core::convert::Infallible; | |||
| 3 | use core::marker::PhantomData; | 3 | use core::marker::PhantomData; |
| 4 | use embassy::util::Unborrow; | 4 | use embassy::util::Unborrow; |
| 5 | use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; | 5 | use embassy_hal_common::{unborrow, unsafe_impl_unborrow}; |
| 6 | use embedded_hal::digital::v2::{toggleable, InputPin, OutputPin, StatefulOutputPin}; | 6 | use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin}; |
| 7 | 7 | ||
| 8 | use crate::pac; | 8 | use crate::pac; |
| 9 | use crate::pac::gpio::{self, vals}; | 9 | use crate::pac::gpio::{self, vals}; |
| @@ -113,6 +113,15 @@ impl<'d, T: Pin> Input<'d, T> { | |||
| 113 | phantom: PhantomData, | 113 | phantom: PhantomData, |
| 114 | } | 114 | } |
| 115 | } | 115 | } |
| 116 | |||
| 117 | pub fn is_high(&self) -> bool { | ||
| 118 | !self.is_low() | ||
| 119 | } | ||
| 120 | |||
| 121 | pub fn is_low(&self) -> bool { | ||
| 122 | let state = unsafe { self.pin.block().idr().read().idr(self.pin.pin() as _) }; | ||
| 123 | state == vals::Idr::LOW | ||
| 124 | } | ||
| 116 | } | 125 | } |
| 117 | 126 | ||
| 118 | impl<'d, T: Pin> Drop for Input<'d, T> { | 127 | impl<'d, T: Pin> Drop for Input<'d, T> { |
| @@ -132,19 +141,6 @@ impl<'d, T: Pin> Drop for Input<'d, T> { | |||
| 132 | } | 141 | } |
| 133 | } | 142 | } |
| 134 | 143 | ||
| 135 | impl<'d, T: Pin> InputPin for Input<'d, T> { | ||
| 136 | type Error = Infallible; | ||
| 137 | |||
| 138 | fn is_high(&self) -> Result<bool, Self::Error> { | ||
| 139 | self.is_low().map(|v| !v) | ||
| 140 | } | ||
| 141 | |||
| 142 | fn is_low(&self) -> Result<bool, Self::Error> { | ||
| 143 | let state = unsafe { self.pin.block().idr().read().idr(self.pin.pin() as _) }; | ||
| 144 | Ok(state == vals::Idr::LOW) | ||
| 145 | } | ||
| 146 | } | ||
| 147 | |||
| 148 | /// Digital input or output level. | 144 | /// Digital input or output level. |
| 149 | #[derive(Debug, Eq, PartialEq)] | 145 | #[derive(Debug, Eq, PartialEq)] |
| 150 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 146 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| @@ -191,6 +187,36 @@ impl<'d, T: Pin> Output<'d, T> { | |||
| 191 | phantom: PhantomData, | 187 | phantom: PhantomData, |
| 192 | } | 188 | } |
| 193 | } | 189 | } |
| 190 | |||
| 191 | /// Set the output as high. | ||
| 192 | pub fn set_high(&mut self) { | ||
| 193 | self.pin.set_high(); | ||
| 194 | } | ||
| 195 | |||
| 196 | /// Set the output as low. | ||
| 197 | pub fn set_low(&mut self) { | ||
| 198 | self.pin.set_low(); | ||
| 199 | } | ||
| 200 | |||
| 201 | /// Is the output pin set as high? | ||
| 202 | pub fn is_set_high(&self) -> bool { | ||
| 203 | !self.is_set_low() | ||
| 204 | } | ||
| 205 | |||
| 206 | /// Is the output pin set as low? | ||
| 207 | pub fn is_set_low(&self) -> bool { | ||
| 208 | let state = unsafe { self.pin.block().odr().read().odr(self.pin.pin() as _) }; | ||
| 209 | state == vals::Odr::LOW | ||
| 210 | } | ||
| 211 | |||
| 212 | /// Toggle pin output | ||
| 213 | pub fn toggle(&mut self) { | ||
| 214 | if self.is_set_low() { | ||
| 215 | self.set_high() | ||
| 216 | } else { | ||
| 217 | self.set_low() | ||
| 218 | } | ||
| 219 | } | ||
| 194 | } | 220 | } |
| 195 | 221 | ||
| 196 | impl<'d, T: Pin> Drop for Output<'d, T> { | 222 | impl<'d, T: Pin> Drop for Output<'d, T> { |
| @@ -214,37 +240,6 @@ impl<'d, T: Pin> Drop for Output<'d, T> { | |||
| 214 | } | 240 | } |
| 215 | } | 241 | } |
| 216 | 242 | ||
| 217 | impl<'d, T: Pin> OutputPin for Output<'d, T> { | ||
| 218 | type Error = Infallible; | ||
| 219 | |||
| 220 | /// Set the output as high. | ||
| 221 | fn set_high(&mut self) -> Result<(), Self::Error> { | ||
| 222 | self.pin.set_high(); | ||
| 223 | Ok(()) | ||
| 224 | } | ||
| 225 | |||
| 226 | /// Set the output as low. | ||
| 227 | fn set_low(&mut self) -> Result<(), Self::Error> { | ||
| 228 | self.pin.set_low(); | ||
| 229 | Ok(()) | ||
| 230 | } | ||
| 231 | } | ||
| 232 | |||
| 233 | impl<'d, T: Pin> StatefulOutputPin for Output<'d, T> { | ||
| 234 | /// Is the output pin set as high? | ||
| 235 | fn is_set_high(&self) -> Result<bool, Self::Error> { | ||
| 236 | self.is_set_low().map(|v| !v) | ||
| 237 | } | ||
| 238 | |||
| 239 | /// Is the output pin set as low? | ||
| 240 | fn is_set_low(&self) -> Result<bool, Self::Error> { | ||
| 241 | let state = unsafe { self.pin.block().odr().read().odr(self.pin.pin() as _) }; | ||
| 242 | Ok(state == vals::Odr::LOW) | ||
| 243 | } | ||
| 244 | } | ||
| 245 | |||
| 246 | impl<'d, T: Pin> toggleable::Default for Output<'d, T> {} | ||
| 247 | |||
| 248 | /// GPIO output open-drain driver. | 243 | /// GPIO output open-drain driver. |
| 249 | pub struct OutputOpenDrain<'d, T: Pin> { | 244 | pub struct OutputOpenDrain<'d, T: Pin> { |
| 250 | pub(crate) pin: T, | 245 | pub(crate) pin: T, |
| @@ -294,6 +289,45 @@ impl<'d, T: Pin> OutputOpenDrain<'d, T> { | |||
| 294 | phantom: PhantomData, | 289 | phantom: PhantomData, |
| 295 | } | 290 | } |
| 296 | } | 291 | } |
| 292 | |||
| 293 | pub fn is_high(&self) -> bool { | ||
| 294 | !self.is_low() | ||
| 295 | } | ||
| 296 | |||
| 297 | pub fn is_low(&self) -> bool { | ||
| 298 | let state = unsafe { self.pin.block().idr().read().idr(self.pin.pin() as _) }; | ||
| 299 | state == vals::Idr::LOW | ||
| 300 | } | ||
| 301 | |||
| 302 | /// Set the output as high. | ||
| 303 | pub fn set_high(&mut self) { | ||
| 304 | self.pin.set_high(); | ||
| 305 | } | ||
| 306 | |||
| 307 | /// Set the output as low. | ||
| 308 | pub fn set_low(&mut self) { | ||
| 309 | self.pin.set_low(); | ||
| 310 | } | ||
| 311 | |||
| 312 | /// Is the output pin set as high? | ||
| 313 | pub fn is_set_high(&self) -> bool { | ||
| 314 | !self.is_set_low() | ||
| 315 | } | ||
| 316 | |||
| 317 | /// Is the output pin set as low? | ||
| 318 | pub fn is_set_low(&self) -> bool { | ||
| 319 | let state = unsafe { self.pin.block().odr().read().odr(self.pin.pin() as _) }; | ||
| 320 | state == vals::Odr::LOW | ||
| 321 | } | ||
| 322 | |||
| 323 | /// Toggle pin output | ||
| 324 | pub fn toggle(&mut self) { | ||
| 325 | if self.is_set_low() { | ||
| 326 | self.set_high() | ||
| 327 | } else { | ||
| 328 | self.set_low() | ||
| 329 | } | ||
| 330 | } | ||
| 297 | } | 331 | } |
| 298 | 332 | ||
| 299 | impl<'d, T: Pin> Drop for OutputOpenDrain<'d, T> { | 333 | impl<'d, T: Pin> Drop for OutputOpenDrain<'d, T> { |
| @@ -317,36 +351,6 @@ impl<'d, T: Pin> Drop for OutputOpenDrain<'d, T> { | |||
| 317 | } | 351 | } |
| 318 | } | 352 | } |
| 319 | 353 | ||
| 320 | impl<'d, T: Pin> OutputPin for OutputOpenDrain<'d, T> { | ||
| 321 | type Error = Infallible; | ||
| 322 | |||
| 323 | /// Set the output as high. | ||
| 324 | fn set_high(&mut self) -> Result<(), Self::Error> { | ||
| 325 | self.pin.set_high(); | ||
| 326 | Ok(()) | ||
| 327 | } | ||
| 328 | |||
| 329 | /// Set the output as low. | ||
| 330 | fn set_low(&mut self) -> Result<(), Self::Error> { | ||
| 331 | self.pin.set_low(); | ||
| 332 | Ok(()) | ||
| 333 | } | ||
| 334 | } | ||
| 335 | |||
| 336 | impl<'d, T: Pin> InputPin for OutputOpenDrain<'d, T> { | ||
| 337 | type Error = Infallible; | ||
| 338 | |||
| 339 | fn is_high(&self) -> Result<bool, Self::Error> { | ||
| 340 | self.is_low().map(|v| !v) | ||
| 341 | } | ||
| 342 | |||
| 343 | fn is_low(&self) -> Result<bool, Self::Error> { | ||
| 344 | // NOTE(safety) Atomic read | ||
| 345 | let state = unsafe { self.pin.block().idr().read().idr(self.pin.pin() as usize) }; | ||
| 346 | Ok(state == vals::Idr::LOW) | ||
| 347 | } | ||
| 348 | } | ||
| 349 | |||
| 350 | pub(crate) mod sealed { | 354 | pub(crate) mod sealed { |
| 351 | use super::*; | 355 | use super::*; |
| 352 | 356 | ||
| @@ -612,3 +616,79 @@ pub(crate) unsafe fn init() { | |||
| 612 | }; | 616 | }; |
| 613 | } | 617 | } |
| 614 | } | 618 | } |
| 619 | |||
| 620 | mod eh02 { | ||
| 621 | use super::*; | ||
| 622 | |||
| 623 | impl<'d, T: Pin> InputPin for Input<'d, T> { | ||
| 624 | type Error = Infallible; | ||
| 625 | |||
| 626 | fn is_high(&self) -> Result<bool, Self::Error> { | ||
| 627 | Ok(self.is_high()) | ||
| 628 | } | ||
| 629 | |||
| 630 | fn is_low(&self) -> Result<bool, Self::Error> { | ||
| 631 | Ok(self.is_low()) | ||
| 632 | } | ||
| 633 | } | ||
| 634 | |||
| 635 | impl<'d, T: Pin> OutputPin for Output<'d, T> { | ||
| 636 | type Error = Infallible; | ||
| 637 | |||
| 638 | fn set_high(&mut self) -> Result<(), Self::Error> { | ||
| 639 | Ok(self.set_high()) | ||
| 640 | } | ||
| 641 | |||
| 642 | fn set_low(&mut self) -> Result<(), Self::Error> { | ||
| 643 | Ok(self.set_low()) | ||
| 644 | } | ||
| 645 | } | ||
| 646 | |||
| 647 | impl<'d, T: Pin> StatefulOutputPin for Output<'d, T> { | ||
| 648 | fn is_set_high(&self) -> Result<bool, Self::Error> { | ||
| 649 | Ok(self.is_set_high()) | ||
| 650 | } | ||
| 651 | |||
| 652 | /// Is the output pin set as low? | ||
| 653 | fn is_set_low(&self) -> Result<bool, Self::Error> { | ||
| 654 | Ok(self.is_set_low()) | ||
| 655 | } | ||
| 656 | } | ||
| 657 | |||
| 658 | impl<'d, T: Pin> ToggleableOutputPin for Output<'d, T> { | ||
| 659 | type Error = Infallible; | ||
| 660 | fn toggle(&mut self) -> Result<(), Self::Error> { | ||
| 661 | Ok(self.toggle()) | ||
| 662 | } | ||
| 663 | } | ||
| 664 | |||
| 665 | impl<'d, T: Pin> OutputPin for OutputOpenDrain<'d, T> { | ||
| 666 | type Error = Infallible; | ||
| 667 | |||
| 668 | fn set_high(&mut self) -> Result<(), Self::Error> { | ||
| 669 | Ok(self.set_high()) | ||
| 670 | } | ||
| 671 | |||
| 672 | fn set_low(&mut self) -> Result<(), Self::Error> { | ||
| 673 | Ok(self.set_low()) | ||
| 674 | } | ||
| 675 | } | ||
| 676 | |||
| 677 | impl<'d, T: Pin> StatefulOutputPin for OutputOpenDrain<'d, T> { | ||
| 678 | fn is_set_high(&self) -> Result<bool, Self::Error> { | ||
| 679 | Ok(self.is_set_high()) | ||
| 680 | } | ||
| 681 | |||
| 682 | /// Is the output pin set as low? | ||
| 683 | fn is_set_low(&self) -> Result<bool, Self::Error> { | ||
| 684 | Ok(self.is_set_low()) | ||
| 685 | } | ||
| 686 | } | ||
| 687 | |||
| 688 | impl<'d, T: Pin> ToggleableOutputPin for OutputOpenDrain<'d, T> { | ||
| 689 | type Error = Infallible; | ||
| 690 | fn toggle(&mut self) -> Result<(), Self::Error> { | ||
| 691 | Ok(self.toggle()) | ||
| 692 | } | ||
| 693 | } | ||
| 694 | } | ||
