1
1
//! General purpose input-output pins
2
2
3
3
use crate :: { adc, pac} ;
4
- use core:: ptr:: { read_volatile, write_volatile} ;
5
4
use cortex_m:: interrupt:: CriticalSection ;
6
5
7
6
pub use embedded_hal:: digital:: v2:: PinState ;
@@ -55,7 +54,6 @@ pub enum Speed {
55
54
#[ repr( u8 ) ]
56
55
#[ derive( Debug , PartialEq , Eq , Clone , Copy ) ]
57
56
#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
58
-
59
57
pub enum Pull {
60
58
/// No pull-up, no pull-down.
61
59
None = 0b00 ,
@@ -65,6 +63,10 @@ pub enum Pull {
65
63
Down = 0b10 ,
66
64
}
67
65
66
+ const GPIOA_BASE : usize = 0x4800_0000 ;
67
+ const GPIOB_BASE : usize = 0x4800_0400 ;
68
+ const GPIOC_BASE : usize = 0x4800_0800 ;
69
+
68
70
#[ derive( Debug ) ]
69
71
#[ cfg_attr( feature = "defmt" , derive( defmt:: Format ) ) ]
70
72
struct Pin < const BASE : usize , const N : u8 > { }
@@ -73,6 +75,10 @@ impl<const BASE: usize, const N: u8> Pin<BASE, N> {
73
75
const _NPANIC: ( ) = if N > 15 {
74
76
core:: panic!( "Pin index is out of range" )
75
77
} ;
78
+ const _BASEPANIC: ( ) = match BASE {
79
+ GPIOA_BASE | GPIOB_BASE | GPIOC_BASE => ( ) ,
80
+ _ => core:: panic!( "Base address is invalid" ) ,
81
+ } ;
76
82
77
83
const MODER_R : * const u32 = BASE as * const u32 ;
78
84
const MODER_W : * mut u32 = BASE as * mut u32 ;
@@ -97,41 +103,41 @@ impl<const BASE: usize, const N: u8> Pin<BASE, N> {
97
103
98
104
#[ inline( always) ]
99
105
pub ( crate ) fn set_mode ( & mut self , _cs : & CriticalSection , mode : sealed:: Mode ) {
100
- let mut val: u32 = unsafe { read_volatile ( Self :: MODER_R ) } ;
106
+ let mut val: u32 = unsafe { Self :: MODER_R . read_volatile ( ) } ;
101
107
val &= !( 0b11 << ( N * 2 ) ) ;
102
108
val |= ( mode as u8 as u32 ) << ( N * 2 ) ;
103
- unsafe { write_volatile ( Self :: MODER_W , val) } ;
109
+ unsafe { Self :: MODER_W . write_volatile ( val) } ;
104
110
}
105
111
106
112
#[ inline( always) ]
107
113
pub ( crate ) fn set_output_type ( & mut self , _cs : & CriticalSection , ot : OutputType ) {
108
- let mut val: u32 = unsafe { read_volatile ( Self :: OTYPER_R ) } ;
114
+ let mut val: u32 = unsafe { Self :: OTYPER_R . read_volatile ( ) } ;
109
115
match ot {
110
116
OutputType :: PushPull => val &= !( 1 << N ) ,
111
117
OutputType :: OpenDrain => val |= 1 << N ,
112
118
}
113
- unsafe { write_volatile ( Self :: OTYPER_W , val) } ;
119
+ unsafe { Self :: OTYPER_W . write_volatile ( val) } ;
114
120
}
115
121
116
122
#[ inline( always) ]
117
123
pub ( crate ) fn set_speed ( & mut self , _cs : & CriticalSection , speed : Speed ) {
118
- let mut val: u32 = unsafe { read_volatile ( Self :: OSPEEDR_R ) } ;
124
+ let mut val: u32 = unsafe { Self :: OSPEEDR_R . read_volatile ( ) } ;
119
125
val &= !( 0b11 << ( N * 2 ) ) ;
120
126
val |= ( speed as u8 as u32 ) << ( N * 2 ) ;
121
- unsafe { write_volatile ( Self :: OSPEEDR_W , val) } ;
127
+ unsafe { Self :: OSPEEDR_W . write_volatile ( val) } ;
122
128
}
123
129
124
130
#[ inline( always) ]
125
131
pub ( crate ) fn set_pull ( & mut self , _cs : & CriticalSection , pull : Pull ) {
126
- let mut val: u32 = unsafe { read_volatile ( Self :: PUPDR_R ) } ;
132
+ let mut val: u32 = unsafe { Self :: PUPDR_R . read_volatile ( ) } ;
127
133
val &= !( 0b11 << ( N * 2 ) ) ;
128
134
val |= ( pull as u8 as u32 ) << ( N * 2 ) ;
129
- unsafe { write_volatile ( Self :: PUPDR_W , val) } ;
135
+ unsafe { Self :: PUPDR_W . write_volatile ( val) } ;
130
136
}
131
137
132
138
#[ inline( always) ]
133
139
pub ( crate ) fn input_level ( & self ) -> PinState {
134
- if unsafe { read_volatile ( Self :: IDR ) } & ( 1 << N ) == 0 {
140
+ if unsafe { Self :: IDR . read_volatile ( ) } & ( 1 << N ) == 0 {
135
141
PinState :: Low
136
142
} else {
137
143
PinState :: High
@@ -140,7 +146,7 @@ impl<const BASE: usize, const N: u8> Pin<BASE, N> {
140
146
141
147
#[ inline( always) ]
142
148
pub ( crate ) fn output_level ( & self ) -> PinState {
143
- if unsafe { read_volatile ( Self :: ODR ) } & ( 1 << N ) == 0 {
149
+ if unsafe { Self :: ODR . read_volatile ( ) } & ( 1 << N ) == 0 {
144
150
PinState :: Low
145
151
} else {
146
152
PinState :: High
@@ -153,16 +159,16 @@ impl<const BASE: usize, const N: u8> Pin<BASE, N> {
153
159
PinState :: Low => 1 << ( N + 16 ) ,
154
160
PinState :: High => 1 << N ,
155
161
} ;
156
- unsafe { write_volatile ( Self :: BSRR , val) }
162
+ unsafe { Self :: BSRR . write_volatile ( val) }
157
163
}
158
164
159
165
#[ inline( always) ]
160
166
pub ( crate ) fn set_alternate_function ( & mut self , cs : & CriticalSection , af : u8 ) {
161
167
self . set_mode ( cs, sealed:: Mode :: Alternate ) ;
162
- let mut val: u32 = unsafe { read_volatile ( Self :: AF_R ) } ;
168
+ let mut val: u32 = unsafe { Self :: AF_R . read_volatile ( ) } ;
163
169
val &= !( 0b1111 << Self :: AF_SHIFT ) ;
164
170
val |= ( af as u8 as u32 ) << Self :: AF_SHIFT ;
165
- unsafe { write_volatile ( Self :: AF_W , val) } ;
171
+ unsafe { Self :: AF_W . write_volatile ( val) } ;
166
172
}
167
173
}
168
174
@@ -442,17 +448,10 @@ pub trait Exti {
442
448
443
449
/// GPIO pins
444
450
pub mod pins {
445
- // Switch to this when avaliable on stable
446
- // https://github.com/rust-lang/rust/issues/51910
447
- // const GPIOA_BASE: usize = pac::GPIOA::PTR as *const _ as usize;
448
- // const GPIOB_BASE: usize = pac::GPIOB::PTR as *const _ as usize;
449
- // const GPIOC_BASE: usize = pac::GPIOC::PTR as *const _ as usize;
450
-
451
- const GPIOA_BASE : usize = 0x4800_0000 ;
452
- const GPIOB_BASE : usize = 0x4800_0400 ;
453
- const GPIOC_BASE : usize = 0x4800_0800 ;
454
-
455
- use super :: { adc, pac, CriticalSection , OutputType , Pin , PinState , Pull , Speed } ;
451
+ use super :: {
452
+ adc, pac, CriticalSection , OutputType , Pin , PinState , Pull , Speed , GPIOA_BASE , GPIOB_BASE ,
453
+ GPIOC_BASE ,
454
+ } ;
456
455
457
456
macro_rules! gpio_struct {
458
457
( $name: ident, $base: expr, $n: expr, $doc: expr) => {
0 commit comments