@@ -72,6 +72,7 @@ use crate::afio::MAPR;
72
72
use crate :: bb;
73
73
use crate :: gpio:: { self , Alternate , PushPull } ;
74
74
use crate :: time:: Hertz ;
75
+ use crate :: time:: U32Ext ;
75
76
use crate :: timer:: Timer ;
76
77
77
78
pub trait Pins < REMAP , P > {
@@ -93,7 +94,7 @@ macro_rules! pins_impl {
93
94
$( $PINX: $TRAIT<REMAP > + gpio:: Mode <Alternate <PushPull >>, ) +
94
95
{
95
96
$( const $ENCHX: bool = true ; ) +
96
- type Channels = ( $( Pwm <TIM , $ENCHX>) ,+) ;
97
+ type Channels = ( $( PwmChannel <TIM , $ENCHX>) ,+) ;
97
98
}
98
99
) +
99
100
} ;
@@ -128,7 +129,7 @@ impl Timer<TIM1> {
128
129
_pins : PINS ,
129
130
mapr : & mut MAPR ,
130
131
freq : T ,
131
- ) -> PINS :: Channels
132
+ ) -> Pwm < TIM1 , REMAP , P , PINS >
132
133
where
133
134
REMAP : Remap < Periph = TIM1 > ,
134
135
PINS : Pins < REMAP , P > ,
@@ -147,7 +148,7 @@ impl Timer<TIM2> {
147
148
_pins : PINS ,
148
149
mapr : & mut MAPR ,
149
150
freq : T ,
150
- ) -> PINS :: Channels
151
+ ) -> Pwm < TIM2 , REMAP , P , PINS >
151
152
where
152
153
REMAP : Remap < Periph = TIM2 > ,
153
154
PINS : Pins < REMAP , P > ,
@@ -166,7 +167,7 @@ impl Timer<TIM3> {
166
167
_pins : PINS ,
167
168
mapr : & mut MAPR ,
168
169
freq : T ,
169
- ) -> PINS :: Channels
170
+ ) -> Pwm < TIM3 , REMAP , P , PINS >
170
171
where
171
172
REMAP : Remap < Periph = TIM3 > ,
172
173
PINS : Pins < REMAP , P > ,
@@ -186,7 +187,7 @@ impl Timer<TIM4> {
186
187
_pins : PINS ,
187
188
mapr : & mut MAPR ,
188
189
freq : T ,
189
- ) -> PINS :: Channels
190
+ ) -> Pwm < TIM4 , REMAP , P , PINS >
190
191
where
191
192
REMAP : Remap < Periph = TIM4 > ,
192
193
PINS : Pins < REMAP , P > ,
@@ -199,7 +200,26 @@ impl Timer<TIM4> {
199
200
}
200
201
}
201
202
202
- pub struct Pwm < TIM , CHANNEL > {
203
+ pub struct Pwm < TIM , REMAP , P , PINS >
204
+ where
205
+ REMAP : Remap < Periph = TIM > ,
206
+ PINS : Pins < REMAP , P >
207
+ {
208
+ clk : Hertz ,
209
+ _pins : PhantomData < ( TIM , REMAP , P , PINS ) > ,
210
+ }
211
+
212
+ impl < TIM , REMAP , P , PINS > Pwm < TIM , REMAP , P , PINS >
213
+ where
214
+ REMAP : Remap < Periph = TIM > ,
215
+ PINS : Pins < REMAP , P >
216
+ {
217
+ pub fn split ( ) -> PINS :: Channels {
218
+ unsafe { mem:: MaybeUninit :: uninit ( ) . assume_init ( ) }
219
+ }
220
+ }
221
+
222
+ pub struct PwmChannel < TIM , CHANNEL > {
203
223
_channel : PhantomData < CHANNEL > ,
204
224
_tim : PhantomData < TIM > ,
205
225
}
@@ -217,7 +237,7 @@ macro_rules! hal {
217
237
_pins: PINS ,
218
238
freq: Hertz ,
219
239
clk: Hertz ,
220
- ) -> PINS :: Channels
240
+ ) -> Pwm <$TIMX , REMAP , P , PINS >
221
241
where
222
242
REMAP : Remap <Periph = $TIMX>,
223
243
PINS : Pins <REMAP , P >,
@@ -258,10 +278,114 @@ macro_rules! hal {
258
278
. set_bit( )
259
279
) ;
260
280
261
- unsafe { mem:: MaybeUninit :: uninit( ) . assume_init( ) }
281
+ Pwm {
282
+ clk,
283
+ _pins: PhantomData ,
284
+ }
285
+ }
286
+
287
+ impl <REMAP , P , PINS > hal:: Pwm for Pwm <$TIMX, REMAP , P , PINS > where
288
+ REMAP : Remap <Periph = $TIMX>,
289
+ PINS : Pins <REMAP , P >,
290
+ {
291
+ type Channel = u8 ;
292
+ type Duty = u16 ;
293
+ type Time = Hertz ;
294
+
295
+ fn enable( & mut self , channel: Self :: Channel ) {
296
+ if channel == 1 && PINS :: C1 {
297
+ unsafe { bb:: set( & ( * $TIMX:: ptr( ) ) . ccer, 0 ) }
298
+ }
299
+ if channel == 2 && PINS :: C2 {
300
+ unsafe { bb:: set( & ( * $TIMX:: ptr( ) ) . ccer, 4 ) }
301
+ }
302
+ if channel == 3 && PINS :: C3 {
303
+ unsafe { bb:: set( & ( * $TIMX:: ptr( ) ) . ccer, 8 ) }
304
+ }
305
+ if channel == 4 && PINS :: C4 {
306
+ unsafe { bb:: set( & ( * $TIMX:: ptr( ) ) . ccer, 12 ) }
307
+ }
308
+ }
309
+
310
+ fn disable( & mut self , channel: Self :: Channel ) {
311
+ if PINS :: C1 {
312
+ unsafe { bb:: clear( & ( * $TIMX:: ptr( ) ) . ccer, 0 ) }
313
+ }
314
+ if PINS :: C2 {
315
+ unsafe { bb:: clear( & ( * $TIMX:: ptr( ) ) . ccer, 4 ) }
316
+ }
317
+ if PINS :: C3 {
318
+ unsafe { bb:: clear( & ( * $TIMX:: ptr( ) ) . ccer, 8 ) }
319
+ }
320
+ if PINS :: C4 {
321
+ unsafe { bb:: clear( & ( * $TIMX:: ptr( ) ) . ccer, 12 ) }
322
+ }
323
+ }
324
+
325
+ fn get_duty( & self , channel: Self :: Channel ) -> Self :: Duty {
326
+ if channel == 1 && PINS :: C1 {
327
+ unsafe { ( * $TIMX:: ptr( ) ) . ccr1. read( ) . ccr( ) . bits( ) }
328
+ } else if channel == 2 && PINS :: C2 {
329
+ unsafe { ( * $TIMX:: ptr( ) ) . ccr2. read( ) . ccr( ) . bits( ) }
330
+ } else if channel == 3 && PINS :: C3 {
331
+ unsafe { ( * $TIMX:: ptr( ) ) . ccr3. read( ) . ccr( ) . bits( ) }
332
+ } else if channel == 4 && PINS :: C4 {
333
+ unsafe { ( * $TIMX:: ptr( ) ) . ccr4. read( ) . ccr( ) . bits( ) }
334
+ } else {
335
+ 0
336
+ }
337
+ }
338
+
339
+ fn set_duty( & mut self , channel: Self :: Channel , duty: Self :: Duty ) {
340
+ if PINS :: C1 {
341
+ unsafe { ( * $TIMX:: ptr( ) ) . ccr1. write( |w| w. ccr( ) . bits( duty) ) }
342
+ }
343
+ if PINS :: C2 {
344
+ unsafe { ( * $TIMX:: ptr( ) ) . ccr2. write( |w| w. ccr( ) . bits( duty) ) }
345
+ }
346
+ if PINS :: C3 {
347
+ unsafe { ( * $TIMX:: ptr( ) ) . ccr3. write( |w| w. ccr( ) . bits( duty) ) }
348
+ }
349
+ if PINS :: C4 {
350
+ unsafe { ( * $TIMX:: ptr( ) ) . ccr4. write( |w| w. ccr( ) . bits( duty) ) }
351
+ }
352
+ }
353
+
354
+ fn get_max_duty( & self ) -> Self :: Duty {
355
+ unsafe { ( * $TIMX:: ptr( ) ) . arr. read( ) . arr( ) . bits( ) }
356
+ }
357
+
358
+ fn get_period( & self ) -> Self :: Time {
359
+ let clk = self . clk;
360
+ let mut psc: u16 = 0 ;
361
+ let mut arr: u16 = 0 ;
362
+ unsafe {
363
+ psc = ( * $TIMX:: ptr( ) ) . psc. read( ) . psc( ) . bits( ) ;
364
+ arr = ( * $TIMX:: ptr( ) ) . arr. read( ) . arr( ) . bits( ) ;
365
+ }
366
+
367
+ // Length in ms of an internal clock pulse
368
+ ( clk. 0 / u32 ( psc * arr) ) . hz( )
369
+ // (((psc as u32) / clk.0) * (1_000_000 as u32) * (arr as u32)).ms()
370
+ }
371
+
372
+ fn set_period<T >( & mut self , period: T ) where
373
+ T : Into <Self :: Time > {
374
+ let clk = self . clk;
375
+
376
+ // let freq = u16(1 / period.into());
377
+
378
+ let ticks = clk. 0 / period. into( ) . 0 ;
379
+ let psc = u16 ( ticks / ( 1 << 16 ) ) . unwrap( ) ;
380
+ let arr = u16 ( ticks / u32 ( psc + 1 ) ) . unwrap( ) ;
381
+ unsafe {
382
+ ( * $TIMX:: ptr( ) ) . psc. write( |w| w. psc( ) . bits( psc) ) ;
383
+ ( * $TIMX:: ptr( ) ) . arr. write( |w| w. arr( ) . bits( arr) ) ;
384
+ }
385
+ }
262
386
}
263
387
264
- impl hal:: PwmPin for Pwm <$TIMX, C1 > {
388
+ impl hal:: PwmPin for PwmChannel <$TIMX, C1 > {
265
389
type Duty = u16 ;
266
390
267
391
fn disable( & mut self ) {
@@ -285,7 +409,7 @@ macro_rules! hal {
285
409
}
286
410
}
287
411
288
- impl hal:: PwmPin for Pwm <$TIMX, C2 > {
412
+ impl hal:: PwmPin for PwmChannel <$TIMX, C2 > {
289
413
type Duty = u16 ;
290
414
291
415
fn disable( & mut self ) {
@@ -309,7 +433,7 @@ macro_rules! hal {
309
433
}
310
434
}
311
435
312
- impl hal:: PwmPin for Pwm <$TIMX, C3 > {
436
+ impl hal:: PwmPin for PwmChannel <$TIMX, C3 > {
313
437
type Duty = u16 ;
314
438
315
439
fn disable( & mut self ) {
@@ -333,7 +457,7 @@ macro_rules! hal {
333
457
}
334
458
}
335
459
336
- impl hal:: PwmPin for Pwm <$TIMX, C4 > {
460
+ impl hal:: PwmPin for PwmChannel <$TIMX, C4 > {
337
461
type Duty = u16 ;
338
462
339
463
fn disable( & mut self ) {
0 commit comments