Skip to content
This repository was archived by the owner on Jul 6, 2019. It is now read-only.

Commit 3a09256

Browse files
committed
Merge pull request #1 from mcoffin/extend-325-stm32f4-pin
stm32f4: switch GPIO to new ioregs macro
2 parents 2afcbd6 + cd1475c commit 3a09256

File tree

1 file changed

+74
-36
lines changed

1 file changed

+74
-36
lines changed

src/hal/stm32f4/pin.rs

Lines changed: 74 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -85,30 +85,28 @@ impl Pin {
8585
#[inline(always)]
8686
pub fn setup(&self) {
8787
use self::Function::*;
88+
use self::reg::GPIO_moder_mode as RegMode;
8889

8990
self.port.clock().enable(); // TODO(farcaller): should be done once per port
9091

91-
let offset: u32 = self.pin as u32 * 2;
92+
let offset = self.pin as usize;
9293
let gpreg = self.get_reg();
9394

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,
9798
_ => unsafe { abort() }, // FIXME(farcaller): not implemented
9899
};
99-
let mask: u32 = !(0b11 << offset as usize);
100-
let val: u32 = gpreg.MODER();
101100

102-
gpreg.set_MODER(val & mask | bits);
101+
gpreg.moder.set_mode(offset, val);
103102
}
104103

105104
/// Toggles the GPIO value
106105
pub fn toggle(&self) {
107-
let bit: u32 = 1 << self.pin as usize;
108106
let reg = self.get_reg();
109-
let val: u32 = reg.ODR();
107+
let offset = self.pin as usize;
110108

111-
reg.set_ODR(val ^ bit);
109+
reg.odr.set_od(offset, !reg.odr.od(offset));
112110
}
113111

114112
fn get_reg(&self) -> &reg::GPIO {
@@ -129,23 +127,23 @@ impl Pin {
129127
impl Gpio for Pin {
130128
/// Sets output GPIO value to high.
131129
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);
134132
}
135133

136134
/// Sets output GPIO value to low.
137135
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);
140138
}
141139

142140
/// Returns input GPIO level.
143141
fn level(&self) -> GpioLevel {
144-
let bit: u32 = 1 << (self.pin as usize);
142+
let offset = self.pin as usize;
145143
let reg = self.get_reg();
146144

147-
match reg.IDR() & bit {
148-
0 => GpioLevel::Low,
145+
match reg.idr.id(offset) {
146+
false => GpioLevel::Low,
149147
_ => GpioLevel::High,
150148
}
151149
}
@@ -154,35 +152,75 @@ impl Gpio for Pin {
154152
fn set_direction(&self, new_mode: GpioDirection) {
155153
// TODO(darayus): Verify that this works
156154
// 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();
159158

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,
163162
};
164-
let mask: u32 = !(0b11 << offset as usize);
165-
let val: u32 = gpreg.MODER();
166163

167-
gpreg.set_MODER(val & mask | bits);
164+
reg.moder.set_mode(offset, val);
168165
}
169166
}
170167

171168
#[allow(dead_code)]
172169
mod reg {
170+
use core::ops::Drop;
173171
use volatile_cell::VolatileCell;
174172

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+
});
186224

187225
extern {
188226
#[link_name="stm32f4_iomem_GPIOA"] pub static GPIO_A: GPIO;

0 commit comments

Comments
 (0)