use crate::gpio::{AltFunc, AnyPin, Pin, Pull};
use embassy_hal_internal::Peri;
impl Pull {
const fn to_pupdr(self) -> u32 {
match self {
Pull::None => 0,
Pull::Up => 1,
Pull::Down => 2,
}
}
}
pub struct Flex<'d> {
pub(crate) pin: Peri<'d, AnyPin>,
}
impl<'d> Flex<'d> {
pub fn new(pin: Peri<'d, impl Pin>) -> Self {
Self { pin: pin.into() }
}
#[inline(never)]
pub fn set_as_input(&mut self, pull: Pull) {
let r = self.pin.block();
let n = 2 * self.pin.pin() as usize;
r.pupdr()
.modify(|w| w.0 = (w.0 & !(0x03 << n)) | (pull.to_pupdr() << n));
r.moder().modify(|w| w.0 = w.0 & !(0x03 << n));
}
#[inline(never)]
pub fn set_as_output(&self) {
let r = self.pin.block();
let n = 2 * self.pin.pin() as usize;
r.ospeedr().modify(|w| w.0 |= 0x03 << n); r.pupdr().modify(|w| w.0 = w.0 & !(0x03 << n)); r.otyper().modify(|w| w.0 = w.0 & !(0x01 << (n >> 1))); r.moder()
.modify(|w| w.0 = (w.0 & !(0x03 << n)) | (0x01 << n));
}
#[inline(never)]
pub fn set_as_input_output_pull(&self, pull: Pull) {
let r = self.pin.block();
let n = 2 * self.pin.pin() as usize;
r.pupdr()
.modify(|w| w.0 = (w.0 & !(0x03 << n)) | (pull.to_pupdr() << n));
r.otyper().modify(|w| w.0 = w.0 | (0x01 << (n >> 1))); r.moder()
.modify(|w| w.0 = (w.0 & !(0x03 << n)) | (0x01 << n));
}
#[inline(never)]
pub fn set_as_alternate(&self, mode: AltFunc) {
let r = self.pin.block();
let pin_num = self.pin.pin() as usize;
let n = 2 * pin_num;
r.moder()
.modify(|w| w.0 = (w.0 & !(0x03 << n)) | (0x02 << n));
let afr = mode as u32;
if self.pin.pin() < 8 {
let n = 4 * pin_num;
r.afrl().modify(|w| w.0 = (w.0 & !(0x0F << n)) | afr << n);
} else {
let n = 4 * pin_num;
r.afrh().modify(|w| w.0 = (w.0 & !(0x0F << n)) | afr << n);
}
}
#[inline(never)]
pub fn set_as_analog(&mut self) {
let r = self.pin.block();
let n = 2 * self.pin.pin() as usize;
r.pupdr().modify(|w| w.0 = w.0 & !(0x03 << n));
r.otyper().modify(|w| w.0 = w.0 | (0x01 << (n >> 1))); r.moder().modify(|w| w.0 |= 0x03 << n);
}
}