IRQ example finished
This commit is contained in:
parent
d2aca83bb5
commit
e4043eac6b
File diff suppressed because it is too large
Load Diff
@ -1,761 +0,0 @@
|
||||
//! General Purpose Input / Output
|
||||
|
||||
use core::convert::Infallible;
|
||||
use core::marker::PhantomData;
|
||||
|
||||
use crate::rcc::Rcc;
|
||||
|
||||
/// Extension trait to split a GPIO peripheral in independent pins and registers
|
||||
pub trait GpioExt {
|
||||
/// The parts to split the GPIO into
|
||||
type Parts;
|
||||
|
||||
/// Splits the GPIO block into independent pins and registers
|
||||
fn split(self, rcc: &mut Rcc) -> Self::Parts;
|
||||
}
|
||||
|
||||
trait GpioRegExt {
|
||||
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
|
||||
pub struct AF0;
|
||||
/// Alternate function 1
|
||||
pub struct AF1;
|
||||
/// Alternate function 2
|
||||
pub struct AF2;
|
||||
/// Alternate function 3
|
||||
pub struct AF3;
|
||||
/// Alternate function 4
|
||||
pub struct AF4;
|
||||
/// Alternate function 5
|
||||
pub struct AF5;
|
||||
/// Alternate function 6
|
||||
pub struct AF6;
|
||||
/// Alternate function 7
|
||||
pub struct AF7;
|
||||
|
||||
/// Alternate function mode (type state)
|
||||
pub struct Alternate<AF> {
|
||||
_mode: PhantomData<AF>,
|
||||
}
|
||||
|
||||
/// Input mode (type state)
|
||||
pub struct Input<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
/// Floating input (type state)
|
||||
pub struct Floating;
|
||||
|
||||
/// Pulled down input (type state)
|
||||
pub struct PullDown;
|
||||
|
||||
/// Pulled up input (type state)
|
||||
pub struct PullUp;
|
||||
|
||||
/// Open drain input or output (type state)
|
||||
pub struct OpenDrain;
|
||||
|
||||
/// Analog mode (type state)
|
||||
pub struct Analog;
|
||||
|
||||
/// Output mode (type state)
|
||||
pub struct Output<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
/// Push pull output (type state)
|
||||
pub struct PushPull;
|
||||
|
||||
use embedded_hal::digital::v2::{toggleable, InputPin, OutputPin, StatefulOutputPin};
|
||||
|
||||
/// Fully erased pin
|
||||
pub struct Pin<MODE> {
|
||||
i: u8,
|
||||
port: *const dyn GpioRegExt,
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
// NOTE(unsafe) The only write acess is to BSRR, which is thread safe
|
||||
unsafe impl<MODE> Sync for Pin<MODE> {}
|
||||
// NOTE(unsafe) this only enables read access to the same pin from multiple
|
||||
// threads
|
||||
unsafe impl<MODE> Send for Pin<MODE> {}
|
||||
|
||||
impl<MODE> StatefulOutputPin for Pin<Output<MODE>> {
|
||||
#[inline(always)]
|
||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||
self.is_set_low().map(|v| !v)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(unsafe { (*self.port).is_set_low(self.i) })
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> OutputPin for Pin<Output<MODE>> {
|
||||
type Error = Infallible;
|
||||
|
||||
#[inline(always)]
|
||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||
unsafe { (*self.port).set_high(self.i) };
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||
unsafe { (*self.port).set_low(self.i) }
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> toggleable::Default for Pin<Output<MODE>> {}
|
||||
|
||||
impl InputPin for Pin<Output<OpenDrain>> {
|
||||
type Error = Infallible;
|
||||
|
||||
#[inline(always)]
|
||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||
self.is_low().map(|v| !v)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn is_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(unsafe { (*self.port).is_low(self.i) })
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> InputPin for Pin<Input<MODE>> {
|
||||
type Error = Infallible;
|
||||
|
||||
#[inline(always)]
|
||||
fn is_high(&self) -> Result<bool, Self::Error> {
|
||||
self.is_low().map(|v| !v)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
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 is_low(&self, pos: u8) -> bool {
|
||||
// NOTE(unsafe) atomic read with no side effects
|
||||
self.idr.read().bits() & (1 << pos) == 0
|
||||
}
|
||||
|
||||
fn is_set_low(&self, pos: u8) -> bool {
|
||||
// NOTE(unsafe) atomic read with no side effects
|
||||
self.odr.read().bits() & (1 << pos) == 0
|
||||
}
|
||||
|
||||
fn set_high(&self, pos: u8) {
|
||||
// NOTE(unsafe) atomic write to a stateless register
|
||||
unsafe { self.bsrr.write(|w| w.bits(1 << pos)) }
|
||||
}
|
||||
|
||||
fn set_low(&self, pos: u8) {
|
||||
// NOTE(unsafe) atomic write to a stateless register
|
||||
unsafe { self.bsrr.write(|w| w.bits(1 << (pos + 16))) }
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
gpio_trait!(gpioa);
|
||||
gpio_trait!(gpiof);
|
||||
|
||||
macro_rules! gpio {
|
||||
([$($GPIOX:ident, $gpiox:ident, $iopxenr:ident, $PXx:ident, $gate:meta => [
|
||||
$($PXi:ident: ($pxi:ident, $i:expr, $MODE:ty),)+
|
||||
]),+]) => {
|
||||
$(
|
||||
/// GPIO
|
||||
#[cfg($gate)]
|
||||
pub mod $gpiox {
|
||||
use core::marker::PhantomData;
|
||||
use core::convert::Infallible;
|
||||
|
||||
use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, toggleable};
|
||||
use crate::{
|
||||
rcc::Rcc,
|
||||
pac::$GPIOX
|
||||
};
|
||||
|
||||
use cortex_m::interrupt::CriticalSection;
|
||||
|
||||
use super::{
|
||||
Alternate, Analog, Floating, GpioExt, Input, OpenDrain, Output,
|
||||
PullDown, PullUp, PushPull, AF0, AF1, AF2, AF3, AF4, AF5, AF6, AF7,
|
||||
Pin, GpioRegExt,
|
||||
};
|
||||
|
||||
/// GPIO parts
|
||||
pub struct Parts {
|
||||
$(
|
||||
/// Pin
|
||||
pub $pxi: $PXi<$MODE>,
|
||||
)+
|
||||
}
|
||||
|
||||
impl GpioExt for $GPIOX {
|
||||
type Parts = Parts;
|
||||
|
||||
fn split(self, rcc: &mut Rcc) -> Parts {
|
||||
rcc.regs.ahbenr.modify(|_, w| w.$iopxenr().set_bit());
|
||||
|
||||
Parts {
|
||||
$(
|
||||
$pxi: $PXi { _mode: PhantomData },
|
||||
)+
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn _set_alternate_mode (index:usize, mode: u32)
|
||||
{
|
||||
let offset = 2 * index;
|
||||
let offset2 = 4 * index;
|
||||
unsafe {
|
||||
let reg = &(*$GPIOX::ptr());
|
||||
if offset2 < 32 {
|
||||
reg.afrl.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b1111 << offset2)) | (mode << offset2))
|
||||
});
|
||||
} else {
|
||||
let offset2 = offset2 - 32;
|
||||
reg.afrh.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b1111 << offset2)) | (mode << offset2))
|
||||
});
|
||||
}
|
||||
reg.moder.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (0b10 << offset))
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$(
|
||||
/// Pin
|
||||
pub struct $PXi<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
|
||||
impl<MODE> $PXi<MODE> {
|
||||
/// Configures the pin to operate in AF0 mode
|
||||
pub fn into_alternate_af0(
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Alternate<AF0>> {
|
||||
_set_alternate_mode($i, 0);
|
||||
$PXi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
/// Configures the pin to operate in AF1 mode
|
||||
pub fn into_alternate_af1(
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Alternate<AF1>> {
|
||||
_set_alternate_mode($i, 1);
|
||||
$PXi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
/// Configures the pin to operate in AF2 mode
|
||||
pub fn into_alternate_af2(
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Alternate<AF2>> {
|
||||
_set_alternate_mode($i, 2);
|
||||
$PXi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
/// Configures the pin to operate in AF3 mode
|
||||
pub fn into_alternate_af3(
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Alternate<AF3>> {
|
||||
_set_alternate_mode($i, 3);
|
||||
$PXi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
/// Configures the pin to operate in AF4 mode
|
||||
pub fn into_alternate_af4(
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Alternate<AF4>> {
|
||||
_set_alternate_mode($i, 4);
|
||||
$PXi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
/// Configures the pin to operate in AF5 mode
|
||||
pub fn into_alternate_af5(
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Alternate<AF5>> {
|
||||
_set_alternate_mode($i, 5);
|
||||
$PXi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
/// Configures the pin to operate in AF6 mode
|
||||
pub fn into_alternate_af6(
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Alternate<AF6>> {
|
||||
_set_alternate_mode($i, 6);
|
||||
$PXi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
/// Configures the pin to operate in AF7 mode
|
||||
pub fn into_alternate_af7(
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Alternate<AF7>> {
|
||||
_set_alternate_mode($i, 7);
|
||||
$PXi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
/// Configures the pin to operate as a floating input pin
|
||||
pub fn into_floating_input(
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Input<Floating>> {
|
||||
let offset = 2 * $i;
|
||||
unsafe {
|
||||
let reg = &(*$GPIOX::ptr());
|
||||
reg.pupdr.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
|
||||
});
|
||||
reg.moder.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
|
||||
});
|
||||
}
|
||||
$PXi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
/// Configures the pin to operate as a pulled down input pin
|
||||
pub fn into_pull_down_input(
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Input<PullDown>> {
|
||||
let offset = 2 * $i;
|
||||
unsafe {
|
||||
let reg = &(*$GPIOX::ptr());
|
||||
reg.pupdr.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (0b10 << offset))
|
||||
});
|
||||
reg.moder.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
|
||||
});
|
||||
}
|
||||
$PXi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
/// Configures the pin to operate as a pulled up input pin
|
||||
pub fn into_pull_up_input(
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Input<PullUp>> {
|
||||
let offset = 2 * $i;
|
||||
unsafe {
|
||||
let reg = &(*$GPIOX::ptr());
|
||||
reg.pupdr.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset))
|
||||
});
|
||||
reg.moder.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
|
||||
});
|
||||
}
|
||||
$PXi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
/// Configures the pin to operate as an analog pin
|
||||
pub fn into_analog(
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Analog> {
|
||||
let offset = 2 * $i;
|
||||
unsafe {
|
||||
let reg = &(*$GPIOX::ptr());
|
||||
reg.pupdr.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
|
||||
});
|
||||
reg.moder.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (0b11 << offset))
|
||||
});
|
||||
}
|
||||
$PXi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
/// Configures the pin to operate as an open drain output pin
|
||||
pub fn into_open_drain_output(
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Output<OpenDrain>> {
|
||||
let offset = 2 * $i;
|
||||
unsafe {
|
||||
let reg = &(*$GPIOX::ptr());
|
||||
reg.pupdr.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
|
||||
});
|
||||
reg.otyper.modify(|r, w| {
|
||||
w.bits(r.bits() | (0b1 << $i))
|
||||
});
|
||||
reg.moder.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset))
|
||||
});
|
||||
}
|
||||
$PXi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
/// Configures the pin to operate as an push pull output pin
|
||||
pub fn into_push_pull_output(
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Output<PushPull>> {
|
||||
let offset = 2 * $i;
|
||||
unsafe {
|
||||
let reg = &(*$GPIOX::ptr());
|
||||
reg.pupdr.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
|
||||
});
|
||||
reg.otyper.modify(|r, w| {
|
||||
w.bits(r.bits() & !(0b1 << $i))
|
||||
});
|
||||
reg.moder.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset))
|
||||
});
|
||||
}
|
||||
$PXi { _mode: PhantomData }
|
||||
}
|
||||
|
||||
/// Configures the pin to operate as an push pull output pin with quick fall
|
||||
/// and rise times
|
||||
pub fn into_push_pull_output_hs(
|
||||
self, _cs: &CriticalSection
|
||||
) -> $PXi<Output<PushPull>> {
|
||||
let offset = 2 * $i;
|
||||
unsafe {
|
||||
let reg = &(*$GPIOX::ptr());
|
||||
reg.pupdr.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset))
|
||||
});
|
||||
reg.otyper.modify(|r, w| {
|
||||
w.bits(r.bits() & !(0b1 << $i))
|
||||
});
|
||||
reg.ospeedr.modify(|r, w| {
|
||||
w.bits(r.bits() & !(0b1 << $i))
|
||||
});
|
||||
reg.moder.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset))
|
||||
});
|
||||
}
|
||||
$PXi { _mode: PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
impl $PXi<Output<OpenDrain>> {
|
||||
/// Enables / disables the internal pull up
|
||||
pub fn internal_pull_up(&mut self, _cs: &CriticalSection, on: bool) {
|
||||
let offset = 2 * $i;
|
||||
let value = if on { 0b01 } else { 0b00 };
|
||||
unsafe {
|
||||
let reg = &(*$GPIOX::ptr());
|
||||
reg.pupdr.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (value << offset))
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<AF> $PXi<Alternate<AF>> {
|
||||
/// Enables / disables the internal pull up
|
||||
pub fn internal_pull_up(self, _cs: &CriticalSection, on: bool) -> Self {
|
||||
let offset = 2 * $i;
|
||||
let value = if on { 0b01 } else { 0b00 };
|
||||
unsafe {
|
||||
let reg = &(*$GPIOX::ptr());
|
||||
reg.pupdr.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b11 << offset)) | (value << offset))
|
||||
});
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<AF> $PXi<Alternate<AF>> {
|
||||
/// Turns pin alternate configuration pin into open drain
|
||||
pub fn set_open_drain(self, _cs: &CriticalSection) -> Self {
|
||||
let offset = $i;
|
||||
unsafe {
|
||||
let reg = &(*$GPIOX::ptr());
|
||||
reg.otyper.modify(|r, w| {
|
||||
w.bits(r.bits() | (1 << offset))
|
||||
});
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> $PXi<Output<MODE>> {
|
||||
/// Erases the pin number from the type
|
||||
///
|
||||
/// This is useful when you want to collect the pins into an array where you
|
||||
/// need all the elements to have the same type
|
||||
pub fn downgrade(self) -> Pin<Output<MODE>> {
|
||||
Pin {
|
||||
i: $i,
|
||||
port: $GPIOX::ptr() as *const dyn GpioRegExt,
|
||||
_mode: self._mode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> StatefulOutputPin for $PXi<Output<MODE>> {
|
||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||
self.is_set_low().map(|v| !v)
|
||||
}
|
||||
|
||||
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 set_high(&mut self) -> Result<(), Self::Error> {
|
||||
Ok(unsafe { (*$GPIOX::ptr()).set_high($i) })
|
||||
}
|
||||
|
||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||
Ok(unsafe { (*$GPIOX::ptr()).set_low($i) })
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> toggleable::Default for $PXi<Output<MODE>> {}
|
||||
|
||||
impl InputPin for $PXi<Output<OpenDrain>> {
|
||||
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> {
|
||||
Ok(unsafe { (*$GPIOX::ptr()).is_low($i) })
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> $PXi<Input<MODE>> {
|
||||
/// Erases the pin number from the type
|
||||
///
|
||||
/// This is useful when you want to collect the pins into an array where you
|
||||
/// need all the elements to have the same type
|
||||
pub fn downgrade(self) -> Pin<Input<MODE>> {
|
||||
Pin {
|
||||
i: $i,
|
||||
port: $GPIOX::ptr() as *const dyn GpioRegExt,
|
||||
_mode: self._mode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<MODE> InputPin for $PXi<Input<MODE>> {
|
||||
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> {
|
||||
Ok(unsafe { (*$GPIOX::ptr()).is_low($i) })
|
||||
}
|
||||
}
|
||||
)+
|
||||
}
|
||||
)+
|
||||
}
|
||||
}
|
||||
|
||||
gpio!([
|
||||
GPIOA, gpioa, iopaen, PA, any(
|
||||
feature = "device-selected"
|
||||
) => [
|
||||
PA0: (pa0, 0, Input<Floating>),
|
||||
PA1: (pa1, 1, Input<Floating>),
|
||||
PA2: (pa2, 2, Input<Floating>),
|
||||
PA3: (pa3, 3, Input<Floating>),
|
||||
PA4: (pa4, 4, Input<Floating>),
|
||||
PA5: (pa5, 5, Input<Floating>),
|
||||
PA6: (pa6, 6, Input<Floating>),
|
||||
PA7: (pa7, 7, Input<Floating>),
|
||||
PA8: (pa8, 8, Input<Floating>),
|
||||
PA9: (pa9, 9, Input<Floating>),
|
||||
PA10: (pa10, 10, Input<Floating>),
|
||||
PA11: (pa11, 11, Input<Floating>),
|
||||
PA12: (pa12, 12, Input<Floating>),
|
||||
PA13: (pa13, 13, Input<Floating>),
|
||||
PA14: (pa14, 14, Input<Floating>),
|
||||
PA15: (pa15, 15, Input<Floating>),
|
||||
],
|
||||
GPIOB, gpiob, iopben, PB, any(
|
||||
feature = "device-selected"
|
||||
) => [
|
||||
PB0: (pb0, 0, Input<Floating>),
|
||||
PB1: (pb1, 1, Input<Floating>),
|
||||
PB2: (pb2, 2, Input<Floating>),
|
||||
PB3: (pb3, 3, Input<Floating>),
|
||||
PB4: (pb4, 4, Input<Floating>),
|
||||
PB5: (pb5, 5, Input<Floating>),
|
||||
PB6: (pb6, 6, Input<Floating>),
|
||||
PB7: (pb7, 7, Input<Floating>),
|
||||
PB8: (pb8, 8, Input<Floating>),
|
||||
PB9: (pb9, 9, Input<Floating>),
|
||||
PB10: (pb10, 10, Input<Floating>),
|
||||
PB11: (pb11, 11, Input<Floating>),
|
||||
PB12: (pb12, 12, Input<Floating>),
|
||||
PB13: (pb13, 13, Input<Floating>),
|
||||
PB14: (pb14, 14, Input<Floating>),
|
||||
PB15: (pb15, 15, Input<Floating>),
|
||||
],
|
||||
GPIOC, gpioc, iopcen, PC, any(
|
||||
feature = "stm32f031",
|
||||
feature = "stm32f038",
|
||||
feature = "stm32f042",
|
||||
feature = "stm32f048"
|
||||
) => [
|
||||
PC13: (pc13, 13, Input<Floating>),
|
||||
PC14: (pc14, 14, Input<Floating>),
|
||||
PC15: (pc15, 15, Input<Floating>),
|
||||
],
|
||||
GPIOC, gpioc, iopcen, PC, any(
|
||||
feature = "stm32f030",
|
||||
feature = "stm32f051",
|
||||
feature = "stm32f058",
|
||||
feature = "stm32f070",
|
||||
feature = "stm32f071",
|
||||
feature = "stm32f072",
|
||||
feature = "stm32f078",
|
||||
feature = "stm32f091",
|
||||
feature = "stm32f098"
|
||||
) => [
|
||||
PC0: (pc0, 0, Input<Floating>),
|
||||
PC1: (pc1, 1, Input<Floating>),
|
||||
PC2: (pc2, 2, Input<Floating>),
|
||||
PC3: (pc3, 3, Input<Floating>),
|
||||
PC4: (pc4, 4, Input<Floating>),
|
||||
PC5: (pc5, 5, Input<Floating>),
|
||||
PC6: (pc6, 6, Input<Floating>),
|
||||
PC7: (pc7, 7, Input<Floating>),
|
||||
PC8: (pc8, 8, Input<Floating>),
|
||||
PC9: (pc9, 9, Input<Floating>),
|
||||
PC10: (pc10, 10, Input<Floating>),
|
||||
PC11: (pc11, 11, Input<Floating>),
|
||||
PC12: (pc12, 12, Input<Floating>),
|
||||
PC13: (pc13, 13, Input<Floating>),
|
||||
PC14: (pc14, 14, Input<Floating>),
|
||||
PC15: (pc15, 15, Input<Floating>),
|
||||
],
|
||||
GPIOD, gpiod, iopden, PD, any(
|
||||
feature = "stm32f030",
|
||||
feature = "stm32f051",
|
||||
feature = "stm32f058",
|
||||
feature = "stm32f070"
|
||||
) => [
|
||||
PD2: (pd2, 2, Input<Floating>),
|
||||
],
|
||||
GPIOD, gpiod, iopden, PD, any(
|
||||
feature = "stm32f071",
|
||||
feature = "stm32f072",
|
||||
feature = "stm32f078",
|
||||
feature = "stm32f091",
|
||||
feature = "stm32f098"
|
||||
) => [
|
||||
PD0: (pd0, 0, Input<Floating>),
|
||||
PD1: (pd1, 1, Input<Floating>),
|
||||
PD2: (pd2, 2, Input<Floating>),
|
||||
PD3: (pd3, 3, Input<Floating>),
|
||||
PD4: (pd4, 4, Input<Floating>),
|
||||
PD5: (pd5, 5, Input<Floating>),
|
||||
PD6: (pd6, 6, Input<Floating>),
|
||||
PD7: (pd7, 7, Input<Floating>),
|
||||
PD8: (pd8, 8, Input<Floating>),
|
||||
PD9: (pd9, 9, Input<Floating>),
|
||||
PD10: (pd10, 10, Input<Floating>),
|
||||
PD11: (pd11, 11, Input<Floating>),
|
||||
PD12: (pd12, 12, Input<Floating>),
|
||||
PD13: (pd13, 13, Input<Floating>),
|
||||
PD14: (pd14, 14, Input<Floating>),
|
||||
PD15: (pd15, 15, Input<Floating>),
|
||||
],
|
||||
GPIOE, gpioe, iopeen, PE, any(
|
||||
feature = "stm32f071",
|
||||
feature = "stm32f072",
|
||||
feature = "stm32f078",
|
||||
feature = "stm32f091",
|
||||
feature = "stm32f098"
|
||||
) => [
|
||||
PE0: (pe0, 0, Input<Floating>),
|
||||
PE1: (pe1, 1, Input<Floating>),
|
||||
PE2: (pe2, 2, Input<Floating>),
|
||||
PE3: (pe3, 3, Input<Floating>),
|
||||
PE4: (pe4, 4, Input<Floating>),
|
||||
PE5: (pe5, 5, Input<Floating>),
|
||||
PE6: (pe6, 6, Input<Floating>),
|
||||
PE7: (pe7, 7, Input<Floating>),
|
||||
PE8: (pe8, 8, Input<Floating>),
|
||||
PE9: (pe9, 9, Input<Floating>),
|
||||
PE10: (pe10, 10, Input<Floating>),
|
||||
PE11: (pe11, 11, Input<Floating>),
|
||||
PE12: (pe12, 12, Input<Floating>),
|
||||
PE13: (pe13, 13, Input<Floating>),
|
||||
PE14: (pe14, 14, Input<Floating>),
|
||||
PE15: (pe15, 15, Input<Floating>),
|
||||
],
|
||||
GPIOF, gpiof, iopfen, PF, any(
|
||||
feature = "stm32f030x4",
|
||||
feature = "stm32f030x6",
|
||||
feature = "stm32f030x8",
|
||||
feature = "stm32f051",
|
||||
feature = "stm32f058",
|
||||
) => [
|
||||
PF0: (pf0, 0, Input<Floating>),
|
||||
PF1: (pf1, 1, Input<Floating>),
|
||||
PF4: (pf4, 4, Input<Floating>),
|
||||
PF5: (pf5, 5, Input<Floating>),
|
||||
PF6: (pf6, 6, Input<Floating>),
|
||||
PF7: (pf7, 7, Input<Floating>),
|
||||
],
|
||||
GPIOF, gpiof, iopfen, PF, any(
|
||||
feature = "stm32f030xc",
|
||||
feature = "stm32f070"
|
||||
) => [
|
||||
PF0: (pf0, 0, Input<Floating>),
|
||||
PF1: (pf1, 1, Input<Floating>),
|
||||
],
|
||||
GPIOF, gpiof, iopfen, PF, any(
|
||||
feature = "stm32f031",
|
||||
feature = "stm32f038"
|
||||
) => [
|
||||
PF0: (pf0, 0, Input<Floating>),
|
||||
PF1: (pf1, 1, Input<Floating>),
|
||||
PF6: (pf6, 6, Input<Floating>),
|
||||
PF7: (pf7, 7, Input<Floating>),
|
||||
],
|
||||
GPIOF, gpiof, iopfen, PF, any(
|
||||
feature = "stm32f042",
|
||||
feature = "stm32f048"
|
||||
) => [
|
||||
PF0: (pf0, 0, Input<Floating>),
|
||||
PF1: (pf1, 1, Input<Floating>),
|
||||
PF11: (pf11, 11, Input<Floating>),
|
||||
],
|
||||
GPIOF, gpiof, iopfen, PF, any(
|
||||
feature = "stm32f071",
|
||||
feature = "stm32f072",
|
||||
feature = "stm32f078",
|
||||
feature = "stm32f091",
|
||||
feature = "stm32f098",
|
||||
) => [
|
||||
PF0: (pf0, 0, Input<Floating>),
|
||||
PF1: (pf1, 1, Input<Floating>),
|
||||
PF2: (pf2, 2, Input<Floating>),
|
||||
PF3: (pf3, 3, Input<Floating>),
|
||||
PF6: (pf6, 6, Input<Floating>),
|
||||
PF9: (pf9, 9, Input<Floating>),
|
||||
PF10: (pf10, 10, Input<Floating>),
|
||||
]
|
||||
]);
|
12410
docs/gpio_stm32f0xx.rs
12410
docs/gpio_stm32f0xx.rs
File diff suppressed because it is too large
Load Diff
@ -1,324 +0,0 @@
|
||||
/// GPIO
|
||||
#[cfg(any(feature = "device-selected"))]
|
||||
pub mod gpioa {
|
||||
use core::marker::PhantomData;
|
||||
use core::convert::Infallible;
|
||||
use embedded_hal::digital::v2::{InputPin, OutputPin, StatefulOutputPin, toggleable};
|
||||
use crate::{rcc::Rcc, pac::GPIOA};
|
||||
use cortex_m::interrupt::CriticalSection;
|
||||
use super::{
|
||||
Alternate, Analog, Floating, GpioExt, Input, OpenDrain, Output, PullDown, PullUp,
|
||||
PushPull, AF0, AF1, AF2, AF3, AF4, AF5, AF6, AF7, Pin, GpioRegExt,
|
||||
};
|
||||
/// GPIO parts
|
||||
pub struct Parts {
|
||||
/// Pin
|
||||
pub pa0: PA0<Input<Floating>>,
|
||||
/// Pin
|
||||
pub pa1: PA1<Input<Floating>>,
|
||||
/// Pin
|
||||
pub pa2: PA2<Input<Floating>>,
|
||||
/// Pin
|
||||
pub pa3: PA3<Input<Floating>>,
|
||||
/// Pin
|
||||
pub pa4: PA4<Input<Floating>>,
|
||||
/// Pin
|
||||
pub pa5: PA5<Input<Floating>>,
|
||||
/// Pin
|
||||
pub pa6: PA6<Input<Floating>>,
|
||||
/// Pin
|
||||
pub pa7: PA7<Input<Floating>>,
|
||||
/// Pin
|
||||
pub pa8: PA8<Input<Floating>>,
|
||||
/// Pin
|
||||
pub pa9: PA9<Input<Floating>>,
|
||||
/// Pin
|
||||
pub pa10: PA10<Input<Floating>>,
|
||||
/// Pin
|
||||
pub pa11: PA11<Input<Floating>>,
|
||||
/// Pin
|
||||
pub pa12: PA12<Input<Floating>>,
|
||||
/// Pin
|
||||
pub pa13: PA13<Input<Floating>>,
|
||||
/// Pin
|
||||
pub pa14: PA14<Input<Floating>>,
|
||||
/// Pin
|
||||
pub pa15: PA15<Input<Floating>>,
|
||||
}
|
||||
impl GpioExt for GPIOA {
|
||||
type Parts = Parts;
|
||||
fn split(self, rcc: &mut Rcc) -> Parts {
|
||||
rcc.regs.ahbenr.modify(|_, w| w.iopaen().set_bit());
|
||||
Parts {
|
||||
pa0: PA0 { _mode: PhantomData },
|
||||
pa1: PA1 { _mode: PhantomData },
|
||||
pa2: PA2 { _mode: PhantomData },
|
||||
pa3: PA3 { _mode: PhantomData },
|
||||
pa4: PA4 { _mode: PhantomData },
|
||||
pa5: PA5 { _mode: PhantomData },
|
||||
pa6: PA6 { _mode: PhantomData },
|
||||
pa7: PA7 { _mode: PhantomData },
|
||||
pa8: PA8 { _mode: PhantomData },
|
||||
pa9: PA9 { _mode: PhantomData },
|
||||
pa10: PA10 { _mode: PhantomData },
|
||||
pa11: PA11 { _mode: PhantomData },
|
||||
pa12: PA12 { _mode: PhantomData },
|
||||
pa13: PA13 { _mode: PhantomData },
|
||||
pa14: PA14 { _mode: PhantomData },
|
||||
pa15: PA15 { _mode: PhantomData },
|
||||
}
|
||||
}
|
||||
}
|
||||
fn _set_alternate_mode(index: usize, mode: u32) {
|
||||
let offset = 2 * index;
|
||||
let offset2 = 4 * index;
|
||||
unsafe {
|
||||
let reg = &(*GPIOA::ptr());
|
||||
if offset2 < 32 {
|
||||
reg.afrl.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b1111 << offset2)) | (mode << offset2))
|
||||
});
|
||||
} else {
|
||||
let offset2 = offset2 - 32;
|
||||
reg.afrh.modify(|r, w| {
|
||||
w.bits((r.bits() & !(0b1111 << offset2)) | (mode << offset2))
|
||||
});
|
||||
}
|
||||
reg.moder
|
||||
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (0b10 << offset)));
|
||||
}
|
||||
}
|
||||
/// Pin
|
||||
pub struct PA0<MODE> {
|
||||
_mode: PhantomData<MODE>,
|
||||
}
|
||||
impl<MODE> PA0<MODE> {
|
||||
/// Configures the pin to operate in AF0 mode
|
||||
pub fn into_alternate_af0(self, _cs: &CriticalSection) -> PA0<Alternate<AF0>> {
|
||||
_set_alternate_mode(0, 0);
|
||||
PA0 { _mode: PhantomData }
|
||||
}
|
||||
/// Configures the pin to operate in AF1 mode
|
||||
pub fn into_alternate_af1(self, _cs: &CriticalSection) -> PA0<Alternate<AF1>> {
|
||||
_set_alternate_mode(0, 1);
|
||||
PA0 { _mode: PhantomData }
|
||||
}
|
||||
/// Configures the pin to operate in AF2 mode
|
||||
pub fn into_alternate_af2(self, _cs: &CriticalSection) -> PA0<Alternate<AF2>> {
|
||||
_set_alternate_mode(0, 2);
|
||||
PA0 { _mode: PhantomData }
|
||||
}
|
||||
/// Configures the pin to operate in AF3 mode
|
||||
pub fn into_alternate_af3(self, _cs: &CriticalSection) -> PA0<Alternate<AF3>> {
|
||||
_set_alternate_mode(0, 3);
|
||||
PA0 { _mode: PhantomData }
|
||||
}
|
||||
/// Configures the pin to operate in AF4 mode
|
||||
pub fn into_alternate_af4(self, _cs: &CriticalSection) -> PA0<Alternate<AF4>> {
|
||||
_set_alternate_mode(0, 4);
|
||||
PA0 { _mode: PhantomData }
|
||||
}
|
||||
/// Configures the pin to operate in AF5 mode
|
||||
pub fn into_alternate_af5(self, _cs: &CriticalSection) -> PA0<Alternate<AF5>> {
|
||||
_set_alternate_mode(0, 5);
|
||||
PA0 { _mode: PhantomData }
|
||||
}
|
||||
/// Configures the pin to operate in AF6 mode
|
||||
pub fn into_alternate_af6(self, _cs: &CriticalSection) -> PA0<Alternate<AF6>> {
|
||||
_set_alternate_mode(0, 6);
|
||||
PA0 { _mode: PhantomData }
|
||||
}
|
||||
/// Configures the pin to operate in AF7 mode
|
||||
pub fn into_alternate_af7(self, _cs: &CriticalSection) -> PA0<Alternate<AF7>> {
|
||||
_set_alternate_mode(0, 7);
|
||||
PA0 { _mode: PhantomData }
|
||||
}
|
||||
/// Configures the pin to operate as a floating input pin
|
||||
pub fn into_floating_input(self, _cs: &CriticalSection) -> PA0<Input<Floating>> {
|
||||
let offset = 2 * 0;
|
||||
unsafe {
|
||||
let reg = &(*GPIOA::ptr());
|
||||
reg.pupdr
|
||||
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset)));
|
||||
reg.moder
|
||||
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset)));
|
||||
}
|
||||
PA0 { _mode: PhantomData }
|
||||
}
|
||||
/// Configures the pin to operate as a pulled down input pin
|
||||
pub fn into_pull_down_input(self, _cs: &CriticalSection) -> PA0<Input<PullDown>> {
|
||||
let offset = 2 * 0;
|
||||
unsafe {
|
||||
let reg = &(*GPIOA::ptr());
|
||||
reg.pupdr
|
||||
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (0b10 << offset)));
|
||||
reg.moder
|
||||
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset)));
|
||||
}
|
||||
PA0 { _mode: PhantomData }
|
||||
}
|
||||
/// Configures the pin to operate as a pulled up input pin
|
||||
pub fn into_pull_up_input(self, _cs: &CriticalSection) -> PA0<Input<PullUp>> {
|
||||
let offset = 2 * 0;
|
||||
unsafe {
|
||||
let reg = &(*GPIOA::ptr());
|
||||
reg.pupdr
|
||||
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset)));
|
||||
reg.moder
|
||||
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset)));
|
||||
}
|
||||
PA0 { _mode: PhantomData }
|
||||
}
|
||||
/// Configures the pin to operate as an analog pin
|
||||
pub fn into_analog(self, _cs: &CriticalSection) -> PA0<Analog> {
|
||||
let offset = 2 * 0;
|
||||
unsafe {
|
||||
let reg = &(*GPIOA::ptr());
|
||||
reg.pupdr
|
||||
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset)));
|
||||
reg.moder
|
||||
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (0b11 << offset)));
|
||||
}
|
||||
PA0 { _mode: PhantomData }
|
||||
}
|
||||
/// Configures the pin to operate as an open drain output pin
|
||||
pub fn into_open_drain_output(self, _cs: &CriticalSection) -> PA0<Output<OpenDrain>> {
|
||||
let offset = 2 * 0;
|
||||
unsafe {
|
||||
let reg = &(*GPIOA::ptr());
|
||||
reg.pupdr
|
||||
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset)));
|
||||
reg.otyper.modify(|r, w| w.bits(r.bits() | (0b1 << 0)));
|
||||
reg.moder
|
||||
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset)));
|
||||
}
|
||||
PA0 { _mode: PhantomData }
|
||||
}
|
||||
/// Configures the pin to operate as an push pull output pin
|
||||
pub fn into_push_pull_output(self, _cs: &CriticalSection) -> PA0<Output<PushPull>> {
|
||||
let offset = 2 * 0;
|
||||
unsafe {
|
||||
let reg = &(*GPIOA::ptr());
|
||||
reg.pupdr
|
||||
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset)));
|
||||
reg.otyper.modify(|r, w| w.bits(r.bits() & !(0b1 << 0)));
|
||||
reg.moder
|
||||
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset)));
|
||||
}
|
||||
PA0 { _mode: PhantomData }
|
||||
}
|
||||
/// Configures the pin to operate as an push pull output pin with quick fall
|
||||
/// and rise times
|
||||
pub fn into_push_pull_output_hs(self, _cs: &CriticalSection) -> PA0<Output<PushPull>> {
|
||||
let offset = 2 * 0;
|
||||
unsafe {
|
||||
let reg = &(*GPIOA::ptr());
|
||||
reg.pupdr
|
||||
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (0b00 << offset)));
|
||||
reg.otyper.modify(|r, w| w.bits(r.bits() & !(0b1 << 0)));
|
||||
reg.ospeedr.modify(|r, w| w.bits(r.bits() & !(0b1 << 0)));
|
||||
reg.moder
|
||||
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (0b01 << offset)));
|
||||
}
|
||||
PA0 { _mode: PhantomData }
|
||||
}
|
||||
}
|
||||
impl PA0<Output<OpenDrain>> {
|
||||
/// Enables / disables the internal pull up
|
||||
pub fn internal_pull_up(&mut self, _cs: &CriticalSection, on: bool) {
|
||||
let offset = 2 * 0;
|
||||
let value = if on { 0b01 } else { 0b00 };
|
||||
unsafe {
|
||||
let reg = &(*GPIOA::ptr());
|
||||
reg.pupdr
|
||||
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (value << offset)));
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<AF> PA0<Alternate<AF>> {
|
||||
/// Enables / disables the internal pull up
|
||||
pub fn internal_pull_up(self, _cs: &CriticalSection, on: bool) -> Self {
|
||||
let offset = 2 * 0;
|
||||
let value = if on { 0b01 } else { 0b00 };
|
||||
unsafe {
|
||||
let reg = &(*GPIOA::ptr());
|
||||
reg.pupdr
|
||||
.modify(|r, w| w.bits((r.bits() & !(0b11 << offset)) | (value << offset)));
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
impl<AF> PA0<Alternate<AF>> {
|
||||
/// Turns pin alternate configuration pin into open drain
|
||||
pub fn set_open_drain(self, _cs: &CriticalSection) -> Self {
|
||||
let offset = 0;
|
||||
unsafe {
|
||||
let reg = &(*GPIOA::ptr());
|
||||
reg.otyper.modify(|r, w| w.bits(r.bits() | (1 << offset)));
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
impl<MODE> PA0<Output<MODE>> {
|
||||
/// Erases the pin number from the type
|
||||
///
|
||||
/// This is useful when you want to collect the pins into an array where you
|
||||
/// need all the elements to have the same type
|
||||
pub fn downgrade(self) -> Pin<Output<MODE>> {
|
||||
Pin {
|
||||
i: 0,
|
||||
port: GPIOA::ptr() as *const dyn GpioRegExt,
|
||||
_mode: self._mode,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<MODE> StatefulOutputPin for PA0<Output<MODE>> {
|
||||
fn is_set_high(&self) -> Result<bool, Self::Error> {
|
||||
self.is_set_low().map(|v| !v)
|
||||
}
|
||||
fn is_set_low(&self) -> Result<bool, Self::Error> {
|
||||
Ok(unsafe { (*GPIOA::ptr()).is_set_low(0) })
|
||||
}
|
||||
}
|
||||
impl<MODE> OutputPin for PA0<Output<MODE>> {
|
||||
type Error = Infallible;
|
||||
fn set_high(&mut self) -> Result<(), Self::Error> {
|
||||
Ok(unsafe { (*GPIOA::ptr()).set_high(0) })
|
||||
}
|
||||
fn set_low(&mut self) -> Result<(), Self::Error> {
|
||||
Ok(unsafe { (*GPIOA::ptr()).set_low(0) })
|
||||
}
|
||||
}
|
||||
impl<MODE> toggleable::Default for PA0<Output<MODE>> {}
|
||||
impl InputPin for PA0<Output<OpenDrain>> {
|
||||
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> {
|
||||
Ok(unsafe { (*GPIOA::ptr()).is_low(0) })
|
||||
}
|
||||
}
|
||||
impl<MODE> PA0<Input<MODE>> {
|
||||
/// Erases the pin number from the type
|
||||
///
|
||||
/// This is useful when you want to collect the pins into an array where you
|
||||
/// need all the elements to have the same type
|
||||
pub fn downgrade(self) -> Pin<Input<MODE>> {
|
||||
Pin {
|
||||
i: 0,
|
||||
port: GPIOA::ptr() as *const dyn GpioRegExt,
|
||||
_mode: self._mode,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<MODE> InputPin for PA0<Input<MODE>> {
|
||||
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> {
|
||||
Ok(unsafe { (*GPIOA::ptr()).is_low(0) })
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -1 +1 @@
|
||||
Subproject commit 2fc982996138216e9c060772481aba53a711dc9b
|
||||
Subproject commit f13af5d32bfad661bcf985948eac36f885d9ddaf
|
@ -1 +1 @@
|
||||
Subproject commit 448b18c9ed17e43b781f317962d3133322aa98a6
|
||||
Subproject commit eb7b036377cb194935c472c7a5bbb0196f52e8fe
|
Loading…
x
Reference in New Issue
Block a user