stm32: Add standard crate-wide macros for pin/dma traits, switch all drivers to use them.

This commit is contained in:
Dario Nieuwenhuis
2022-02-10 21:38:03 +01:00
parent 9d682aa1fa
commit b99ab3d5d9
26 changed files with 913 additions and 1781 deletions

View File

@ -1,11 +1,3 @@
#[cfg(feature = "unstable-pac")]
#[macro_use]
pub mod pins;
#[cfg(not(feature = "unstable-pac"))]
#[macro_use]
pub(crate) mod pins;
pub mod simple_pwm;
#[cfg(feature = "unstable-pac")]
@ -62,7 +54,7 @@ impl From<OutputCompareMode> for stm32_metapac::timer::vals::Ocm {
pub(crate) mod sealed {
use super::*;
pub trait CaptureCompareCapable16bitInstance: crate::timer::sealed::Basic16bitInstance {
pub trait CaptureCompare16bitInstance: crate::timer::sealed::Basic16bitInstance {
unsafe fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode);
unsafe fn enable_channel(&mut self, channel: Channel, enable: bool);
@ -72,7 +64,7 @@ pub(crate) mod sealed {
unsafe fn get_max_compare_value(&self) -> u16;
}
pub trait CaptureCompareCapable32bitInstance:
pub trait CaptureCompare32bitInstance:
crate::timer::sealed::GeneralPurpose32bitInstance
{
unsafe fn set_output_compare_mode(&mut self, channel: Channel, mode: OutputCompareMode);
@ -85,19 +77,22 @@ pub(crate) mod sealed {
}
}
pub trait CaptureCompareCapable16bitInstance:
sealed::CaptureCompareCapable16bitInstance + crate::timer::Basic16bitInstance + 'static
pub trait CaptureCompare16bitInstance:
sealed::CaptureCompare16bitInstance + crate::timer::Basic16bitInstance + 'static
{
}
pub trait CaptureCompareCapable32bitInstance:
sealed::CaptureCompareCapable32bitInstance + crate::timer::GeneralPurpose32bitInstance + 'static
pub trait CaptureCompare32bitInstance:
sealed::CaptureCompare32bitInstance
+ CaptureCompare16bitInstance
+ crate::timer::GeneralPurpose32bitInstance
+ 'static
{
}
#[allow(unused)]
macro_rules! impl_compare_capable_16bit {
($inst:ident) => {
impl crate::pwm::sealed::CaptureCompareCapable16bitInstance for crate::peripherals::$inst {
impl crate::pwm::sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {
unsafe fn set_output_compare_mode(
&mut self,
channel: crate::pwm::Channel,
@ -134,7 +129,7 @@ macro_rules! impl_compare_capable_16bit {
crate::pac::interrupts! {
($inst:ident, timer, TIM_GP16, UP, $irq:ident) => {
impl crate::pwm::sealed::CaptureCompareCapable16bitInstance for crate::peripherals::$inst {
impl crate::pwm::sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {
unsafe fn set_output_compare_mode(
&mut self,
channel: crate::pwm::Channel,
@ -167,14 +162,14 @@ crate::pac::interrupts! {
}
}
impl CaptureCompareCapable16bitInstance for crate::peripherals::$inst {
impl CaptureCompare16bitInstance for crate::peripherals::$inst {
}
};
($inst:ident, timer, TIM_GP32, UP, $irq:ident) => {
impl_compare_capable_16bit!($inst);
impl crate::pwm::sealed::CaptureCompareCapable32bitInstance for crate::peripherals::$inst {
impl crate::pwm::sealed::CaptureCompare32bitInstance for crate::peripherals::$inst {
unsafe fn set_output_compare_mode(
&mut self,
channel: crate::pwm::Channel,
@ -200,16 +195,16 @@ crate::pac::interrupts! {
self.regs_gp32().arr().read().arr() as u32
}
}
impl CaptureCompareCapable16bitInstance for crate::peripherals::$inst {
impl CaptureCompare16bitInstance for crate::peripherals::$inst {
}
impl CaptureCompareCapable32bitInstance for crate::peripherals::$inst {
impl CaptureCompare32bitInstance for crate::peripherals::$inst {
}
};
($inst:ident, timer, TIM_ADV, UP, $irq:ident) => {
impl crate::pwm::sealed::CaptureCompareCapable16bitInstance for crate::peripherals::$inst {
impl crate::pwm::sealed::CaptureCompare16bitInstance for crate::peripherals::$inst {
unsafe fn set_output_compare_mode(
&mut self,
channel: crate::pwm::Channel,
@ -242,56 +237,72 @@ crate::pac::interrupts! {
}
}
impl CaptureCompareCapable16bitInstance for crate::peripherals::$inst {
impl CaptureCompare16bitInstance for crate::peripherals::$inst {
}
};
}
pin_trait!(Channel1Pin, CaptureCompare16bitInstance);
pin_trait!(Channel1ComplementaryPin, CaptureCompare16bitInstance);
pin_trait!(Channel2Pin, CaptureCompare16bitInstance);
pin_trait!(Channel2ComplementaryPin, CaptureCompare16bitInstance);
pin_trait!(Channel3Pin, CaptureCompare16bitInstance);
pin_trait!(Channel3ComplementaryPin, CaptureCompare16bitInstance);
pin_trait!(Channel4Pin, CaptureCompare16bitInstance);
pin_trait!(Channel4ComplementaryPin, CaptureCompare16bitInstance);
pin_trait!(ExternalTriggerPin, CaptureCompare16bitInstance);
pin_trait!(BreakInputPin, CaptureCompare16bitInstance);
pin_trait!(BreakInputComparator1Pin, CaptureCompare16bitInstance);
pin_trait!(BreakInputComparator2Pin, CaptureCompare16bitInstance);
pin_trait!(BreakInput2Pin, CaptureCompare16bitInstance);
pin_trait!(BreakInput2Comparator1Pin, CaptureCompare16bitInstance);
pin_trait!(BreakInput2Comparator2Pin, CaptureCompare16bitInstance);
crate::pac::peripheral_pins!(
($inst:ident, timer, $block:ident, $pin:ident, CH1, $af:expr) => {
impl_pin!($inst, Channel1Pin, $pin, $af);
pin_trait_impl!(Channel1Pin, $inst, $pin, $af);
};
($inst:ident, timer, $block:ident, $pin:ident, CH1N, $af:expr) => {
impl_pin!($inst, Channel1ComplementaryPin, $pin, $af);
pin_trait_impl!(Channel1ComplementaryPin, $inst, $pin, $af);
};
($inst:ident, timer, $block:ident, $pin:ident, CH2, $af:expr) => {
impl_pin!($inst, Channel2Pin, $pin, $af);
pin_trait_impl!(Channel2Pin, $inst, $pin, $af);
};
($inst:ident, timer, $block:ident, $pin:ident, CH2N, $af:expr) => {
impl_pin!($inst, Channel2ComplementaryPin, $pin, $af);
pin_trait_impl!(Channel2ComplementaryPin, $inst, $pin, $af);
};
($inst:ident, timer, $block:ident, $pin:ident, CH3, $af:expr) => {
impl_pin!($inst, Channel3Pin, $pin, $af);
pin_trait_impl!(Channel3Pin, $inst, $pin, $af);
};
($inst:ident, timer, $block:ident, $pin:ident, CH3N, $af:expr) => {
impl_pin!($inst, Channel3ComplementaryPin, $pin, $af);
pin_trait_impl!(Channel3ComplementaryPin, $inst, $pin, $af);
};
($inst:ident, timer, $block:ident, $pin:ident, CH4, $af:expr) => {
impl_pin!($inst, Channel4Pin, $pin, $af);
pin_trait_impl!(Channel4Pin, $inst, $pin, $af);
};
($inst:ident, timer, $block:ident, $pin:ident, CH4N, $af:expr) => {
impl_pin!($inst, Channel4ComplementaryPin, $pin, $af);
pin_trait_impl!(Channel4ComplementaryPin, $inst, $pin, $af);
};
($inst:ident, timer, $block:ident, $pin:ident, ETR, $af:expr) => {
impl_pin!($inst, ExternalTriggerPin, $pin, $af);
pin_trait_impl!(ExternalTriggerPin, $inst, $pin, $af);
};
($inst:ident, timer, $block:ident, $pin:ident, BKIN, $af:expr) => {
impl_pin!($inst, BreakInputPin, $pin, $af);
pin_trait_impl!(BreakInputPin, $inst, $pin, $af);
};
($inst:ident, timer, $block:ident, $pin:ident, BKIN_COMP1, $af:expr) => {
impl_pin!($inst, BreakInputComparator1Pin, $pin, $af);
pin_trait_impl!(BreakInputComparator1Pin, $inst, $pin, $af);
};
($inst:ident, timer, $block:ident, $pin:ident, BKIN_COMP2, $af:expr) => {
impl_pin!($inst, BreakInputComparator2Pin, $pin, $af);
pin_trait_impl!(BreakInputComparator2Pin, $inst, $pin, $af);
};
($inst:ident, timer, $block:ident, $pin:ident, BKIN2, $af:expr) => {
impl_pin!($inst, BreakInput2Pin, $pin, $af);
pin_trait_impl!(BreakInput2Pin, $inst, $pin, $af);
};
($inst:ident, timer, $block:ident, $pin:ident, BKIN2_COMP1, $af:expr) => {
impl_pin!($inst, BreakInput2Comparator1Pin, $pin, $af);
pin_trait_impl!(BreakInput2Comparator1Pin, $inst, $pin, $af);
};
($inst:ident, timer, $block:ident, $pin:ident, BKIN2_COMP2, $af:expr) => {
impl_pin!($inst, BreakInput2Comparator2Pin, $pin, $af);
pin_trait_impl!(BreakInput2Comparator2Pin, $inst, $pin, $af);
};
);

View File

@ -1,126 +0,0 @@
use crate::gpio::Pin;
#[cfg(feature = "unstable-pac")]
pub mod low_level {
pub use super::sealed::*;
}
pub(crate) mod sealed {
use crate::gpio::sealed::Pin;
pub trait Channel1Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait Channel1ComplementaryPin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait Channel2Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait Channel2ComplementaryPin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait Channel3Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait Channel3ComplementaryPin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait Channel4Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait Channel4ComplementaryPin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait ExternalTriggerPin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait BreakInputPin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait BreakInputComparator1Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait BreakInputComparator2Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait BreakInput2Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait BreakInput2Comparator1Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
pub trait BreakInput2Comparator2Pin<Timer>: Pin {
unsafe fn configure(&mut self);
}
}
pub trait Channel1Pin<Timer>: sealed::Channel1Pin<Timer> + Pin + 'static {}
pub trait Channel1ComplementaryPin<Timer>:
sealed::Channel1ComplementaryPin<Timer> + Pin + 'static
{
}
pub trait Channel2Pin<Timer>: sealed::Channel2Pin<Timer> + 'static {}
pub trait Channel2ComplementaryPin<Timer>:
sealed::Channel2ComplementaryPin<Timer> + Pin + 'static
{
}
pub trait Channel3Pin<Timer>: sealed::Channel3Pin<Timer> + 'static {}
pub trait Channel3ComplementaryPin<Timer>:
sealed::Channel3ComplementaryPin<Timer> + Pin + 'static
{
}
pub trait Channel4Pin<Timer>: sealed::Channel4Pin<Timer> + 'static {}
pub trait Channel4ComplementaryPin<Timer>:
sealed::Channel4ComplementaryPin<Timer> + Pin + 'static
{
}
pub trait ExternalTriggerPin<Timer>: sealed::ExternalTriggerPin<Timer> + Pin + 'static {}
pub trait BreakInputPin<Timer>: sealed::BreakInputPin<Timer> + Pin + 'static {}
pub trait BreakInputComparator1Pin<Timer>:
sealed::BreakInputComparator1Pin<Timer> + Pin + 'static
{
}
pub trait BreakInputComparator2Pin<Timer>:
sealed::BreakInputComparator2Pin<Timer> + Pin + 'static
{
}
pub trait BreakInput2Pin<Timer>: sealed::BreakInput2Pin<Timer> + Pin + 'static {}
pub trait BreakInput2Comparator1Pin<Timer>:
sealed::BreakInput2Comparator1Pin<Timer> + Pin + 'static
{
}
pub trait BreakInput2Comparator2Pin<Timer>:
sealed::BreakInput2Comparator2Pin<Timer> + Pin + 'static
{
}
#[allow(unused)]
macro_rules! impl_pin {
($timer:ident, $signal:ident, $pin:ident, $af:expr) => {
impl crate::pwm::pins::sealed::$signal<crate::peripherals::$timer>
for crate::peripherals::$pin
{
unsafe fn configure(&mut self) {
use crate::gpio::sealed::{AFType, Pin};
use crate::gpio::Speed;
self.set_low();
self.set_speed(Speed::VeryHigh);
self.set_as_af($af, AFType::OutputPushPull);
}
}
impl crate::pwm::pins::$signal<crate::peripherals::$timer> for crate::peripherals::$pin {}
};
}

View File

@ -1,25 +1,40 @@
use crate::{
pwm::{pins::*, CaptureCompareCapable16bitInstance, Channel, OutputCompareMode},
time::Hertz,
};
use core::marker::PhantomData;
use embassy::util::Unborrow;
use embassy_hal_common::unborrow;
use super::*;
#[allow(unused_imports)]
use crate::gpio::sealed::{AFType, Pin};
use crate::time::Hertz;
pub struct SimplePwm<'d, T> {
phantom: PhantomData<&'d mut T>,
inner: T,
}
impl<'d, T: CaptureCompareCapable16bitInstance> SimplePwm<'d, T> {
macro_rules! config_pins {
($($pin:ident),*) => {
unborrow!($($pin),*);
// NOTE(unsafe) Exclusive access to the registers
critical_section::with(|_| unsafe {
$(
$pin.set_low();
$pin.set_as_af($pin.af_num(), AFType::OutputPushPull);
#[cfg(gpio_v2)]
$pin.set_speed(crate::gpio::Speed::VeryHigh);
)*
})
};
}
impl<'d, T: CaptureCompare16bitInstance> SimplePwm<'d, T> {
pub fn new_1ch<F: Into<Hertz>>(
tim: impl Unborrow<Target = T> + 'd,
ch1: impl Unborrow<Target = impl Channel1Pin<T>> + 'd,
freq: F,
) -> Self {
unborrow!(ch1);
Self::new_inner(tim, freq, move || unsafe {
ch1.configure();
Self::new_inner(tim, freq, move || {
config_pins!(ch1);
})
}
@ -29,10 +44,8 @@ impl<'d, T: CaptureCompareCapable16bitInstance> SimplePwm<'d, T> {
ch2: impl Unborrow<Target = impl Channel2Pin<T>> + 'd,
freq: F,
) -> Self {
unborrow!(ch1, ch2);
Self::new_inner(tim, freq, move || unsafe {
ch1.configure();
ch2.configure();
Self::new_inner(tim, freq, move || {
config_pins!(ch1, ch2);
})
}
@ -43,11 +56,8 @@ impl<'d, T: CaptureCompareCapable16bitInstance> SimplePwm<'d, T> {
ch3: impl Unborrow<Target = impl Channel3Pin<T>> + 'd,
freq: F,
) -> Self {
unborrow!(ch1, ch2, ch3);
Self::new_inner(tim, freq, move || unsafe {
ch1.configure();
ch2.configure();
ch3.configure();
Self::new_inner(tim, freq, move || {
config_pins!(ch1, ch2, ch3);
})
}
@ -59,12 +69,8 @@ impl<'d, T: CaptureCompareCapable16bitInstance> SimplePwm<'d, T> {
ch4: impl Unborrow<Target = impl Channel4Pin<T>> + 'd,
freq: F,
) -> Self {
unborrow!(ch1, ch2, ch3, ch4);
Self::new_inner(tim, freq, move || unsafe {
ch1.configure();
ch2.configure();
ch3.configure();
ch4.configure();
Self::new_inner(tim, freq, move || {
config_pins!(ch1, ch2, ch3, ch4);
})
}