Skip to content

Commit 673ec82

Browse files
committed
Implement ExtiPin for pins in output mode
1 parent b072300 commit 673ec82

File tree

1 file changed

+120
-104
lines changed

1 file changed

+120
-104
lines changed

src/gpio.rs

Lines changed: 120 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,122 @@ pub trait ExtiPin {
9292
fn clear_interrupt_pending_bit(&mut self);
9393
}
9494

95+
macro_rules! exti_erased {
96+
($PIN:ty, $extigpionr:expr) => {
97+
impl<MODE> ExtiPin for $PIN {
98+
/// Make corresponding EXTI line sensitive to this pin
99+
fn make_interrupt_source(&mut self, syscfg: &mut SYSCFG) {
100+
let offset = 4 * (self.i % 4);
101+
match self.i {
102+
0..=3 => {
103+
syscfg.exticr1.modify(|r, w| unsafe {
104+
w.bits((r.bits() & !(0xf << offset)) | ($extigpionr << offset))
105+
});
106+
},
107+
4..=7 => {
108+
syscfg.exticr2.modify(|r, w| unsafe {
109+
w.bits((r.bits() & !(0xf << offset)) | ($extigpionr << offset))
110+
});
111+
},
112+
8..=11 => {
113+
syscfg.exticr3.modify(|r, w| unsafe {
114+
w.bits((r.bits() & !(0xf << offset)) | ($extigpionr << offset))
115+
});
116+
},
117+
12..=15 => {
118+
syscfg.exticr4.modify(|r, w| unsafe {
119+
w.bits((r.bits() & !(0xf << offset)) | ($extigpionr << offset))
120+
});
121+
},
122+
_ => {}
123+
}
124+
}
125+
126+
/// Generate interrupt on rising edge, falling edge or both
127+
fn trigger_on_edge(&mut self, exti: &mut EXTI, edge: Edge) {
128+
match edge {
129+
Edge::RISING => {
130+
exti.rtsr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.i)) });
131+
exti.ftsr.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << self.i)) });
132+
},
133+
Edge::FALLING => {
134+
exti.ftsr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.i)) });
135+
exti.rtsr.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << self.i)) });
136+
},
137+
Edge::RISING_FALLING => {
138+
exti.rtsr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.i)) });
139+
exti.ftsr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.i)) });
140+
}
141+
}
142+
}
143+
144+
/// Enable external interrupts from this pin.
145+
fn enable_interrupt(&mut self, exti: &mut EXTI) {
146+
exti.imr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.i)) });
147+
}
148+
149+
/// Disable external interrupts from this pin
150+
fn disable_interrupt(&mut self, exti: &mut EXTI) {
151+
exti.imr.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << self.i)) });
152+
}
153+
154+
/// Clear the interrupt pending bit for this pin
155+
fn clear_interrupt_pending_bit(&mut self) {
156+
unsafe { (*EXTI::ptr()).pr.write(|w| w.bits(1 << self.i) ) };
157+
}
158+
}
159+
}
160+
}
161+
162+
macro_rules! exti {
163+
($PIN:ty, $extigpionr:expr, $i:expr, $exticri:ident) => {
164+
impl<MODE> ExtiPin for $PIN {
165+
/// Configure EXTI Line $i to trigger from this pin.
166+
fn make_interrupt_source(&mut self, syscfg: &mut SYSCFG) {
167+
let offset = 4 * ($i % 4);
168+
syscfg.$exticri.modify(|r, w| unsafe {
169+
let mut exticr = r.bits();
170+
exticr = (exticr & !(0xf << offset)) | ($extigpionr << offset);
171+
w.bits(exticr)
172+
});
173+
}
174+
175+
/// Generate interrupt on rising edge, falling edge or both
176+
fn trigger_on_edge(&mut self, exti: &mut EXTI, edge: Edge) {
177+
match edge {
178+
Edge::RISING => {
179+
exti.rtsr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) });
180+
exti.ftsr.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) });
181+
},
182+
Edge::FALLING => {
183+
exti.ftsr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) });
184+
exti.rtsr.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) });
185+
},
186+
Edge::RISING_FALLING => {
187+
exti.rtsr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) });
188+
exti.ftsr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) });
189+
}
190+
}
191+
}
192+
193+
/// Enable external interrupts from this pin.
194+
fn enable_interrupt(&mut self, exti: &mut EXTI) {
195+
exti.imr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) });
196+
}
197+
198+
/// Disable external interrupts from this pin
199+
fn disable_interrupt(&mut self, exti: &mut EXTI) {
200+
exti.imr.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) });
201+
}
202+
203+
/// Clear the interrupt pending bit for this pin
204+
fn clear_interrupt_pending_bit(&mut self) {
205+
unsafe { (*EXTI::ptr()).pr.write(|w| w.bits(1 << $i) ) };
206+
}
207+
}
208+
}
209+
}
210+
95211
macro_rules! gpio {
96212
($GPIOX:ident, $gpiox:ident, $iopxenr:ident, $PXx:ident, $extigpionr:expr, [
97213
$($PXi:ident: ($pxi:ident, $i:expr, $MODE:ty, $exticri:ident),)+
@@ -202,68 +318,9 @@ macro_rules! gpio {
202318
}
203319
}
204320

205-
impl<MODE> ExtiPin for $PXx<Input<MODE>> {
206-
/// Make corresponding EXTI line sensitive to this pin
207-
fn make_interrupt_source(&mut self, syscfg: &mut SYSCFG) {
208-
let offset = 4 * (self.i % 4);
209-
match self.i {
210-
0..=3 => {
211-
syscfg.exticr1.modify(|r, w| unsafe {
212-
w.bits((r.bits() & !(0xf << offset)) | ($extigpionr << offset))
213-
});
214-
},
215-
4..=7 => {
216-
syscfg.exticr2.modify(|r, w| unsafe {
217-
w.bits((r.bits() & !(0xf << offset)) | ($extigpionr << offset))
218-
});
219-
},
220-
8..=11 => {
221-
syscfg.exticr3.modify(|r, w| unsafe {
222-
w.bits((r.bits() & !(0xf << offset)) | ($extigpionr << offset))
223-
});
224-
},
225-
12..=15 => {
226-
syscfg.exticr4.modify(|r, w| unsafe {
227-
w.bits((r.bits() & !(0xf << offset)) | ($extigpionr << offset))
228-
});
229-
},
230-
_ => {}
231-
}
232-
}
233-
234-
/// Generate interrupt on rising edge, falling edge or both
235-
fn trigger_on_edge(&mut self, exti: &mut EXTI, edge: Edge) {
236-
match edge {
237-
Edge::RISING => {
238-
exti.rtsr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.i)) });
239-
exti.ftsr.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << self.i)) });
240-
},
241-
Edge::FALLING => {
242-
exti.ftsr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.i)) });
243-
exti.rtsr.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << self.i)) });
244-
},
245-
Edge::RISING_FALLING => {
246-
exti.rtsr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.i)) });
247-
exti.ftsr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.i)) });
248-
}
249-
}
250-
}
251-
252-
/// Enable external interrupts from this pin.
253-
fn enable_interrupt(&mut self, exti: &mut EXTI) {
254-
exti.imr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << self.i)) });
255-
}
321+
exti_erased!($PXx<Output<MODE>>, $extigpionr);
256322

