use core::marker::PhantomData;
#[cfg(feature = "embedded-hal")]
use embedded_hal::digital::v2::InputPin;
use crate::{protocol::Capture, receiver::time::InfraMonotonic, Protocol};
mod bufferinputreceiver;
mod builder;
mod decoder;
mod error;
mod iter;
mod multireceiver;
mod ppoll;
pub mod time;
pub use bufferinputreceiver::BufferInputReceiver;
pub use builder::Builder;
pub use decoder::{DecoderFactory, ProtocolDecoder, State};
pub use error::{DecodingError, Error};
pub use multireceiver::{MultiReceiver, MultiReceiverCommand};
pub use ppoll::PeriodicPoll;
pub struct NoPin;
pub struct Receiver<
Proto: DecoderFactory<Mono>,
Pin = NoPin,
Mono: InfraMonotonic = u32,
Cmd: From<Proto::Cmd> = <Proto as Protocol>::Cmd,
> {
pub(crate) decoder: Proto::Decoder,
pub(crate) pin: Pin,
prev_instant: Mono::Instant,
pub(crate) cmd: PhantomData<Cmd>,
}
impl Receiver<Capture<u32>> {
pub fn builder() -> Builder {
Builder::default()
}
}
impl<Proto, Mono, Cmd> Receiver<Proto, NoPin, Mono, Cmd>
where
Proto: DecoderFactory<Mono>,
Mono: InfraMonotonic,
Cmd: From<Proto::Cmd>,
{
pub fn new(freq: u32) -> Receiver<Proto, NoPin, Mono, Cmd> {
let decoder = Proto::decoder(freq);
Receiver {
decoder,
pin: NoPin {},
prev_instant: Mono::ZERO_INSTANT,
cmd: PhantomData,
}
}
}
impl<Proto, Input, Mono, Cmd> Receiver<Proto, Input, Mono, Cmd>
where
Proto: DecoderFactory<Mono>,
Mono: InfraMonotonic,
Cmd: From<Proto::Cmd>,
{
pub fn with_input(freq: u32, input: Input) -> Self {
let decoder = Proto::decoder(freq);
Receiver {
decoder,
pin: input,
prev_instant: Mono::ZERO_INSTANT,
cmd: PhantomData,
}
}
pub fn event_edge(
&mut self,
dt: Mono::Duration,
edge: bool,
) -> Result<Option<Cmd>, DecodingError> {
let state = self.decoder.event(edge, dt);
match state {
State::Done => {
let cmd = self.decoder.command().map(Into::into);
self.decoder.reset();
Ok(cmd)
}
State::Error(err) => {
self.decoder.reset();
Err(err)
}
State::Idle | State::Receiving => Ok(None),
}
}
}
#[cfg(feature = "embedded-hal")]
impl<Proto, Pin, Mono, Cmd> Receiver<Proto, Pin, Mono, Cmd>
where
Proto: DecoderFactory<Mono>,
Pin: InputPin,
Mono: InfraMonotonic,
Cmd: From<Proto::Cmd>,
{
pub fn with_pin(resolution: u32, pin: Pin) -> Self {
Self::with_input(resolution, pin)
}
}
#[cfg(feature = "embedded")]
impl<Proto, Pin, const HZ: u32, Cmd> Receiver<Proto, Pin, fugit::TimerInstantU32<HZ>, Cmd>
where
Proto: DecoderFactory<fugit::TimerInstantU32<HZ>>,
Pin: InputPin,
Cmd: From<Proto::Cmd>,
{
pub fn with_fugit(pin: Pin) -> Self {
Self::with_input(HZ, pin)
}
}
#[cfg(feature = "embedded")]
impl<Proto, Pin, const HZ: u32, Cmd> Receiver<Proto, Pin, fugit::TimerInstantU64<HZ>, Cmd>
where
Proto: DecoderFactory<fugit::TimerInstantU64<HZ>>,
Pin: InputPin,
Cmd: From<Proto::Cmd>,
{
pub fn with_fugit64(pin: Pin) -> Self {
Self::with_input(HZ, pin)
}
}
impl<Proto, Mono, Cmd> Receiver<Proto, NoPin, Mono, Cmd>
where
Proto: DecoderFactory<Mono>,
Mono: InfraMonotonic,
Cmd: From<Proto::Cmd>,
{
pub fn event(&mut self, dt: Mono::Duration, edge: bool) -> Result<Option<Cmd>, DecodingError> {
Ok(self.event_edge(dt, edge)?.map(Into::into))
}
pub fn event_instant(
&mut self,
t: Mono::Instant,
edge: bool,
) -> Result<Option<Cmd>, DecodingError> {
let dt = Mono::checked_sub(t, self.prev_instant).unwrap_or(Mono::ZERO_DURATION);
self.prev_instant = t;
Ok(self.event_edge(dt, edge)?.map(Into::into))
}
}
#[cfg(feature = "embedded-hal")]
impl<Proto, Pin, Mono, Cmd> Receiver<Proto, Pin, Mono, Cmd>
where
Proto: DecoderFactory<Mono>,
Pin: InputPin,
Mono: InfraMonotonic,
Cmd: From<Proto::Cmd>,
{
pub fn event(&mut self, dt: Mono::Duration) -> Result<Option<Cmd>, Error<Pin::Error>> {
let edge = self.pin.is_low().map_err(Error::Hal)?;
Ok(self.event_edge(dt, edge)?.map(Into::into))
}
pub fn event_instant(&mut self, t: Mono::Instant) -> Result<Option<Cmd>, Error<Pin::Error>> {
let edge = self.pin.is_low().map_err(Error::Hal)?;
let dt = Mono::checked_sub(t, self.prev_instant).unwrap_or(Mono::ZERO_DURATION);
self.prev_instant = t;
Ok(self.event_edge(dt, edge)?.map(Into::into))
}
pub fn pin(&self) -> &Pin {
&self.pin
}
pub fn pin_mut(&mut self) -> &mut Pin {
&mut self.pin
}
pub fn release(self) -> Pin {
self.pin
}
}