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)
}
}
}