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
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
//! Pulse Width Modulation

/// Blocking pulse width modulation traits
pub mod blocking {
    /// Pulse Width Modulation
    ///
    /// # Examples
    ///
    /// Use this interface to control the power output of some actuator
    ///
    /// ```
    /// extern crate embedded_hal as hal;
    ///
    /// use hal::pwm::blocking::Pwm;
    ///
    /// fn main() {
    ///     let mut pwm: Pwm1 = {
    ///         // ..
    /// #       Pwm1
    ///     };
    ///
    ///     pwm.set_period(1.khz()).unwrap();
    ///
    ///     let max_duty = pwm.get_max_duty().unwrap();
    ///
    ///     // brightest LED
    ///     pwm.set_duty(&Channel::_1, max_duty).unwrap();
    ///
    ///     // dimmer LED
    ///     pwm.set_duty(&Channel::_2, max_duty / 4).unwrap();
    /// }
    ///
    /// # use core::convert::Infallible;
    /// # struct KiloHertz(u32);
    /// # trait U32Ext { fn khz(self) -> KiloHertz; }
    /// # impl U32Ext for u32 { fn khz(self) -> KiloHertz { KiloHertz(self) } }
    /// # enum Channel { _1, _2 }
    /// # struct Pwm1;
    /// # impl hal::pwm::blocking::Pwm for Pwm1 {
    /// #     type Error = Infallible;
    /// #     type Channel = Channel;
    /// #     type Time = KiloHertz;
    /// #     type Duty = u16;
    /// #     fn disable(&mut self, _: &Channel) -> Result<(), Self::Error> { unimplemented!() }
    /// #     fn enable(&mut self, _: &Channel) -> Result<(), Self::Error> { unimplemented!() }
    /// #     fn get_duty(&self, _: &Channel) -> Result<u16, Self::Error> { unimplemented!() }
    /// #     fn get_max_duty(&self) -> Result<u16, Self::Error> { Ok(0) }
    /// #     fn set_duty(&mut self, _: &Channel, _: u16) -> Result<(), Self::Error> { Ok(()) }
    /// #     fn get_period(&self) -> Result<KiloHertz, Self::Error> { unimplemented!() }
    /// #     fn set_period<T>(&mut self, _: T) -> Result<(), Self::Error> where T: Into<KiloHertz> { Ok(()) }
    /// # }
    /// ```
    // unproven reason: pre-singletons API. The `PwmPin` trait seems more useful because it models independent
    // PWM channels. Here a certain number of channels are multiplexed in a single implementer.
    pub trait Pwm {
        /// Enumeration of `Pwm` errors
        type Error: core::fmt::Debug;

        /// Enumeration of channels that can be used with this `Pwm` interface
        ///
        /// If your `Pwm` interface has no channels you can use the type `()`
        /// here
        type Channel;

        /// A time unit that can be converted into a human time unit (e.g. seconds)
        type Time;

        /// Type for the `duty` methods
        ///
        /// The implementer is free to choose a float / percentage representation
        /// (e.g. `0.0 .. 1.0`) or an integer representation (e.g. `0 .. 65535`)
        type Duty;

        /// Disables a PWM `channel`
        fn disable(&mut self, channel: &Self::Channel) -> Result<(), Self::Error>;

        /// Enables a PWM `channel`
        fn enable(&mut self, channel: &Self::Channel) -> Result<(), Self::Error>;

        /// Returns the current PWM period
        fn get_period(&self) -> Result<Self::Time, Self::Error>;

        /// Returns the current duty cycle
        ///
        /// While the pin is transitioning to the new duty cycle after a `set_duty` call, this may
        /// return the old or the new duty cycle depending on the implementation.
        fn get_duty(&self, channel: &Self::Channel) -> Result<Self::Duty, Self::Error>;

        /// Returns the maximum duty cycle value
        fn get_max_duty(&self) -> Result<Self::Duty, Self::Error>;

        /// Sets a new duty cycle
        fn set_duty(
            &mut self,
            channel: &Self::Channel,
            duty: Self::Duty,
        ) -> Result<(), Self::Error>;

        /// Sets a new PWM period
        fn set_period<P>(&mut self, period: P) -> Result<(), Self::Error>
        where
            P: Into<Self::Time>;
    }

    impl<T: Pwm> Pwm for &mut T {
        type Error = T::Error;

        type Channel = T::Channel;

        type Time = T::Time;

        type Duty = T::Duty;

        fn disable(&mut self, channel: &Self::Channel) -> Result<(), Self::Error> {
            T::disable(self, channel)
        }

        fn enable(&mut self, channel: &Self::Channel) -> Result<(), Self::Error> {
            T::enable(self, channel)
        }

        fn get_period(&self) -> Result<Self::Time, Self::Error> {
            T::get_period(self)
        }

        fn get_duty(&self, channel: &Self::Channel) -> Result<Self::Duty, Self::Error> {
            T::get_duty(self, channel)
        }

        fn get_max_duty(&self) -> Result<Self::Duty, Self::Error> {
            T::get_max_duty(self)
        }

        fn set_duty(
            &mut self,
            channel: &Self::Channel,
            duty: Self::Duty,
        ) -> Result<(), Self::Error> {
            T::set_duty(self, channel, duty)
        }

        fn set_period<P>(&mut self, period: P) -> Result<(), Self::Error>
        where
            P: Into<Self::Time>,
        {
            T::set_period(self, period)
        }
    }

    /// A single PWM channel / pin
    ///
    /// See `Pwm` for details
    pub trait PwmPin {
        /// Enumeration of `PwmPin` errors
        type Error: core::fmt::Debug;

        /// Type for the `duty` methods
        ///
        /// The implementer is free to choose a float / percentage representation
        /// (e.g. `0.0 .. 1.0`) or an integer representation (e.g. `0 .. 65535`)
        type Duty;

        /// Disables a PWM `channel`
        fn disable(&mut self) -> Result<(), Self::Error>;

        /// Enables a PWM `channel`
        fn enable(&mut self) -> Result<(), Self::Error>;

        /// Returns the current duty cycle
        ///
        /// While the pin is transitioning to the new duty cycle after a `set_duty` call, this may
        /// return the old or the new duty cycle depending on the implementation.
        fn get_duty(&self) -> Result<Self::Duty, Self::Error>;

        /// Returns the maximum duty cycle value
        fn get_max_duty(&self) -> Result<Self::Duty, Self::Error>;

        /// Sets a new duty cycle
        fn set_duty(&mut self, duty: Self::Duty) -> Result<(), Self::Error>;
    }

    impl<T: PwmPin> PwmPin for &mut T {
        type Error = T::Error;

        type Duty = T::Duty;

        fn disable(&mut self) -> Result<(), Self::Error> {
            T::disable(self)
        }

        fn enable(&mut self) -> Result<(), Self::Error> {
            T::enable(self)
        }

        fn get_duty(&self) -> Result<Self::Duty, Self::Error> {
            T::get_duty(self)
        }

        fn get_max_duty(&self) -> Result<Self::Duty, Self::Error> {
            T::get_max_duty(self)
        }

        fn set_duty(&mut self, duty: Self::Duty) -> Result<(), Self::Error> {
            T::set_duty(self, duty)
        }
    }
}