Skip to content

Commit 5d2a62f

Browse files
committed
Enable GPIO Pin Interrupts
Add interrupt-related API calls to the LPC55 `gpio_driver`. Also: Fix app/gimletlet/app-mgmt.toml stack size which was found while building all targets. --- A task on an LPC55 can now configue and use GPIO interrupts. app.toml example shows Pin Interrupt configuration: [tasks.foo] ... interrupts = { "pint.irq0" = "button-irq" } ... task-slots = ["gpio_driver", ...] [tasks.foo.config] pins = [ { name="BUTTON', pin={ port=1, pin=9}, alt=0, pint=0, direction="input", opendrain="normal" } ]
1 parent 8ac3cb2 commit 5d2a62f

File tree

17 files changed

+383
-27
lines changed

17 files changed

+383
-27
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/gimletlet/app-mgmt.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ task-slots = ["sys", "user_leds"]
4949

5050
[tasks.net]
5151
name = "task-net"
52-
stacksize = 3000
52+
stacksize = 3328
5353
priority = 3
5454
features = ["mgmt", "h753", "use-spi-core", "spi2"]
5555
max-sizes = {flash = 131072, ram = 16384, sram1_mac = 16384}

app/lpc55xpresso/app-sprot.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ task-slots = ["jefe"]
7676
name = "drv-lpc55-gpio"
7777
priority = 3
7878
max-sizes = {flash = 8192, ram = 2048}
79-
uses = ["gpio", "iocon"]
79+
uses = ["gpio", "iocon", "pint", "inputmux"]
8080
start = true
8181
stacksize = 1000
8282
task-slots = ["syscon_driver"]

app/lpc55xpresso/app.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ task-slots = ["jefe"]
7070
name = "drv-lpc55-gpio"
7171
priority = 3
7272
max-sizes = {flash = 8192, ram = 2048}
73-
uses = ["gpio", "iocon"]
73+
uses = ["gpio", "iocon", "pint", "inputmux"]
7474
start = true
7575
stacksize = 1000
7676
task-slots = ["syscon_driver"]

app/oxide-rot-1/app-dev.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ task-slots = ["jefe"]
7575
name = "drv-lpc55-gpio"
7676
priority = 3
7777
max-sizes = {flash = 8192, ram = 2048}
78-
uses = ["gpio", "iocon"]
78+
uses = ["gpio", "iocon", "pint", "inputmux"]
7979
start = true
8080
task-slots = ["syscon_driver"]
8181

app/oxide-rot-1/app.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ task-slots = ["jefe"]
6161
name = "drv-lpc55-gpio"
6262
priority = 3
6363
max-sizes = {flash = 8192, ram = 2048}
64-
uses = ["gpio", "iocon"]
64+
uses = ["gpio", "iocon", "pint", "inputmux"]
6565
start = true
6666
task-slots = ["syscon_driver"]
6767

app/rot-carrier/app.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,15 @@ task-slots = ["jefe"]
6767
name = "drv-lpc55-gpio"
6868
priority = 3
6969
max-sizes = {flash = 8192, ram = 2048}
70-
uses = ["gpio", "iocon"]
70+
uses = ["gpio", "iocon", "pint", "inputmux"]
7171
start = true
7272
task-slots = ["syscon_driver"]
7373

7474
[tasks.user_leds]
7575
name = "drv-user-leds"
7676
features = ["lpc55"]
7777
priority = 6
78-
max-sizes = {flash = 8192, ram = 1056}
78+
max-sizes = {flash = 8192, ram = 1120}
7979
start = true
8080
task-slots = ["gpio_driver"]
8181
notifications = ["timer"]

build/lpc55pins/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ serde = { workspace = true }
1515
syn = { workspace = true }
1616

1717
build-util = { path = "../util" }
18+
call_rustfmt = { path = "../call_rustfmt"}
1819

1920
[lints]
2021
workspace = true

build/lpc55pins/src/lib.rs

Lines changed: 97 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ pub struct PinConfig {
5454
direction: Option<Direction>,
5555
value: Option<bool>,
5656
name: Option<String>,
57+
pint: Option<usize>,
5758
}
5859

5960
#[derive(Copy, Clone, Debug, Default, Deserialize)]
@@ -98,6 +99,53 @@ pub enum Opendrain {
9899
Opendrain,
99100
}
100101

102+
#[derive(Copy, Clone, Debug, Deserialize, PartialEq)]
103+
#[serde(rename_all = "lowercase")]
104+
#[repr(u32)]
105+
pub enum PintSlot {
106+
None = 8,
107+
Slot0 = 0,
108+
Slot1 = 1,
109+
Slot2 = 2,
110+
Slot3 = 3,
111+
Slot4 = 4,
112+
Slot5 = 5,
113+
Slot6 = 6,
114+
Slot7 = 7,
115+
}
116+
117+
impl From<u32> for PintSlot {
118+
fn from(slot: u32) -> Self {
119+
match slot {
120+
0 => PintSlot::Slot0,
121+
1 => PintSlot::Slot1,
122+
2 => PintSlot::Slot2,
123+
3 => PintSlot::Slot3,
124+
4 => PintSlot::Slot4,
125+
5 => PintSlot::Slot5,
126+
6 => PintSlot::Slot6,
127+
7 => PintSlot::Slot7,
128+
_ => PintSlot::None,
129+
}
130+
}
131+
}
132+
133+
impl From<usize> for PintSlot {
134+
fn from(slot: usize) -> Self {
135+
match slot {
136+
0 => PintSlot::Slot0,
137+
1 => PintSlot::Slot1,
138+
2 => PintSlot::Slot2,
139+
3 => PintSlot::Slot3,
140+
4 => PintSlot::Slot4,
141+
5 => PintSlot::Slot5,
142+
6 => PintSlot::Slot6,
143+
7 => PintSlot::Slot7,
144+
_ => PintSlot::None,
145+
}
146+
}
147+
}
148+
101149
#[derive(Copy, Clone, Debug, Deserialize)]
102150
#[serde(rename_all = "lowercase")]
103151
pub enum Direction {
@@ -113,6 +161,25 @@ impl PinConfig {
113161

114162
self.alt
115163
}
164+
165+
fn get_pint_slot(&self, used: &mut u8) -> PintSlot {
166+
if let Some(pint_slot) = self.pint {
167+
if self.pin.port > 1 || self.pin.pin > 32 {
168+
panic!("Invalid gpio pin for interrupt");
169+
}
170+
if pint_slot > 7 {
171+
panic!("Invalid pint setting {} > 7", pint_slot);
172+
}
173+
let mask = 1 << pint_slot;
174+
if (*used & mask) != 0 {
175+
panic!("Duplicate interrupt slot assignment: {:?}", self.pin);
176+
}
177+
*used |= mask;
178+
PintSlot::from(pint_slot)
179+
} else {
180+
PintSlot::None
181+
}
182+
}
116183
}
117184

118185
impl ToTokens for PinConfig {
@@ -140,21 +207,27 @@ impl ToTokens for PinConfig {
140207
pub fn codegen(pins: Vec<PinConfig>) -> Result<()> {
141208
let out_dir = build_util::out_dir();
142209
let dest_path = out_dir.join("pin_config.rs");
143-
let mut file = std::fs::File::create(dest_path)?;
144-
210+
let mut file = std::fs::File::create(&dest_path)?;
145211
let mut buf = BufWriter::new(Vec::new());
212+
let mut used_slots = 0u8;
213+
146214
if pins.iter().any(|p| p.name.is_some()) {
147-
writeln!(&mut buf, "use drv_lpc55_gpio_api::Pin;")?;
215+
writeln!(&mut file, "use drv_lpc55_gpio_api::Pin;")?;
148216
}
149217
writeln!(
150218
&mut file,
151-
"fn setup_pins(task : TaskId) -> Result<(), ()> {{"
219+
"fn setup_pins(task : userlib::TaskId) -> Result<(), ()> {{"
152220
)?;
153221
writeln!(&mut file, "use drv_lpc55_gpio_api::*;")?;
154222
writeln!(&mut file, "let iocon = Pins::from(task);")?;
155223
for p in pins {
156224
writeln!(&mut file, "iocon.iocon_configure(")?;
157225
writeln!(&mut file, "{}", p.to_token_stream())?;
226+
writeln!(
227+
&mut file,
228+
"PintSlot::{:?}",
229+
p.get_pint_slot(&mut used_slots)
230+
)?;
158231
writeln!(&mut file, ");")?;
159232

160233
// Output pins can specify their value, which is set before configuring
@@ -183,21 +256,38 @@ pub fn codegen(pins: Vec<PinConfig>) -> Result<()> {
183256
}
184257
match p.name {
185258
None => (),
186-
Some(name) => {
259+
Some(ref name) => {
187260
let pin = p.pin.get_port_pin();
188261
writeln!(&mut buf, "#[allow(unused)]")?;
189262
writeln!(
190263
&mut buf,
191264
"const {}: Pin = Pin::PIO{}_{};",
192-
name, pin.0, pin.1
265+
&name, pin.0, pin.1
193266
)?;
267+
268+
let mut ignore = 0u8;
269+
let slot = p.get_pint_slot(&mut ignore);
270+
if slot != PintSlot::None {
271+
writeln!(&mut buf, "#[allow(unused)]")?;
272+
writeln!(
273+
&mut buf,
274+
"pub const {}_PINT_MASK: u32 = 1 << {};",
275+
&name, slot as u32
276+
)?;
277+
}
194278
}
195279
}
196280
}
197281

198282
writeln!(&mut file, "Ok(())")?;
199283
writeln!(&mut file, "}}")?;
200-
write!(file, "{}", String::from_utf8(buf.into_inner()?).unwrap())?;
284+
285+
write!(
286+
&mut file,
287+
"{}",
288+
String::from_utf8(buf.into_inner()?).unwrap()
289+
)?;
290+
call_rustfmt::rustfmt(&dest_path)?;
201291

202292
Ok(())
203293
}

chips/lpc55/chip.toml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,3 +77,12 @@ size = 0x1000
7777
[bootrom]
7878
address = 0x03000000
7979
size = 0x10000
80+
81+
[pint]
82+
address = 0x4000_4000
83+
size = 0x1000
84+
interrupts = { irq0 = 4, irq1 = 5, irq2 = 6, irq3 = 7, irq4 = 32, irq5 = 33, irq6 = 34, irq7 = 35 }
85+
86+
[inputmux]
87+
address = 0x4000_6000
88+
size = 0x1000

0 commit comments

Comments
 (0)