Skip to content

Commit 73323d4

Browse files
committed
move Exti impl to submodule
1 parent 6607f5d commit 73323d4

File tree

2 files changed

+113
-113
lines changed

2 files changed

+113
-113
lines changed

src/gpio.rs

+3-113
Original file line numberDiff line numberDiff line change
@@ -80,9 +80,7 @@
8080
8181
use core::marker::PhantomData;
8282

83-
use crate::pac::{Interrupt, EXTI};
8483
use crate::rcc::AHB;
85-
use crate::Switch;
8684

8785
mod convert;
8886
use convert::PinMode;
@@ -91,6 +89,7 @@ pub use partially_erased::PartiallyErasedPin;
9189
mod erased;
9290
pub use erased::ErasedPin;
9391
mod dynamic;
92+
mod exti;
9493
pub use dynamic::{Dynamic, DynamicPin};
9594
mod hal_02;
9695

@@ -172,6 +171,8 @@ mod marker {
172171
pub trait IntoAf<const A: u8>: super::HL {}
173172
}
174173

174+
impl<MODE> marker::Interruptable for Output<MODE> {}
175+
impl marker::Interruptable for Input {}
175176
impl marker::Readable for Input {}
176177
impl marker::Readable for Output<OpenDrain> {}
177178
impl marker::Active for Input {}
@@ -207,10 +208,6 @@ pub enum Edge {
207208
RisingFalling,
208209
}
209210

210-
use marker::Interruptable;
211-
impl<MODE> Interruptable for Output<MODE> {}
212-
impl Interruptable for Input {}
213-
214211
/// Opaque MODER register
215212
pub struct MODER<const P: char>(());
216213

