@@ -8,45 +8,72 @@ use crate::timer::*;
8
8
use core:: marker:: PhantomData ;
9
9
10
10
pub trait OpmExt : Sized {
11
- fn opm < PIN > ( self , _: PIN , pulse_width : MicroSecond , rcc : & mut Rcc ) -> Opm < Self , PIN :: Channel >
12
- where
13
- PIN : TimerPin < Self > ;
11
+ fn opm ( self , period : MicroSecond , rcc : & mut Rcc ) -> Opm < Self > ;
14
12
}
15
13
16
- pub struct Opm < TIM , CHANNEL > {
17
- rb : TIM ,
14
+ pub struct OpmPin < TIM , CH > {
15
+ tim : PhantomData < TIM > ,
16
+ channel : PhantomData < CH > ,
18
17
clk : Hertz ,
19
- pulse_width : MicroSecond ,
20
18
delay : MicroSecond ,
21
- _channel : PhantomData < CHANNEL > ,
19
+ }
20
+
21
+ pub struct Opm < TIM > {
22
+ tim : PhantomData < TIM > ,
23
+ clk : Hertz ,
24
+ }
25
+
26
+ impl < TIM > Opm < TIM > {
27
+ pub fn bind_pin < PIN > ( & self , pin : PIN ) -> OpmPin < TIM , PIN :: Channel >
28
+ where
29
+ PIN : TimerPin < TIM > ,
30
+ {
31
+ pin. setup ( ) ;
32
+ OpmPin {
33
+ tim : PhantomData ,
34
+ channel : PhantomData ,
35
+ clk : self . clk ,
36
+ delay : 0 . ms ( ) ,
37
+ }
38
+ }
22
39
}
23
40
24
41
macro_rules! opm {
25
- ( $( $TIMX: ident: ( $apbXenr: ident, $apbXrstr: ident, $timX: ident, $timXen: ident, $timXrst: ident) , ) +) => {
42
+ ( $( $TIMX: ident: ( $apbXenr: ident, $apbXrstr: ident, $timX: ident, $timXen: ident, $timXrst: ident, $arr : ident $ ( , $arr_h : ident ) * ) , ) +) => {
26
43
$(
27
44
impl OpmExt for $TIMX {
28
- fn opm<PIN >( self , pin: PIN , pulse_width: MicroSecond , rcc: & mut Rcc ) -> Opm <Self , PIN :: Channel >
29
- where
30
- PIN : TimerPin <Self >
31
- {
32
- $timX( self , pin, pulse_width, rcc)
45
+ fn opm( self , period: MicroSecond , rcc: & mut Rcc ) -> Opm <Self > {
46
+ $timX( self , period, rcc)
33
47
}
34
48
}
35
49
36
- fn $timX<PIN >( tim: $TIMX, pin: PIN , pulse_width: MicroSecond , rcc: & mut Rcc ) -> Opm <$TIMX, PIN :: Channel >
37
- where
38
- PIN : TimerPin <$TIMX>,
39
- {
50
+ fn $timX( tim: $TIMX, period: MicroSecond , rcc: & mut Rcc ) -> Opm <$TIMX> {
40
51
rcc. rb. $apbXenr. modify( |_, w| w. $timXen( ) . set_bit( ) ) ;
41
52
rcc. rb. $apbXrstr. modify( |_, w| w. $timXrst( ) . set_bit( ) ) ;
42
53
rcc. rb. $apbXrstr. modify( |_, w| w. $timXrst( ) . clear_bit( ) ) ;
43
- pin. setup( ) ;
54
+
55
+ let cycles_per_period = rcc. clocks. apb_tim_clk / period. into( ) ;
56
+ let psc = ( cycles_per_period - 1 ) / 0xffff ;
57
+ tim. psc. write( |w| unsafe { w. psc( ) . bits( psc as u16 ) } ) ;
58
+
59
+ let freq = ( rcc. clocks. apb_tim_clk. 0 / ( psc + 1 ) ) . hz( ) ;
60
+ let reload = period. cycles( freq) ;
61
+ unsafe {
62
+ tim. arr. write( |w| w. $arr( ) . bits( reload as u16 ) ) ;
63
+ $(
64
+ tim. arr. modify( |_, w| w. $arr_h( ) . bits( ( reload >> 16 ) as u16 ) ) ;
65
+ ) *
66
+ }
44
67
Opm {
45
- rb: tim,
46
- clk: rcc. clocks. apb_tim_clk,
47
- pulse_width,
48
- delay: 0 . us( ) ,
49
- _channel: PhantomData ,
68
+ clk: freq,
69
+ tim: PhantomData ,
70
+ }
71
+ }
72
+
73
+ impl Opm <$TIMX> {
74
+ pub fn generate( & mut self ) {
75
+ let tim = unsafe { & * $TIMX:: ptr( ) } ;
76
+ tim. cr1. write( |w| w. opm( ) . set_bit( ) . cen( ) . set_bit( ) ) ;
50
77
}
51
78
}
52
79
) +
@@ -55,60 +82,39 @@ macro_rules! opm {
55
82
56
83
macro_rules! opm_hal {
57
84
( $( $TIMX: ident:
58
- ( $CH: ty, $ccxe: ident, $ccmrx_output: ident, $ocxm: ident, $ocxfe: ident, $ccrx: ident, $arr : ident $ ( , $arr_h : ident ) * ) , ) +
85
+ ( $CH: ty, $ccxe: ident, $ccmrx_output: ident, $ocxm: ident, $ocxfe: ident, $ccrx: ident) , ) +
59
86
) => {
60
87
$(
61
- impl Opm <$TIMX, $CH> {
62
- pub fn enable ( & mut self ) {
63
- self . rb. ccer. modify( |_, w| w. $ccxe( ) . set_bit( ) ) ;
88
+ impl OpmPin <$TIMX, $CH> {
89
+ pub fn enable( & mut self ) {
90
+ let tim = unsafe { & * $TIMX:: ptr( ) } ;
91
+ tim. ccer. modify( |_, w| w. $ccxe( ) . set_bit( ) ) ;
64
92
self . setup( ) ;
65
93
}
66
94
67
- pub fn disable ( & mut self ) {
68
- self . rb. ccer. modify( |_, w| w. $ccxe( ) . clear_bit( ) ) ;
95
+ pub fn disable( & mut self ) {
96
+ let tim = unsafe { & * $TIMX:: ptr( ) } ;
97
+ tim. ccer. modify( |_, w| w. $ccxe( ) . clear_bit( ) ) ;
69
98
}
70
99
71
- pub fn generate( & mut self ) {
72
- self . rb. cr1. write( |w| w. opm( ) . set_bit( ) . cen( ) . set_bit( ) ) ;
73
- }
74
-
75
- pub fn set_pulse_width<T > ( & mut self , pulse_width: T )
76
- where
77
- T : Into <MicroSecond >
78
- {
79
- self . pulse_width = pulse_width. into( ) ;
80
- self . setup( ) ;
81
- }
82
-
83
- pub fn set_delay<T > ( & mut self , delay: T )
100
+ pub fn set_delay<T >( & mut self , delay: T )
84
101
where
85
102
T : Into <MicroSecond >
86
103
{
87
104
self . delay = delay. into( ) ;
88
105
self . setup( ) ;
89
106
}
90
107
91
- fn setup ( & mut self ) {
92
- let period = self . pulse_width + self . delay;
93
-
94
- let cycles_per_period = self . clk / period. into( ) ;
95
- let psc = ( cycles_per_period - 1 ) / 0xffff ;
96
-
97
- self . rb. psc. write( |w| unsafe { w. psc( ) . bits( psc as u16 ) } ) ;
98
- let freq = ( self . clk. 0 / ( psc + 1 ) ) . hz( ) ;
99
- let reload = cycles_per_period / ( psc + 1 ) ;
108
+ fn setup( & mut self ) {
109
+ let tim = unsafe { & * $TIMX:: ptr( ) } ;
100
110
let compare = if self . delay. 0 > 0 {
101
- self . delay. cycles( freq )
111
+ self . delay. cycles( self . clk )
102
112
} else {
103
113
1
104
114
} ;
105
115
unsafe {
106
- self . rb. arr. write( |w| w. $arr( ) . bits( reload as u16 ) ) ;
107
- self . rb. $ccrx. write( |w| w. bits( compare) ) ;
108
- $(
109
- self . rb. arr. modify( |_, w| w. $arr_h( ) . bits( ( reload >> 16 ) as u16 ) ) ;
110
- ) *
111
- self . rb. $ccmrx_output( ) . modify( |_, w| w. $ocxm( ) . bits( 7 ) . $ocxfe( ) . set_bit( ) ) ;
116
+ tim. $ccrx. write( |w| w. bits( compare) ) ;
117
+ tim. $ccmrx_output( ) . modify( |_, w| w. $ocxm( ) . bits( 7 ) . $ocxfe( ) . set_bit( ) ) ;
112
118
}
113
119
}
114
120
}
@@ -117,41 +123,41 @@ macro_rules! opm_hal {
117
123
}
118
124
119
125
opm_hal ! {
120
- TIM1 : ( Channel1 , cc1e, ccmr1_output, oc1m, oc1fe, ccr1, arr ) ,
121
- TIM1 : ( Channel2 , cc2e, ccmr1_output, oc2m, oc2fe, ccr2, arr ) ,
122
- TIM1 : ( Channel3 , cc3e, ccmr2_output, oc3m, oc3fe, ccr3, arr ) ,
123
- TIM1 : ( Channel4 , cc4e, ccmr2_output, oc4m, oc4fe, ccr4, arr ) ,
124
- TIM3 : ( Channel1 , cc1e, ccmr1_output, oc1m, oc1fe, ccr1, arr_l , arr_h ) ,
125
- TIM3 : ( Channel2 , cc2e, ccmr1_output, oc2m, oc2fe, ccr2, arr_l , arr_h ) ,
126
- TIM3 : ( Channel3 , cc3e, ccmr2_output, oc3m, oc3fe, ccr3, arr_l , arr_h ) ,
127
- TIM3 : ( Channel4 , cc4e, ccmr2_output, oc4m, oc4fe, ccr4, arr_l , arr_h ) ,
128
- TIM14 : ( Channel1 , cc1e, ccmr1_output, oc1m, oc1fe, ccr1, arr ) ,
129
- TIM16 : ( Channel1 , cc1e, ccmr1_output, oc1m, oc1fe, ccr1, arr ) ,
130
- TIM17 : ( Channel1 , cc1e, ccmr1_output, oc1m, oc1fe, ccr1, arr ) ,
126
+ TIM1 : ( Channel1 , cc1e, ccmr1_output, oc1m, oc1fe, ccr1) ,
127
+ TIM1 : ( Channel2 , cc2e, ccmr1_output, oc2m, oc2fe, ccr2) ,
128
+ TIM1 : ( Channel3 , cc3e, ccmr2_output, oc3m, oc3fe, ccr3) ,
129
+ TIM1 : ( Channel4 , cc4e, ccmr2_output, oc4m, oc4fe, ccr4) ,
130
+ TIM3 : ( Channel1 , cc1e, ccmr1_output, oc1m, oc1fe, ccr1) ,
131
+ TIM3 : ( Channel2 , cc2e, ccmr1_output, oc2m, oc2fe, ccr2) ,
132
+ TIM3 : ( Channel3 , cc3e, ccmr2_output, oc3m, oc3fe, ccr3) ,
133
+ TIM3 : ( Channel4 , cc4e, ccmr2_output, oc4m, oc4fe, ccr4) ,
134
+ TIM14 : ( Channel1 , cc1e, ccmr1_output, oc1m, oc1fe, ccr1) ,
135
+ TIM16 : ( Channel1 , cc1e, ccmr1_output, oc1m, oc1fe, ccr1) ,
136
+ TIM17 : ( Channel1 , cc1e, ccmr1_output, oc1m, oc1fe, ccr1) ,
131
137
}
132
138
133
139
#[ cfg( feature = "stm32g0x1" ) ]
134
140
opm_hal ! {
135
- TIM2 : ( Channel1 , cc1e, ccmr1_output, oc1m, oc1fe, ccr1, arr_l , arr_h ) ,
136
- TIM2 : ( Channel2 , cc2e, ccmr1_output, oc2m, oc2fe, ccr2, arr_l , arr_h ) ,
137
- TIM2 : ( Channel3 , cc3e, ccmr2_output, oc3m, oc3fe, ccr3, arr_l , arr_h ) ,
138
- TIM2 : ( Channel4 , cc4e, ccmr2_output, oc4m, oc4fe, ccr4, arr_l , arr_h ) ,
141
+ TIM2 : ( Channel1 , cc1e, ccmr1_output, oc1m, oc1fe, ccr1) ,
142
+ TIM2 : ( Channel2 , cc2e, ccmr1_output, oc2m, oc2fe, ccr2) ,
143
+ TIM2 : ( Channel3 , cc3e, ccmr2_output, oc3m, oc3fe, ccr3) ,
144
+ TIM2 : ( Channel4 , cc4e, ccmr2_output, oc4m, oc4fe, ccr4) ,
139
145
}
140
146
141
147
opm ! {
142
- TIM1 : ( apbenr2, apbrstr2, tim1, tim1en, tim1rst) ,
143
- TIM3 : ( apbenr1, apbrstr1, tim3, tim3en, tim3rst) ,
144
- TIM14 : ( apbenr2, apbrstr2, tim14, tim14en, tim14rst) ,
145
- TIM16 : ( apbenr2, apbrstr2, tim16, tim16en, tim16rst) ,
146
- TIM17 : ( apbenr2, apbrstr2, tim17, tim17en, tim17rst) ,
148
+ TIM1 : ( apbenr2, apbrstr2, tim1, tim1en, tim1rst, arr ) ,
149
+ TIM3 : ( apbenr1, apbrstr1, tim3, tim3en, tim3rst, arr_l , arr_h ) ,
150
+ TIM14 : ( apbenr2, apbrstr2, tim14, tim14en, tim14rst, arr ) ,
151
+ TIM16 : ( apbenr2, apbrstr2, tim16, tim16en, tim16rst, arr ) ,
152
+ TIM17 : ( apbenr2, apbrstr2, tim17, tim17en, tim17rst, arr ) ,
147
153
}
148
154
149
155
#[ cfg( feature = "stm32g0x1" ) ]
150
156
opm ! {
151
- TIM2 : ( apbenr1, apbrstr1, tim2, tim2en, tim2rst) ,
157
+ TIM2 : ( apbenr1, apbrstr1, tim2, tim2en, tim2rst, arr_l , arr_h ) ,
152
158
}
153
159
154
160
#[ cfg( any( feature = "stm32g070" , feature = "stm32g071" , feature = "stm32g081" ) ) ]
155
161
opm ! {
156
- TIM15 : ( apbenr2, apbrstr2, tim15, tim15en, tim15rst) ,
162
+ TIM15 : ( apbenr2, apbrstr2, tim15, tim15en, tim15rst, arr ) ,
157
163
}
0 commit comments