|
|
|
@ -15,10 +15,10 @@ pub trait GpioExt {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
trait GpioRegExt {
|
|
|
|
|
fn try_is_low(&self, pos: u8) -> bool;
|
|
|
|
|
fn try_is_set_low(&self, pos: u8) -> bool;
|
|
|
|
|
fn try_set_high(&self, pos: u8);
|
|
|
|
|
fn try_set_low(&self, pos: u8);
|
|
|
|
|
fn is_low(&self, pos: u8) -> bool;
|
|
|
|
|
fn is_set_low(&self, pos: u8) -> bool;
|
|
|
|
|
fn set_high(&self, pos: u8);
|
|
|
|
|
fn set_low(&self, pos: u8);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Alternate function 0
|
|
|
|
@ -71,7 +71,7 @@ pub struct Output<MODE> {
|
|
|
|
|
/// Push pull output (type state)
|
|
|
|
|
pub struct PushPull;
|
|
|
|
|
|
|
|
|
|
use embedded_hal::digital::{toggleable, InputPin, OutputPin, StatefulOutputPin};
|
|
|
|
|
use embedded_hal::digital::v2::{toggleable, InputPin, OutputPin, StatefulOutputPin};
|
|
|
|
|
|
|
|
|
|
/// Fully erased pin
|
|
|
|
|
pub struct Pin<MODE> {
|
|
|
|
@ -88,13 +88,13 @@ unsafe impl<MODE> Send for Pin<MODE> {}
|
|
|
|
|
|
|
|
|
|
impl<MODE> StatefulOutputPin for Pin<Output<MODE>> {
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn try_is_set_high(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
self.try_is_set_low().map(|v| !v)
|
|
|
|
|
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
self.is_set_low().map(|v| !v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn try_is_set_low(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
Ok(unsafe { (*self.port).try_is_set_low(self.i) })
|
|
|
|
|
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
Ok(unsafe { (*self.port).is_set_low(self.i) })
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -102,14 +102,14 @@ impl<MODE> OutputPin for Pin<Output<MODE>> {
|
|
|
|
|
type Error = Infallible;
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn try_set_high(&mut self) -> Result<(), Self::Error> {
|
|
|
|
|
unsafe { (*self.port).try_set_high(self.i) };
|
|
|
|
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
|
|
|
|
unsafe { (*self.port).set_high(self.i) };
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn try_set_low(&mut self) -> Result<(), Self::Error> {
|
|
|
|
|
unsafe { (*self.port).try_set_low(self.i) }
|
|
|
|
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
|
|
|
|
unsafe { (*self.port).set_low(self.i) }
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -120,13 +120,13 @@ impl InputPin for Pin<Output<OpenDrain>> {
|
|
|
|
|
type Error = Infallible;
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn try_is_high(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
self.try_is_low().map(|v| !v)
|
|
|
|
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
self.is_low().map(|v| !v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn try_is_low(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
Ok(unsafe { (*self.port).try_is_low(self.i) })
|
|
|
|
|
fn is_low(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
Ok(unsafe { (*self.port).is_low(self.i) })
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -134,35 +134,35 @@ impl<MODE> InputPin for Pin<Input<MODE>> {
|
|
|
|
|
type Error = Infallible;
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn try_is_high(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
self.try_is_low().map(|v| !v)
|
|
|
|
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
self.is_low().map(|v| !v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[inline(always)]
|
|
|
|
|
fn try_is_low(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
Ok(unsafe { (*self.port).try_is_low(self.i) })
|
|
|
|
|
fn is_low(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
Ok(unsafe { (*self.port).is_low(self.i) })
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
macro_rules! gpio_trait {
|
|
|
|
|
($gpiox:ident) => {
|
|
|
|
|
impl GpioRegExt for crate::pac::$gpiox::RegisterBlock {
|
|
|
|
|
fn try_is_low(&self, pos: u8) -> bool {
|
|
|
|
|
fn is_low(&self, pos: u8) -> bool {
|
|
|
|
|
// NOTE(unsafe) atomic read with no side effects
|
|
|
|
|
self.idr.read().bits() & (1 << pos) == 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn try_is_set_low(&self, pos: u8) -> bool {
|
|
|
|
|
fn is_set_low(&self, pos: u8) -> bool {
|
|
|
|
|
// NOTE(unsafe) atomic read with no side effects
|
|
|
|
|
self.odr.read().bits() & (1 << pos) == 0
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn try_set_high(&self, pos: u8) {
|
|
|
|
|
fn set_high(&self, pos: u8) {
|
|
|
|
|
// NOTE(unsafe) atomic write to a stateless register
|
|
|
|
|
unsafe { self.bsrr.write(|w| w.bits(1 << pos)) }
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn try_set_low(&self, pos: u8) {
|
|
|
|
|
fn set_low(&self, pos: u8) {
|
|
|
|
|
// NOTE(unsafe) atomic write to a stateless register
|
|
|
|
|
unsafe { self.bsrr.write(|w| w.bits(1 << (pos + 16))) }
|
|
|
|
|
}
|
|
|
|
@ -184,7 +184,7 @@ macro_rules! gpio {
|
|
|
|
|
use core::marker::PhantomData;
|
|
|
|
|
use core::convert::Infallible;
|
|
|
|
|
|
|
|
|
|
use embedded_hal::digital::{InputPin, OutputPin, StatefulOutputPin, toggleable};
|
|
|
|
|
use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, toggleable};
|
|
|
|
|
use crate::{
|
|
|
|
|
rcc::Rcc,
|
|
|
|
|
pac::$GPIOX
|
|
|
|
@ -504,24 +504,24 @@ macro_rules! gpio {
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<MODE> StatefulOutputPin for $PXi<Output<MODE>> {
|
|
|
|
|
fn try_is_set_high(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
self.try_is_set_low().map(|v| !v)
|
|
|
|
|
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
self.is_set_low().map(|v| !v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn try_is_set_low(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
Ok(unsafe { (*$GPIOX::ptr()).try_is_set_low($i) })
|
|
|
|
|
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
Ok(unsafe { (*$GPIOX::ptr()).is_set_low($i) })
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl<MODE> OutputPin for $PXi<Output<MODE>> {
|
|
|
|
|
type Error = Infallible;
|
|
|
|
|
|
|
|
|
|
fn try_set_high(&mut self) -> Result<(), Self::Error> {
|
|
|
|
|
Ok(unsafe { (*$GPIOX::ptr()).try_set_high($i) })
|
|
|
|
|
fn set_high(&mut self) -> Result<(), Self::Error> {
|
|
|
|
|
Ok(unsafe { (*$GPIOX::ptr()).set_high($i) })
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn try_set_low(&mut self) -> Result<(), Self::Error> {
|
|
|
|
|
Ok(unsafe { (*$GPIOX::ptr()).try_set_low($i) })
|
|
|
|
|
fn set_low(&mut self) -> Result<(), Self::Error> {
|
|
|
|
|
Ok(unsafe { (*$GPIOX::ptr()).set_low($i) })
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -530,12 +530,12 @@ macro_rules! gpio {
|
|
|
|
|
impl InputPin for $PXi<Output<OpenDrain>> {
|
|
|
|
|
type Error = Infallible;
|
|
|
|
|
|
|
|
|
|
fn try_is_high(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
self.try_is_low().map(|v| !v)
|
|
|
|
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
self.is_low().map(|v| !v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn try_is_low(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
Ok(unsafe { (*$GPIOX::ptr()).try_is_low($i) })
|
|
|
|
|
fn is_low(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
Ok(unsafe { (*$GPIOX::ptr()).is_low($i) })
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -556,12 +556,12 @@ macro_rules! gpio {
|
|
|
|
|
impl<MODE> InputPin for $PXi<Input<MODE>> {
|
|
|
|
|
type Error = Infallible;
|
|
|
|
|
|
|
|
|
|
fn try_is_high(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
self.try_is_low().map(|v| !v)
|
|
|
|
|
fn is_high(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
self.is_low().map(|v| !v)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn try_is_low(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
Ok(unsafe { (*$GPIOX::ptr()).try_is_low($i) })
|
|
|
|
|
fn is_low(&self) -> Result<bool, Self::Error> {
|
|
|
|
|
Ok(unsafe { (*$GPIOX::ptr()).is_low($i) })
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)+
|
|
|
|
|