3
3
//! You can use the `PWM` with these [Pwm] instances
4
4
//!
5
5
//! # PWM0 - 8 bit period and duty
6
- //! - Channel 1: Pin 9 IOF1
7
- //! - Channel 2: Pin 10 IOF1
8
- //! - Channel 3: Pin 11 IOF1
6
+ //! - Channel 1: Pin 1 IOF1
7
+ //! - Channel 2: Pin 2 IOF1
8
+ //! - Channel 3: Pin 3 IOF1
9
9
//!
10
10
//! # PWM1 - 16 bit period and duty
11
- //! - Channel 1: Pin 3 IOF1
12
- //! - Channel 2: Pin 5 IOF1
13
- //! - Channel 3: Pin 6 IOF1
11
+ //! - Channel 1: Pin 19 IOF1
12
+ //! - Channel 2: Pin 21 IOF1
13
+ //! - Channel 3: Pin 22 IOF1
14
14
//!
15
15
//! # PWM2 - 16 bit period and duty
16
- //! - Channel 1: Pin 17 IOF1
17
- //! - Channel 2: Pin 18 IOF1
18
- //! - Channel 3: Pin 19 IOF1
19
-
20
- use core:: { marker:: PhantomData , ops:: Deref } ;
16
+ //! - Channel 1: Pin 11 IOF1
17
+ //! - Channel 2: Pin 12 IOF1
18
+ //! - Channel 3: Pin 13 IOF1
21
19
20
+ use core:: ops:: Deref ;
22
21
use e310x:: { pwm0, Pwm0 , Pwm1 , Pwm2 } ;
22
+ use embedded_hal:: pwm:: { ErrorKind , ErrorType , SetDutyCycle } ;
23
23
24
24
/// PWM comparator index
25
25
#[ derive( Copy , Clone ) ]
@@ -33,71 +33,53 @@ pub enum CmpIndex {
33
33
}
34
34
35
35
/// PWM pin
36
- pub trait Pin < PWM > : private:: Sealed {
36
+ pub trait Pin < PWM : PwmX > : private:: Sealed {
37
37
/// Channel index associated with the pin
38
38
const CMP_INDEX : CmpIndex ;
39
39
}
40
40
41
41
mod pwm_impl {
42
42
use super :: { CmpIndex , Pin , Pwm0 , Pwm1 , Pwm2 } ;
43
- use crate :: gpio:: { gpio0, NoInvert , IOF1 } ;
43
+ use crate :: gpio:: { gpio0, Invert , IOF1 } ;
44
44
45
45
// PWM0
46
- impl Pin < Pwm0 > for gpio0:: Pin1 < IOF1 < NoInvert > > {
46
+ impl Pin < Pwm0 > for gpio0:: Pin1 < IOF1 < Invert > > {
47
47
const CMP_INDEX : CmpIndex = CmpIndex :: Cmp1 ;
48
48
}
49
- impl Pin < Pwm0 > for gpio0:: Pin2 < IOF1 < NoInvert > > {
49
+ impl Pin < Pwm0 > for gpio0:: Pin2 < IOF1 < Invert > > {
50
50
const CMP_INDEX : CmpIndex = CmpIndex :: Cmp2 ;
51
51
}
52
- impl Pin < Pwm0 > for gpio0:: Pin3 < IOF1 < NoInvert > > {
52
+ impl Pin < Pwm0 > for gpio0:: Pin3 < IOF1 < Invert > > {
53
53
const CMP_INDEX : CmpIndex = CmpIndex :: Cmp3 ;
54
54
}
55
55
56
56
// PWM1
57
- impl Pin < Pwm1 > for gpio0:: Pin19 < IOF1 < NoInvert > > {
57
+ impl Pin < Pwm1 > for gpio0:: Pin19 < IOF1 < Invert > > {
58
58
const CMP_INDEX : CmpIndex = CmpIndex :: Cmp1 ;
59
59
}
60
- impl Pin < Pwm1 > for gpio0:: Pin21 < IOF1 < NoInvert > > {
60
+ impl Pin < Pwm1 > for gpio0:: Pin21 < IOF1 < Invert > > {
61
61
const CMP_INDEX : CmpIndex = CmpIndex :: Cmp2 ;
62
62
}
63
- impl Pin < Pwm1 > for gpio0:: Pin22 < IOF1 < NoInvert > > {
63
+ impl Pin < Pwm1 > for gpio0:: Pin22 < IOF1 < Invert > > {
64
64
const CMP_INDEX : CmpIndex = CmpIndex :: Cmp3 ;
65
65
}
66
66
67
67
// PWM2
68
- impl Pin < Pwm2 > for gpio0:: Pin11 < IOF1 < NoInvert > > {
68
+ impl Pin < Pwm2 > for gpio0:: Pin11 < IOF1 < Invert > > {
69
69
const CMP_INDEX : CmpIndex = CmpIndex :: Cmp1 ;
70
70
}
71
- impl Pin < Pwm2 > for gpio0:: Pin12 < IOF1 < NoInvert > > {
71
+ impl Pin < Pwm2 > for gpio0:: Pin12 < IOF1 < Invert > > {
72
72
const CMP_INDEX : CmpIndex = CmpIndex :: Cmp2 ;
73
73
}
74
- impl Pin < Pwm2 > for gpio0:: Pin13 < IOF1 < NoInvert > > {
74
+ impl Pin < Pwm2 > for gpio0:: Pin13 < IOF1 < Invert > > {
75
75
const CMP_INDEX : CmpIndex = CmpIndex :: Cmp3 ;
76
76
}
77
77
}
78
78
79
- /// PWM channel
80
- #[ derive( Copy , Clone ) ]
81
- pub struct Channel < PWM > {
82
- _pwm : PhantomData < PWM > ,
83
- cmp_index : CmpIndex ,
84
- }
85
-
86
- impl < PWM > Channel < PWM > {
87
- /// Constructs a PWM channel from a PWM pin for use with [Pwm]
88
- pub fn from < PIN : Pin < PWM > > ( _: PIN ) -> Channel < PWM > {
89
- Channel {
90
- _pwm : PhantomData ,
91
- cmp_index : PIN :: CMP_INDEX ,
92
- }
93
- }
94
- }
95
-
96
79
/// PwmX trait extends the PWM peripherals
97
80
#[ doc( hidden) ]
98
81
pub trait PwmX : Deref < Target = pwm0:: RegisterBlock > + private:: Sealed {
99
82
type CmpWidth : Ord ;
100
- fn peripheral ( ) -> Self ;
101
83
fn bits_from_cmp_width ( other : Self :: CmpWidth ) -> u32 ;
102
84
fn bits_into_cmp_width ( other : u32 ) -> Self :: CmpWidth ;
103
85
}
@@ -106,9 +88,6 @@ macro_rules! pwmx_impl {
106
88
( $PWM: ident, $CMP_WIDTH: ident) => {
107
89
impl PwmX for $PWM {
108
90
type CmpWidth = $CMP_WIDTH;
109
- fn peripheral( ) -> Self {
110
- unsafe { Self :: steal( ) }
111
- }
112
91
fn bits_from_cmp_width( other: Self :: CmpWidth ) -> u32 {
113
92
other as u32
114
93
}
@@ -152,103 +131,148 @@ impl<PWM: PwmX> Pwm<PWM> {
152
131
Self { pwm }
153
132
}
154
133
134
+ /// Frees the PWM device
135
+ pub fn free ( self ) -> PWM {
136
+ self . pwm
137
+ }
138
+
139
+ /// Returns the period of the PWM
140
+ pub fn get_period ( & self ) -> PWM :: CmpWidth {
141
+ PWM :: bits_into_cmp_width ( self . pwm . cmp0 ( ) . read ( ) . bits ( ) )
142
+ }
143
+
144
+ /// Sets the period of the PWM
145
+ pub fn set_period ( & mut self , period : PWM :: CmpWidth ) {
146
+ let period = PWM :: bits_from_cmp_width ( period) ;
147
+ self . pwm . count ( ) . reset ( ) ;
148
+ self . pwm . cmp0 ( ) . write ( |w| unsafe { w. bits ( period) } ) ;
149
+ }
150
+
151
+ /// Returns the duty cycle of the PWM
152
+ fn get_duty ( & self , cmp_index : CmpIndex ) -> PWM :: CmpWidth {
153
+ let duty = match cmp_index {
154
+ CmpIndex :: Cmp1 => self . pwm . cmp1 ( ) . read ( ) . bits ( ) ,
155
+ CmpIndex :: Cmp2 => self . pwm . cmp2 ( ) . read ( ) . bits ( ) ,
156
+ CmpIndex :: Cmp3 => self . pwm . cmp3 ( ) . read ( ) . bits ( ) ,
157
+ } ;
158
+ PWM :: bits_into_cmp_width ( duty)
159
+ }
160
+
161
+ /// Sets the duty cycle of the PWM
162
+ fn set_duty ( & self , cmp_index : CmpIndex , duty : PWM :: CmpWidth ) {
163
+ let duty = PWM :: bits_from_cmp_width ( duty. min ( self . get_period ( ) ) ) ;
164
+ match cmp_index {
165
+ CmpIndex :: Cmp1 => self . pwm . cmp1 ( ) . write ( |w| unsafe { w. bits ( duty) } ) ,
166
+ CmpIndex :: Cmp2 => self . pwm . cmp2 ( ) . write ( |w| unsafe { w. bits ( duty) } ) ,
167
+ CmpIndex :: Cmp3 => self . pwm . cmp3 ( ) . write ( |w| unsafe { w. bits ( duty) } ) ,
168
+ }
169
+ }
170
+
155
171
/// Enables the PWM channel
156
- pub fn enable ( & mut self , channel : & Channel < PWM > ) {
157
- match channel . cmp_index {
172
+ fn enable ( & self , cmp_index : CmpIndex ) {
173
+ match cmp_index {
158
174
CmpIndex :: Cmp1 => self . pwm . cmp1 ( ) . write ( |w| unsafe { w. bits ( u32:: MAX ) } ) ,
159
175
CmpIndex :: Cmp2 => self . pwm . cmp2 ( ) . write ( |w| unsafe { w. bits ( u32:: MAX ) } ) ,
160
176
CmpIndex :: Cmp3 => self . pwm . cmp3 ( ) . write ( |w| unsafe { w. bits ( u32:: MAX ) } ) ,
161
177
}
162
178
}
163
179
164
180
/// Disables the PWM channel
165
- pub fn disable ( & mut self , channel : & Channel < PWM > ) {
166
- match channel . cmp_index {
181
+ fn disable ( & self , cmp_index : CmpIndex ) {
182
+ match cmp_index {
167
183
CmpIndex :: Cmp1 => self . pwm . cmp1 ( ) . reset ( ) ,
168
184
CmpIndex :: Cmp2 => self . pwm . cmp2 ( ) . reset ( ) ,
169
185
CmpIndex :: Cmp3 => self . pwm . cmp3 ( ) . reset ( ) ,
170
186
}
171
187
}
172
188
189
+ /// Returns the PWM channel associated with the given index
190
+ pub fn channel < PIN : Pin < PWM > > ( & self , pin : PIN ) -> Channel < ' _ , PWM , PIN > {
191
+ Channel { pwm : self , pin }
192
+ }
193
+ }
194
+
195
+ /// PWM channel
196
+ pub struct Channel < ' a , PWM , PIN > {
197
+ pwm : & ' a Pwm < PWM > ,
198
+ pin : PIN ,
199
+ }
200
+
201
+ impl < ' a , PWM , PIN > Channel < ' a , PWM , PIN > {
202
+ /// Frees the PWM channel
203
+ pub fn free ( self ) -> PIN {
204
+ self . pin
205
+ }
206
+ }
207
+
208
+ impl < ' a , PWM : PwmX , PIN : Pin < PWM > > Channel < ' a , PWM , PIN > {
173
209
/// Returns the period of the PWM
174
210
pub fn get_period ( & self ) -> PWM :: CmpWidth {
175
- PWM :: bits_into_cmp_width ( self . pwm . cmp0 ( ) . read ( ) . bits ( ) )
211
+ self . pwm . get_period ( )
212
+ }
213
+
214
+ /// Returns the maximum duty cycle of the PWM (equal to the period)
215
+ pub fn max_duty ( & self ) -> PWM :: CmpWidth {
216
+ self . pwm . get_period ( )
176
217
}
177
218
178
219
/// Returns the duty cycle of the PWM
179
- pub fn get_duty ( & self , channel : & Channel < PWM > ) -> PWM :: CmpWidth {
180
- let duty = match channel. cmp_index {
181
- CmpIndex :: Cmp1 => self . pwm . cmp1 ( ) . read ( ) . bits ( ) ,
182
- CmpIndex :: Cmp2 => self . pwm . cmp2 ( ) . read ( ) . bits ( ) ,
183
- CmpIndex :: Cmp3 => self . pwm . cmp3 ( ) . read ( ) . bits ( ) ,
184
- } ;
185
- PWM :: bits_into_cmp_width ( duty)
220
+ pub fn get_duty ( & self ) -> PWM :: CmpWidth {
221
+ self . pwm . get_duty ( PIN :: CMP_INDEX )
186
222
}
187
223
188
- /// Returns the maximum duty cycle of the PWM (equal to the period)
189
- pub fn get_max_duty ( & self ) -> PWM :: CmpWidth {
190
- self . get_period ( )
224
+ /// Sets the duty cycle to 100%
225
+ pub fn enable ( & mut self ) {
226
+ self . pwm . enable ( PIN :: CMP_INDEX ) ;
191
227
}
192
228
193
- /// Sets the duty cycle of the PWM
194
- pub fn set_duty ( & mut self , channel : & Channel < PWM > , duty : PWM :: CmpWidth ) {
195
- let duty = PWM :: bits_from_cmp_width ( duty. min ( self . get_max_duty ( ) ) ) ;
196
- match channel. cmp_index {
197
- CmpIndex :: Cmp1 => self . pwm . cmp1 ( ) . write ( |w| unsafe { w. bits ( duty) } ) ,
198
- CmpIndex :: Cmp2 => self . pwm . cmp2 ( ) . write ( |w| unsafe { w. bits ( duty) } ) ,
199
- CmpIndex :: Cmp3 => self . pwm . cmp3 ( ) . write ( |w| unsafe { w. bits ( duty) } ) ,
200
- }
229
+ /// Sets the duty cycle to 0%
230
+ pub fn disable ( & mut self ) {
231
+ self . pwm . disable ( PIN :: CMP_INDEX ) ;
201
232
}
202
233
203
- /// Sets the period of the PWM
204
- pub fn set_period ( & mut self , period : PWM :: CmpWidth ) {
205
- let period = PWM :: bits_from_cmp_width ( period) ;
206
- self . pwm . count ( ) . reset ( ) ;
207
- self . pwm . cmp0 ( ) . write ( |w| unsafe { w. bits ( period) } ) ;
234
+ /// Sets the duty cycle of the PWM
235
+ pub fn set_duty ( & mut self , duty : PWM :: CmpWidth ) {
236
+ self . pwm . set_duty ( PIN :: CMP_INDEX , duty) ;
208
237
}
209
238
}
210
239
211
- impl < PWM : PwmX > embedded_hal :: pwm :: ErrorType for Channel < PWM > {
212
- type Error = embedded_hal :: pwm :: ErrorKind ;
240
+ impl < ' a , PWM : PwmX , PIN : Pin < PWM > > ErrorType for Channel < ' a , PWM , PIN > {
241
+ type Error = ErrorKind ;
213
242
}
214
243
215
- impl < PWM : PwmX > embedded_hal :: pwm :: SetDutyCycle for Channel < PWM > {
244
+ impl < ' a , PWM : PwmX , PIN : Pin < PWM > > SetDutyCycle for Channel < ' a , PWM , PIN > {
216
245
fn max_duty_cycle ( & self ) -> u16 {
217
- let pwm: Pwm < PWM > = Pwm {
218
- pwm : PWM :: peripheral ( ) ,
219
- } ;
220
- PWM :: bits_from_cmp_width ( pwm. get_max_duty ( ) ) as _
246
+ PWM :: bits_from_cmp_width ( self . max_duty ( ) ) as _
221
247
}
222
248
223
249
fn set_duty_cycle ( & mut self , duty : u16 ) -> Result < ( ) , Self :: Error > {
224
- let mut pwm: Pwm < PWM > = Pwm {
225
- pwm : PWM :: peripheral ( ) ,
226
- } ;
227
- pwm. set_duty ( self , PWM :: bits_into_cmp_width ( duty as _ ) ) ;
250
+ self . pwm
251
+ . set_duty ( PIN :: CMP_INDEX , PWM :: bits_into_cmp_width ( duty as _ ) ) ;
228
252
Ok ( ( ) )
229
253
}
230
254
}
231
255
232
256
mod private {
233
257
use super :: { Pwm0 , Pwm1 , Pwm2 } ;
234
- use crate :: gpio:: { gpio0, NoInvert , IOF1 } ;
258
+ use crate :: gpio:: { gpio0, Invert , IOF1 } ;
235
259
pub trait Sealed { }
236
260
237
261
// PWM0
238
262
impl Sealed for Pwm0 { }
239
- impl Sealed for gpio0:: Pin1 < IOF1 < NoInvert > > { }
240
- impl Sealed for gpio0:: Pin2 < IOF1 < NoInvert > > { }
241
- impl Sealed for gpio0:: Pin3 < IOF1 < NoInvert > > { }
263
+ impl Sealed for gpio0:: Pin1 < IOF1 < Invert > > { }
264
+ impl Sealed for gpio0:: Pin2 < IOF1 < Invert > > { }
265
+ impl Sealed for gpio0:: Pin3 < IOF1 < Invert > > { }
242
266
243
267
// PWM1
244
268
impl Sealed for Pwm1 { }
245
- impl Sealed for gpio0:: Pin19 < IOF1 < NoInvert > > { }
246
- impl Sealed for gpio0:: Pin21 < IOF1 < NoInvert > > { }
247
- impl Sealed for gpio0:: Pin22 < IOF1 < NoInvert > > { }
269
+ impl Sealed for gpio0:: Pin19 < IOF1 < Invert > > { }
270
+ impl Sealed for gpio0:: Pin21 < IOF1 < Invert > > { }
271
+ impl Sealed for gpio0:: Pin22 < IOF1 < Invert > > { }
248
272
249
273
// PWM2
250
274
impl Sealed for Pwm2 { }
251
- impl Sealed for gpio0:: Pin11 < IOF1 < NoInvert > > { }
252
- impl Sealed for gpio0:: Pin12 < IOF1 < NoInvert > > { }
253
- impl Sealed for gpio0:: Pin13 < IOF1 < NoInvert > > { }
275
+ impl Sealed for gpio0:: Pin11 < IOF1 < Invert > > { }
276
+ impl Sealed for gpio0:: Pin12 < IOF1 < Invert > > { }
277
+ impl Sealed for gpio0:: Pin13 < IOF1 < Invert > > { }
254
278
}
0 commit comments