@@ -262,113 +259,6 @@ macro_rules! af {
262259

263260
af!([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
264261

265-
/// Return an EXTI register for the current CPU
266-
#[cfg(feature = "svd-f373")]
267-
macro_rules! reg_for_cpu {
268-
($exti:expr, $xr:ident) => {
269-
$exti.$xr
270-
};
271-
}
272-
273-
/// Return an EXTI register for the current CPU
274-
#[cfg(not(feature = "svd-f373"))]
275-
macro_rules! reg_for_cpu {
276-
($exti:expr, $xr:ident) => {
277-
paste::paste! {
278-
$exti.[<$xr 1>]
279-
}
280-
};
281-
}
282-
283-
impl<const P: char, const N: u8, MODE> Pin<P, N, MODE>
284-
where
285-
MODE: Interruptable,
286-
{
287-
/// NVIC interrupt number of interrupt from this pin
288-
///
289-
/// Used to unmask / enable the interrupt with [`cortex_m::peripheral::NVIC::unmask()`].
290-
/// This is also useful for all other [`cortex_m::peripheral::NVIC`] functions.
291-
// TODO(Sh3rm4n): It would be cool to have this either const or have a const function.
292-
// But this is currenlty not possible, because index() is runtime defined.
293-
pub fn interrupt(&self) -> Interrupt {
294-
match N {
295-
0 => Interrupt::EXTI0,
296-
1 => Interrupt::EXTI1,
297-
#[cfg(feature = "svd-f373")]
298-
2 => Interrupt::EXTI2_TS,
299-
#[cfg(not(feature = "svd-f373"))]
300-
2 => Interrupt::EXTI2_TSC,
301-
3 => Interrupt::EXTI3,
302-
4 => Interrupt::EXTI4,
303-
#[cfg(feature = "svd-f373")]
304-
5..=9 => Interrupt::EXTI5_9,
305-
#[cfg(not(feature = "svd-f373"))]
306-
5..=9 => Interrupt::EXTI9_5,
307-
10..=15 => Interrupt::EXTI15_10,
308-
_ => crate::unreachable!(),
309-
}
310-
}
311-
312-
/// Generate interrupt on rising edge, falling edge, or both
313-
pub fn trigger_on_edge(&mut self, exti: &mut EXTI, edge: Edge) {
314-
const BITWIDTH: u8 = 1;
315-
let (rise, fall) = match edge {
316-
Edge::Rising => (true as u32, false as u32),
317-
Edge::Falling => (false as u32, true as u32),
318-
Edge::RisingFalling => (true as u32, true as u32),
319-
};
320-
// SAFETY: Unguarded write to the register, but behind a &mut
321-
unsafe {
322-
crate::modify_at!(reg_for_cpu!(exti, rtsr), BITWIDTH, N, rise);
323-
crate::modify_at!(reg_for_cpu!(exti, ftsr), BITWIDTH, N, fall);
324-
}
325-
}
326-
327-
/// Configure external interrupts from this pin
328-
///
329-
/// # Note
330-
///
331-
/// Remeber to also configure the interrupt pin on
332-
/// the SysCfg site, with [`crate::syscfg::SysCfg::select_exti_interrupt_source()`]
333-
pub fn configure_interrupt(&mut self, exti: &mut EXTI, enable: impl Into<Switch>) {
334-
const BITWIDTH: u8 = 1;
335-
336-
let enable: Switch = enable.into();
337-
let enable: bool = enable.into();
338-
339-
let value = u32::from(enable);
340-
// SAFETY: Unguarded write to the register, but behind a &mut
341-
unsafe { crate::modify_at!(reg_for_cpu!(exti, imr), BITWIDTH, N, value) };
342-
}
343-
344-
/// Enable external interrupts from this pin
345-
///
346-
/// # Note
347-
///
348-
/// Remeber to also configure the interrupt pin on
349-
/// the SysCfg site, with [`crate::syscfg::SysCfg::select_exti_interrupt_source()`]
350-
pub fn enable_interrupt(&mut self, exti: &mut EXTI) {
351-
self.configure_interrupt(exti, Switch::On)
352-
}
353-
354-
/// Disable external interrupts from this pin
355-
pub fn disable_interrupt(&mut self, exti: &mut EXTI) {
356-
self.configure_interrupt(exti, Switch::Off)
357-
}
358-
359-
/// Clear the interrupt pending bit for this pin
360-
pub fn clear_interrupt(&mut self) {
361-
// SAFETY: Atomic write to register without side-effects.
362-
unsafe { reg_for_cpu!((*EXTI::ptr()), pr).write(|w| w.bits(1 << N)) };
363-
}
364-
365-
/// Reads the interrupt pending bit for this pin
366-
pub fn is_interrupt_pending(&self) -> bool {
367-
// SAFETY: Atomic write to register without side-effects.
368-
unsafe { reg_for_cpu!((*EXTI::ptr()), pr).read().bits() & (1 << N) != 0 }
369-
}
370-
}
371-
372262
/// Generic pin type
373263
///
374264
/// - `MODE` is one of the pin modes (see [Modes](crate::gpio#modes) section).

src/gpio/exti.rs

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
use super::{marker, Edge, Pin};
2+
use crate::pac::{Interrupt, EXTI};
3+
use crate::Switch;
4+
5+
/// Return an EXTI register for the current CPU
6+
#[cfg(feature = "svd-f373")]
7+
macro_rules! reg_for_cpu {
8+
($exti:expr, $xr:ident) => {
9+
$exti.$xr
10+
};
11+
}
12+
13+
/// Return an EXTI register for the current CPU
14+
#[cfg(not(feature = "svd-f373"))]
15+
macro_rules! reg_for_cpu {
16+
($exti:expr, $xr:ident) => {
17+
paste::paste! {
18+
$exti.[<$xr 1>]
19+
}
20+
};
21+
}
22+
23+
impl<const P: char, const N: u8, MODE> Pin<P, N, MODE> {
24+
/// NVIC interrupt number of interrupt from this pin
25+
///
26+
/// Used to unmask / enable the interrupt with [`cortex_m::peripheral::NVIC::unmask()`].
27+
/// This is also useful for all other [`cortex_m::peripheral::NVIC`] functions.
28+
pub const fn interrupt(&self) -> Interrupt {
29+
match N {
30+
0 => Interrupt::EXTI0,
31+
1 => Interrupt::EXTI1,
32+
#[cfg(feature = "svd-f373")]
33+
2 => Interrupt::EXTI2_TS,
34+
#[cfg(not(feature = "svd-f373"))]
35+
2 => Interrupt::EXTI2_TSC,
36+
3 => Interrupt::EXTI3,
37+
4 => Interrupt::EXTI4,
38+
#[cfg(feature = "svd-f373")]
39+
5..=9 => Interrupt::EXTI5_9,
40+
#[cfg(not(feature = "svd-f373"))]
41+
5..=9 => Interrupt::EXTI9_5,
42+
10..=15 => Interrupt::EXTI15_10,
43+
_ => panic!("Unsupported pin number"),
44+
}
45+
}
46+
}
47+
48+
impl<const P: char, const N: u8, MODE> Pin<P, N, MODE>
49+
where
50+
MODE: marker::Interruptable,
51+
{
52+
/// Generate interrupt on rising edge, falling edge, or both
53+
pub fn trigger_on_edge(&mut self, exti: &mut EXTI, edge: Edge) {
54+
const BITWIDTH: u8 = 1;
55+
let (rise, fall) = match edge {
56+
Edge::Rising => (true as u32, false as u32),
57+
Edge::Falling => (false as u32, true as u32),
58+
Edge::RisingFalling => (true as u32, true as u32),
59+
};
60+
// SAFETY: Unguarded write to the register, but behind a &mut
61+
unsafe {
62+
crate::modify_at!(reg_for_cpu!(exti, rtsr), BITWIDTH, N, rise);
63+
crate::modify_at!(reg_for_cpu!(exti, ftsr), BITWIDTH, N, fall);
64+
}
65+
}
66+
67+
/// Configure external interrupts from this pin
68+
///
69+
/// # Note
70+
///
71+
/// Remeber to also configure the interrupt pin on
72+
/// the SysCfg site, with [`crate::syscfg::SysCfg::select_exti_interrupt_source()`]
73+
pub fn configure_interrupt(&mut self, exti: &mut EXTI, enable: impl Into<Switch>) {
74+
const BITWIDTH: u8 = 1;
75+
76+
let enable: Switch = enable.into();
77+
let enable: bool = enable.into();
78+
79+
let value = u32::from(enable);
80+
// SAFETY: Unguarded write to the register, but behind a &mut
81+
unsafe { crate::modify_at!(reg_for_cpu!(exti, imr), BITWIDTH, N, value) };
82+
}
83+
84+
/// Enable external interrupts from this pin
85+
///
86+
/// # Note
87+
///
88+
/// Remeber to also configure the interrupt pin on
89+
/// the SysCfg site, with [`crate::syscfg::SysCfg::select_exti_interrupt_source()`]
90+
pub fn enable_interrupt(&mut self, exti: &mut EXTI) {
91+
self.configure_interrupt(exti, Switch::On)
92+
}
93+
94+
/// Disable external interrupts from this pin
95+
pub fn disable_interrupt(&mut self, exti: &mut EXTI) {
96+
self.configure_interrupt(exti, Switch::Off)
97+
}
98+
99+
/// Clear the interrupt pending bit for this pin
100+
pub fn clear_interrupt(&mut self) {
101+
// SAFETY: Atomic write to register without side-effects.
102+
unsafe { reg_for_cpu!((*EXTI::ptr()), pr).write(|w| w.bits(1 << N)) };
103+
}
104+
105+
/// Reads the interrupt pending bit for this pin
106+
pub fn is_interrupt_pending(&self) -> bool {
107+
// SAFETY: Atomic write to register without side-effects.
108+
unsafe { reg_for_cpu!((*EXTI::ptr()), pr).read().bits() & (1 << N) != 0 }
109+
}
110+
}

0 commit comments

Comments
 (0)