stm32/pwm: add output type control

This commit is contained in:
xoviat 2023-07-29 12:01:32 -05:00
parent fcbfd224a7
commit 0d7b005252
7 changed files with 35 additions and 16 deletions

View File

@ -4,6 +4,7 @@ use core::convert::Infallible;
use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef}; use embassy_hal_internal::{impl_peripheral, into_ref, PeripheralRef};
use crate::pac::gpio::{self, vals}; use crate::pac::gpio::{self, vals};
use crate::usb_otg::Out;
use crate::{pac, peripherals, Peripheral}; use crate::{pac, peripherals, Peripheral};
/// GPIO flexible pin. /// GPIO flexible pin.
@ -502,6 +503,20 @@ impl<'d, T: Pin> OutputOpenDrain<'d, T> {
} }
} }
pub enum OutputType {
PushPull,
OpenDrain,
}
impl From<OutputType> for sealed::AFType {
fn from(value: OutputType) -> Self {
match value {
OutputType::OpenDrain => sealed::AFType::OutputOpenDrain,
OutputType::PushPull => sealed::AFType::OutputPushPull,
}
}
}
pub(crate) mod sealed { pub(crate) mod sealed {
use super::*; use super::*;

View File

@ -7,7 +7,7 @@ use super::simple_pwm::*;
use super::*; use super::*;
#[allow(unused_imports)] #[allow(unused_imports)]
use crate::gpio::sealed::{AFType, Pin}; use crate::gpio::sealed::{AFType, Pin};
use crate::gpio::AnyPin; use crate::gpio::{AnyPin, OutputType};
use crate::time::Hertz; use crate::time::Hertz;
use crate::Peripheral; use crate::Peripheral;
@ -17,13 +17,13 @@ pub struct ComplementaryPwmPin<'d, Perip, Channel> {
} }
macro_rules! complementary_channel_impl { macro_rules! complementary_channel_impl {
($new_chx:ident, $channel:ident, $pin_trait:ident, $complementary_pin_trait:ident) => { ($new_chx:ident, $channel:ident, $pin_trait:ident) => {
impl<'d, Perip: CaptureCompare16bitInstance> ComplementaryPwmPin<'d, Perip, $channel> { impl<'d, Perip: CaptureCompare16bitInstance> ComplementaryPwmPin<'d, Perip, $channel> {
pub fn $new_chx(pin: impl Peripheral<P = impl $complementary_pin_trait<Perip>> + 'd) -> Self { pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<Perip>> + 'd, output_type: OutputType) -> Self {
into_ref!(pin); into_ref!(pin);
critical_section::with(|_| { critical_section::with(|_| {
pin.set_low(); pin.set_low();
pin.set_as_af(pin.af_num(), AFType::OutputPushPull); pin.set_as_af(pin.af_num(), output_type.into());
#[cfg(gpio_v2)] #[cfg(gpio_v2)]
pin.set_speed(crate::gpio::Speed::VeryHigh); pin.set_speed(crate::gpio::Speed::VeryHigh);
}); });
@ -36,10 +36,10 @@ macro_rules! complementary_channel_impl {
}; };
} }
complementary_channel_impl!(new_ch1, Ch1, Channel1Pin, Channel1ComplementaryPin); complementary_channel_impl!(new_ch1, Ch1, Channel1ComplementaryPin);
complementary_channel_impl!(new_ch2, Ch2, Channel2Pin, Channel2ComplementaryPin); complementary_channel_impl!(new_ch2, Ch2, Channel2ComplementaryPin);
complementary_channel_impl!(new_ch3, Ch3, Channel3Pin, Channel3ComplementaryPin); complementary_channel_impl!(new_ch3, Ch3, Channel3ComplementaryPin);
complementary_channel_impl!(new_ch4, Ch4, Channel4Pin, Channel4ComplementaryPin); complementary_channel_impl!(new_ch4, Ch4, Channel4ComplementaryPin);
pub struct ComplementaryPwm<'d, T> { pub struct ComplementaryPwm<'d, T> {
inner: PeripheralRef<'d, T>, inner: PeripheralRef<'d, T>,

View File

@ -5,7 +5,7 @@ use embassy_hal_internal::{into_ref, PeripheralRef};
use super::*; use super::*;
#[allow(unused_imports)] #[allow(unused_imports)]
use crate::gpio::sealed::{AFType, Pin}; use crate::gpio::sealed::{AFType, Pin};
use crate::gpio::AnyPin; use crate::gpio::{AnyPin, OutputType};
use crate::time::Hertz; use crate::time::Hertz;
use crate::Peripheral; use crate::Peripheral;
@ -22,11 +22,11 @@ pub struct PwmPin<'d, Perip, Channel> {
macro_rules! channel_impl { macro_rules! channel_impl {
($new_chx:ident, $channel:ident, $pin_trait:ident) => { ($new_chx:ident, $channel:ident, $pin_trait:ident) => {
impl<'d, Perip: CaptureCompare16bitInstance> PwmPin<'d, Perip, $channel> { impl<'d, Perip: CaptureCompare16bitInstance> PwmPin<'d, Perip, $channel> {
pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<Perip>> + 'd) -> Self { pub fn $new_chx(pin: impl Peripheral<P = impl $pin_trait<Perip>> + 'd, output_type: OutputType) -> Self {
into_ref!(pin); into_ref!(pin);
critical_section::with(|_| { critical_section::with(|_| {
pin.set_low(); pin.set_low();
pin.set_as_af(pin.af_num(), AFType::OutputPushPull); pin.set_as_af(pin.af_num(), output_type.into());
#[cfg(gpio_v2)] #[cfg(gpio_v2)]
pin.set_speed(crate::gpio::Speed::VeryHigh); pin.set_speed(crate::gpio::Speed::VeryHigh);
}); });

View File

@ -4,6 +4,7 @@
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::gpio::OutputType;
use embassy_stm32::time::khz; use embassy_stm32::time::khz;
use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm};
use embassy_stm32::timer::Channel; use embassy_stm32::timer::Channel;
@ -15,7 +16,7 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default()); let p = embassy_stm32::init(Default::default());
info!("Hello World!"); info!("Hello World!");
let ch1 = PwmPin::new_ch1(p.PE9); let ch1 = PwmPin::new_ch1(p.PE9, OutputType::PushPull);
let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10)); let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10));
let max = pwm.get_max_duty(); let max = pwm.get_max_duty();
pwm.enable(Channel::Ch1); pwm.enable(Channel::Ch1);

View File

@ -4,6 +4,7 @@
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::gpio::OutputType;
use embassy_stm32::time::khz; use embassy_stm32::time::khz;
use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin}; use embassy_stm32::timer::complementary_pwm::{ComplementaryPwm, ComplementaryPwmPin};
use embassy_stm32::timer::simple_pwm::PwmPin; use embassy_stm32::timer::simple_pwm::PwmPin;
@ -16,8 +17,8 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default()); let p = embassy_stm32::init(Default::default());
info!("Hello World!"); info!("Hello World!");
let ch1 = PwmPin::new_ch1(p.PE9); let ch1 = PwmPin::new_ch1(p.PE9, OutputType::PushPull);
let ch1n = ComplementaryPwmPin::new_ch1(p.PA7); let ch1n = ComplementaryPwmPin::new_ch1(p.PA7, OutputType::PushPull);
let mut pwm = ComplementaryPwm::new( let mut pwm = ComplementaryPwm::new(
p.TIM1, p.TIM1,
Some(ch1), Some(ch1),

View File

@ -4,6 +4,7 @@
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::gpio::OutputType;
use embassy_stm32::time::khz; use embassy_stm32::time::khz;
use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm};
use embassy_stm32::timer::Channel; use embassy_stm32::timer::Channel;
@ -15,7 +16,7 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(Default::default()); let p = embassy_stm32::init(Default::default());
info!("Hello World!"); info!("Hello World!");
let ch1 = PwmPin::new_ch1(p.PC0); let ch1 = PwmPin::new_ch1(p.PC0, OutputType::PushPull);
let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10)); let mut pwm = SimplePwm::new(p.TIM1, Some(ch1), None, None, None, khz(10));
let max = pwm.get_max_duty(); let max = pwm.get_max_duty();
pwm.enable(Channel::Ch1); pwm.enable(Channel::Ch1);

View File

@ -4,6 +4,7 @@
use defmt::*; use defmt::*;
use embassy_executor::Spawner; use embassy_executor::Spawner;
use embassy_stm32::gpio::OutputType;
use embassy_stm32::time::{khz, mhz}; use embassy_stm32::time::{khz, mhz};
use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm}; use embassy_stm32::timer::simple_pwm::{PwmPin, SimplePwm};
use embassy_stm32::timer::Channel; use embassy_stm32::timer::Channel;
@ -24,7 +25,7 @@ async fn main(_spawner: Spawner) {
let p = embassy_stm32::init(config); let p = embassy_stm32::init(config);
info!("Hello World!"); info!("Hello World!");
let ch1 = PwmPin::new_ch1(p.PA6); let ch1 = PwmPin::new_ch1(p.PA6, OutputType::PushPull);
let mut pwm = SimplePwm::new(p.TIM3, Some(ch1), None, None, None, khz(10)); let mut pwm = SimplePwm::new(p.TIM3, Some(ch1), None, None, None, khz(10));
let max = pwm.get_max_duty(); let max = pwm.get_max_duty();
pwm.enable(Channel::Ch1); pwm.enable(Channel::Ch1);