Skip to content

Commit 3433e4c

Browse files
committed
WithCapture
1 parent bfba917 commit 3433e4c

File tree

1 file changed

+209
-33
lines changed

1 file changed

+209
-33
lines changed

src/timer.rs

Lines changed: 209 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,21 @@ pub enum Channel {
9090
C4 = 3,
9191
}
9292

93-
/// Enum for IO polarity
93+
/// Compare/PWM polarity
9494
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
9595
pub enum Polarity {
9696
ActiveHigh,
9797
ActiveLow,
9898
}
9999

100+
/// Capture polarity
101+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
102+
pub enum CapturePolarity {
103+
ActiveHigh,
104+
ActiveLow,
105+
ActiveBoth,
106+
}
107+
100108
/// Output Idle state
101109
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
102110
pub enum IdleState {
@@ -272,11 +280,82 @@ pub enum Ocm {
272280
PwmMode2 = 7,
273281
}
274282

283+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
284+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
285+
#[repr(u8)]
286+
/// Capture mode
287+
/// Enum for configuring the mode of the Capture channels (CC1S, CC2S, CC3S, CC4S).
288+
/// Defines how each channel is used in Input Capture mode, considering TI1, TI2, TI3, and TI4.
289+
pub enum CaptureMode {
290+
/// Input Capture on the corresponding channel (e.g., CC1 -> TI1, CC2 -> TI2, etc.).
291+
InputCapture = 1,
292+
/// Input Capture on the inverted channel (e.g., CC1 -> TI2, CC2 -> TI1, CC3 -> TI4, CC4 -> TI3).
293+
InvChannelInputCapture = 2,
294+
}
295+
296+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
297+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
298+
#[repr(u8)]
299+
/// Enum for configuring the Input Capture prescaler.
300+
/// Determines how many input events are required for one capture.
301+
pub enum CapturePrescaler {
302+
/// No prescaler (00): Capture every input event.
303+
No = 0,
304+
/// Prescaler 2 (01): Capture every second input event.
305+
Two = 1,
306+
/// Prescaler 4 (10): Capture every fourth input event.
307+
Four = 2,
308+
/// Prescaler 8 (11): Capture every eighth input event.
309+
Eight = 3,
310+
}
311+
312+
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
313+
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
314+
#[repr(u8)]
315+
/// Enum representing the input capture filter settings.
316+
pub enum CaptureFilter {
317+
/// No filter, sampling frequency = fDTS, N = 1
318+
NoFilter,
319+
/// Sampling frequency = fCK_INT, N = 2
320+
FckIntN2,
321+
/// Sampling frequency = fCK_INT, N = 4
322+
FckIntN4,
323+
/// Sampling frequency = fCK_INT, N = 8
324+
FckIntN8,
325+
/// Sampling frequency = fDTS/2, N = 6
326+
FdtsDiv2N6,
327+
/// Sampling frequency = fDTS/2, N = 8
328+
FdtsDiv2N8,
329+
/// Sampling frequency = fDTS/4, N = 6
330+
FdtsDiv4N6,
331+
/// Sampling frequency = fDTS/4, N = 8
332+
FdtsDiv4N8,
333+
/// Sampling frequency = fDTS/8, N = 6
334+
FdtsDiv8N6,
335+
/// Sampling frequency = fDTS/8, N = 8
336+
FdtsDiv8N8,
337+
/// Sampling frequency = fDTS/16, N = 5
338+
FdtsDiv16N5,
339+
/// Sampling frequency = fDTS/16, N = 6
340+
FdtsDiv16N6,
341+
/// Sampling frequency = fDTS/16, N = 8
342+
FdtsDiv16N8,
343+
/// Sampling frequency = fDTS/32, N = 5
344+
FdtsDiv32N5,
345+
/// Sampling frequency = fDTS/32, N = 6
346+
FdtsDiv32N6,
347+
/// Sampling frequency = fDTS/32, N = 8
348+
FdtsDiv32N8,
349+
}
350+
275351
// Center-aligned mode selection
276352
pub use pac::tim1::cr1::CMS as CenterAlignedMode;
277353

278354
mod sealed {
279-
use super::{CenterAlignedMode, Event, IdleState, Ocm, Polarity, DBG};
355+
use super::{
356+
CaptureFilter, CaptureMode, CapturePolarity, CapturePrescaler, CenterAlignedMode, Event,
357+
IdleState, Ocm, Polarity, DBG,
358+
};
280359
pub trait General {
281360
type Width: Into<u32> + From<u16>;
282361
fn max_auto_reload() -> u32;
@@ -300,37 +379,47 @@ mod sealed {
300379
fn stop_in_debug(&mut self, dbg: &mut DBG, state: bool);
301380
}
302381

303-
pub trait WithPwmCommon: General {
382+
pub trait WithChannel: General {
304383
const CH_NUMBER: u8;
305384
const COMP_CH_NUMBER: u8;
306385
fn read_cc_value(channel: u8) -> u32;
307386
fn set_cc_value(channel: u8, value: u32);
308387
fn enable_channel(channel: u8, b: bool);
309388
fn set_channel_polarity(channel: u8, p: Polarity);
310389
fn set_nchannel_polarity(channel: u8, p: Polarity);
390+
391+
fn set_capture_channel_polarity(channel: u8, p: CapturePolarity);
311392
}
312393

313394
#[allow(unused)]
314-
pub trait Advanced: WithPwmCommon {
395+
pub trait Advanced: WithChannel {
315396
fn enable_nchannel(channel: u8, b: bool);
316397
fn set_dtg_value(value: u8);
317398
fn read_dtg_value() -> u8;
318399
fn idle_state(channel: u8, comp: bool, s: IdleState);
319400
fn set_cms(mode: CenterAlignedMode);
320401
}
321402

322-
pub trait WithPwm: WithPwmCommon {
403+
pub trait WithPwm: WithChannel {
323404
fn preload_output_channel_in_mode(&mut self, c: u8, mode: Ocm);
324405
fn freeze_output_channel(&mut self, c: u8);
325406
fn start_pwm(&mut self);
326407
}
327408

409+
#[allow(unused)]
410+
pub trait WithCapture: WithChannel {
411+
fn preload_capture(&mut self, c: u8, mode: CaptureMode);
412+
fn prescaler_capture(&mut self, c: u8, psc: CapturePrescaler);
413+
fn filter_capture(&mut self, c: u8, filter: CaptureFilter);
414+
fn start_capture(&mut self);
415+
}
416+
328417
pub trait MasterTimer: General {
329418
type Mms;
330419
fn master_mode(&mut self, mode: Self::Mms);
331420
}
332421
}
333-
pub(crate) use sealed::{Advanced, General, MasterTimer, WithPwm, WithPwmCommon};
422+
pub(crate) use sealed::{Advanced, General, MasterTimer, WithCapture, WithChannel, WithPwm};
334423

335424
pub trait Instance:
336425
crate::Sealed + rcc::Enable + rcc::Reset + rcc::BusTimerClock + General
@@ -342,7 +431,7 @@ macro_rules! hal {
342431
$Timer:ident,
343432
$bits:ty,
344433
$dbg_timX_stop:ident,
345-
$(c: ($cnum:tt $(, $aoe:ident)?),)?
434+
$(c: ($cnum:tt, $ncnum:tt $(, $aoe:ident)?),)?
346435
$(m: $timbase:ident,)?
347436
]) => {
348437
impl Instance for $TIM { }
@@ -446,9 +535,9 @@ macro_rules! hal {
446535
}
447536
}
448537
$(
449-
impl WithPwmCommon for $TIM {
538+
impl WithChannel for $TIM {
450539
const CH_NUMBER: u8 = $cnum;
451-
const COMP_CH_NUMBER: u8 = $cnum;
540+
const COMP_CH_NUMBER: u8 = $ncnum;
452541

453542
#[inline(always)]
454543
fn read_cc_value(c: u8) -> u32 {
@@ -491,6 +580,40 @@ macro_rules! hal {
491580
unsafe { bb::write(tim.ccer(), c*4 + 3, p == Polarity::ActiveLow); }
492581
}
493582
}
583+
584+
#[inline(always)]
585+
fn set_capture_channel_polarity(c: u8, p: CapturePolarity) {
586+
let tim = unsafe { &*<$TIM>::ptr() };
587+
if c < Self::CH_NUMBER {
588+
match p {
589+
CapturePolarity::ActiveLow => {
590+
tim.ccer().modify(|r, w| {
591+
if c < Self::COMP_CH_NUMBER {
592+
unsafe { w.bits(r.bits() & !(1 << (c*4 + 3))); }
593+
}
594+
w.ccp(c).set_bit()
595+
});
596+
}
597+
CapturePolarity::ActiveHigh => {
598+
tim.ccer().modify(|r, w| {
599+
if c < Self::COMP_CH_NUMBER {
600+
unsafe { w.bits(r.bits() & !(1 << (c*4 + 3))); }
601+
}
602+
w.ccp(c).clear_bit()
603+
});
604+
}
605+
CapturePolarity::ActiveBoth => {
606+
tim.ccer().modify(|r, w| {
607+
if c < Self::COMP_CH_NUMBER {
608+
unsafe { w.bits(r.bits() | (1 << (c*4 + 3))); }
609+
}
610+
w.ccp(c).set_bit()
611+
});
612+
}
613+
}
614+
615+
}
616+
}
494617
}
495618

496619
$(
@@ -530,7 +653,7 @@ macro_rules! hal {
530653
}
531654
)?
532655

533-
with_pwm!($TIM: $cnum $(, $aoe)?);
656+
with_output!($TIM: $cnum $(, $aoe)?);
534657
)?
535658

536659
$(impl MasterTimer for $TIM {
@@ -542,16 +665,17 @@ macro_rules! hal {
542665
}
543666
}
544667

545-
macro_rules! with_pwm {
546-
($TIM:ty: [$($Cx:literal, $ccmrx_output:ident, $ocxpe:ident, $ocxm:ident;)+] $(, $aoe:ident)?) => {
668+
macro_rules! with_output {
669+
($TIM:ty: [$($Cx:literal, $ccmrx_input:ident, $ccmrx_output:ident, $ccxs:ident, $dc:literal;)+] $(, $aoe:ident)?) => {
547670
impl WithPwm for $TIM {
548671
#[inline(always)]
549672
fn preload_output_channel_in_mode(&mut self, c: u8, mode: Ocm) {
550673
match c {
551674
$(
552675
$Cx => {
676+
let c = c-$dc;
553677
self.$ccmrx_output()
554-
.modify(|_, w| w.$ocxpe().set_bit().$ocxm().set(mode as _) );
678+
.modify(|_, w| w.ocpe(c).set_bit().ocm(c).set(mode as _) );
555679
}
556680
)+
557681
#[allow(unreachable_patterns)]
@@ -562,8 +686,9 @@ macro_rules! with_pwm {
562686
match c {
563687
$(
564688
$Cx => {
689+
let c = c-$dc;
565690
self.$ccmrx_output()
566-
.modify(|_, w| w.$ocxpe().clear_bit().$ocxm().set(Ocm::Frozen as _) );
691+
.modify(|_, w| w.ocpe(c).clear_bit().ocm(c).set(Ocm::Frozen as _) );
567692
}
568693
)+
569694
#[allow(unreachable_patterns)]
@@ -577,24 +702,75 @@ macro_rules! with_pwm {
577702
self.cr1().modify(|_, w| w.cen().set_bit());
578703
}
579704
}
705+
706+
impl WithCapture for $TIM {
707+
#[inline(always)]
708+
fn preload_capture(&mut self, c: u8, mode: CaptureMode) {
709+
match c {
710+
$(
711+
$Cx => {
712+
self.$ccmrx_input()
713+
.modify(|_, w| unsafe { w.$ccxs().bits(mode as _) } );
714+
}
715+
)+
716+
#[allow(unreachable_patterns)]
717+
_ => {},
718+
}
719+
}
720+
721+
#[inline(always)]
722+
fn prescaler_capture(&mut self, c: u8, psc: CapturePrescaler) {
723+
match c {
724+
$(
725+
$Cx => {
726+
let c = c-$dc;
727+
self.$ccmrx_input()
728+
.modify(|_, w| unsafe { w.icpsc(c).bits(psc as _) } );
729+
}
730+
)+
731+
#[allow(unreachable_patterns)]
732+
_ => {},
733+
}
734+
}
735+
736+
fn filter_capture(&mut self, c: u8, filter: CaptureFilter) {
737+
match c {
738+
$(
739+
$Cx => {
740+
let c = c-$dc;
741+
self.$ccmrx_input()
742+
.modify(|_, w| unsafe { w.icf(c).bits(filter as _) } );
743+
}
744+
)+
745+
#[allow(unreachable_patterns)]
746+
_ => {},
747+
}
748+
}
749+
750+
751+
#[inline(always)]
752+
fn start_capture(&mut self) {
753+
self.cr1().modify(|_, w| w.cen().set_bit());
754+
}
755+
}
580756
};
581757
($TIM:ty: 1) => {
582-
with_pwm!($TIM: [
583-
0, ccmr1_output, oc1pe, oc1m;
758+
with_output!($TIM: [
759+
0, ccmr1_input, ccmr1_output, cc1s, 0;
584760
]);
585761
};
586762
($TIM:ty: 2) => {
587-
with_pwm!($TIM: [
588-
0, ccmr1_output, oc1pe, oc1m;
589-
1, ccmr1_output, oc2pe, oc2m;
763+
with_output!($TIM: [
764+
0, ccmr1_input, ccmr1_output, cc1s, 0;
765+
1, ccmr1_input, ccmr1_output, cc2s, 0;
590766
]);
591767
};
592768
($TIM:ty: 4 $(, $aoe:ident)?) => {
593-
with_pwm!($TIM: [
594-
0, ccmr1_output, oc1pe, oc1m;
595-
1, ccmr1_output, oc2pe, oc2m;
596-
2, ccmr2_output, oc3pe, oc3m;
597-
3, ccmr2_output, oc4pe, oc4m;
769+
with_output!($TIM: [
770+
0, ccmr1_input, ccmr1_output, cc1s, 0;
771+
1, ccmr1_input, ccmr1_output, cc2s, 0;
772+
2, ccmr2_input, ccmr2_output, cc3s, 2;
773+
3, ccmr2_input, ccmr2_output, cc4s, 2;
598774
] $(, $aoe)?);
599775
};
600776
}
@@ -757,16 +933,16 @@ const fn compute_arr_presc(freq: u32, clock: u32) -> (u16, u32) {
757933
}
758934

759935
#[cfg(any(feature = "stm32f100", feature = "stm32f103", feature = "connectivity"))]
760-
hal!(pac::TIM1: [Timer1, u16, dbg_tim1_stop, c: (4, _aoe), m: tim1,]);
936+
hal!(pac::TIM1: [Timer1, u16, dbg_tim1_stop, c: (4, 4, _aoe), m: tim1,]);
761937

762-
hal!(pac::TIM2: [Timer2, u16, dbg_tim2_stop, c: (4), m: tim2,]);
763-
hal!(pac::TIM3: [Timer3, u16, dbg_tim3_stop, c: (4), m: tim2,]);
938+
hal!(pac::TIM2: [Timer2, u16, dbg_tim2_stop, c: (4, 0), m: tim2,]);
939+
hal!(pac::TIM3: [Timer3, u16, dbg_tim3_stop, c: (4, 0), m: tim2,]);
764940

765941
#[cfg(feature = "medium")]
766-
hal!(pac::TIM4: [Timer4, u16, dbg_tim4_stop, c: (4), m: tim2,]);
942+
hal!(pac::TIM4: [Timer4, u16, dbg_tim4_stop, c: (4, 0), m: tim2,]);
767943

768944
#[cfg(any(feature = "high", feature = "connectivity"))]
769-
hal!(pac::TIM5: [Timer5, u16, dbg_tim5_stop, c: (4), m: tim2,]);
945+
hal!(pac::TIM5: [Timer5, u16, dbg_tim5_stop, c: (4, 0), m: tim2,]);
770946

771947
#[cfg(any(feature = "stm32f100", feature = "high", feature = "connectivity"))]
772948
hal!(pac::TIM6: [Timer6, u16, dbg_tim6_stop, m: tim6,]);
@@ -778,14 +954,14 @@ hal!(pac::TIM6: [Timer6, u16, dbg_tim6_stop, m: tim6,]);
778954
hal!(pac::TIM7: [Timer7, u16, dbg_tim7_stop, m: tim6,]);
779955

780956
#[cfg(all(feature = "stm32f103", feature = "high"))]
781-
hal!(pac::TIM8: [Timer8, u16, dbg_tim8_stop, c: (4, _aoe), m: tim1,]);
957+
hal!(pac::TIM8: [Timer8, u16, dbg_tim8_stop, c: (4, 4, _aoe), m: tim1,]);
782958

783959
#[cfg(feature = "stm32f100")]
784-
hal!(pac::TIM15: [Timer15, u16, dbg_tim15_stop, c: (2),]);
960+
hal!(pac::TIM15: [Timer15, u16, dbg_tim15_stop, c: (2, 2),]);
785961
#[cfg(feature = "stm32f100")]
786-
hal!(pac::TIM16: [Timer16, u16, dbg_tim16_stop, c: (1),]);
962+
hal!(pac::TIM16: [Timer16, u16, dbg_tim16_stop, c: (1, 1),]);
787963
#[cfg(feature = "stm32f100")]
788-
hal!(pac::TIM17: [Timer17, u16, dbg_tim17_stop, c: (1),]);
964+
hal!(pac::TIM17: [Timer17, u16, dbg_tim17_stop, c: (1, 1),]);
789965

790966
//TODO: restore these timers once stm32-rs has been updated
791967
/*

0 commit comments

Comments
 (0)