@@ -85,30 +85,28 @@ impl Pin {
85
85
#[ inline( always) ]
86
86
pub fn setup ( & self ) {
87
87
use self :: Function :: * ;
88
+ use self :: reg:: GPIO_moder_mode as RegMode ;
88
89
89
90
self . port . clock ( ) . enable ( ) ; // TODO(farcaller): should be done once per port
90
91
91
- let offset: u32 = self . pin as u32 * 2 ;
92
+ let offset = self . pin as usize ;
92
93
let gpreg = self . get_reg ( ) ;
93
94
94
- let bits : u32 = match self . function {
95
- GPIOOut => 0b01 << offset as usize ,
96
- GPIOIn => 0b00 << offset as usize ,
95
+ let val = match self . function {
96
+ GPIOOut => RegMode :: Output ,
97
+ GPIOIn => RegMode :: Input ,
97
98
_ => unsafe { abort ( ) } , // FIXME(farcaller): not implemented
98
99
} ;
99
- let mask: u32 = !( 0b11 << offset as usize ) ;
100
- let val: u32 = gpreg. MODER ( ) ;
101
100
102
- gpreg. set_MODER ( val & mask | bits ) ;
101
+ gpreg. moder . set_mode ( offset , val ) ;
103
102
}
104
103
105
104
/// Toggles the GPIO value
106
105
pub fn toggle ( & self ) {
107
- let bit: u32 = 1 << self . pin as usize ;
108
106
let reg = self . get_reg ( ) ;
109
- let val : u32 = reg . ODR ( ) ;
107
+ let offset = self . pin as usize ;
110
108
111
- reg. set_ODR ( val ^ bit ) ;
109
+ reg. odr . set_od ( offset , !reg . odr . od ( offset ) ) ;
112
110
}
113
111
114
112
fn get_reg ( & self ) -> & reg:: GPIO {
@@ -129,23 +127,23 @@ impl Pin {
129
127
impl Gpio for Pin {
130
128
/// Sets output GPIO value to high.
131
129
fn set_high ( & self ) {
132
- let bit : u32 = 1 << self . pin as usize ;
133
- self . get_reg ( ) . set_BSRR ( bit ) ;
130
+ let offset = self . pin as usize ;
131
+ self . get_reg ( ) . bsrr . set_bs ( offset , true ) ;
134
132
}
135
133
136
134
/// Sets output GPIO value to low.
137
135
fn set_low ( & self ) {
138
- let bit : u32 = 1 << ( self . pin as usize + 16 ) ;
139
- self . get_reg ( ) . set_BSRR ( bit ) ;
136
+ let offset = self . pin as usize ;
137
+ self . get_reg ( ) . bsrr . set_br ( offset , true ) ;
140
138
}
141
139
142
140
/// Returns input GPIO level.
143
141
fn level ( & self ) -> GpioLevel {
144
- let bit : u32 = 1 << ( self . pin as usize ) ;
142
+ let offset = self . pin as usize ;
145
143
let reg = self . get_reg ( ) ;
146
144
147
- match reg. IDR ( ) & bit {
148
- 0 => GpioLevel :: Low ,
145
+ match reg. idr . id ( offset ) {
146
+ false => GpioLevel :: Low ,
149
147
_ => GpioLevel :: High ,
150
148
}
151
149
}
@@ -154,35 +152,75 @@ impl Gpio for Pin {
154
152
fn set_direction ( & self , new_mode : GpioDirection ) {
155
153
// TODO(darayus): Verify that this works
156
154
// TODO(darayus): Change the Pin.function field to the new mode
157
- let offset: u32 = self . pin as u32 * 2 ;
158
- let gpreg = self . get_reg ( ) ;
155
+ use self :: reg:: GPIO_moder_mode as RegMode ;
156
+ let offset = self . pin as usize ;
157
+ let reg = self . get_reg ( ) ;
159
158
160
- let bits : u32 = match new_mode {
161
- GpioDirection :: Out => 0b01 << offset as usize ,
162
- GpioDirection :: In => 0b00 << offset as usize ,
159
+ let val = match new_mode {
160
+ GpioDirection :: Out => RegMode :: Output ,
161
+ GpioDirection :: In => RegMode :: Input ,
163
162
} ;
164
- let mask: u32 = !( 0b11 << offset as usize ) ;
165
- let val: u32 = gpreg. MODER ( ) ;
166
163
167
- gpreg . set_MODER ( val & mask | bits ) ;
164
+ reg . moder . set_mode ( offset , val ) ;
168
165
}
169
166
}
170
167
171
168
#[ allow( dead_code) ]
172
169
mod reg {
170
+ use core:: ops:: Drop ;
173
171
use volatile_cell:: VolatileCell ;
174
172
175
- ioreg_old ! ( GPIO : u32 , MODER , OTYPER , OSPEEDER , PUPDR , IDR , ODR , BSRR , LCKR , AFRL , AFRH ) ;
176
- reg_rw ! ( GPIO , u32 , MODER , set_MODER, MODER ) ;
177
- reg_rw ! ( GPIO , u32 , OTYPER , set_OTYPER, OTYPER ) ;
178
- reg_rw ! ( GPIO , u32 , OSPEEDER , set_OSPEEDER, OSPEEDER ) ;
179
- reg_rw ! ( GPIO , u32 , PUPDR , set_PUPDR, PUPDR ) ;
180
- reg_rw ! ( GPIO , u32 , IDR , set_IDR, IDR ) ;
181
- reg_rw ! ( GPIO , u32 , ODR , set_ODR, ODR ) ;
182
- reg_rw ! ( GPIO , u32 , BSRR , set_BSRR, BSRR ) ;
183
- reg_rw ! ( GPIO , u32 , LCKR , set_LCKR, LCKR ) ;
184
- reg_rw ! ( GPIO , u32 , AFRL , set_AFRL, AFRL ) ;
185
- reg_rw ! ( GPIO , u32 , AFRH , set_AFRH, AFRH ) ;
173
+ ioregs ! ( GPIO = {
174
+ 0x0 => reg32 moder {
175
+ 0 ..31 => mode[ 16 ] {
176
+ 0 => Input ,
177
+ 1 => Output ,
178
+ 3 => Alternate ,
179
+ 4 => Analog
180
+ }
181
+ }
182
+ 0x04 => reg32 otyper {
183
+ 0 ..15 => ot[ 16 ] {
184
+ 0 => PushPull ,
185
+ 1 => OpenDrain
186
+ }
187
+ }
188
+ 0x08 => reg32 ospeedr {
189
+ 0 ..31 => ospeed[ 16 ] {
190
+ 0 => Low ,
191
+ 1 => Medium ,
192
+ 2 => Fast ,
193
+ 3 => High
194
+ }
195
+ }
196
+ 0x0c => reg32 pupdr {
197
+ 0 ..31 => pupd[ 16 ] {
198
+ 0 => None ,
199
+ 1 => PullUp ,
200
+ 2 => PullDown
201
+ }
202
+ }
203
+ 0x10 => reg32 idr {
204
+ 0 ..15 => id[ 16 ] : ro
205
+ }
206
+ 0x14 => reg32 odr {
207
+ 0 ..15 => od[ 16 ]
208
+ }
209
+ 0x18 => reg32 bsrr {
210
+ 0 ..15 => bs[ 16 ] : wo,
211
+ 16 ..31 => br[ 16 ] : wo
212
+ }
213
+ 0x1c => reg32 lckr {
214
+ 0 ..15 => lck[ 16 ] ,
215
+ 16 => lckk
216
+ }
217
+ 0x20 => reg32 afrl {
218
+ 0 ..31 => afrl[ 8 ]
219
+ }
220
+ 0x24 => reg32 afrh {
221
+ 0 ..31 => afrh[ 8 ]
222
+ }
223
+ } ) ;
186
224
187
225
extern {
188
226
#[ link_name="stm32f4_iomem_GPIOA" ] pub static GPIO_A : GPIO ;
0 commit comments