Skip to content

Commit 70ecce9

Browse files
committed
Consolidate the various GPIO Pin Interrupt functions into a combined API.
The functions: fn {clear,detected,disable,enable}_{rising,falling,status}(PintSlot) and fn read_pint_status(...) become fn pint_op(PintSlot, PintOp, PintCondition) This leaves a couple permutations not covered (enable/disable interrupt at the NVIC level). Those can are left as no-ops for the time being. Future: The unimplemented combinations could return an error/fault if called.
1 parent 681cfea commit 70ecce9

File tree

10 files changed

+233
-254
lines changed

10 files changed

+233
-254
lines changed

Cargo.lock

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

build/lpc55pins/src/lib.rs

Lines changed: 50 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,6 @@ pub enum Opendrain {
103103
#[serde(rename_all = "lowercase")]
104104
#[repr(u32)]
105105
pub enum PintSlot {
106-
None = 8,
107106
Slot0 = 0,
108107
Slot1 = 1,
109108
Slot2 = 2,
@@ -114,35 +113,30 @@ pub enum PintSlot {
114113
Slot7 = 7,
115114
}
116115

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,
116+
impl TryFrom<usize> for PintSlot {
117+
type Error = ();
118+
119+
fn try_from(v: usize) -> Result<Self, Self::Error> {
120+
match v {
121+
0 => Ok(PintSlot::Slot0),
122+
1 => Ok(PintSlot::Slot1),
123+
2 => Ok(PintSlot::Slot2),
124+
3 => Ok(PintSlot::Slot3),
125+
4 => Ok(PintSlot::Slot4),
126+
5 => Ok(PintSlot::Slot5),
127+
6 => Ok(PintSlot::Slot6),
128+
7 => Ok(PintSlot::Slot7),
129+
_ => Err(()),
129130
}
130131
}
131132
}
132133

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-
}
134+
impl PintSlot {
135+
pub fn index(self) -> usize {
136+
self as usize
137+
}
138+
pub fn mask(self) -> u32 {
139+
1u32 << self.index()
146140
}
147141
}
148142

@@ -162,22 +156,26 @@ impl PinConfig {
162156
self.alt
163157
}
164158

165-
fn get_pint_slot(&self, used: &mut u8) -> PintSlot {
166-
if let Some(pint_slot) = self.pint {
159+
fn get_pint_slot(&self, used: &mut u32) -> Option<PintSlot> {
160+
if let Some(slot_number) = self.pint {
167161
if self.pin.port > 1 || self.pin.pin > 32 {
168162
panic!("Invalid gpio pin for interrupt");
169163
}
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);
164+
if let Ok(pint_slot) = PintSlot::try_from(slot_number) {
165+
let mask = pint_slot.mask();
166+
if (*used & mask) != 0 {
167+
panic!(
168+
"Duplicate interrupt slot assignment: {:?}",
169+
self.pin
170+
);
171+
}
172+
*used |= mask;
173+
Some(pint_slot)
174+
} else {
175+
panic!("Invalid pint slot number {}", slot_number);
176176
}
177-
*used |= mask;
178-
PintSlot::from(pint_slot)
179177
} else {
180-
PintSlot::None
178+
None
181179
}
182180
}
183181
}
@@ -209,11 +207,15 @@ pub fn codegen(pins: Vec<PinConfig>) -> Result<()> {
209207
let dest_path = out_dir.join("pin_config.rs");
210208
let mut file = std::fs::File::create(&dest_path)?;
211209

212-
let mut used_slots = 0u8;
210+
let mut used_slots = 0u32;
213211
let mut buf = BufWriter::new(Vec::new());
212+
214213
if pins.iter().any(|p| p.name.is_some()) {
215214
writeln!(&mut buf, "use drv_lpc55_gpio_api::Pin;")?;
216215
}
216+
if pins.iter().any(|p| p.pint.is_some()) {
217+
writeln!(&mut buf, "use drv_lpc55_gpio_api::PintSlot;")?;
218+
}
217219
writeln!(
218220
&mut file,
219221
"fn setup_pins(task : TaskId) -> Result<(), ()> {{"
@@ -223,11 +225,11 @@ pub fn codegen(pins: Vec<PinConfig>) -> Result<()> {
223225
for p in pins {
224226
writeln!(&mut file, "iocon.iocon_configure(")?;
225227
writeln!(&mut file, "{}", p.to_token_stream())?;
226-
writeln!(
227-
&mut file,
228-
"PintSlot::{:?}",
229-
p.get_pint_slot(&mut used_slots)
230-
)?;
228+
if let Some(slot) = p.get_pint_slot(&mut used_slots) {
229+
writeln!(&mut file, "Some(PintSlot::Slot{}),", slot.index())?;
230+
} else {
231+
writeln!(&mut file, "None")?;
232+
}
231233
writeln!(&mut file, ");")?;
232234

233235
// Output pins can specify their value, which is set before configuring
@@ -265,14 +267,14 @@ pub fn codegen(pins: Vec<PinConfig>) -> Result<()> {
265267
&name, pin.0, pin.1
266268
)?;
267269

268-
let mut ignore = 0u8;
269-
let slot = p.get_pint_slot(&mut ignore);
270-
if slot != PintSlot::None {
270+
let mut ignore = 0u32;
271+
if let Some(slot) = p.get_pint_slot(&mut ignore) {
271272
writeln!(&mut buf, "#[allow(unused)]")?;
272273
writeln!(
273274
&mut buf,
274-
"pub const {}_PINT_MASK: u32 = 1 << {};",
275-
&name, slot as u32
275+
"pub const {}_PINT_SLOT: PintSlot = PintSlot::Slot{};",
276+
&name,
277+
slot.index(),
276278
)?;
277279
}
278280
}

drv/lpc55-gpio-api/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ cfg-if.workspace = true
99
idol-runtime.workspace = true
1010
num-traits.workspace = true
1111
zerocopy.workspace = true
12+
serde.workspace = true
13+
hubpack.workspace = true
1214

1315
counters = { path = "../../lib/counters" }
1416
derive-idol-err = { path = "../../lib/derive-idol-err" }

drv/lpc55-gpio-api/src/lib.rs

Lines changed: 71 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
#![no_std]
66

7+
use hubpack::SerializedSize;
8+
use serde::{Deserialize, Serialize};
79
use userlib::{sys_send, FromPrimitive};
810
use zerocopy::AsBytes;
911

@@ -14,7 +16,7 @@ use zerocopy::AsBytes;
1416
// goes 0 - 64
1517
cfg_if::cfg_if! {
1618
if #[cfg(any(target_board = "lpcxpresso55s69"))] {
17-
#[derive(Copy, Clone, Debug, FromPrimitive, AsBytes)]
19+
#[derive(Copy, Clone, Debug, FromPrimitive, AsBytes, Deserialize, Serialize, SerializedSize)]
1820
#[repr(u32)]
1921
pub enum Pin {
2022
PIO0_0 = 0,
@@ -85,7 +87,7 @@ cfg_if::cfg_if! {
8587
}
8688

8789
} else {
88-
#[derive(Copy, Clone, Debug, FromPrimitive, AsBytes)]
90+
#[derive(Copy, Clone, Debug, FromPrimitive, AsBytes, Deserialize, Serialize, SerializedSize)]
8991
#[repr(u32)]
9092
pub enum Pin {
9193
PIO0_0 = 0,
@@ -200,7 +202,18 @@ pub enum Value {
200202
One = 1,
201203
}
202204

203-
#[derive(Copy, Clone, Debug, Eq, PartialEq, AsBytes, FromPrimitive)]
205+
#[derive(
206+
Copy,
207+
Clone,
208+
Debug,
209+
Eq,
210+
PartialEq,
211+
AsBytes,
212+
FromPrimitive,
213+
Serialize,
214+
Deserialize,
215+
SerializedSize,
216+
)]
204217
#[repr(u8)]
205218
pub enum PintSlot {
206219
Slot0 = 0,
@@ -211,7 +224,60 @@ pub enum PintSlot {
211224
Slot5 = 5,
212225
Slot6 = 6,
213226
Slot7 = 7,
214-
None = 8,
227+
}
228+
229+
impl PintSlot {
230+
pub fn index(self) -> usize {
231+
self as usize
232+
}
233+
pub fn mask(self) -> u32 {
234+
1u32 << self.index()
235+
}
236+
}
237+
238+
#[derive(
239+
Copy,
240+
Clone,
241+
Debug,
242+
Eq,
243+
PartialEq,
244+
AsBytes,
245+
FromPrimitive,
246+
Serialize,
247+
Deserialize,
248+
SerializedSize,
249+
)]
250+
#[repr(u8)]
251+
pub enum PintOp {
252+
Clear,
253+
Enable,
254+
Disable,
255+
Detected,
256+
}
257+
258+
#[derive(
259+
Copy,
260+
Clone,
261+
Debug,
262+
Eq,
263+
PartialEq,
264+
AsBytes,
265+
FromPrimitive,
266+
Serialize,
267+
Deserialize,
268+
SerializedSize,
269+
)]
270+
#[repr(u8)]
271+
pub enum PintCondition {
272+
/// Interrupt state for this Pin Interrupt
273+
Status,
274+
/// Rising Edge detection
275+
Rising,
276+
/// Falling Edge detection
277+
Falling,
278+
// TODO: Support Level triggered interrupts.
279+
// High,
280+
// Low,
215281
}
216282

217283
impl Pins {
@@ -247,7 +313,7 @@ impl Pins {
247313
invert: Invert,
248314
digimode: Digimode,
249315
od: Opendrain,
250-
pint_slot: PintSlot,
316+
pint_slot: Option<PintSlot>,
251317
) {
252318
let (_, conf) =
253319
Pins::iocon_conf_val(pin, alt, mode, slew, invert, digimode, od);

drv/lpc55-gpio/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ idol-runtime = { workspace = true }
88
lpc55-pac = { workspace = true }
99
num-traits = { workspace = true }
1010
zerocopy = { workspace = true }
11+
serde = { workspace = true }
12+
hubpack = { workspace = true }
1113

1214
drv-lpc55-gpio-api = { path = "../lpc55-gpio-api" }
1315
drv-lpc55-syscon-api = { path = "../lpc55-syscon-api" }

0 commit comments

Comments
 (0)