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

Commit f342ba3

Browse files
committed
Merge pull request #136 from bgamari/ioreg-lpc
Refactor LPC17xx to use `ioregs!` Reviewed-by:
2 parents 2af9fe6 + 59dc8db commit f342ba3

File tree

2 files changed

+80
-57
lines changed

2 files changed

+80
-57
lines changed

src/hal/lpc17xx/iomem.ld

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,7 @@ lpc17xx_iomem_TIMER1 = 0x40008000;
4747

4848
lpc17xx_iomem_UART0 = 0x4000C000;
4949

50-
lpc17xx_iomem_PINSEL0 = 0x4002C000;
51-
lpc17xx_iomem_PINSEL1 = 0x4002C004;
52-
lpc17xx_iomem_PINSEL2 = 0x4002C008;
53-
lpc17xx_iomem_PINSEL3 = 0x4002C00C;
54-
lpc17xx_iomem_PINSEL4 = 0x4002C010;
55-
lpc17xx_iomem_PINSEL7 = 0x4002C01C;
56-
lpc17xx_iomem_PINSEL9 = 0x4002C024;
57-
lpc17xx_iomem_PINSEL10 = 0x4002C028;
50+
lpc17xx_iomem_PINSEL = 0x4002C000;
5851

5952
lpc17xx_iomem_SSP1 = 0x40030000;
6053
lpc17xx_iomem_SSP0 = 0x40088000;

src/hal/lpc17xx/pin.rs

