1
+ use core:: marker:: PhantomData ;
2
+
3
+ use stm32g4:: stm32g474:: {
4
+ HRTIM_TIMA ,
5
+ HRTIM_TIMB ,
6
+ HRTIM_TIMC ,
7
+ HRTIM_TIMD ,
8
+ HRTIM_TIME ,
9
+ HRTIM_TIMF ,
10
+ } ;
11
+
12
+
13
+ pub struct Ch1 ;
14
+ pub struct Ch2 ;
15
+
16
+ pub struct HrCapt < TIM , PSCL , CH > {
17
+ _x : PhantomData < ( TIM , PSCL , CH ) >
18
+ }
19
+
20
+ pub enum CountingDirection {
21
+ Up = 0 ,
22
+ Down = 1 ,
23
+ }
24
+
25
+ pub trait CaptureEvent < TIM , PSCL > {
26
+ const BITS : u32 ;
27
+ }
28
+
29
+ trait HrCapture {
30
+ fn get ( & self ) -> ( u16 , CountingDirection ) ;
31
+
32
+ /// Get number of ticks relative to beginning of upcounting
33
+ ///
34
+ /// where captures during down counting count as negative (before the upcount)
35
+ fn get_signed ( & self ) -> i32 {
36
+ let ( value, dir) = self . get ( ) ;
37
+ let dir_bit = dir as i32 ;
38
+ dir_bit << 31 | i32:: from ( value)
39
+ }
40
+
41
+ /// Get number of ticks relative to beginning of upcounting
42
+ ///
43
+ /// where captures during down counting count as larger (after upcount)
44
+ fn get_unsigned ( & self ) -> u32 {
45
+ let ( value, dir) = self . get ( ) ;
46
+ let dir_bit = dir as u32 ;
47
+ dir_bit << 16 | u32:: from ( value)
48
+ }
49
+ }
50
+
51
+ macro_rules! impl_capture {
52
+ ( $( $TIMX: ident, $CH: ident, $cptXYr: ident, $cptXYcr: ident, $cptXx: ident) ,+) => {
53
+ $( impl <PSCL > HrCapt <$TIMX, PSCL , $CH> {
54
+ /// Add event to capture
55
+ ///
56
+ /// If multiple events are added, they will be ORed together meaning
57
+ /// that a capture will be trigger if any one of the events triggers
58
+ pub fn add_event<E : CaptureEvent <$TIMX, PSCL >>( & mut self , _event: & E ) {
59
+ let tim = unsafe { & * $TIMX:: ptr( ) } ;
60
+
61
+ // SAFETY: We are the only one with access to cptXYcr
62
+ unsafe {
63
+ tim. $cptXYcr. modify( |r, w| w. bits( r. bits( ) | E :: BITS ) ) ;
64
+ }
65
+ }
66
+
67
+ /// Remove event to capture
68
+ pub fn remove_event<E : CaptureEvent <$TIMX, PSCL >>( & mut self , _event: & E ) {
69
+ let tim = unsafe { & * $TIMX:: ptr( ) } ;
70
+
71
+ // SAFETY: We are the only one with access to cptXYcr
72
+ unsafe {
73
+ tim. $cptXYcr. modify( |r, w| w. bits( r. bits( ) & !E :: BITS ) ) ;
74
+ }
75
+ }
76
+
77
+ /// Force capture trigger now
78
+ pub fn trigger_now( & mut self ) {
79
+ // SAFETY: We are the only one with access to cptXYcr
80
+ let tim = unsafe { & * $TIMX:: ptr( ) } ;
81
+
82
+ tim. $cptXYcr. modify( |_, w| w. swcpt( ) . set_bit( ) ) ;
83
+ }
84
+ }
85
+
86
+ impl <PSCL > HrCapture for HrCapt <$TIMX, PSCL , $CH> {
87
+ fn get( & self ) -> ( u16 , CountingDirection ) {
88
+ let tim = unsafe { & * $TIMX:: ptr( ) } ;
89
+ let data = tim. $cptXYr. read( ) ;
90
+ let dir = match data. dir( ) . bit( ) {
91
+ true => CountingDirection :: Down ,
92
+ false => CountingDirection :: Up ,
93
+ } ;
94
+ let value = data. $cptXx( ) . bits( ) ;
95
+
96
+ ( value, dir)
97
+ }
98
+ } ) +
99
+ } ;
100
+ }
101
+
102
+ impl_capture ! (
103
+ HRTIM_TIMA , Ch1 , cpt1ar, cpt1acr, cpt1x,
104
+ HRTIM_TIMA , Ch2 , cpt2ar, cpt2acr, cpt2x,
105
+
106
+ HRTIM_TIMB , Ch1 , cpt1br, cpt1bcr, cpt1x,
107
+ HRTIM_TIMB , Ch2 , cpt2br, cpt2bcr, cpt2x,
108
+
109
+ HRTIM_TIMC , Ch1 , cpt1cr, cpt1ccr, cpt1x,
110
+ HRTIM_TIMC , Ch2 , cpt2cr, cpt2ccr, cpt2x,
111
+
112
+ HRTIM_TIMD , Ch1 , cpt1dr, cpt1dcr, cpt1x,
113
+ HRTIM_TIMD , Ch2 , cpt2dr, cpt2dcr, cpt2x,
114
+
115
+ HRTIM_TIME , Ch1 , cpt1er, cpt1ecr, cpt1x,
116
+ HRTIM_TIME , Ch2 , cpt2er, cpt2ecr, cpt2x,
117
+
118
+ HRTIM_TIMF , Ch1 , cpt1fr, cpt1fcr, cpt1x,
119
+ HRTIM_TIMF , Ch2 , cpt2fr, cpt2fcr, cpt2x
120
+ ) ;
0 commit comments