/// 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>,
/// Pin
pub pa1: PA1>,
/// Pin
pub pa2: PA2>,
/// Pin
pub pa3: PA3>,
/// Pin
pub pa4: PA4>,
/// Pin
pub pa5: PA5>,
/// Pin
pub pa6: PA6>,
/// Pin
pub pa7: PA7>,
/// Pin
pub pa8: PA8>,
/// Pin
pub pa9: PA9>,
/// Pin
pub pa10: PA10>,
/// Pin
pub pa11: PA11>,
/// Pin
pub pa12: PA12>,
/// Pin
pub pa13: PA13>,
/// Pin
pub pa14: PA14>,
/// Pin
pub pa15: PA15>,
}
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: PhantomData,
}
impl PA0 {
/// Configures the pin to operate in AF0 mode
pub fn into_alternate_af0(self, _cs: &CriticalSection) -> PA0> {
_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> {
_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> {
_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> {
_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> {
_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> {
_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> {
_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> {
_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> {
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> {
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> {
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 {
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