Skip to content

Commit

Permalink
digital v2
Browse files Browse the repository at this point in the history
  • Loading branch information
burrbull committed Aug 2, 2019
1 parent ecbe3d9 commit a582de0
Show file tree
Hide file tree
Showing 10 changed files with 84 additions and 58 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
5 changes: 3 additions & 2 deletions examples/blinky.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ use stm32f1xx_hal::{
timer::Timer,
};
use cortex_m_rt::entry;
use embedded_hal::digital::v2::OutputPin;

#[entry]
fn main() -> ! {
Expand Down Expand Up @@ -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();
}
}
1 change: 1 addition & 0 deletions examples/blinky_rtc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use stm32f1xx_hal::{

use nb::block;
use cortex_m_rt::entry;
use embedded_hal::digital::v2::OutputPin;

#[entry]
fn main() -> ! {
Expand Down
5 changes: 3 additions & 2 deletions examples/delay.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use stm32f1xx_hal::{
delay::Delay,
};
use cortex_m_rt::entry;
use embedded_hal::digital::v2::OutputPin;

#[entry]
fn main() -> ! {
Expand All @@ -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);
}
}
7 changes: 4 additions & 3 deletions examples/led.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use stm32f1xx_hal::{
pac,
};
use cortex_m_rt::entry;
use embedded_hal::digital::v2::OutputPin;

#[entry]
fn main() -> ! {
Expand All @@ -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 {}
}
5 changes: 3 additions & 2 deletions examples/mfrc522.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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() -> ! {
Expand Down Expand Up @@ -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() {
Expand Down
4 changes: 1 addition & 3 deletions examples/serial_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@

use panic_halt as _;

use cortex_m::asm;

use nb::block;

use stm32f1xx_hal::{
Expand Down Expand Up @@ -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();
Expand Down
108 changes: 65 additions & 43 deletions src/gpio.rs
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 })
}
}

Expand Down Expand Up @@ -354,7 +372,7 @@ macro_rules! gpio {
match initial_state {
State::High => res.set_high(),
State::Low => res.set_low(),
}
}.unwrap();

cr
.cr()
Expand Down Expand Up @@ -392,7 +410,7 @@ macro_rules! gpio {
match initial_state {
State::High => res.set_high(),
State::Low => res.set_low(),
}
}.unwrap();

cr
.cr()
Expand Down Expand Up @@ -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 })
}
}
)+
Expand Down
4 changes: 2 additions & 2 deletions src/prelude.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit a582de0

Please sign in to comment.