257-
/// Disable external interrupts from this pin
258-
fn disable_interrupt(&mut self, exti: &mut EXTI) {
259-
exti.imr.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << self.i)) });
260-
}
261-
262-
/// Clear the interrupt pending bit for this pin
263-
fn clear_interrupt_pending_bit(&mut self) {
264-
unsafe { (*EXTI::ptr()).pr.write(|w| w.bits(1 << self.i) ) };
265-
}
266-
}
323+
exti_erased!($PXx<Input<MODE>>, $extigpionr);
267324

268325
fn _set_alternate_mode (index: usize, mode: u32)
269326
{
@@ -722,50 +779,9 @@ macro_rules! gpio {
722779
}
723780
}
724781

725-
impl<MODE> ExtiPin for $PXi<Input<MODE>> {
726-
/// Configure EXTI Line $i to trigger from this pin.
727-
fn make_interrupt_source(&mut self, syscfg: &mut SYSCFG) {
728-
let offset = 4 * ($i % 4);
729-
syscfg.$exticri.modify(|r, w| unsafe {
730-
let mut exticr = r.bits();
731-
exticr = (exticr & !(0xf << offset)) | ($extigpionr << offset);
732-
w.bits(exticr)
733-
});
734-
}
782+
exti!($PXi<Output<MODE>>, $extigpionr, $i, $exticri);
735783

736-
/// Generate interrupt on rising edge, falling edge or both
737-
fn trigger_on_edge(&mut self, exti: &mut EXTI, edge: Edge) {
738-
match edge {
739-
Edge::RISING => {
740-
exti.rtsr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) });
741-
exti.ftsr.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) });
742-
},
743-
Edge::FALLING => {
744-
exti.ftsr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) });
745-
exti.rtsr.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) });
746-
},
747-
Edge::RISING_FALLING => {
748-
exti.rtsr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) });
749-
exti.ftsr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) });
750-
}
751-
}
752-
}
753-
754-
/// Enable external interrupts from this pin.
755-
fn enable_interrupt(&mut self, exti: &mut EXTI) {
756-
exti.imr.modify(|r, w| unsafe { w.bits(r.bits() | (1 << $i)) });
757-
}
758-
759-
/// Disable external interrupts from this pin
760-
fn disable_interrupt(&mut self, exti: &mut EXTI) {
761-
exti.imr.modify(|r, w| unsafe { w.bits(r.bits() & !(1 << $i)) });
762-
}
763-
764-
/// Clear the interrupt pending bit for this pin
765-
fn clear_interrupt_pending_bit(&mut self) {
766-
unsafe { (*EXTI::ptr()).pr.write(|w| w.bits(1 << $i) ) };
767-
}
768-
}
784+
exti!($PXi<Input<MODE>>, $extigpionr, $i, $exticri);
769785

770786
)+
771787
}

0 commit comments

Comments
 (0)