use super::*;
pub struct DynamicPin<const P: char, const N: u8> {
pub(crate) mode: Dynamic,
}
pub enum Dynamic {
InputFloating,
InputPullUp,
InputPullDown,
OutputPushPull,
OutputOpenDrain,
}
#[derive(Debug, PartialEq, Eq)]
pub enum PinModeError {
IncorrectMode,
}
impl Dynamic {
pub fn is_input(&self) -> bool {
use Dynamic::*;
match self {
InputFloating | InputPullUp | InputPullDown | OutputOpenDrain => {
true
}
OutputPushPull => false,
}
}
pub fn is_output(&self) -> bool {
use Dynamic::*;
match self {
InputFloating | InputPullUp | InputPullDown => false,
OutputPushPull | OutputOpenDrain => true,
}
}
}
struct Unknown;
impl crate::Sealed for Unknown {}
impl PinMode for Unknown {}
impl<const P: char, const N: u8> DynamicPin<P, N> {
pub(super) const fn new(mode: Dynamic) -> Self {
Self { mode }
}
#[inline]
pub fn make_pull_up_input(&mut self) {
Pin::<P, N, Unknown>::new().into_pull_up_input();
self.mode = Dynamic::InputPullUp;
}
#[inline]
pub fn make_pull_down_input(&mut self) {
Pin::<P, N, Unknown>::new().into_pull_down_input();
self.mode = Dynamic::InputPullDown;
}
#[inline]
pub fn make_floating_input(&mut self) {
Pin::<P, N, Unknown>::new().into_floating_input();
self.mode = Dynamic::InputFloating;
}
#[inline]
pub fn make_push_pull_output(&mut self) {
Pin::<P, N, Unknown>::new().into_push_pull_output();
self.mode = Dynamic::OutputPushPull;
}
#[inline]
pub fn make_push_pull_output_in_state(&mut self, state: PinState) {
Pin::<P, N, Unknown>::new().into_push_pull_output_in_state(state);
self.mode = Dynamic::OutputPushPull;
}
#[inline]
pub fn make_open_drain_output(&mut self) {
Pin::<P, N, Unknown>::new().into_open_drain_output();
self.mode = Dynamic::OutputOpenDrain;
}
#[inline]
pub fn make_open_drain_output_in_state(&mut self, state: PinState) {
Pin::<P, N, Unknown>::new().into_open_drain_output_in_state(state);
self.mode = Dynamic::OutputOpenDrain;
}
pub fn set_high(&mut self) -> Result<(), PinModeError> {
if self.mode.is_output() {
Pin::<P, N, Unknown>::new()._set_state(PinState::High);
Ok(())
} else {
Err(PinModeError::IncorrectMode)
}
}
pub fn set_low(&mut self) -> Result<(), PinModeError> {
if self.mode.is_output() {
Pin::<P, N, Unknown>::new()._set_state(PinState::Low);
Ok(())
} else {
Err(PinModeError::IncorrectMode)
}
}
pub fn is_high(&self) -> Result<bool, PinModeError> {
self.is_low().map(|b| !b)
}
pub fn is_low(&self) -> Result<bool, PinModeError> {
if self.mode.is_input() {
Ok(Pin::<P, N, Unknown>::new()._is_low())
} else {
Err(PinModeError::IncorrectMode)
}
}
}