1
1
use super :: * ;
2
2
3
- pub use ErasedPin as AnyPin ;
4
-
5
3
/// Fully erased pin
6
4
///
7
5
/// `MODE` is one of the pin modes (see [Modes](crate::gpio#modes) section).
8
- pub struct ErasedPin < MODE > {
6
+ pub struct AnyPin < MODE > {
9
7
// Bits 0-3: Pin, Bits 4-7: Port
10
8
pin_port : u8 ,
11
9
_mode : PhantomData < MODE > ,
12
10
}
13
11
14
- impl < MODE > fmt:: Debug for ErasedPin < MODE > {
12
+ impl < MODE > fmt:: Debug for AnyPin < MODE > {
15
13
fn fmt ( & self , formatter : & mut fmt:: Formatter ) -> fmt:: Result {
16
14
formatter. write_fmt ( format_args ! (
17
15
"P({}{})<{}>" ,
@@ -23,7 +21,7 @@ impl<MODE> fmt::Debug for ErasedPin<MODE> {
23
21
}
24
22
25
23
#[ cfg( feature = "defmt" ) ]
26
- impl < MODE > defmt:: Format for ErasedPin < MODE > {
24
+ impl < MODE > defmt:: Format for AnyPin < MODE > {
27
25
fn format ( & self , f : defmt:: Formatter ) {
28
26
defmt:: write!(
29
27
f,
@@ -35,7 +33,7 @@ impl<MODE> defmt::Format for ErasedPin<MODE> {
35
33
}
36
34
}
37
35
38
- impl < MODE > PinExt for ErasedPin < MODE > {
36
+ impl < MODE > PinExt for AnyPin < MODE > {
39
37
type Mode = MODE ;
40
38
41
39
#[ inline( always) ]
@@ -48,7 +46,7 @@ impl<MODE> PinExt for ErasedPin<MODE> {
48
46
}
49
47
}
50
48
51
- impl < MODE > ErasedPin < MODE > {
49
+ impl < MODE > AnyPin < MODE > {
52
50
pub ( crate ) fn from_pin_port ( pin_port : u8 ) -> Self {
53
51
Self {
54
52
pin_port,
@@ -73,7 +71,7 @@ impl<MODE> ErasedPin<MODE> {
73
71
}
74
72
75
73
#[ inline]
76
- pub ( crate ) fn block ( & self ) -> & crate :: pac:: gpioa:: RegisterBlock {
74
+ pub ( crate ) unsafe fn block ( & self ) -> * const crate :: pac:: gpioa:: RegisterBlock {
77
75
// This function uses pointer arithmetic instead of branching to be more efficient
78
76
79
77
// The logic relies on the following assumptions:
@@ -86,29 +84,30 @@ impl<MODE> ErasedPin<MODE> {
86
84
const GPIO_REGISTER_OFFSET : usize = 0x0400 ;
87
85
88
86
let offset = GPIO_REGISTER_OFFSET * self . port_id ( ) as usize ;
89
- let block_ptr =
90
- ( crate :: pac:: GPIOA :: ptr ( ) as usize + offset) as * const crate :: pac:: gpioa:: RegisterBlock ;
91
-
92
- unsafe { & * block_ptr }
87
+ ( crate :: pac:: GPIOA :: ptr ( ) as usize + offset) as * const crate :: pac:: gpioa:: RegisterBlock
93
88
}
94
89
}
95
90
96
- impl < MODE > ErasedPin < Output < MODE > > {
91
+ impl < MODE > AnyPin < Output < MODE > > {
97
92
/// Drives the pin high
98
93
#[ inline( always) ]
99
94
pub fn set_high ( & mut self ) {
100
95
// NOTE(unsafe) atomic write to a stateless register
101
- unsafe { self . block ( ) . bsrr ( ) . write ( |w| w. bits ( 1 << self . pin_id ( ) ) ) } ;
96
+ unsafe {
97
+ ( * self . block ( ) )
98
+ . bsrr ( )
99
+ . write ( |w| w. bs ( self . pin_id ( ) ) . set_bit ( ) )
100
+ } ;
102
101
}
103
102
104
103
/// Drives the pin low
105
104
#[ inline( always) ]
106
105
pub fn set_low ( & mut self ) {
107
106
// NOTE(unsafe) atomic write to a stateless register
108
107
unsafe {
109
- self . block ( )
108
+ ( * self . block ( ) )
110
109
. bsrr ( )
111
- . write ( |w| w. bits ( 1 << ( self . pin_id ( ) + 16 ) ) )
110
+ . write ( |w| w. br ( self . pin_id ( ) ) . set_bit ( ) )
112
111
} ;
113
112
}
114
113
@@ -140,7 +139,13 @@ impl<MODE> ErasedPin<Output<MODE>> {
140
139
/// Is the pin in drive low mode?
141
140
#[ inline( always) ]
142
141
pub fn is_set_low ( & self ) -> bool {
143
- self . block ( ) . odr ( ) . read ( ) . bits ( ) & ( 1 << self . pin_id ( ) ) == 0
142
+ unsafe {
143
+ ( * self . block ( ) )
144
+ . odr ( )
145
+ . read ( )
146
+ . odr ( self . pin_id ( ) )
147
+ . bit_is_clear ( )
148
+ }
144
149
}
145
150
146
151
/// Toggle pin output
@@ -154,7 +159,7 @@ impl<MODE> ErasedPin<Output<MODE>> {
154
159
}
155
160
}
156
161
157
- impl < MODE > ErasedPin < MODE >
162
+ impl < MODE > AnyPin < MODE >
158
163
where
159
164
MODE : marker:: Readable ,
160
165
{
@@ -167,6 +172,12 @@ where
167
172
/// Is the input pin low?
168
173
#[ inline( always) ]
169
174
pub fn is_low ( & self ) -> bool {
170
- self . block ( ) . idr ( ) . read ( ) . bits ( ) & ( 1 << self . pin_id ( ) ) == 0
175
+ unsafe {
176
+ ( * self . block ( ) )
177
+ . idr ( )
178
+ . read ( )
179
+ . idr ( self . pin_id ( ) )
180
+ . bit_is_clear ( )
181
+ }
171
182
}
172
183
}
0 commit comments