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
//! Pulse Width Modulation /// Pulse Width Modulation /// /// # Examples /// /// Use this interface to control the power output of some actuator /// /// ``` /// extern crate embedded_hal as hal; /// /// use hal::prelude::*; /// /// fn main() { /// let mut pwm: Pwm1 = { /// // .. /// # Pwm1 /// }; /// /// pwm.try_set_period(1.khz()).unwrap(); /// /// let max_duty = pwm.try_get_max_duty().unwrap(); /// /// // brightest LED /// pwm.try_set_duty(Channel::_1, max_duty).unwrap(); /// /// // dimmer LED /// pwm.try_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::Pwm for Pwm1 { /// # type Error = Infallible; /// # type Channel = Channel; /// # type Time = KiloHertz; /// # type Duty = u16; /// # fn try_disable(&mut self, _: Channel) -> Result<(), Self::Error> { unimplemented!() } /// # fn try_enable(&mut self, _: Channel) -> Result<(), Self::Error> { unimplemented!() } /// # fn try_get_duty(&self, _: Channel) -> Result<u16, Self::Error> { unimplemented!() } /// # fn try_get_max_duty(&self) -> Result<u16, Self::Error> { Ok(0) } /// # fn try_set_duty(&mut self, _: Channel, _: u16) -> Result<(), Self::Error> { Ok(()) } /// # fn try_get_period(&self) -> Result<KiloHertz, Self::Error> { unimplemented!() } /// # fn try_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; /// 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 try_disable(&mut self, channel: Self::Channel) -> Result<(), Self::Error>; /// Enables a PWM `channel` fn try_enable(&mut self, channel: Self::Channel) -> Result<(), Self::Error>; /// Returns the current PWM period fn try_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 `try_set_duty` call, this may /// return the old or the new duty cycle depending on the implementation. fn try_get_duty(&self, channel: Self::Channel) -> Result<Self::Duty, Self::Error>; /// Returns the maximum duty cycle value fn try_get_max_duty(&self) -> Result<Self::Duty, Self::Error>; /// Sets a new duty cycle fn try_set_duty(&mut self, channel: Self::Channel, duty: Self::Duty) -> Result<(), Self::Error>; /// Sets a new PWM period fn try_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; /// 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 try_disable(&mut self) -> Result<(), Self::Error>; /// Enables a PWM `channel` fn try_enable(&mut self) -> Result<(), Self::Error>; /// Returns the current duty cycle /// /// While the pin is transitioning to the new duty cycle after a `try_set_duty` call, this may /// return the old or the new duty cycle depending on the implementation. fn try_get_duty(&self) -> Result<Self::Duty, Self::Error>; /// Returns the maximum duty cycle value fn try_get_max_duty(&self) -> Result<Self::Duty, Self::Error>; /// Sets a new duty cycle fn try_set_duty(&mut self, duty: Self::Duty) -> Result<(), Self::Error>; }