Selaa lähdekoodia

Update to digital v2 traits (#93)

Zgarbul Andrey 4 vuotta sitten
vanhempi
säilyke
33d175c5ab
10 muutettua tiedostoa jossa 86 lisäystä ja 60 poistoa
  1. 1 0
      CHANGELOG.md
  2. 1 1
      Cargo.toml
  3. 3 2
      examples/blinky.rs
  4. 3 2
      examples/blinky_rtc.rs
  5. 3 2
      examples/delay.rs
  6. 4 3
      examples/led.rs
  7. 3 2
      examples/mfrc522.rs
  8. 1 3
      examples/serial_config.rs
  9. 65 43
      src/gpio.rs
  10. 2 2
      src/prelude.rs

+ 1 - 0
CHANGELOG.md

@@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
 
 ### Breaking changes
 
+- Replace gpio traits with digital::v2
 - Bump `stm32f1` dependency (`0.8.0`)
 - ADC now requires the clock configuration for intialisation
 - `disable_jtag` now transforms PA15, PB3 and PB4 to forbid their use without desactivating JTAG

+ 1 - 1
Cargo.toml

@@ -33,8 +33,8 @@ default-features = false
 version = "0.2.2"
 
 [dependencies.embedded-hal]
+version = "0.2.3"
 features = ["unproven"]
-version = "0.2.2"
 
 [dev-dependencies]
 panic-halt = "0.2.0"

+ 3 - 2
examples/blinky.rs

@@ -19,6 +19,7 @@ use stm32f1xx_hal::{
     timer::Timer,
 };
 use cortex_m_rt::entry;
+use embedded_hal::digital::v2::OutputPin;
 
 #[entry]
 fn main() -> ! {
@@ -48,8 +49,8 @@ fn main() -> ! {
     // Wait for the timer to trigger an update and change the state of the LED
     loop {
         block!(timer.wait()).unwrap();
-        led.set_high();
+        led.set_high().unwrap();
         block!(timer.wait()).unwrap();
-        led.set_low();
+        led.set_low().unwrap();
     }
 }

+ 3 - 2
examples/blinky_rtc.rs

@@ -20,6 +20,7 @@ use stm32f1xx_hal::{
 
 use nb::block;
 use cortex_m_rt::entry;
+use embedded_hal::digital::v2::OutputPin;
 
 #[entry]
 fn main() -> ! {
@@ -46,11 +47,11 @@ fn main() -> ! {
         rtc.set_alarm(5);
         block!(rtc.wait_alarm()).unwrap();
         if led_on {
-            led.set_low();
+            led.set_low().unwrap();
             led_on = false;
         }
         else {
-            led.set_high();
+            led.set_high().unwrap();
             led_on = true;
         }
     }

+ 3 - 2
examples/delay.rs

@@ -12,6 +12,7 @@ use stm32f1xx_hal::{
     delay::Delay,
 };
 use cortex_m_rt::entry;
+use embedded_hal::digital::v2::OutputPin;
 
 #[entry]
 fn main() -> ! {
@@ -37,9 +38,9 @@ fn main() -> ! {
     let mut delay = Delay::new(cp.SYST, clocks);
 
     loop {
-        led.set_high();
+        led.set_high().unwrap();
         delay.delay_ms(1_000_u16);
-        led.set_low();
+        led.set_low().unwrap();
         delay.delay_ms(1_000_u16);
     }
 }

+ 4 - 3
examples/led.rs

@@ -20,6 +20,7 @@ use stm32f1xx_hal::{
     pac,
 };
 use cortex_m_rt::entry;
+use embedded_hal::digital::v2::OutputPin;
 
 #[entry]
 fn main() -> ! {
@@ -29,13 +30,13 @@ fn main() -> ! {
     let mut gpioc = p.GPIOC.split(&mut rcc.apb2);
 
     #[cfg(feature = "stm32f100")]
-    gpioc.pc9.into_push_pull_output(&mut gpioc.crh).set_high();
+    gpioc.pc9.into_push_pull_output(&mut gpioc.crh).set_high().unwrap();
 
     #[cfg(feature = "stm32f101")]
-    gpioc.pc9.into_push_pull_output(&mut gpioc.crh).set_high();
+    gpioc.pc9.into_push_pull_output(&mut gpioc.crh).set_high().unwrap();
 
     #[cfg(feature = "stm32f103")]
-    gpioc.pc13.into_push_pull_output(&mut gpioc.crh).set_low();
+    gpioc.pc13.into_push_pull_output(&mut gpioc.crh).set_low().unwrap();
 
     loop {}
 }

+ 3 - 2
examples/mfrc522.rs

@@ -13,6 +13,7 @@ use stm32f1xx_hal::{
 };
 use mfrc522::Mfrc522;
 use cortex_m_rt::entry;
+use embedded_hal::digital::{v1_compat::OldOutputPin, v2::OutputPin};
 
 #[entry]
 fn main() -> ! {
@@ -42,10 +43,10 @@ fn main() -> ! {
     );
 
     let nss = gpioa.pa4.into_push_pull_output(&mut gpioa.crl);
-    let mut mfrc522 = Mfrc522::new(spi, nss).unwrap();
+    let mut mfrc522 = Mfrc522::new(spi, OldOutputPin::from(nss)).unwrap();
 
     let mut led = gpioc.pc13.into_push_pull_output(&mut gpioc.crh);
-    led.set_high();
+    led.set_high().unwrap();
 
     loop {
         if let Ok(atqa) = mfrc522.reqa() {

+ 1 - 3
examples/serial_config.rs

@@ -8,8 +8,6 @@
 
 use panic_halt as _;
 
-use cortex_m::asm;
-
 use nb::block;
 
 use stm32f1xx_hal::{
@@ -73,7 +71,7 @@ fn main() -> ! {
     );
 
     // Split the serial struct into a receiving and a transmitting part
-    let (mut tx, mut rx) = serial.split();
+    let (mut tx, _rx) = serial.split();
 
     let sent = b'U';
     block!(tx.write(sent)).ok();

+ 65 - 43
src/gpio.rs

@@ -1,4 +1,18 @@
 //! # General Purpose I/Os
+//!
+//! # Interfacing with v1 traits
+//!
+//! `embedded-hal` has two versions of the digital traits, `v2` which is used
+//! by this crate and `v1` which is deprecated but still used by a lot of drivers.
+//! If you want to use such a driver with this crate, you need to convert the digital pins to the `v1` type.
+//!
+//! This is done using `embedded-hal::digital::v1_compat::OldOutputPin`. For example:
+//!
+//! ```rust
+//! let nss = gpioa.pa4.into_push_pull_output(&mut gpioa.crl);
+//! let mut mfrc522 = Mfrc522::new(spi, OldOutputPin::from(nss)).unwrap();
+//! ```
+//!
 
 use core::marker::PhantomData;
 
@@ -63,9 +77,10 @@ macro_rules! gpio {
     ]) => {
         /// GPIO
         pub mod $gpiox {
+            use void::Void;
             use core::marker::PhantomData;
 
-            use crate::hal::digital::{InputPin, OutputPin, StatefulOutputPin, toggleable};
+            use crate::hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, toggleable};
             use crate::pac::{$gpioy, $GPIOX};
 
             use crate::rcc::APB2;
@@ -143,49 +158,52 @@ macro_rules! gpio {
             }
 
             impl<MODE> OutputPin for $PXx<Output<MODE>> {
-                fn set_high(&mut self) {
+                type Error = Void;
+                fn set_high(&mut self) -> Result<(), Self::Error> {
                     // NOTE(unsafe) atomic write to a stateless register
-                    unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << self.i)) }
+                    Ok(unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << self.i)) })
                 }
 
-                fn set_low(&mut self) {
+                fn set_low(&mut self) -> Result<(), Self::Error> {
                     // NOTE(unsafe) atomic write to a stateless register
-                    unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + self.i))) }
+                    Ok(unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + self.i))) })
                 }
             }
 
             impl<MODE> InputPin for $PXx<Input<MODE>> {
-                fn is_high(&self) -> bool {
-                    !self.is_low()
+                type Error = Void;
+                fn is_high(&self) -> Result<bool, Self::Error> {
+                    self.is_low().map(|b| !b)
                 }
 
-                fn is_low(&self) -> bool {
+                fn is_low(&self) -> Result<bool, Self::Error> {
                     // NOTE(unsafe) atomic read with no side effects
-                    unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << self.i) == 0 }
+                    Ok(unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << self.i) == 0 })
                 }
             }
 
             impl <MODE> StatefulOutputPin for $PXx<Output<MODE>> {
-                fn is_set_high(&self) -> bool {
-                    !self.is_set_low()
+                fn is_set_high(&self) -> Result<bool, Self::Error> {
+                    self.is_set_low().map(|b| !b)
                 }
 
-                fn is_set_low(&self) -> bool {
+                fn is_set_low(&self) -> Result<bool, Self::Error> {
                     // NOTE(unsafe) atomic read with no side effects
-                    unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << self.i) == 0 }
+                    Ok(unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << self.i) == 0 })
                 }
             }
 
             impl <MODE> toggleable::Default for $PXx<Output<MODE>> {}
 
             impl InputPin for $PXx<Output<OpenDrain>> {
-                fn is_high(&self) -> bool {
-                    !self.is_low()
+                type Error = Void;
+                fn is_high(&self) -> Result<bool, Self::Error> {
+                    self.is_low().map(|b| !b)
                 }
 
-                fn is_low(&self) -> bool {
+                fn is_low(&self) -> Result<bool, Self::Error> {
                     // NOTE(unsafe) atomic read with no side effects
-                    unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << self.i) == 0 }
+                    Ok(unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << self.i) == 0 })
                 }
             }
 
