Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

digital v2 #93

Merged
merged 2 commits into from
Aug 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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();
}
}
5 changes: 3 additions & 2 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 All @@ -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;
}
}
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