diff --git a/src/gpio.rs b/src/gpio.rs index 806125f94..748d8bf80 100644 --- a/src/gpio.rs +++ b/src/gpio.rs @@ -57,7 +57,7 @@ macro_rules! gpio { use rcc::APB2; use super::{ Alternate, Floating, GpioExt, Input, - // OpenDrain, + OpenDrain, Output, // PullDown, PullUp, PushPull, @@ -148,6 +148,17 @@ macro_rules! gpio { impl toggleable::Default for $PXx> {} + impl InputPin for $PXx> { + fn is_high(&self) -> bool { + !self.is_low() + } + + fn is_low(&self) -> bool { + // NOTE(unsafe) atomic read with no side effects + unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << self.i) == 0 } + } + } + $( /// Pin pub struct $PXi { @@ -241,27 +252,26 @@ macro_rules! gpio { // $PXi { _mode: PhantomData } // } - // /// Configures the pin to operate as an open drain output pin - // pub fn into_open_drain_output( - // self, - // moder: &mut MODER, - // otyper: &mut OTYPER, - // ) -> $PXi> { - // let offset = 2 * $i; - - // // general purpose output mode - // let mode = 0b01; - // moder.moder().modify(|r, w| unsafe { - // w.bits((r.bits() & !(0b11 << offset)) | (mode << offset)) - // }); + /// Configures the pin to operate as an open drain output pin + pub fn into_open_drain_output( + self, + cr: &mut $CR, + ) -> $PXi> { + let offset = (4 * $i) % 32; + // General purpose output open-drain + let cnf = 0b01; + // Open-Drain Output mode, max speed 50 MHz + let mode = 0b11; + let bits = (cnf << 2) | mode; - // // open drain output - // otyper - // .otyper() - // .modify(|r, w| unsafe { w.bits(r.bits() | (0b1 << $i)) }); + cr + .cr() + .modify(|r, w| unsafe { + w.bits((r.bits() & !(0b1111 << offset)) | (bits << offset)) + }); - // $PXi { _mode: PhantomData } - // } + $PXi { _mode: PhantomData } + } /// Configures the pin to operate as an push pull output pin pub fn into_push_pull_output( @@ -333,6 +343,17 @@ macro_rules! gpio { unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << $i) == 0 } } } + + impl InputPin for $PXi> { + fn is_high(&self) -> bool { + !self.is_low() + } + + fn is_low(&self) -> bool { + // NOTE(unsafe) atomic read with no side effects + unsafe { (*$GPIOX::ptr()).idr.read().bits() & (1 << $i) == 0 } + } + } )+ } }