@@ -354,7 +372,7 @@ macro_rules! gpio {
                         match initial_state {
                             State::High => res.set_high(),
                             State::Low  => res.set_low(),
-                        }
+                        }.unwrap();
 
                         cr
                             .cr()
@@ -392,7 +410,7 @@ macro_rules! gpio {
                         match initial_state {
                             State::High => res.set_high(),
                             State::Low  => res.set_low(),
-                        }
+                        }.unwrap();
 
                         cr
                             .cr()
@@ -437,72 +455,76 @@ macro_rules! gpio {
                 }
 
                 impl<MODE> OutputPin for $PXi<Output<MODE>> {
-                    fn set_high(&mut self) {
+                    type Error = Void;
+                    fn set_high(&mut self) -> Result<(), Self::Error> {
                         // NOTE(unsafe) atomic write to a stateless register
-                        unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << $i)) }
+                        Ok(unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << $i)) })
                     }
 
-                    fn set_low(&mut self) {
+                    fn set_low(&mut self) -> Result<(), Self::Error> {
                         // NOTE(unsafe) atomic write to a stateless register
-                        unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + $i))) }
+                        Ok(unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + $i))) })
                     }
                 }
 
                 impl<MODE> StatefulOutputPin for $PXi<Output<MODE>> {
-                    fn is_set_high(&self) -> bool {
-                        !self.is_set_low()
+                    fn is_set_high(&self) -> Result<bool, Self::Error> {
+                        self.is_set_low().map(|b| !b)
                     }
 
-                    fn is_set_low(&self) -> bool {
+                    fn is_set_low(&self) -> Result<bool, Self::Error> {
                         // NOTE(unsafe) atomic read with no side effects
-                        unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << $i) == 0 }
+                        Ok(unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << $i) == 0 })
                     }
                 }
 
                 impl<MODE> toggleable::Default for $PXi<Output<MODE>> {}
 
                 impl<MODE> OutputPin for $PXi<Alternate<MODE>> {
-                    fn set_high(&mut self) {
+                    type Error = Void;
+                    fn set_high(&mut self) -> Result<(), Self::Error> {
                         // NOTE(unsafe) atomic write to a stateless register
-                        unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << $i)) }
+                        Ok(unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << $i)) })
                     }
 
