diff options
| author | Dario Nieuwenhuis <[email protected]> | 2025-03-11 18:09:47 +0000 |
|---|---|---|
| committer | GitHub <[email protected]> | 2025-03-11 18:09:47 +0000 |
| commit | 38f26137fc67beb874aa73c9a7ab2150d9f3d372 (patch) | |
| tree | 84d33d192ffdc78dbb5a1482fb520235d7cbbc0c | |
| parent | 5af720d9bb74f39d376d4dc22def649146da1d68 (diff) | |
| parent | 5e3cfc7b5c3b0dbadb37870462741d6b417cf028 (diff) | |
Merge pull request #3950 from Matt-Allen-Bose/stm32-pwm-pin-config
Add ability to create STM32 timer channels with full pin configuration
| -rw-r--r-- | embassy-stm32/src/lptim/pwm.rs | 44 | ||||
| -rw-r--r-- | embassy-stm32/src/timer/simple_pwm.rs | 47 |
2 files changed, 82 insertions, 9 deletions
diff --git a/embassy-stm32/src/lptim/pwm.rs b/embassy-stm32/src/lptim/pwm.rs index 1f43eb6ee..132f5815e 100644 --- a/embassy-stm32/src/lptim/pwm.rs +++ b/embassy-stm32/src/lptim/pwm.rs | |||
| @@ -10,6 +10,8 @@ use super::OutputPin; | |||
| 10 | #[cfg(any(lptim_v2a, lptim_v2b))] | 10 | #[cfg(any(lptim_v2a, lptim_v2b))] |
| 11 | use super::{channel::Channel, timer::ChannelDirection, Channel1Pin, Channel2Pin}; | 11 | use super::{channel::Channel, timer::ChannelDirection, Channel1Pin, Channel2Pin}; |
| 12 | use super::{BasicInstance, Instance}; | 12 | use super::{BasicInstance, Instance}; |
| 13 | #[cfg(gpio_v2)] | ||
| 14 | use crate::gpio::Pull; | ||
| 13 | use crate::gpio::{AfType, AnyPin, OutputType, Speed}; | 15 | use crate::gpio::{AfType, AnyPin, OutputType, Speed}; |
| 14 | use crate::time::Hertz; | 16 | use crate::time::Hertz; |
| 15 | use crate::Peripheral; | 17 | use crate::Peripheral; |
| @@ -29,8 +31,21 @@ pub struct PwmPin<'d, T, C> { | |||
| 29 | phantom: PhantomData<(T, C)>, | 31 | phantom: PhantomData<(T, C)>, |
| 30 | } | 32 | } |
| 31 | 33 | ||
| 34 | /// PWM pin config | ||
| 35 | /// | ||
| 36 | /// This configures the pwm pin settings | ||
| 37 | pub struct PwmPinConfig { | ||
| 38 | /// PWM Pin output type | ||
| 39 | pub output_type: OutputType, | ||
| 40 | /// PWM Pin speed | ||
| 41 | pub speed: Speed, | ||
| 42 | /// PWM Pin pull type | ||
| 43 | #[cfg(gpio_v2)] | ||
| 44 | pub pull: Pull, | ||
| 45 | } | ||
| 46 | |||
| 32 | macro_rules! channel_impl { | 47 | macro_rules! channel_impl { |
| 33 | ($new_chx:ident, $channel:ident, $pin_trait:ident) => { | 48 | ($new_chx:ident, $new_chx_with_config:ident, $channel:ident, $pin_trait:ident) => { |
| 34 | impl<'d, T: BasicInstance> PwmPin<'d, T, $channel> { | 49 | impl<'d, T: BasicInstance> PwmPin<'d, T, $channel> { |
| 35 | #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] | 50 | #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] |
| 36 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd) -> Self { | 51 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd) -> Self { |
| @@ -47,16 +62,37 @@ macro_rules! channel_impl { | |||
| 47 | phantom: PhantomData, | 62 | phantom: PhantomData, |
| 48 | } | 63 | } |
| 49 | } | 64 | } |
| 65 | #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance with config.")] | ||
| 66 | pub fn $new_chx_with_config( | ||
| 67 | pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, | ||
| 68 | pin_config: PwmPinConfig, | ||
| 69 | ) -> Self { | ||
| 70 | into_ref!(pin); | ||
| 71 | critical_section::with(|_| { | ||
| 72 | pin.set_low(); | ||
| 73 | pin.set_as_af( | ||
| 74 | pin.af_num(), | ||
| 75 | #[cfg(gpio_v1)] | ||
| 76 | AfType::output(pin_config.output_type, pin_config.speed), | ||
| 77 | #[cfg(gpio_v2)] | ||
| 78 | AfType::output_pull(pin_config.output_type, pin_config.speed, pin_config.pull), | ||
| 79 | ); | ||
| 80 | }); | ||
| 81 | PwmPin { | ||
| 82 | _pin: pin.map_into(), | ||
| 83 | phantom: PhantomData, | ||
| 84 | } | ||
| 85 | } | ||
| 50 | } | 86 | } |
| 51 | }; | 87 | }; |
| 52 | } | 88 | } |
| 53 | 89 | ||
| 54 | #[cfg(not(any(lptim_v2a, lptim_v2b)))] | 90 | #[cfg(not(any(lptim_v2a, lptim_v2b)))] |
| 55 | channel_impl!(new, Output, OutputPin); | 91 | channel_impl!(new, new_with_config, Output, OutputPin); |
| 56 | #[cfg(any(lptim_v2a, lptim_v2b))] | 92 | #[cfg(any(lptim_v2a, lptim_v2b))] |
| 57 | channel_impl!(new_ch1, Ch1, Channel1Pin); | 93 | channel_impl!(new_ch1, new_ch1_with_config, Ch1, Channel1Pin); |
| 58 | #[cfg(any(lptim_v2a, lptim_v2b))] | 94 | #[cfg(any(lptim_v2a, lptim_v2b))] |
| 59 | channel_impl!(new_ch2, Ch2, Channel2Pin); | 95 | channel_impl!(new_ch2, new_ch2_with_config, Ch2, Channel2Pin); |
| 60 | 96 | ||
| 61 | /// PWM driver. | 97 | /// PWM driver. |
| 62 | pub struct Pwm<'d, T: Instance> { | 98 | pub struct Pwm<'d, T: Instance> { |
diff --git a/embassy-stm32/src/timer/simple_pwm.rs b/embassy-stm32/src/timer/simple_pwm.rs index 1dff3f9ae..c5a366cd5 100644 --- a/embassy-stm32/src/timer/simple_pwm.rs +++ b/embassy-stm32/src/timer/simple_pwm.rs | |||
| @@ -7,6 +7,8 @@ use embassy_hal_internal::{into_ref, PeripheralRef}; | |||
| 7 | 7 | ||
| 8 | use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; | 8 | use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer}; |
| 9 | use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel, TimerBits}; | 9 | use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel, TimerBits}; |
| 10 | #[cfg(gpio_v2)] | ||
| 11 | use crate::gpio::Pull; | ||
| 10 | use crate::gpio::{AfType, AnyPin, OutputType, Speed}; | 12 | use crate::gpio::{AfType, AnyPin, OutputType, Speed}; |
| 11 | use crate::time::Hertz; | 13 | use crate::time::Hertz; |
| 12 | use crate::Peripheral; | 14 | use crate::Peripheral; |
| @@ -28,8 +30,21 @@ pub struct PwmPin<'d, T, C> { | |||
| 28 | phantom: PhantomData<(T, C)>, | 30 | phantom: PhantomData<(T, C)>, |
| 29 | } | 31 | } |
| 30 | 32 | ||
| 33 | /// PWM pin config | ||
| 34 | /// | ||
| 35 | /// This configures the pwm pin settings | ||
| 36 | pub struct PwmPinConfig { | ||
| 37 | /// PWM Pin output type | ||
| 38 | pub output_type: OutputType, | ||
| 39 | /// PWM Pin speed | ||
| 40 | pub speed: Speed, | ||
| 41 | /// PWM Pin pull type | ||
| 42 | #[cfg(gpio_v2)] | ||
| 43 | pub pull: Pull, | ||
| 44 | } | ||
| 45 | |||
| 31 | macro_rules! channel_impl { | 46 | macro_rules! channel_impl { |
| 32 | ($new_chx:ident, $channel:ident, $pin_trait:ident) => { | 47 | ($new_chx:ident, $new_chx_with_config:ident, $channel:ident, $pin_trait:ident) => { |
| 33 | impl<'d, T: GeneralInstance4Channel> PwmPin<'d, T, $channel> { | 48 | impl<'d, T: GeneralInstance4Channel> PwmPin<'d, T, $channel> { |
| 34 | #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] | 49 | #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")] |
| 35 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self { | 50 | pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, output_type: OutputType) -> Self { |
| @@ -43,14 +58,36 @@ macro_rules! channel_impl { | |||
| 43 | phantom: PhantomData, | 58 | phantom: PhantomData, |
| 44 | } | 59 | } |
| 45 | } | 60 | } |
| 61 | |||
| 62 | #[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance with config.")] | ||
| 63 | pub fn $new_chx_with_config( | ||
| 64 | pin: impl Peripheral<P = impl $pin_trait<T>> + 'd, | ||
| 65 | pin_config: PwmPinConfig, | ||
| 66 | ) -> Self { | ||
| 67 | into_ref!(pin); | ||
| 68 | critical_section::with(|_| { | ||
| 69 | pin.set_low(); | ||
| 70 | pin.set_as_af( | ||
| 71 | pin.af_num(), | ||
| 72 | #[cfg(gpio_v1)] | ||
| 73 | AfType::output(pin_config.output_type, pin_config.speed), | ||
| 74 | #[cfg(gpio_v2)] | ||
| 75 | AfType::output_pull(pin_config.output_type, pin_config.speed, pin_config.pull), | ||
| 76 | ); | ||
| 77 | }); | ||
| 78 | PwmPin { | ||
| 79 | _pin: pin.map_into(), | ||
| 80 | phantom: PhantomData, | ||
| 81 | } | ||
| 82 | } | ||
| 46 | } | 83 | } |
| 47 | }; | 84 | }; |
| 48 | } | 85 | } |
| 49 | 86 | ||
| 50 | channel_impl!(new_ch1, Ch1, Channel1Pin); | 87 | channel_impl!(new_ch1, new_ch1_with_config, Ch1, Channel1Pin); |
| 51 | channel_impl!(new_ch2, Ch2, Channel2Pin); | 88 | channel_impl!(new_ch2, new_ch2_with_config, Ch2, Channel2Pin); |
| 52 | channel_impl!(new_ch3, Ch3, Channel3Pin); | 89 | channel_impl!(new_ch3, new_ch3_with_config, Ch3, Channel3Pin); |
| 53 | channel_impl!(new_ch4, Ch4, Channel4Pin); | 90 | channel_impl!(new_ch4, new_ch4_with_config, Ch4, Channel4Pin); |
| 54 | 91 | ||
| 55 | /// A single channel of a pwm, obtained from [`SimplePwm::split`], | 92 | /// A single channel of a pwm, obtained from [`SimplePwm::split`], |
| 56 | /// [`SimplePwm::channel`], [`SimplePwm::ch1`], etc. | 93 | /// [`SimplePwm::channel`], [`SimplePwm::ch1`], etc. |
