@@ -10,14 +10,7 @@ impl<const L: u8, const R: u8> Assert<L, R> {
10
10
impl < const P : char , const N : u8 , const A : u8 > Pin < P , N , Alternate < A , PushPull > > {
11
11
/// Turns pin alternate configuration pin into open drain
12
12
pub fn set_open_drain ( self ) -> Pin < P , N , Alternate < A , OpenDrain > > {
13
- let offset = { N } ;
14
- unsafe {
15
- ( * Gpio :: < P > :: ptr ( ) )
16
- . otyper
17
- . modify ( |r, w| w. bits ( r. bits ( ) | ( 1 << offset) ) )
18
- } ;
19
-
20
- Pin :: new ( )
13
+ self . into_mode ( )
21
14
}
22
15
}
23
16
@@ -32,6 +25,8 @@ impl<const P: char, const N: u8, const A: u8> From<Pin<P, N, Input>>
32
25
33
26
impl < const P : char , const N : u8 , const A : u8 , MODE > From < Pin < P , N , Output < MODE > > >
34
27
for Pin < P , N , Alternate < A , PushPull > >
28
+ where
29
+ Output < MODE > : PinMode ,
35
30
{
36
31
#[ inline( always) ]
37
32
fn from ( f : Pin < P , N , Output < MODE > > ) -> Self {
@@ -68,6 +63,8 @@ impl<const P: char, const N: u8, const A: u8> From<Pin<P, N, Input>>
68
63
69
64
impl < const P : char , const N : u8 , const A : u8 , MODE > From < Pin < P , N , Output < MODE > > >
70
65
for Pin < P , N , Alternate < A , OpenDrain > >
66
+ where
67
+ Output < MODE > : PinMode ,
71
68
{
72
69
#[ inline( always) ]
73
70
fn from ( f : Pin < P , N , Output < MODE > > ) -> Self {
@@ -93,7 +90,10 @@ impl<const P: char, const N: u8, const A: u8, const B: u8> From<Pin<P, N, Altern
93
90
}
94
91
}
95
92
96
- impl < const P : char , const N : u8 , MODE > From < Pin < P , N , Output < MODE > > > for Pin < P , N , Input > {
93
+ impl < const P : char , const N : u8 , MODE > From < Pin < P , N , Output < MODE > > > for Pin < P , N , Input >
94
+ where
95
+ Output < MODE > : PinMode ,
96
+ {
97
97
#[ inline( always) ]
98
98
fn from ( f : Pin < P , N , Output < MODE > > ) -> Self {
99
99
f. into_input ( )
@@ -214,7 +214,10 @@ impl<const P: char, const N: u8> From<Pin<P, N, Input>> for Pin<P, N, Analog> {
214
214
}
215
215
}
216
216
217
- impl < const P : char , const N : u8 , MODE > From < Pin < P , N , Output < MODE > > > for Pin < P , N , Analog > {
217
+ impl < const P : char , const N : u8 , MODE > From < Pin < P , N , Output < MODE > > > for Pin < P , N , Analog >
218
+ where
219
+ Output < MODE > : PinMode ,
220
+ {
218
221
#[ inline( always) ]
219
222
fn from ( f : Pin < P , N , Output < MODE > > ) -> Self {
220
223
f. into_analog ( )
@@ -239,40 +242,24 @@ impl<const P: char, const N: u8, const A: u8> From<Pin<P, N, Alternate<A, OpenDr
239
242
}
240
243
}
241
244
242
- impl < const P : char , const N : u8 , MODE > Pin < P , N , MODE > {
243
- pub ( super ) fn set_alternate < const A : u8 > ( & mut self ) {
245
+ impl < const P : char , const N : u8 , MODE : PinMode > Pin < P , N , MODE > {
246
+ /// Configures the pin to operate alternate mode
247
+ pub fn into_alternate < const A : u8 > ( self ) -> Pin < P , N , Alternate < A , PushPull > > {
244
248
#[ allow( path_statements, clippy:: no_effect) ]
245
249
{
246
250
Assert :: < A , 16 > :: LESS ;
247
251
}
248
- let offset = 2 * { N } ;
249
- unsafe {
250
- if N < 8 {
251
- let offset2 = 4 * { N } ;
252
- ( * Gpio :: < P > :: ptr ( ) ) . afrl . modify ( |r, w| {
253
- w. bits ( ( r. bits ( ) & !( 0b1111 << offset2) ) | ( ( A as u32 ) << offset2) )
254
- } ) ;
255
- } else {
256
- let offset2 = 4 * { N - 8 } ;
257
- ( * Gpio :: < P > :: ptr ( ) ) . afrh . modify ( |r, w| {
258
- w. bits ( ( r. bits ( ) & !( 0b1111 << offset2) ) | ( ( A as u32 ) << offset2) )
259
- } ) ;
260
- }
261
- ( * Gpio :: < P > :: ptr ( ) )
262
- . moder
263
- . modify ( |r, w| w. bits ( ( r. bits ( ) & !( 0b11 << offset) ) | ( 0b10 << offset) ) ) ;
264
- }
265
- }
266
- /// Configures the pin to operate alternate mode
267
- pub fn into_alternate < const A : u8 > ( mut self ) -> Pin < P , N , Alternate < A , PushPull > > {
268
- self . set_alternate :: < A > ( ) ;
269
- Pin :: new ( )
252
+ self . into_mode ( )
270
253
}
271
254
272
255
/// Configures the pin to operate in alternate open drain mode
273
256
#[ allow( path_statements) ]
274
257
pub fn into_alternate_open_drain < const A : u8 > ( self ) -> Pin < P , N , Alternate < A , OpenDrain > > {
275
- self . into_alternate :: < A > ( ) . set_open_drain ( )
258
+ #[ allow( path_statements, clippy:: no_effect) ]
259
+ {
260
+ Assert :: < A , 16 > :: LESS ;
261
+ }
262
+ self . into_mode ( )
276
263
}
277
264
278
265
/// Configures the pin to operate as a input pin
@@ -349,26 +336,49 @@ impl<const P: char, const N: u8, MODE> Pin<P, N, MODE> {
349
336
pub ( super ) fn mode < M : PinMode > ( & mut self ) {
350
337
let offset = 2 * N ;
351
338
unsafe {
352
- if let Some ( pudpr) = M :: PUPDR {
353
- ( * Gpio :: < P > :: ptr ( ) )
354
- . pupdr
355
- . modify ( |r, w| w. bits ( ( r. bits ( ) & !( 0b11 << offset) ) | ( pudpr << offset) ) ) ;
339
+ if MODE :: PUPDR != M :: PUPDR {
340
+ if let Some ( pudpr) = M :: PUPDR {
341
+ ( * Gpio :: < P > :: ptr ( ) )
342
+ . pupdr
343
+ . modify ( |r, w| w. bits ( ( r. bits ( ) & !( 0b11 << offset) ) | ( pudpr << offset) ) ) ;
344
+ }
356
345
}
357
346
358
- if let Some ( otyper) = M :: OTYPER {
359
- ( * Gpio :: < P > :: ptr ( ) )
360
- . otyper
361
- . modify ( |r, w| w. bits ( r. bits ( ) & !( 0b1 << N ) | ( otyper << N ) ) ) ;
347
+ if MODE :: OTYPER != M :: OTYPER {
348
+ if let Some ( otyper) = M :: OTYPER {
349
+ ( * Gpio :: < P > :: ptr ( ) )
350
+ . otyper
351
+ . modify ( |r, w| w. bits ( r. bits ( ) & !( 0b1 << N ) | ( otyper << N ) ) ) ;
352
+ }
353
+ }
354
+
355
+ if MODE :: AFR != M :: AFR {
356
+ if let Some ( afr) = M :: AFR {
357
+ if N < 8 {
358
+ let offset2 = 4 * { N } ;
359
+ ( * Gpio :: < P > :: ptr ( ) ) . afrl . modify ( |r, w| {
360
+ w. bits ( ( r. bits ( ) & !( 0b1111 << offset2) ) | ( afr << offset2) )
361
+ } ) ;
362
+ } else {
363
+ let offset2 = 4 * { N - 8 } ;
364
+ ( * Gpio :: < P > :: ptr ( ) ) . afrh . modify ( |r, w| {
365
+ w. bits ( ( r. bits ( ) & !( 0b1111 << offset2) ) | ( afr << offset2) )
366
+ } ) ;
367
+ }
368
+ }
362
369
}
363
370
364
- ( * Gpio :: < P > :: ptr ( ) )
365
- . moder
366
- . modify ( |r, w| w. bits ( ( r. bits ( ) & !( 0b11 << offset) ) | ( M :: MODER << offset) ) ) ;
371
+ if MODE :: MODER != M :: MODER {
372
+ ( * Gpio :: < P > :: ptr ( ) )
373
+ . moder
374
+ . modify ( |r, w| w. bits ( ( r. bits ( ) & !( 0b11 << offset) ) | ( M :: MODER << offset) ) ) ;
375
+ }
367
376
}
368
377
}
369
378
370
379
#[ inline( always) ]
371
- pub ( super ) fn into_mode < M : PinMode > ( mut self ) -> Pin < P , N , M > {
380
+ /// Converts pin into specified mode
381
+ pub fn into_mode < M : PinMode > ( mut self ) -> Pin < P , N , M > {
372
382
self . mode :: < M > ( ) ;
373
383
Pin :: new ( )
374
384
}
@@ -489,9 +499,11 @@ pub trait PinMode: crate::Sealed {
489
499
#[ doc( hidden) ]
490
500
const PUPDR : Option < u32 > = None ;
491
501
#[ doc( hidden) ]
492
- const MODER : u32 ;
502
+ const MODER : u32 = u32 :: MAX ;
493
503
#[ doc( hidden) ]
494
504
const OTYPER : Option < u32 > = None ;
505
+ #[ doc( hidden) ]
506
+ const AFR : Option < u32 > = None ;
495
507
}
496
508
497
509
impl crate :: Sealed for Input { }
@@ -505,14 +517,26 @@ impl PinMode for Analog {
505
517
const MODER : u32 = 0b11 ;
506
518
}
507
519
508
- impl crate :: Sealed for Output < OpenDrain > { }
520
+ impl < Otype > crate :: Sealed for Output < Otype > { }
509
521
impl PinMode for Output < OpenDrain > {
510
522
const MODER : u32 = 0b01 ;
511
523
const OTYPER : Option < u32 > = Some ( 0b1 ) ;
512
524
}
513
525
514
- impl crate :: Sealed for Output < PushPull > { }
515
526
impl PinMode for Output < PushPull > {
516
527
const MODER : u32 = 0b01 ;
517
528
const OTYPER : Option < u32 > = Some ( 0b0 ) ;
518
529
}
530
+
531
+ impl < const A : u8 , Otype > crate :: Sealed for Alternate < A , Otype > { }
532
+ impl < const A : u8 > PinMode for Alternate < A , OpenDrain > {
533
+ const MODER : u32 = 0b10 ;
534
+ const OTYPER : Option < u32 > = Some ( 0b1 ) ;
535
+ const AFR : Option < u32 > = Some ( A as _ ) ;
536
+ }
537
+
538
+ impl < const A : u8 > PinMode for Alternate < A , PushPull > {
539
+ const MODER : u32 = 0b10 ;
540
+ const OTYPER : Option < u32 > = Some ( 0b0 ) ;
541
+ const AFR : Option < u32 > = Some ( A as _ ) ;
542
+ }
0 commit comments