-                    fn set_low(&mut self) {
+                    fn set_low(&mut self) -> Result<(), Self::Error> {
                         // NOTE(unsafe) atomic write to a stateless register
-                        unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + $i))) }
+                        Ok(unsafe { (*$GPIOX::ptr()).bsrr.write(|w| w.bits(1 << (16 + $i))) })
                     }
                 }
 
                 impl<MODE> StatefulOutputPin for $PXi<Alternate<MODE>> {
-                    fn is_set_high(&self) -> bool {
-                        !self.is_set_low()
+                    fn is_set_high(&self) -> Result<bool, Self::Error> {
+                        self.is_set_low().map(|b| !b)
                     }
 
-                    fn is_set_low(&self) -> bool {
+                    fn is_set_low(&self) -> Result<bool, Self::Error> {
                         // NOTE(unsafe) atomic read with no side effects
-                        unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << $i) == 0 }
+                        Ok(unsafe { (*$GPIOX::ptr()).odr.read().bits() & (1 << $i) == 0 })
                     }
                 }
 
                 impl<MODE> InputPin for $PXi<Input<MODE>> {
-                    fn is_high(&self) -> bool {
-                        !self.is_low()
+                    type Error = Void;
+                    fn is_high(&self) -> Result<bool, Self::Error> {
+                        self.is_low().map(|b| !b)
                     }
 
-                    fn is_low(&self) -> bool {
+                    fn is_low(&self) -> Result<bool, Self::Error> {
                         // NOTE(unsafe) atomic read with no side effects
-                        unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << $i) == 0 }
+                        Ok(unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << $i) == 0 })
                     }
                 }
 
                 impl InputPin for $PXi<Output<OpenDrain>> {
-                    fn is_high(&self) -> bool {
-                        !self.is_low()
+                    type Error = Void;
+                    fn is_high(&self) -> Result<bool, Self::Error> {
+                        self.is_low().map(|b| !b)
                     }
 
-                    fn is_low(&self) -> bool {
+                    fn is_low(&self) -> Result<bool, Self::Error> {
                         // NOTE(unsafe) atomic read with no side effects
-                        unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << $i) == 0 }
+                        Ok(unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << $i) == 0 })
                     }
                 }
             )+

+ 2 - 2
src/prelude.rs

@@ -3,8 +3,8 @@ pub use crate::dma::DmaExt as _stm32_hal_dma_DmaExt;
 pub use crate::flash::FlashExt as _stm32_hal_flash_FlashExt;
 pub use crate::gpio::GpioExt as _stm32_hal_gpio_GpioExt;
 pub use crate::hal::adc::OneShot as _embedded_hal_adc_OneShot;
-pub use crate::hal::digital::StatefulOutputPin as _embedded_hal_digital_StatefulOutputPin;
-pub use crate::hal::digital::ToggleableOutputPin as _embedded_hal_digital_ToggleableOutputPin;
+pub use crate::hal::digital::v2::StatefulOutputPin as _embedded_hal_digital_StatefulOutputPin;
+pub use crate::hal::digital::v2::ToggleableOutputPin as _embedded_hal_digital_ToggleableOutputPin;
 pub use crate::hal::prelude::*;
 pub use crate::pwm::PwmExt as _stm32_hal_pwm_PwmExt;
 pub use crate::rcc::RccExt as _stm32_hal_rcc_RccExt;