Skip to content

Commit 38f2613

Browse files
authored
Merge pull request #3950 from Matt-Allen-Bose/stm32-pwm-pin-config
Add ability to create STM32 timer channels with full pin configuration
2 parents 5af720d + 5e3cfc7 commit 38f2613

File tree

2 files changed

+82
-9
lines changed

2 files changed

+82
-9
lines changed

embassy-stm32/src/lptim/pwm.rs

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ use super::OutputPin;
1010
#[cfg(any(lptim_v2a, lptim_v2b))]
1111
use super::{channel::Channel, timer::ChannelDirection, Channel1Pin, Channel2Pin};
1212
use super::{BasicInstance, Instance};
13+
#[cfg(gpio_v2)]
14+
use crate::gpio::Pull;
1315
use crate::gpio::{AfType, AnyPin, OutputType, Speed};
1416
use crate::time::Hertz;
1517
use crate::Peripheral;
@@ -29,8 +31,21 @@ pub struct PwmPin<'d, T, C> {
2931
phantom: PhantomData<(T, C)>,
3032
}
3133

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+
3247
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) => {
3449
impl<'d, T: BasicInstance> PwmPin<'d, T, $channel> {
3550
#[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")]
3651
pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd) -> Self {
@@ -47,16 +62,37 @@ macro_rules! channel_impl {
4762
phantom: PhantomData,
4863
}
4964
}
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+
}
5086
}
5187
};
5288
}
5389

5490
#[cfg(not(any(lptim_v2a, lptim_v2b)))]
55-
channel_impl!(new, Output, OutputPin);
91+
channel_impl!(new, new_with_config, Output, OutputPin);
5692
#[cfg(any(lptim_v2a, lptim_v2b))]
57-
channel_impl!(new_ch1, Ch1, Channel1Pin);
93+
channel_impl!(new_ch1, new_ch1_with_config, Ch1, Channel1Pin);
5894
#[cfg(any(lptim_v2a, lptim_v2b))]
59-
channel_impl!(new_ch2, Ch2, Channel2Pin);
95+
channel_impl!(new_ch2, new_ch2_with_config, Ch2, Channel2Pin);
6096

6197
/// PWM driver.
6298
pub struct Pwm<'d, T: Instance> {

embassy-stm32/src/timer/simple_pwm.rs

Lines changed: 42 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
77

88
use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer};
99
use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel, TimerBits};
10+
#[cfg(gpio_v2)]
11+
use crate::gpio::Pull;
1012
use crate::gpio::{AfType, AnyPin, OutputType, Speed};
1113
use crate::time::Hertz;
1214
use crate::Peripheral;
@@ -28,8 +30,21 @@ pub struct PwmPin<'d, T, C> {
2830
phantom: PhantomData<(T, C)>,
2931
}
3032

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+
3146
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) => {
3348
impl<'d, T: GeneralInstance4Channel> PwmPin<'d, T, $channel> {
3449
#[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")]
3550
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 {
4358
phantom: PhantomData,
4459
}
4560
}
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+
}
4683
}
4784
};
4885
}
4986

50-
channel_impl!(new_ch1, Ch1, Channel1Pin);
51-
channel_impl!(new_ch2, Ch2, Channel2Pin);
52-
channel_impl!(new_ch3, Ch3, Channel3Pin);
53-
channel_impl!(new_ch4, Ch4, Channel4Pin);
87+
channel_impl!(new_ch1, new_ch1_with_config, Ch1, Channel1Pin);
88+
channel_impl!(new_ch2, new_ch2_with_config, Ch2, Channel2Pin);
89+
channel_impl!(new_ch3, new_ch3_with_config, Ch3, Channel3Pin);
90+
channel_impl!(new_ch4, new_ch4_with_config, Ch4, Channel4Pin);
5491

5592
/// A single channel of a pwm, obtained from [`SimplePwm::split`],
5693
/// [`SimplePwm::channel`], [`SimplePwm::ch1`], etc.

0 commit comments

Comments
 (0)