@@ -102,18 +102,19 @@ pub trait PinExt {
102
102
pub struct Alternate < const A : u8 , Otype = PushPull > ( PhantomData < Otype > ) ;
103
103
104
104
/// Input mode (type state)
105
- pub struct Input < MODE = Floating > {
106
- _mode : PhantomData < MODE > ,
107
- }
108
-
109
- /// Floating input (type state)
110
- pub struct Floating ;
105
+ pub struct Input ;
111
106
112
- /// Pulled down input (type state)
113
- pub struct PullDown ;
114
-
115
- /// Pulled up input (type state)
116
- pub struct PullUp ;
107
+ /// Pull setting for an input.
108
+ #[ derive( Debug , Eq , PartialEq ) ]
109
+ #[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
110
+ pub enum Pull {
111
+ /// Floating
112
+ None = 0 ,
113
+ /// Pulled up
114
+ Up = 1 ,
115
+ /// Pulled down
116
+ Down = 2 ,
117
+ }
117
118
118
119
/// Open drain input or output (type state)
119
120
pub struct OpenDrain ;
@@ -131,6 +132,26 @@ pub struct Analog;
131
132
132
133
pub type Debugger = Alternate < 0 , PushPull > ;
133
134
135
+ mod sealed {
136
+ /// Marker trait that show if `ExtiPin` can be implemented
137
+ pub trait Interruptable { }
138
+ /// Marker trait for slew rate configurable pin modes
139
+ pub trait OutputSpeed { }
140
+ /// Marker trait for active pin modes
141
+ pub trait Active { }
142
+ /// Marker trait for all pin modes except alternate
143
+ pub trait NotAlt { }
144
+ }
145
+
146
+ impl sealed:: Active for Input { }
147
+ impl < Otype > sealed:: OutputSpeed for Output < Otype > { }
148
+ impl < const A : u8 , Otype > sealed:: OutputSpeed for Alternate < A , Otype > { }
149
+ impl < Otype > sealed:: Active for Output < Otype > { }
150
+ impl < const A : u8 , Otype > sealed:: Active for Alternate < A , Otype > { }
151
+ impl sealed:: NotAlt for Input { }
152
+ impl < Otype > sealed:: NotAlt for Output < Otype > { }
153
+ impl sealed:: NotAlt for Analog { }
154
+
134
155
/// GPIO Pin speed selection
135
156
#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
136
157
#[ derive( Debug , PartialEq , Eq , Clone , Copy ) ]
@@ -149,14 +170,9 @@ pub enum Edge {
149
170
RisingFalling ,
150
171
}
151
172
152
- mod sealed {
153
- /// Marker trait that show if `ExtiPin` can be implemented
154
- pub trait Interruptable { }
155
- }
156
-
157
173
use sealed:: Interruptable ;
158
174
impl < MODE > Interruptable for Output < MODE > { }
159
- impl < MODE > Interruptable for Input < MODE > { }
175
+ impl Interruptable for Input { }
160
176
161
177
/// External Interrupt Pin
162
178
pub trait ExtiPin {
@@ -262,7 +278,7 @@ where
262
278
/// - `MODE` is one of the pin modes (see [Modes](crate::gpio#modes) section).
263
279
/// - `P` is port name: `A` for GPIOA, `B` for GPIOB, etc.
264
280
/// - `N` is pin number: from `0` to `15`.
265
- pub struct Pin < const P : char , const N : u8 , MODE = Input < Floating > > {
281
+ pub struct Pin < const P : char , const N : u8 , MODE = Input > {
266
282
_mode : PhantomData < MODE > ,
267
283
}
268
284
impl < const P : char , const N : u8 , MODE > Pin < P , N , MODE > {
@@ -302,7 +318,10 @@ impl<const P: char, const N: u8, MODE> PinExt for Pin<P, N, MODE> {
302
318
}
303
319
}
304
320
305
- impl < const P : char , const N : u8 , MODE > Pin < P , N , Output < MODE > > {
321
+ impl < const P : char , const N : u8 , MODE > Pin < P , N , MODE >
322
+ where
323
+ MODE : sealed:: OutputSpeed ,
324
+ {
306
325
/// Set pin speed
307
326
pub fn set_speed ( self , speed : Speed ) -> Self {
308
327
let offset = 2 * { N } ;
@@ -317,24 +336,11 @@ impl<const P: char, const N: u8, MODE> Pin<P, N, Output<MODE>> {
317
336
}
318
337
}
319
338
320
- impl < const P : char , const N : u8 > Pin < P , N , Output < OpenDrain > > {
321
- /// Enables / disables the internal pull up
322
- pub fn internal_pull_up ( self , on : bool ) -> Self {
323
- let offset = 2 * { N } ;
324
- let value = if on { 0b01 } else { 0b00 } ;
325
- unsafe {
326
- ( * Gpio :: < P > :: ptr ( ) )
327
- . pupdr
328
- . modify ( |r, w| w. bits ( ( r. bits ( ) & !( 0b11 << offset) ) | ( value << offset) ) )
329
- } ;
330
-
331
- self
332
- }
333
-
334
- /// Enables / disables the internal pull down
335
- pub fn internal_pull_down ( self , on : bool ) -> Self {
339
+ impl < const P : char , const N : u8 , MODE > Pin < P , N , MODE > {
340
+ /// Set the internal pull-up and pull-down resistor
341
+ fn _internal_resistor ( self , resistor : Pull ) -> Self {
336
342
let offset = 2 * { N } ;
337
- let value = if on { 0b10 } else { 0b00 } ;
343
+ let value = resistor as u32 ;
338
344
unsafe {
339
345
( * Gpio :: < P > :: ptr ( ) )
340
346
. pupdr
@@ -345,58 +351,31 @@ impl<const P: char, const N: u8> Pin<P, N, Output<OpenDrain>> {
345
351
}
346
352
}
347
353
348
- impl < const P : char , const N : u8 , const A : u8 > Pin < P , N , Alternate < A , PushPull > > {
349
- /// Set pin speed
350
- pub fn set_speed ( self , speed : Speed ) -> Self {
351
- let offset = 2 * { N } ;
352
-
353
- unsafe {
354
- ( * Gpio :: < P > :: ptr ( ) )
355
- . ospeedr
356
- . modify ( |r, w| w. bits ( ( r. bits ( ) & !( 0b11 << offset) ) | ( ( speed as u32 ) << offset) ) )
357
- } ;
358
-
359
- self
354
+ impl < const P : char , const N : u8 , MODE > Pin < P , N , MODE >
355
+ where
356
+ MODE : sealed:: Active ,
357
+ {
358
+ /// Set the internal pull-up and pull-down resistor
359
+ pub fn internal_resistor ( self , resistor : Pull ) -> Self {
360
+ self . _internal_resistor ( resistor)
360
361
}
361
362
362
363
/// Enables / disables the internal pull up
363
364
pub fn internal_pull_up ( self , on : bool ) -> Self {
364
- let offset = 2 * { N } ;
365
- let value = if on { 0b01 } else { 0b00 } ;
366
- unsafe {
367
- ( * Gpio :: < P > :: ptr ( ) )
368
- . pupdr
369
- . modify ( |r, w| w. bits ( ( r. bits ( ) & !( 0b11 << offset) ) | ( value << offset) ) )
370
- } ;
371
-
372
- self
365
+ if on {
366
+ self . internal_resistor ( Pull :: Up )
367
+ } else {
368
+ self . internal_resistor ( Pull :: None )
369
+ }
373
370
}
374
371
375
372
/// Enables / disables the internal pull down
376
373
pub fn internal_pull_down ( self , on : bool ) -> Self {
377
- let offset = 2 * { N } ;
378
- let value = if on { 0b10 } else { 0b00 } ;
379
- unsafe {
380
- ( * Gpio :: < P > :: ptr ( ) )
381
- . pupdr
382
- . modify ( |r, w| w. bits ( ( r. bits ( ) & !( 0b11 << offset) ) | ( value << offset) ) )
383
- } ;
384
-
385
- self
386
- }
387
- }
388
-
389
- impl < const P : char , const N : u8 , const A : u8 > Pin < P , N , Alternate < A , PushPull > > {
390
- /// Turns pin alternate configuration pin into open drain
391
- pub fn set_open_drain ( self ) -> Pin < P , N , Alternate < A , OpenDrain > > {
392
- let offset = { N } ;
393
- unsafe {
394
- ( * Gpio :: < P > :: ptr ( ) )
395
- . otyper
396
- . modify ( |r, w| w. bits ( r. bits ( ) | ( 1 << offset) ) )
397
- } ;
398
-
399
- Pin :: new ( )
374
+ if on {
375
+ self . internal_resistor ( Pull :: Down )
376
+ } else {
377
+ self . internal_resistor ( Pull :: None )
378
+ }
400
379
}
401
380
}
402
381
@@ -512,7 +491,7 @@ impl<const P: char, const N: u8> Pin<P, N, Output<OpenDrain>> {
512
491
}
513
492
}
514
493
515
- impl < const P : char , const N : u8 , MODE > Pin < P , N , Input < MODE > > {
494
+ impl < const P : char , const N : u8 > Pin < P , N , Input > {
516
495
#[ inline( always) ]
517
496
pub fn is_high ( & self ) -> bool {
518
497
!self . is_low ( )
@@ -533,7 +512,7 @@ macro_rules! gpio {
533
512
use crate :: pac:: { $GPIOX, RCC } ;
534
513
use crate :: rcc:: { Enable , Reset } ;
535
514
use super :: {
536
- Floating , Input ,
515
+ Input ,
537
516
} ;
538
517
539
518
/// GPIO parts
@@ -567,7 +546,7 @@ macro_rules! gpio {
567
546
pub type $PXn<MODE > = super :: PEPin <$port_id, MODE >;
568
547
569
548
$(
570
- pub type $PXi<MODE = Input < Floating > > = super :: Pin <$port_id, $i, MODE >;
549
+ pub type $PXi<MODE = Input > = super :: Pin <$port_id, $i, MODE >;
571
550
) +
572
551
573
552
}
0 commit comments