diff options
| -rw-r--r-- | embassy-stm32/src/pwm/simple_pwm.rs | 100 | ||||
| -rw-r--r-- | examples/stm32f4/src/bin/pwm.rs | 5 | ||||
| -rw-r--r-- | examples/stm32g4/src/bin/pwm.rs | 5 | ||||
| -rw-r--r-- | examples/stm32h7/src/bin/pwm.rs | 5 |
4 files changed, 52 insertions, 63 deletions
diff --git a/embassy-stm32/src/pwm/simple_pwm.rs b/embassy-stm32/src/pwm/simple_pwm.rs index 7b2cdbc01..b045a2d78 100644 --- a/embassy-stm32/src/pwm/simple_pwm.rs +++ b/embassy-stm32/src/pwm/simple_pwm.rs | |||
| @@ -1,85 +1,71 @@ | |||
| 1 | use core::marker::PhantomData; | ||
| 2 | |||
| 1 | use embassy_hal_common::{into_ref, PeripheralRef}; | 3 | use embassy_hal_common::{into_ref, PeripheralRef}; |
| 2 | 4 | ||
| 3 | use super::*; | 5 | use super::*; |
| 4 | #[allow(unused_imports)] | 6 | #[allow(unused_imports)] |
| 5 | use crate::gpio::sealed::{AFType, Pin}; | 7 | use crate::gpio::sealed::{AFType, Pin}; |
| 8 | use crate::gpio::AnyPin; | ||
| 6 | use crate::time::Hertz; | 9 | use crate::time::Hertz; |
| 7 | use crate::Peripheral; | 10 | use crate::Peripheral; |
| 8 | 11 | ||
| 9 | pub struct SimplePwm<'d, T> { | 12 | pub struct Ch1; |
| 10 | inner: PeripheralRef<'d, T>, | 13 | pub struct Ch2; |
| 14 | pub struct Ch3; | ||
| 15 | pub struct Ch4; | ||
| 16 | |||
| 17 | pub struct PwmPin<'d, Perip, Channel> { | ||
| 18 | _pin: PeripheralRef<'d, AnyPin>, | ||
| 19 | phantom: PhantomData<(Perip, Channel)>, | ||
| 11 | } | 20 | } |
| 12 | 21 | ||
| 13 | macro_rules! config_pins { | 22 | macro_rules! channel_impl { |
| 14 | ($($pin:ident),*) => { | 23 | ($new_chx:ident, $channel:ident, $pin_trait:ident) => { |
| 15 | into_ref!($($pin),*); | 24 | impl<'d, Perip: CaptureCompare16bitInstance> PwmPin<'d, Perip, $channel> { |
| 16 | // NOTE(unsafe) Exclusive access to the registers | 25 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<Perip>> + 'd) -> Self { |
| 17 | critical_section::with(|_| unsafe { | 26 | into_ref!(pin); |
| 18 | $( | 27 | critical_section::with(|_| unsafe { |
| 19 | $pin.set_low(); | 28 | pin.set_low(); |
| 20 | $pin.set_as_af($pin.af_num(), AFType::OutputPushPull); | 29 | pin.set_as_af(pin.af_num(), AFType::OutputPushPull); |
| 21 | #[cfg(gpio_v2)] | 30 | #[cfg(gpio_v2)] |
| 22 | $pin.set_speed(crate::gpio::Speed::VeryHigh); | 31 | pin.set_speed(crate::gpio::Speed::VeryHigh); |
| 23 | )* | 32 | }); |
| 24 | }) | 33 | PwmPin { |
| 34 | _pin: pin.map_into(), | ||
| 35 | phantom: PhantomData, | ||
| 36 | } | ||
| 37 | } | ||
| 38 | } | ||
| 25 | }; | 39 | }; |
| 26 | } | 40 | } |
| 27 | 41 | ||
| 28 | impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { | 42 | channel_impl!(new_ch1, Ch1, Channel1Pin); |
| 29 | pub fn new_1ch( | 43 | channel_impl!(new_ch2, Ch2, Channel2Pin); |
| 30 | tim: impl Peripheral<P = T> + 'd, | 44 | channel_impl!(new_ch3, Ch3, Channel3Pin); |
| 31 | ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd, | 45 | channel_impl!(new_ch4, Ch4, Channel4Pin); |
| 32 | freq: Hertz, | ||
| 33 | ) -> Self { | ||
| 34 | Self::new_inner(tim, freq, move || { | ||
| 35 | config_pins!(ch1); | ||
| 36 | }) | ||
| 37 | } | ||
| 38 | |||
| 39 | pub fn new_2ch( | ||
| 40 | tim: impl Peripheral<P = T> + 'd, | ||
| 41 | ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd, | ||
| 42 | ch2: impl Peripheral<P = impl Channel2Pin<T>> + 'd, | ||
| 43 | freq: Hertz, | ||
| 44 | ) -> Self { | ||
| 45 | Self::new_inner(tim, freq, move || { | ||
| 46 | config_pins!(ch1, ch2); | ||
| 47 | }) | ||
| 48 | } | ||
| 49 | 46 | ||
| 50 | pub fn new_3ch( | 47 | pub struct SimplePwm<'d, T> { |
| 51 | tim: impl Peripheral<P = T> + 'd, | 48 | inner: PeripheralRef<'d, T>, |
| 52 | ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd, | 49 | } |
| 53 | ch2: impl Peripheral<P = impl Channel2Pin<T>> + 'd, | ||
| 54 | ch3: impl Peripheral<P = impl Channel3Pin<T>> + 'd, | ||
| 55 | freq: Hertz, | ||
| 56 | ) -> Self { | ||
| 57 | Self::new_inner(tim, freq, move || { | ||
| 58 | config_pins!(ch1, ch2, ch3); | ||
| 59 | }) | ||
| 60 | } | ||
| 61 | 50 | ||
| 62 | pub fn new_4ch( | 51 | impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> { |
| 52 | pub fn new( | ||
| 63 | tim: impl Peripheral<P = T> + 'd, | 53 | tim: impl Peripheral<P = T> + 'd, |
| 64 | ch1: impl Peripheral<P = impl Channel1Pin<T>> + 'd, | 54 | _ch1: Option<PwmPin<'d, T, Ch1>>, |
| 65 | ch2: impl Peripheral<P = impl Channel2Pin<T>> + 'd, | 55 | _ch2: Option<PwmPin<'d, T, Ch2>>, |
| 66 | ch3: impl Peripheral<P = impl Channel3Pin<T>> + 'd, | 56 | _ch3: Option<PwmPin<'d, T, Ch3>>, |
| 67 | ch4: impl Peripheral<P = impl Channel4Pin<T>> + 'd, | 57 | _ch4: Option<PwmPin<'d, T, Ch4>>, |
| 68 | freq: Hertz, | 58 | freq: Hertz, |
| 69 | ) -> Self { | 59 | ) -> Self { |
| 70 | Self::new_inner(tim, freq, move || { | 60 | Self::new_inner(tim, freq) |
| 71 | config_pins!(ch1, ch2, ch3, ch4); | ||
| 72 | }) | ||
| 73 | } | 61 | } |
| 74 | 62 | ||
| 75 | fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz, configure_pins: impl FnOnce()) -> Self { | 63 | fn new_inner(tim: impl Peripheral<P = T> + 'd, freq: Hertz) -> Self { |
| 76 | into_ref!(tim); | 64 | into_ref!(tim); |
| 77 | 65 | ||
| 78 | T::enable(); | 66 | T::enable(); |
| 79 | <T as crate::rcc::sealed::RccPeripheral>::reset(); | 67 | <T as crate::rcc::sealed::RccPeripheral>::reset(); |
| 80 | 68 | ||
| 81 | configure_pins(); | ||
| 82 | |||
| 83 | let mut this = Self { inner: tim }; | 69 | let mut this = Self { inner: tim }; |
| 84 | 70 | ||
| 85 | this.inner.set_frequency(freq); | 71 | this.inner.set_frequency(freq); |
diff --git a/examples/stm32f4/src/bin/pwm.rs b/examples/stm32f4/src/bin/pwm.rs index c99f3cc26..b39bbbe28 100644 --- a/examples/stm32f4/src/bin/pwm.rs +++ b/examples/stm32f4/src/bin/pwm.rs | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy::executor::Spawner; | 6 | use embassy::executor::Spawner; |
| 7 | use embassy::time::{Duration, Timer}; | 7 | use embassy::time::{Duration, Timer}; |
| 8 | use embassy_stm32::pwm::simple_pwm::SimplePwm; | 8 | use embassy_stm32::pwm::simple_pwm::{PwmPin, SimplePwm}; |
| 9 | use embassy_stm32::pwm::Channel; | 9 | use embassy_stm32::pwm::Channel; |
| 10 | use embassy_stm32::time::khz; | 10 | use embassy_stm32::time::khz; |
| 11 | use embassy_stm32::Peripherals; | 11 | use embassy_stm32::Peripherals; |
| @@ -15,7 +15,8 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 15 | async fn main(_spawner: Spawner, p: Peripherals) { | 15 | async fn main(_spawner: Spawner, p: Peripherals) { |
| 16 | info!("Hello World!"); | 16 | info!("Hello World!"); |
| 17 | 17 | ||
| 18 | let mut pwm = SimplePwm::new_1ch(p.TIM1, p.PE9, khz(10)); | 18 | let ch1 = PwmPin::new_ch1(p.PE9); |
| 19 | let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10)); | ||
| 19 | let max = pwm.get_max_duty(); | 20 | let max = pwm.get_max_duty(); |
| 20 | pwm.enable(Channel::Ch1); | 21 | pwm.enable(Channel::Ch1); |
| 21 | 22 | ||
diff --git a/examples/stm32g4/src/bin/pwm.rs b/examples/stm32g4/src/bin/pwm.rs index 579e289b0..dc4e164ab 100644 --- a/examples/stm32g4/src/bin/pwm.rs +++ b/examples/stm32g4/src/bin/pwm.rs | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy::executor::Spawner; | 6 | use embassy::executor::Spawner; |
| 7 | use embassy::time::{Duration, Timer}; | 7 | use embassy::time::{Duration, Timer}; |
| 8 | use embassy_stm32::pwm::simple_pwm::SimplePwm; | 8 | use embassy_stm32::pwm::simple_pwm::{PwmPin, SimplePwm}; |
| 9 | use embassy_stm32::pwm::Channel; | 9 | use embassy_stm32::pwm::Channel; |
| 10 | use embassy_stm32::time::khz; | 10 | use embassy_stm32::time::khz; |
| 11 | use embassy_stm32::Peripherals; | 11 | use embassy_stm32::Peripherals; |
| @@ -15,7 +15,8 @@ use {defmt_rtt as _, panic_probe as _}; | |||
| 15 | async fn main(_spawner: Spawner, p: Peripherals) { | 15 | async fn main(_spawner: Spawner, p: Peripherals) { |
| 16 | info!("Hello World!"); | 16 | info!("Hello World!"); |
| 17 | 17 | ||
| 18 | let mut pwm = SimplePwm::new_1ch(p.TIM2, p.PA5, khz(10)); | 18 | let ch1 = PwmPin::new_ch1(p.PA5); |
| 19 | let mut pwm = SimplePwm::new(p.TIM2, Some(ch1), None, None, None, khz(10)); | ||
| 19 | let max = pwm.get_max_duty(); | 20 | let max = pwm.get_max_duty(); |
| 20 | pwm.enable(Channel::Ch1); | 21 | pwm.enable(Channel::Ch1); |
| 21 | 22 | ||
diff --git a/examples/stm32h7/src/bin/pwm.rs b/examples/stm32h7/src/bin/pwm.rs index f072c5375..730f637e9 100644 --- a/examples/stm32h7/src/bin/pwm.rs +++ b/examples/stm32h7/src/bin/pwm.rs | |||
| @@ -5,7 +5,7 @@ | |||
| 5 | use defmt::*; | 5 | use defmt::*; |
| 6 | use embassy::executor::Spawner; | 6 | use embassy::executor::Spawner; |
| 7 | use embassy::time::{Duration, Timer}; | 7 | use embassy::time::{Duration, Timer}; |
| 8 | use embassy_stm32::pwm::simple_pwm::SimplePwm; | 8 | use embassy_stm32::pwm::simple_pwm::{PwmPin, SimplePwm}; |
| 9 | use embassy_stm32::pwm::Channel; | 9 | use embassy_stm32::pwm::Channel; |
| 10 | use embassy_stm32::time::{khz, mhz}; | 10 | use embassy_stm32::time::{khz, mhz}; |
| 11 | use embassy_stm32::{Config, Peripherals}; | 11 | use embassy_stm32::{Config, Peripherals}; |
| @@ -27,7 +27,8 @@ pub fn config() -> Config { | |||
| 27 | async fn main(_spawner: Spawner, p: Peripherals) { | 27 | async fn main(_spawner: Spawner, p: Peripherals) { |
| 28 | info!("Hello World!"); | 28 | info!("Hello World!"); |
| 29 | 29 | ||
| 30 | let mut pwm = SimplePwm::new_1ch(p.TIM3, p.PA6, khz(10)); | 30 | let ch1 = PwmPin::new_ch1(p.PA6); |
| 31 | let mut pwm = SimplePwm::new(p.TIM3, Some(ch1), None, None, None, khz(10)); | ||
| 31 | let max = pwm.get_max_duty(); | 32 | let max = pwm.get_max_duty(); |
| 32 | pwm.enable(Channel::Ch1); | 33 | pwm.enable(Channel::Ch1); |
| 33 | 34 | ||
