mirror of
https://github.com/embassy-rs/embassy.git
synced 2025-09-27 04:10:25 +00:00
stm32: generify timer::one_pulse and timer::qei pin constructors
This commit is contained in:
parent
3e78f8a108
commit
1623d4e639
@ -7,7 +7,7 @@ use core::pin::Pin;
|
||||
use core::task::{Context, Poll};
|
||||
|
||||
use super::low_level::{
|
||||
CountingMode, FilterValue, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource,
|
||||
CountingMode, FilterValue, InputCaptureMode, InputTISelection, SlaveMode, Timer, TriggerSource as Ts,
|
||||
};
|
||||
use super::{CaptureCompareInterruptHandler, ExternalTriggerPin, GeneralInstance4Channel, TimerChannel, TimerPin};
|
||||
pub use super::{Ch1, Ch2};
|
||||
@ -46,33 +46,71 @@ pub struct TriggerPin<'d, T, C> {
|
||||
phantom: PhantomData<(T, C)>,
|
||||
}
|
||||
|
||||
// TODO: Generify trigger inputs
|
||||
trait SealedTriggerSource {}
|
||||
|
||||
impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, Ch1> {
|
||||
/// Marker trait for a trigger source.
|
||||
#[expect(private_bounds)]
|
||||
pub trait TriggerSource: SealedTriggerSource {}
|
||||
|
||||
impl TriggerSource for Ch1 {}
|
||||
impl TriggerSource for Ch2 {}
|
||||
impl TriggerSource for Ext {}
|
||||
|
||||
impl SealedTriggerSource for Ch1 {}
|
||||
impl SealedTriggerSource for Ch2 {}
|
||||
impl SealedTriggerSource for Ext {}
|
||||
|
||||
trait SealedTimerTriggerPin<T, S>: crate::gpio::Pin {}
|
||||
|
||||
/// Marker trait for a trigger pin.
|
||||
#[expect(private_bounds)]
|
||||
// TODO: find better naming scheme than prefixing all pin traits with "Timer".
|
||||
// The trait name cannot conflict with the corresponding type's name.
|
||||
// Applies to other timer submodules as well.
|
||||
pub trait TimerTriggerPin<T, S>: SealedTimerTriggerPin<T, S> {
|
||||
/// Get the AF number needed to use this pin as a trigger source.
|
||||
fn af_num(&self) -> u8;
|
||||
}
|
||||
|
||||
impl<T, P, C> TimerTriggerPin<T, C> for P
|
||||
where
|
||||
T: GeneralInstance4Channel,
|
||||
P: TimerPin<T, C>,
|
||||
C: super::Channel + TriggerSource,
|
||||
{
|
||||
fn af_num(&self) -> u8 {
|
||||
TimerPin::af_num(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, P> TimerTriggerPin<T, Ext> for P
|
||||
where
|
||||
T: GeneralInstance4Channel,
|
||||
P: ExternalTriggerPin<T>,
|
||||
{
|
||||
fn af_num(&self) -> u8 {
|
||||
ExternalTriggerPin::af_num(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, P, C> SealedTimerTriggerPin<T, C> for P
|
||||
where
|
||||
T: GeneralInstance4Channel,
|
||||
P: TimerPin<T, C>,
|
||||
C: super::Channel + TriggerSource,
|
||||
{
|
||||
}
|
||||
|
||||
impl<T, P> SealedTimerTriggerPin<T, Ext> for P
|
||||
where
|
||||
T: GeneralInstance4Channel,
|
||||
P: ExternalTriggerPin<T>,
|
||||
{
|
||||
}
|
||||
|
||||
impl<'d, T: GeneralInstance4Channel, C: TriggerSource> TriggerPin<'d, T, C> {
|
||||
/// "Create a new Ch1 trigger pin instance.
|
||||
pub fn new_ch1(pin: Peri<'d, impl TimerPin<T, Ch1>>, pull: Pull) -> Self {
|
||||
pin.set_as_af(pin.af_num(), AfType::input(pull));
|
||||
TriggerPin {
|
||||
_pin: pin.into(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, Ch2> {
|
||||
/// "Create a new Ch2 trigger pin instance.
|
||||
pub fn new_ch2(pin: Peri<'d, impl TimerPin<T, Ch2>>, pull: Pull) -> Self {
|
||||
pin.set_as_af(pin.af_num(), AfType::input(pull));
|
||||
TriggerPin {
|
||||
_pin: pin.into(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'d, T: GeneralInstance4Channel> TriggerPin<'d, T, Ext> {
|
||||
/// "Create a new EXT trigger pin instance.
|
||||
pub fn new_ext(pin: Peri<'d, impl ExternalTriggerPin<T>>, pull: Pull) -> Self {
|
||||
pub fn new(pin: Peri<'d, impl TimerTriggerPin<T, C>>, pull: Pull) -> Self {
|
||||
pin.set_as_af(pin.af_num(), AfType::input(pull));
|
||||
TriggerPin {
|
||||
_pin: pin.into(),
|
||||
@ -103,7 +141,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> {
|
||||
) -> Self {
|
||||
let mut this = Self { inner: Timer::new(tim) };
|
||||
|
||||
this.inner.set_trigger_source(TriggerSource::TI1F_ED);
|
||||
this.inner.set_trigger_source(Ts::TI1F_ED);
|
||||
this.inner
|
||||
.set_input_ti_selection(TimerChannel::Ch1, InputTISelection::Normal);
|
||||
this.inner
|
||||
@ -128,7 +166,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> {
|
||||
) -> Self {
|
||||
let mut this = Self { inner: Timer::new(tim) };
|
||||
|
||||
this.inner.set_trigger_source(TriggerSource::TI1FP1);
|
||||
this.inner.set_trigger_source(Ts::TI1FP1);
|
||||
this.inner
|
||||
.set_input_ti_selection(TimerChannel::Ch1, InputTISelection::Normal);
|
||||
this.inner
|
||||
@ -154,7 +192,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> {
|
||||
) -> Self {
|
||||
let mut this = Self { inner: Timer::new(tim) };
|
||||
|
||||
this.inner.set_trigger_source(TriggerSource::TI2FP2);
|
||||
this.inner.set_trigger_source(Ts::TI2FP2);
|
||||
this.inner
|
||||
.set_input_ti_selection(TimerChannel::Ch2, InputTISelection::Normal);
|
||||
this.inner
|
||||
@ -186,7 +224,7 @@ impl<'d, T: GeneralInstance4Channel> OnePulse<'d, T> {
|
||||
// No filtering
|
||||
r.set_etf(FilterValue::NO_FILTER);
|
||||
});
|
||||
this.inner.set_trigger_source(TriggerSource::ETRF);
|
||||
this.inner.set_trigger_source(Ts::ETRF);
|
||||
this.new_inner(freq, pulse_end, counting_mode);
|
||||
|
||||
this
|
||||
|
@ -8,6 +8,7 @@ use super::low_level::Timer;
|
||||
pub use super::{Ch1, Ch2};
|
||||
use super::{GeneralInstance4Channel, TimerPin};
|
||||
use crate::gpio::{AfType, AnyPin, Pull};
|
||||
use crate::timer::Channel;
|
||||
use crate::Peri;
|
||||
|
||||
/// Counting direction
|
||||
@ -24,28 +25,31 @@ pub struct QeiPin<'d, T, Channel> {
|
||||
phantom: PhantomData<(T, Channel)>,
|
||||
}
|
||||
|
||||
// TODO: generify QEI channels
|
||||
|
||||
macro_rules! channel_impl {
|
||||
($new_chx:ident, $channel:ident, $pin_trait:ident) => {
|
||||
impl<'d, T: GeneralInstance4Channel> QeiPin<'d, T, $channel> {
|
||||
#[doc = concat!("Create a new ", stringify!($channel), " QEI pin instance.")]
|
||||
pub fn $new_chx(pin: Peri<'d, impl $pin_trait<T, $channel>>) -> Self {
|
||||
critical_section::with(|_| {
|
||||
pin.set_low();
|
||||
pin.set_as_af(pin.af_num(), AfType::input(Pull::None));
|
||||
});
|
||||
QeiPin {
|
||||
_pin: pin.into(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
impl<'d, T: GeneralInstance4Channel, C: QeiChannel> QeiPin<'d, T, C> {
|
||||
/// Create a new QEI pin instance.
|
||||
pub fn new(pin: Peri<'d, impl TimerPin<T, C>>) -> Self {
|
||||
critical_section::with(|_| {
|
||||
pin.set_low();
|
||||
pin.set_as_af(pin.af_num(), AfType::input(Pull::None));
|
||||
});
|
||||
QeiPin {
|
||||
_pin: pin.into(),
|
||||
phantom: PhantomData,
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
channel_impl!(new_ch1, Ch1, TimerPin);
|
||||
channel_impl!(new_ch2, Ch2, TimerPin);
|
||||
trait SealedQeiChannel: Channel {}
|
||||
|
||||
/// Marker trait for a timer channel eligible for use with QEI.
|
||||
#[expect(private_bounds)]
|
||||
pub trait QeiChannel: SealedQeiChannel {}
|
||||
|
||||
impl QeiChannel for Ch1 {}
|
||||
impl QeiChannel for Ch2 {}
|
||||
|
||||
impl SealedQeiChannel for Ch1 {}
|
||||
impl SealedQeiChannel for Ch2 {}
|
||||
|
||||
/// Quadrature decoder driver.
|
||||
pub struct Qei<'d, T: GeneralInstance4Channel> {
|
||||
|
Loading…
x
Reference in New Issue
Block a user