kernel/hil/
pwm.rs

1// Licensed under the Apache License, Version 2.0 or the MIT License.
2// SPDX-License-Identifier: Apache-2.0 OR MIT
3// Copyright Tock Contributors 2022.
4
5//! Interfaces for Pulse Width Modulation output.
6
7use crate::ErrorCode;
8
9/// PWM control for a single pin.
10pub trait Pwm {
11    /// The chip-dependent type of a PWM pin.
12    type Pin;
13
14    /// Generate a PWM signal on the given pin at the given frequency and duty
15    /// cycle.
16    ///
17    /// - `frequency_hz` is specified in Hertz.
18    /// - `duty_cycle` is specified as a portion of the max duty cycle supported
19    ///   by the chip. Clients should call `get_maximum_duty_cycle()` to get the
20    ///   value that corresponds to 100% duty cycle, and divide that
21    ///   appropriately to get the desired duty cycle value. For example, a 25%
22    ///   duty cycle would be `PWM0.get_maximum_duty_cycle() / 4`.
23    fn start(
24        &self,
25        pin: &Self::Pin,
26        frequency_hz: usize,
27        duty_cycle: usize,
28    ) -> Result<(), ErrorCode>;
29
30    /// Stop a PWM pin output.
31    fn stop(&self, pin: &Self::Pin) -> Result<(), ErrorCode>;
32
33    /// Return the maximum PWM frequency supported by the PWM implementation.
34    /// The frequency will be specified in Hertz.
35    fn get_maximum_frequency_hz(&self) -> usize;
36
37    /// Return an opaque number that represents a 100% duty cycle. This value
38    /// will be hardware specific, and essentially represents the precision
39    /// of the underlying PWM hardware.
40    ///
41    /// Users of this HIL should divide this number to calculate a duty cycle
42    /// value suitable for calling `start()`. For example, to generate a 50%
43    /// duty cycle:
44    ///
45    /// ```ignore
46    /// let max = PWM0.get_maximum_duty_cycle();
47    /// let dc  = max / 2;
48    /// PWM0.start(pin, freq, dc);
49    /// ```
50    fn get_maximum_duty_cycle(&self) -> usize;
51}
52
53/// Higher-level PWM interface that restricts the user to a specific PWM pin.
54/// This is particularly useful for passing to capsules that need to control
55/// only a specific pin.
56pub trait PwmPin {
57    /// Start a PWM output. Same as the `start` function in the `Pwm` trait.
58    fn start(&self, frequency_hz: usize, duty_cycle: usize) -> Result<(), ErrorCode>;
59
60    /// Stop a PWM output. Same as the `stop` function in the `Pwm` trait.
61    fn stop(&self) -> Result<(), ErrorCode>;
62
63    /// Return the maximum PWM frequency supported by the PWM implementation.
64    /// Same as the `get_maximum_frequency_hz` function in the `Pwm` trait.
65    fn get_maximum_frequency_hz(&self) -> usize;
66
67    /// Return an opaque number that represents a 100% duty cycle. This value
68    /// Same as the `get_maximum_duty_cycle` function in the `Pwm` trait.
69    fn get_maximum_duty_cycle(&self) -> usize;
70}