stm32/gpio: expose all functionality as inherent methods.
This commit is contained in:
@ -94,17 +94,25 @@ impl<'d, T: GpioPin> ExtiInput<'d, T> {
|
||||
pub fn new(pin: Input<'d, T>, _ch: impl Unborrow<Target = T::ExtiChannel> + 'd) -> Self {
|
||||
Self { pin }
|
||||
}
|
||||
|
||||
pub fn is_high(&self) -> bool {
|
||||
self.pin.is_high()
|
||||
}
|
||||
|
||||
pub fn is_low(&self) -> bool {
|
||||
self.pin.is_low()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: GpioPin> InputPin for ExtiInput<'d, T> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||
self.pin.is_high()
|
||||
Ok(self.is_high())
|
||||
}
|
||||
|
||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||
self.pin.is_low()
|
||||
Ok(self.is_low())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,7 +3,7 @@ use core::convert::Infallible;
|
||||
use core::marker::PhantomData;
|
||||
use embassy::util::Unborrow;
|
||||
use embassy_hal_common::{unborrow, unsafe_impl_unborrow};
|
||||
use embedded_hal::digital::v2::{toggleable, InputPin, OutputPin, StatefulOutputPin};
|
||||
use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, ToggleableOutputPin};
|
||||
|
||||
use crate::pac;
|
||||
use crate::pac::gpio::{self, vals};
|
||||
@ -113,6 +113,15 @@ impl<'d, T: Pin> Input<'d, T> {
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_high(&self) -> bool {
|
||||
!self.is_low()
|
||||
}
|
||||
|
||||
pub fn is_low(&self) -> bool {
|
||||
let state = unsafe { self.pin.block().idr().read().idr(self.pin.pin() as _) };
|
||||
state == vals::Idr::LOW
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> Drop for Input<'d, T> {
|
||||
@ -132,19 +141,6 @@ impl<'d, T: Pin> Drop for Input<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> InputPin for Input<'d, T> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||
self.is_low().map(|v| !v)
|
||||
}
|
||||
|
||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||
let state = unsafe { self.pin.block().idr().read().idr(self.pin.pin() as _) };
|
||||
Ok(state == vals::Idr::LOW)
|
||||
}
|
||||
}
|
||||
|
||||
/// Digital input or output level.
|
||||
#[derive(Debug, Eq, PartialEq)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
@ -191,6 +187,36 @@ impl<'d, T: Pin> Output<'d, T> {
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
/// Set the output as high.
|
||||
pub fn set_high(&mut self) {
|
||||
self.pin.set_high();
|
||||
}
|
||||
|
||||
/// Set the output as low.
|
||||
pub fn set_low(&mut self) {
|
||||
self.pin.set_low();
|
||||
}
|
||||
|
||||
/// Is the output pin set as high?
|
||||
pub fn is_set_high(&self) -> bool {
|
||||
!self.is_set_low()
|
||||
}
|
||||
|
||||
/// Is the output pin set as low?
|
||||
pub fn is_set_low(&self) -> bool {
|
||||
let state = unsafe { self.pin.block().odr().read().odr(self.pin.pin() as _) };
|
||||
state == vals::Odr::LOW
|
||||
}
|
||||
|
||||
/// Toggle pin output
|
||||
pub fn toggle(&mut self) {
|
||||
if self.is_set_low() {
|
||||
self.set_high()
|
||||
} else {
|
||||
self.set_low()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> Drop for Output<'d, T> {
|
||||
@ -214,37 +240,6 @@ impl<'d, T: Pin> Drop for Output<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> OutputPin for Output<'d, T> {
|
||||
type Error = Infallible;
|
||||
|
||||
/// Set the output as high.
|
||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||
self.pin.set_high();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set the output as low.
|
||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||
self.pin.set_low();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> StatefulOutputPin for Output<'d, T> {
|
||||
/// Is the output pin set as high?
|
||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||
self.is_set_low().map(|v| !v)
|
||||
}
|
||||
|
||||
/// Is the output pin set as low?
|
||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||
let state = unsafe { self.pin.block().odr().read().odr(self.pin.pin() as _) };
|
||||
Ok(state == vals::Odr::LOW)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> toggleable::Default for Output<'d, T> {}
|
||||
|
||||
/// GPIO output open-drain driver.
|
||||
pub struct OutputOpenDrain<'d, T: Pin> {
|
||||
pub(crate) pin: T,
|
||||
@ -294,6 +289,45 @@ impl<'d, T: Pin> OutputOpenDrain<'d, T> {
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_high(&self) -> bool {
|
||||
!self.is_low()
|
||||
}
|
||||
|
||||
pub fn is_low(&self) -> bool {
|
||||
let state = unsafe { self.pin.block().idr().read().idr(self.pin.pin() as _) };
|
||||
state == vals::Idr::LOW
|
||||
}
|
||||
|
||||
/// Set the output as high.
|
||||
pub fn set_high(&mut self) {
|
||||
self.pin.set_high();
|
||||
}
|
||||
|
||||
/// Set the output as low.
|
||||
pub fn set_low(&mut self) {
|
||||
self.pin.set_low();
|
||||
}
|
||||
|
||||
/// Is the output pin set as high?
|
||||
pub fn is_set_high(&self) -> bool {
|
||||
!self.is_set_low()
|
||||
}
|
||||
|
||||
/// Is the output pin set as low?
|
||||
pub fn is_set_low(&self) -> bool {
|
||||
let state = unsafe { self.pin.block().odr().read().odr(self.pin.pin() as _) };
|
||||
state == vals::Odr::LOW
|
||||
}
|
||||
|
||||
/// Toggle pin output
|
||||
pub fn toggle(&mut self) {
|
||||
if self.is_set_low() {
|
||||
self.set_high()
|
||||
} else {
|
||||
self.set_low()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> Drop for OutputOpenDrain<'d, T> {
|
||||
@ -317,36 +351,6 @@ impl<'d, T: Pin> Drop for OutputOpenDrain<'d, T> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> OutputPin for OutputOpenDrain<'d, T> {
|
||||
type Error = Infallible;
|
||||
|
||||
/// Set the output as high.
|
||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||
self.pin.set_high();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Set the output as low.
|
||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||
self.pin.set_low();
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> InputPin for OutputOpenDrain<'d, T> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||
self.is_low().map(|v| !v)
|
||||
}
|
||||
|
||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||
// NOTE(safety) Atomic read
|
||||
let state = unsafe { self.pin.block().idr().read().idr(self.pin.pin() as usize) };
|
||||
Ok(state == vals::Idr::LOW)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) mod sealed {
|
||||
use super::*;
|
||||
|
||||
@ -612,3 +616,79 @@ pub(crate) unsafe fn init() {
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
mod eh02 {
|
||||
use super::*;
|
||||
|
||||
impl<'d, T: Pin> InputPin for Input<'d, T> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.is_high())
|
||||
}
|
||||
|
||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.is_low())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> OutputPin for Output<'d, T> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||
Ok(self.set_high())
|
||||
}
|
||||
|
||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||
Ok(self.set_low())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> StatefulOutputPin for Output<'d, T> {
|
||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.is_set_high())
|
||||
}
|
||||
|
||||
/// Is the output pin set as low?
|
||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.is_set_low())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> ToggleableOutputPin for Output<'d, T> {
|
||||
type Error = Infallible;
|
||||
fn toggle(&mut self) -> Result<(), Self::Error> {
|
||||
Ok(self.toggle())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> OutputPin for OutputOpenDrain<'d, T> {
|
||||
type Error = Infallible;
|
||||
|
||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||
Ok(self.set_high())
|
||||
}
|
||||
|
||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||
Ok(self.set_low())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> StatefulOutputPin for OutputOpenDrain<'d, T> {
|
||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.is_set_high())
|
||||
}
|
||||
|
||||
/// Is the output pin set as low?
|
||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(self.is_set_low())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: Pin> ToggleableOutputPin for OutputOpenDrain<'d, T> {
|
||||
type Error = Infallible;
|
||||
fn toggle(&mut self) -> Result<(), Self::Error> {
|
||||
Ok(self.toggle())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user