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
//! 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>;
    }

    /// 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>;
    }
}