1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
use crate::{
drivers::pins::Pin,
peripherals::{inputmux::InputMux, syscon},
raw,
typestates::{
init_state,
pin::{gpio::direction, state, PinId},
},
};
use core::ops::Deref;
pub enum Mode {
RisingEdge,
FallingEdge,
ActiveLow,
ActiveHigh,
}
/// Bit position 0 - 7 indicating which of the 8 external interrupt positions to use
#[repr(u8)]
#[derive(Copy, Clone, Debug)]
pub enum Slot {
Slot0 = 0,
Slot1 = 1,
Slot2 = 2,
Slot3 = 3,
Slot4 = 4,
Slot5 = 5,
Slot6 = 6,
Slot7 = 7,
}
use Mode::*;
impl<State> Deref for Pint<State> {
type Target = raw::pint::RegisterBlock;
fn deref(&self) -> &Self::Target {
&self.raw
}
}
crate::wrap_stateful_peripheral!(Pint, PINT);
impl<State> Pint<State> {
pub fn enabled(mut self, syscon: &mut syscon::Syscon) -> Pint<init_state::Enabled> {
syscon.enable_clock(&mut self.raw);
Pint {
raw: self.raw,
_state: init_state::Enabled(()),
}
}
pub fn disabled(mut self, syscon: &mut syscon::Syscon) -> Pint<init_state::Disabled> {
syscon.disable_clock(&mut self.raw);
Pint {
raw: self.raw,
_state: init_state::Disabled,
}
}
}
impl Pint<init_state::Enabled> {
/// LPC55 supports 8 external pin interrupts, from any PIO pin.
/// Use `slot` to indicate (0-7) which slot you'd like to use.
/// `mode` indicates what kind of interrupt to generate.
/// You can call this function twice to enable both `RisingEdge` and `FallingEdge` interrupts for same pin + slot.
pub fn enable_interrupt<PIN: PinId>(
&mut self,
mux: &mut InputMux<init_state::Enabled>,
_pin: &Pin<PIN, state::Gpio<direction::Input>>,
slot: Slot,
mode: Mode,
) {
// Enable pin as external interrupt for ext int source `slot`
mux.raw.pintsel[slot as usize]
.write(|w| unsafe { w.intpin().bits((PIN::PORT << 5) as u8 | (PIN::NUMBER)) });
let bit = 1 << (slot as u8);
// Clear respective slot bit (default rising)
self.raw
.isel
.modify(|r, w| unsafe { w.pmode().bits(r.pmode().bits() & (!bit)) });
match mode {
RisingEdge => {
// enable level/rising interrupt
self.raw.sienr.write(|w| unsafe { w.setenrl().bits(bit) });
}
FallingEdge => {
// enable falling interrupt
self.raw.sienf.write(|w| unsafe { w.setenaf().bits(bit) });
}
_ => {
// Make level interrupt
self.raw
.isel
.modify(|r, w| unsafe { w.pmode().bits(r.pmode().bits() | bit) });
// enable level/rising interrupt
self.raw.sienr.write(|w| unsafe { w.setenrl().bits(bit) });
match mode {
ActiveHigh => {
// Make level active high
self.raw.sienf.write(|w| unsafe { w.setenaf().bits(bit) });
}
ActiveLow => {
// Make level active low
self.raw.cienf.write(|w| unsafe { w.cenaf().bits(bit) });
}
_ => {}
}
}
}
}
}