Merge pull request #3950 from Matt-Allen-Bose/stm32-pwm-pin-config

Add ability to create STM32 timer channels with full pin configuration
This commit is contained in:
Dario Nieuwenhuis 2025-03-11 18:09:47 +00:00 committed by GitHub
commit 38f26137fc
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 82 additions and 9 deletions

View File

@ -10,6 +10,8 @@ use super::OutputPin;
#[cfg(any(lptim_v2a, lptim_v2b))]
use super::{channel::Channel, timer::ChannelDirection, Channel1Pin, Channel2Pin};
use super::{BasicInstance, Instance};
#[cfg(gpio_v2)]
use crate::gpio::Pull;
use crate::gpio::{AfType, AnyPin, OutputType, Speed};
use crate::time::Hertz;
use crate::Peripheral;
@ -29,8 +31,21 @@ pub struct PwmPin<'d, T, C> {
phantom: PhantomData<(T, C)>,
}
/// PWM pin config
///
/// This configures the pwm pin settings
pub struct PwmPinConfig {
/// PWM Pin output type
pub output_type: OutputType,
/// PWM Pin speed
pub speed: Speed,
/// PWM Pin pull type
#[cfg(gpio_v2)]
pub pull: Pull,
}
macro_rules! channel_impl {
($new_chx:ident, $channel:ident, $pin_trait:ident) => {
($new_chx:ident, $new_chx_with_config:ident, $channel:ident, $pin_trait:ident) => {
impl<'d, T: BasicInstance> PwmPin<'d, T, $channel> {
#[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")]
pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<T>> + 'd) -> Self {
@ -47,16 +62,37 @@ macro_rules! channel_impl {
phantom: PhantomData,
}
}
#[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance with config.")]
pub fn $new_chx_with_config(
pin: impl Peripheral<P = impl $pin_trait<T>> + 'd,
pin_config: PwmPinConfig,
) -> Self {
into_ref!(pin);
critical_section::with(|_| {
pin.set_low();
pin.set_as_af(
pin.af_num(),
#[cfg(gpio_v1)]
AfType::output(pin_config.output_type, pin_config.speed),
#[cfg(gpio_v2)]
AfType::output_pull(pin_config.output_type, pin_config.speed, pin_config.pull),
);
});
PwmPin {
_pin: pin.map_into(),
phantom: PhantomData,
}
}
}
};
}
#[cfg(not(any(lptim_v2a, lptim_v2b)))]
channel_impl!(new, Output, OutputPin);
channel_impl!(new, new_with_config, Output, OutputPin);
#[cfg(any(lptim_v2a, lptim_v2b))]
channel_impl!(new_ch1, Ch1, Channel1Pin);
channel_impl!(new_ch1, new_ch1_with_config, Ch1, Channel1Pin);
#[cfg(any(lptim_v2a, lptim_v2b))]
channel_impl!(new_ch2, Ch2, Channel2Pin);
channel_impl!(new_ch2, new_ch2_with_config, Ch2, Channel2Pin);
/// PWM driver.
pub struct Pwm<'d, T: Instance> {

View File

@ -7,6 +7,8 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
use super::low_level::{CountingMode, OutputCompareMode, OutputPolarity, Timer};
use super::{Channel, Channel1Pin, Channel2Pin, Channel3Pin, Channel4Pin, GeneralInstance4Channel, TimerBits};
#[cfg(gpio_v2)]
use crate::gpio::Pull;
use crate::gpio::{AfType, AnyPin, OutputType, Speed};
use crate::time::Hertz;
use crate::Peripheral;
@ -28,8 +30,21 @@ pub struct PwmPin<'d, T, C> {
phantom: PhantomData<(T, C)>,
}
/// PWM pin config
///
/// This configures the pwm pin settings
pub struct PwmPinConfig {
/// PWM Pin output type
pub output_type: OutputType,
/// PWM Pin speed
pub speed: Speed,
/// PWM Pin pull type
#[cfg(gpio_v2)]
pub pull: Pull,
}
macro_rules! channel_impl {
($new_chx:ident, $channel:ident, $pin_trait:ident) => {
($new_chx:ident, $new_chx_with_config:ident, $channel:ident, $pin_trait:ident) => {
impl<'d, T: GeneralInstance4Channel> PwmPin<'d, T, $channel> {
#[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance.")]
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 {
phantom: PhantomData,
}
}
#[doc = concat!("Create a new ", stringify!($channel), " PWM pin instance with config.")]
pub fn $new_chx_with_config(
pin: impl Peripheral<P = impl $pin_trait<T>> + 'd,
pin_config: PwmPinConfig,
) -> Self {
into_ref!(pin);
critical_section::with(|_| {
pin.set_low();
pin.set_as_af(
pin.af_num(),
#[cfg(gpio_v1)]
AfType::output(pin_config.output_type, pin_config.speed),
#[cfg(gpio_v2)]
AfType::output_pull(pin_config.output_type, pin_config.speed, pin_config.pull),
);
});
PwmPin {
_pin: pin.map_into(),
phantom: PhantomData,
}
}
}
};
}
channel_impl!(new_ch1, Ch1, Channel1Pin);
channel_impl!(new_ch2, Ch2, Channel2Pin);
channel_impl!(new_ch3, Ch3, Channel3Pin);
channel_impl!(new_ch4, Ch4, Channel4Pin);
channel_impl!(new_ch1, new_ch1_with_config, Ch1, Channel1Pin);
channel_impl!(new_ch2, new_ch2_with_config, Ch2, Channel2Pin);
channel_impl!(new_ch3, new_ch3_with_config, Ch3, Channel3Pin);
channel_impl!(new_ch4, new_ch4_with_config, Ch4, Channel4Pin);
/// A single channel of a pwm, obtained from [`SimplePwm::split`],
/// [`SimplePwm::channel`], [`SimplePwm::ch1`], etc.