Lines changed: 79 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -69,20 +69,14 @@ impl Pin {
6969
fn setup_regs(&self, function: Function,
7070
gpiodir: Option<::hal::pin::GPIODirection>) {
7171
let (offset, reg) = self.get_pinsel_reg_and_offset();
72-
73-
let fun_bits: u32 = function as u32 << (offset as uint * 2);
74-
let mask_bits: u32 = !(3u32 << (offset as uint * 2));
75-
76-
let val: u32 = reg.value();
77-
let new_val = (val & mask_bits) | fun_bits;
78-
reg.set_value(new_val);
72+
reg.set_pin(offset as uint, function as u32);
7973

8074
if function == GPIO {
8175
(self as &::hal::pin::GPIO).set_direction(gpiodir.unwrap());
8276
}
8377
}
8478

85-
fn gpioreg(&self) -> &reg::GPIO {
79+
fn gpioreg(&self) -> &'static reg::GPIO {
8680
match self.port {
8781
Port0 => &reg::GPIO0,
8882
Port1 => &reg::GPIO1,
@@ -92,28 +86,28 @@ impl Pin {
9286
}
9387
}
9488

95-
fn get_pinsel_reg_and_offset(&self) -> (u8, &reg::PINSEL) {
89+
fn get_pinsel_reg_and_offset(&self) -> (u8, &'static reg::PINSEL_pinsel) {
9690
match self.port {
9791
Port0 => match self.pin {
98-
0..15 => (self.pin, &reg::PINSEL0),
99-
16..30 => (self.pin-16, &reg::PINSEL1),
92+
0..15 => (self.pin, &reg::PINSEL.pinsel[0]),
93+
16..30 => (self.pin-16, &reg::PINSEL.pinsel[1]),
10094
_ => unsafe { abort() },
10195
},
10296
Port1 => match self.pin {
103-
0..15 => (self.pin, &reg::PINSEL2),
104-
16..31 => (self.pin-16, &reg::PINSEL3),
97+
0..15 => (self.pin, &reg::PINSEL.pinsel[2]),
98+
16..31 => (self.pin-16, &reg::PINSEL.pinsel[3]),
10599
_ => unsafe { abort() },
106100
},
107101
Port2 => match self.pin {
108-
0..13 => (self.pin, &reg::PINSEL4),
102+
0..13 => (self.pin, &reg::PINSEL.pinsel[4]),
109103
_ => unsafe { abort() },
110104
},
111105
Port3 => match self.pin {
112-
25|26 => (self.pin-16, &reg::PINSEL7),
106+
25|26 => (self.pin-16, &reg::PINSEL.pinsel[7]),
113107
_ => unsafe { abort() },
114108
},
115109
Port4 => match self.pin {
116-
28|29 => (self.pin-16, &reg::PINSEL9),
110+
28|29 => (self.pin-16, &reg::PINSEL.pinsel[9]),
117111
_ => unsafe { abort() },
118112
},
119113
}
@@ -123,69 +117,105 @@ impl Pin {
123117
impl ::hal::pin::GPIO for Pin {
124118
/// Sets output GPIO value to high.
125119
fn set_high(&self) {
126-
self.gpioreg().set_FIOSET(1 << (self.pin as uint));
120+
self.gpioreg().fioset.set_set(self.pin as uint, true);
127121
}
128122

129123
/// Sets output GPIO value to low.
130124
fn set_low(&self) {
131-
self.gpioreg().set_FIOCLR(1 << (self.pin as uint));
125+
self.gpioreg().fioclr.set_clr(self.pin as uint, true);
132126
}
133127

134128
/// Returns input GPIO level.
135129
fn level(&self) -> ::hal::pin::GPIOLevel {
136-
let bit: u32 = 1 << (self.pin as uint);
137130
let reg = self.gpioreg();
138-
139-
match reg.FIOPIN() & bit {
140-
0 => ::hal::pin::Low,
141-
_ => ::hal::pin::High,
131+
match reg.fiopin.pin(self.pin as uint) {
132+
false => ::hal::pin::Low,
133+
_ => ::hal::pin::High,
142134
}
143135
}
144136

145137
/// Sets output GPIO direction.
146138
fn set_direction(&self, new_mode: ::hal::pin::GPIODirection) {
147-
let bit: u32 = 1 << (self.pin as uint);
148-
let mask: u32 = !bit;
149139
let reg = self.gpioreg();
150-
let val: u32 = reg.FIODIR();
151-
let new_val: u32 = match new_mode {
152-
::hal::pin::In => val & mask,
153-
::hal::pin::Out => (val & mask) | bit,
140+
match new_mode {
141+
::hal::pin::In => reg.fiodir.set_dir(self.pin as uint, reg::INPUT),
142+
::hal::pin::Out => reg.fiodir.set_dir(self.pin as uint, reg::OUTPUT),
154143
};
155-
156-
reg.set_FIODIR(new_val);
157144
}
158145
}
159146

160147
/// Sets the state of trace port interface.
161148
pub fn set_trace_port_interface_enabled(enabled: bool) {
162-
let value: u32 = if enabled { 0b1000 } else { 0 };
163-
reg::PINSEL10.set_value(value);
149+
reg::PINSEL.pinsel10.set_gpio_trace(enabled);
164150
}
165151

166152
mod reg {
167153
use lib::volatile_cell::VolatileCell;
154+
use core::ops::Drop;
155+
156+
ioregs!(PINSEL = {
157+
0x0 => reg32 pinsel[10] /// Pin function select register
158+
{
159+
0..31 => pin[16]
160+
}
161+
162+
0x28 => reg32 pinsel10 /// TPIU interface enable register
163+
{
164+
3 => gpio_trace,
165+
}
166+
167+
0x40 => reg32 pinmode[10] /// Pin pull-up/down select register
168+
{
169+
0..31 => pin[16] {
170+
0x0 => PULL_UP,
171+
0x1 => REPEATER,
172+
0x2 => NO_PULL,
173+
0x3 => PULL_DOWN,
174+
}
175+
}
176+
177+
0x68 => reg32 pinmode_od[5] /// Pin open-drain mode select register
178+
{
179+
0..31 => pin[32],
180+
}
168181

169-
ioreg_old!(PINSEL: u32, value)
170-
reg_rw!(PINSEL, u32, value, set_value, value)
182+
0x7c => reg32 i2cpadcfg /// I2C pin configuration register
183+
{
184+
0 => sdadrv0,
185+
1 => sdai2c0,
186+
2 => scldrv0,
187+
3 => scli2c0,
188+
}
189+
})
171190

172191
extern {
173-
#[link_name="lpc17xx_iomem_PINSEL0"] pub static PINSEL0: PINSEL;
174-
#[link_name="lpc17xx_iomem_PINSEL1"] pub static PINSEL1: PINSEL;
175-
#[link_name="lpc17xx_iomem_PINSEL2"] pub static PINSEL2: PINSEL;
176-
#[link_name="lpc17xx_iomem_PINSEL3"] pub static PINSEL3: PINSEL;
177-
#[link_name="lpc17xx_iomem_PINSEL4"] pub static PINSEL4: PINSEL;
178-
#[link_name="lpc17xx_iomem_PINSEL7"] pub static PINSEL7: PINSEL;
179-
#[link_name="lpc17xx_iomem_PINSEL9"] pub static PINSEL9: PINSEL;
180-
#[link_name="lpc17xx_iomem_PINSEL10"] pub static PINSEL10: PINSEL;
192+
#[link_name="lpc17xx_iomem_PINSEL"] pub static PINSEL: PINSEL;
181193
}
182194

183-
ioreg_old!(GPIO: u32, FIODIR, _r0, _r1, _r2, FIOMASK, FIOPIN, FIOSET, FIOCLR)
184-
reg_rw!(GPIO, u32, FIODIR, set_FIODIR, FIODIR)
185-
reg_rw!(GPIO, u32, FIOMASK, set_FIOMASK, FIOMASK)
186-
reg_rw!(GPIO, u32, FIOPIN, set_FIOPIN, FIOPIN)
187-
reg_rw!(GPIO, u32, FIOSET, set_FIOSET, FIOSET)
188-
reg_rw!(GPIO, u32, FIOCLR, set_FIOCLR, FIOCLR)
195+
ioregs!(GPIO = {
196+
0x0 => reg32 fiodir {
197+
0..31 => dir[32] {
198+
0x0 => INPUT,
199+
0x1 => OUTPUT,
200+
}
201+
}
202+
203+
0x10 => reg32 fiomask {
204+
0..31 => mask[32],
205+
}
206+
207+
0x14 => reg32 fiopin {
208+
0..31 => pin[32],
209+
}
210+
211+
0x18 => reg32 fioset {
212+
0..31 => set[32],
213+
}
214+
215+
0x1c => reg32 fioclr {
216+
0..31 => clr[32],
217+
}
218+
})
189219

190220
extern {
191221
#[link_name="lpc17xx_iomem_GPIO0"] pub static GPIO0: GPIO;

0 commit comments

Comments
 (0)