use embedded_hal::digital::PinState;
mod sealed {
pub trait Sealed {}
}
pub trait Polarity: sealed::Sealed {
fn physical_on() -> PinState;
fn physical_off() -> PinState;
fn is_logical_on(physical_high: bool) -> bool;
fn map_duty(brightness: u8) -> u8;
const MODE: PolarityMode;
}
pub struct ActiveHigh;
impl sealed::Sealed for ActiveHigh {}
impl Polarity for ActiveHigh {
const MODE: PolarityMode = PolarityMode::ActiveHigh;
#[inline]
fn physical_on() -> PinState {
PinState::High
}
#[inline]
fn physical_off() -> PinState {
PinState::Low
}
#[inline]
fn is_logical_on(physical_high: bool) -> bool {
physical_high
}
#[inline]
fn map_duty(brightness: u8) -> u8 {
brightness
}
}
pub struct ActiveLow;
impl sealed::Sealed for ActiveLow {}
impl Polarity for ActiveLow {
const MODE: PolarityMode = PolarityMode::ActiveLow;
#[inline]
fn physical_on() -> PinState {
PinState::Low
}
#[inline]
fn physical_off() -> PinState {
PinState::High
}
#[inline]
fn is_logical_on(physical_high: bool) -> bool {
!physical_high
}
#[inline]
fn map_duty(brightness: u8) -> u8 {
255 - brightness
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum PolarityMode {
ActiveHigh,
ActiveLow,
}
impl PolarityMode {
#[inline]
pub(crate) fn physical_on(self) -> PinState {
match self {
Self::ActiveHigh => PinState::High,
Self::ActiveLow => PinState::Low,
}
}
#[inline]
pub(crate) fn physical_off(self) -> PinState {
match self {
Self::ActiveHigh => PinState::Low,
Self::ActiveLow => PinState::High,
}
}
#[inline]
pub(crate) fn is_logical_on(self, physical_high: bool) -> bool {
match self {
Self::ActiveHigh => physical_high,
Self::ActiveLow => !physical_high,
}
}
#[inline]
#[allow(dead_code)] pub(crate) fn map_duty(self, brightness: u8) -> u8 {
match self {
Self::ActiveHigh => brightness,
Self::ActiveLow => 255 - brightness,
}
}
}