@@ -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 ) ]
9595pub 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 ) ]
102110pub 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
276352pub use pac:: tim1:: cr1:: CMS as CenterAlignedMode ;
277353
278354mod 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
335424pub 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" ) ) ]
772948hal ! ( pac:: TIM6 : [ Timer6 , u16 , dbg_tim6_stop, m: tim6, ] ) ;
@@ -778,14 +954,14 @@ hal!(pac::TIM6: [Timer6, u16, dbg_tim6_stop, m: tim6,]);
778954hal ! ( 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