1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
//! Embedded-hal based Receiver types

use embedded_hal::digital::v2::InputPin;

use crate::recv::{self, ReceiverSM};
use crate::remotecontrol::{Button, RemoteControl};

/// Event driven Hal receiver
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>,
{
    /// Create a new EventReceiver
    /// `pin`: The Inputpin connected to the receiver,
    /// `samplerate`: Sample rate of the receiver
    pub fn new(pin: PIN, samplerate: u32) -> Self {
        Self {
            recv: recv::EventReceiver::new(samplerate),
            pin,
        }
    }

    /// Destroy Receiver and hand back pin
    pub fn destroy(self) -> PIN {
        self.pin
    }

    /// Tell the receiver to read the new pin value and update the receiver state machine
    ///
    /// Returns Ok(None) until a command is detected
    #[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),
        }
    }
}

/// Periodic and polled Embedded hal Receiver
///
/// The poll methods should be called periodically for this receiver to work
pub struct PeriodicReceiver<PROTOCOL, PIN> {
    /// The receiver state machine
    recv: recv::PeriodicReceiver<PROTOCOL>,
    /// Input pin
    pin: PIN,
    /// Internal sample counter
    counter: u32,
}

impl<PIN, PINERR, PROTOCOL> PeriodicReceiver<PROTOCOL, PIN>
where
    PROTOCOL: ReceiverSM,
    PIN: InputPin<Error = PINERR>,
{
    /// Create a new PeriodicReceiver
    /// `pin` : The gpio pin the hw is connected to
    /// `samplerate` : Rate of which you intend to call poll.
    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!(
    /// Receiver for two protocols
    PeriodicReceiver2,
    [(recv1, RECV1, CMD1), (recv2, RECV2, CMD2)]
);

multireceiver!(
    /// Receiver for three protocols
    PeriodicReceiver3,
    [
        (recv1, RECV1, CMD1),
        (recv2, RECV2, CMD2),
        (recv3, RECV3, CMD3)
    ]
);

multireceiver!(
    /// Receiver for four protocols
    PeriodicReceiver4,
    [
        (recv1, RECV1, CMD1),
        (recv2, RECV2, CMD2),
        (recv3, RECV3, CMD3),
        (recv4, RECV4, CMD4)
    ]
);

multireceiver!(
    /// Receiver for five protocols
    PeriodicReceiver5,
    [
        (recv1, RECV1, CMD1),
        (recv2, RECV2, CMD2),
        (recv3, RECV3, CMD3),
        (recv4, RECV4, CMD4),
        (recv5, RECV5, CMD5)
    ]
);