use embedded_hal::digital::v2::InputPin;
use crate::recv::{self, ReceiverSM};
use crate::remotecontrol::{Button, RemoteControl};
pub struct EventReceiver<PROTOCOL, PIN> {
recv: recv::EventReceiver<PROTOCOL>,
pub pin: PIN,
}
impl<PIN, PINERR, PROTOCOL> EventReceiver<PROTOCOL, PIN>
where
PROTOCOL: ReceiverSM,
PIN: InputPin<Error = PINERR>,
{
pub fn new(pin: PIN, samplerate: u32) -> Self {
Self {
recv: recv::EventReceiver::new(samplerate),
pin,
}
}
pub fn destroy(self) -> PIN {
self.pin
}
#[inline(always)]
pub fn edge_event(&mut self, dt: u32) -> Result<Option<PROTOCOL::Cmd>, PINERR> {
let pinval = self.pin.is_low()?;
match self.recv.edge_event(pinval, dt) {
Ok(cmd) => Ok(cmd),
Err(_err) => Ok(None),
}
}
}
pub struct PeriodicReceiver<PROTOCOL, PIN> {
recv: recv::PeriodicReceiver<PROTOCOL>,
pin: PIN,
counter: u32,
}
impl<PIN, PINERR, PROTOCOL> PeriodicReceiver<PROTOCOL, PIN>
where
PROTOCOL: ReceiverSM,
PIN: InputPin<Error = PINERR>,
{
pub fn new(pin: PIN, samplerate: u32) -> Self {
Self {
recv: recv::PeriodicReceiver::new(samplerate),
pin,
counter: 0,
}
}
pub fn destroy(self) -> PIN {
self.pin
}
pub fn poll(&mut self) -> Result<Option<PROTOCOL::Cmd>, PINERR> {
let pinval = self.pin.is_low()?;
self.counter = self.counter.wrapping_add(1);
match self.recv.poll(pinval, self.counter) {
Ok(cmd) => Ok(cmd),
Err(_err) => Ok(None),
}
}
#[cfg(feature = "remotes")]
pub fn poll_button<RC: RemoteControl<Cmd = PROTOCOL::Cmd>>(
&mut self,
) -> Result<Option<Button>, PINERR> {
self.poll().map(|cmd| cmd.and_then(RC::decode))
}
}
macro_rules! multireceiver {
(
$(#[$outer:meta])*
$name:ident, [ $( ($N:ident, $P:ident, $C:ident) ),* ]
) => {
$(#[$outer])*
pub struct $name<$( $P ),* , PIN> {
pin: PIN,
counter: u32,
$( $N : recv::PeriodicReceiver<$P> ),*
}
impl<PIN, PINERR, $( $P, $C ),* > $name <$( $P ),* , PIN>
where
PIN: InputPin<Error = PINERR>,
$( $P: ReceiverSM<Cmd = $C>),*,
$( $C: crate::Command ),*,
{
pub fn new(pin: PIN, samplerate: u32) -> Self {
Self {
pin,
counter: 0,
$( $N: recv::PeriodicReceiver::new(samplerate)),*,
}
}
pub fn destroy(self) -> PIN {
self.pin
}
pub fn poll(&mut self) -> Result<( $( Option<$C>),*), PINERR> {
let pinval = self.pin.is_low()?;
self.counter = self.counter.wrapping_add(1);
Ok(($(
match self.$N.poll(pinval, self.counter) {
Ok(cmd) => cmd,
Err(_err) => None,
}
),* ))
}
}
};
}
multireceiver!(
PeriodicReceiver2,
[(recv1, RECV1, CMD1), (recv2, RECV2, CMD2)]
);
multireceiver!(
PeriodicReceiver3,
[
(recv1, RECV1, CMD1),
(recv2, RECV2, CMD2),
(recv3, RECV3, CMD3)
]
);
multireceiver!(
PeriodicReceiver4,
[
(recv1, RECV1, CMD1),
(recv2, RECV2, CMD2),
(recv3, RECV3, CMD3),
(recv4, RECV4, CMD4)
]
);
multireceiver!(
PeriodicReceiver5,
[
(recv1, RECV1, CMD1),
(recv2, RECV2, CMD2),
(recv3, RECV3, CMD3),
(recv4, RECV4, CMD4),
(recv5, RECV5, CMD5)
]
);