Skip to content

Commit 87af39a

Browse files
committed
Generalize associated interrupt constant through trait
1 parent 66721f6 commit 87af39a

File tree

10 files changed

+52
-49
lines changed

10 files changed

+52
-49
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
3838
for configuration purposes. ([#253])
3939
- Add an associated const to `serial::Instance` to return the corresponding
4040
`pac::Interrupt`-number, which is useful to `unmask()` interrupts.
41-
An `nvic()` function to `Serial` was also added for convinience. ([#253])
41+
An `interrupt()` function to `Serial` was also added for convinience. ([#253])
4242
- Add a `Serial::is_busy()` function to check, if the serial device is busy.
4343
Useful to block on this function, e.g. `while serial.is_busy() {}`. ([#253])
4444
- Add `BaudTable` a convinience wrapper around `Baud` to configure the `Serial`

examples/gpio_interrupts.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ fn main() -> ! {
4747
syscfg.select_exti_interrupt_source(&user_button);
4848
user_button.trigger_on_edge(&mut exti, Edge::Rising);
4949
user_button.enable_interrupt(&mut exti);
50-
let interrupt_num = user_button.nvic(); // hal::pac::Interrupt::EXTI0
50+
let interrupt_num = user_button.interrupt(); // hal::pac::Interrupt::EXTI0
5151

5252
// Moving ownership to the global BUTTON so we can clear the interrupt pending bit.
5353
cortex_m::interrupt::free(|cs| *BUTTON.borrow(cs).borrow_mut() = Some(user_button));

src/gpio.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ where
592592
/// This is also useful for all other [`cortex_m::peripheral::NVIC`] functions.
593593
// TODO(Sh3rm4n): It would be cool to have this either const or have a const function.
594594
// But this is currenlty not possible, because index() is runtime defined.
595-
pub fn nvic(&self) -> Interrupt {
595+
pub fn interrupt(&self) -> Interrupt {
596596
match self.index.index() {
597597
0 => Interrupt::EXTI0,
598598
1 => Interrupt::EXTI1,

src/interrupts.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//! Common Interrupt interface defintions shared between peipherals.
2+
3+
/// A common interrupt number interface, which returns the associated interrupt
4+
/// of the peripheral.
5+
///
6+
/// Used to unmask / enable the interrupt with [`cortex_m::peripheral::NVIC::unmask()`].
7+
/// This is useful for all `cortex_m::peripheral::INTERRUPT` functions.
8+
pub trait InterruptNumber {
9+
/// The type used to represent the Interrupt Number.
10+
///
11+
/// This type of interrupt should be compatible with [`cortex_m::peripheral::NVIC`].
12+
type Interrupt;
13+
14+
/// The assocaited constant of the interrupt
15+
const INTERRUPT: Self::Interrupt;
16+
}

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ pub mod dma;
176176
pub mod flash;
177177
pub mod gpio;
178178
pub mod i2c;
179+
pub mod interrupts;
179180
pub mod prelude;
180181
pub mod pwm;
181182
pub mod rcc;

src/serial.rs

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -735,15 +735,15 @@ where
735735
/// ```
736736
/// use cortex_m::peripheral::INTERRUPT;
737737
/// use stm32f3xx_hal::pac::USART1;
738-
/// use stm32f3xx_hal::serial::Instance;
738+
/// use stm32f3xx_hal::interrupt::InterruptNumber;
739739
///
740-
/// const interrupt: INTERRUPT = <USART1 as Instance>::INTERRUPT;
740+
/// const INTERRUPT: Interrupt = <USART1 as InterruptNumber>::INTERRUPT;
741741
/// ```
742742
///
743743
/// though this function can not be used in a const context.
744744
#[doc(alias = "unmask")]
745-
pub fn nvic(&self) -> Interrupt {
746-
<Usart as Instance>::INTERRUPT
745+
pub fn interrupt(&self) -> <Usart as crate::interrupts::InterruptNumber>::Interrupt {
746+
<Usart as crate::interrupts::InterruptNumber>::INTERRUPT
747747
}
748748

749749
/// Enable the interrupt for the specified [`Event`].
@@ -1291,14 +1291,12 @@ impl ReceiverTimeoutExt for USART2 {}
12911291
impl ReceiverTimeoutExt for USART3 {}
12921292

12931293
/// UART instance
1294-
pub trait Instance: Deref<Target = RegisterBlock> + crate::private::Sealed {
1294+
pub trait Instance:
1295+
Deref<Target = RegisterBlock> + crate::interrupts::InterruptNumber + crate::private::Sealed
1296+
{
12951297
/// Peripheral bus instance which is responsible for the peripheral
12961298
type APB;
12971299

1298-
/// The associated interrupt number, used to unmask / enable the interrupt
1299-
/// with [`cortex_m::peripheral::NVIC::unmask()`]
1300-
const INTERRUPT: Interrupt;
1301-
13021300
#[doc(hidden)]
13031301
fn enable_clock(apb1: &mut Self::APB);
13041302
#[doc(hidden)]
@@ -1321,9 +1319,13 @@ macro_rules! usart {
13211319
) => {
13221320
$(
13231321
impl crate::private::Sealed for $USARTX {}
1322+
impl crate::interrupts::InterruptNumber for $USARTX {
1323+
type Interrupt = Interrupt;
1324+
const INTERRUPT: Interrupt = $INTERRUPT;
1325+
}
1326+
13241327
impl Instance for $USARTX {
13251328
type APB = $APB;
1326-
const INTERRUPT: Interrupt = $INTERRUPT;
13271329
fn enable_clock(apb: &mut Self::APB) {
13281330
apb.enr().modify(|_, w| w.$usartXen().enabled());
13291331
apb.rstr().modify(|_, w| w.$usartXrst().reset());

src/timer.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use crate::pac::RCC;
1818
use crate::rcc::{Clocks, APB1, APB2};
1919
use crate::time::{duration, fixed_point::FixedPoint, rate::Hertz};
2020

21-
pub mod interrupts;
21+
mod interrupts;
2222

2323
/// A monotonic nondecreasing timer.
2424
#[derive(Debug, Clone, Copy)]
@@ -146,8 +146,9 @@ where
146146
/// ```
147147
///
148148
/// though this function can not be used in a const context.
149-
pub fn nvic(&self) -> <TIM as self::interrupts::InterruptNumber>::Interrupt {
150-
<TIM as self::interrupts::InterruptNumber>::INTERRUPT
149+
#[doc(alias = "unmask")]
150+
pub fn interrupt(&self) -> <TIM as crate::interrupts::InterruptNumber>::Interrupt {
151+
<TIM as crate::interrupts::InterruptNumber>::INTERRUPT
151152
}
152153

153154
/// Enable or disable the interrupt for the specified [`Event`].
@@ -324,7 +325,7 @@ pub trait CommonRegisterBlock: crate::private::Sealed {
324325

325326
/// Associated clocks with timers
326327
pub trait Instance:
327-
CommonRegisterBlock + self::interrupts::InterruptNumber + crate::private::Sealed
328+
CommonRegisterBlock + crate::interrupts::InterruptNumber + crate::private::Sealed
328329
{
329330
/// Peripheral bus instance which is responsible for the peripheral
330331
type APB;

src/timer/interrupts.rs

Lines changed: 4 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@ use crate::pac::Interrupt;
22

33
/// Wrapper around interrupt types for the timers.
44
#[derive(Copy, Clone, Debug)]
5-
// FIXME: Interrupt is not formattable?
6-
// #[cfg_attr(feature = "defmt", derive(defmt::Format))]
7-
// TODO: Does it make sense to introduce an enum for that?
8-
// enum ItrTypes {Global, Break, Update, Trigger, CaptureCompare}
9-
#[non_exhaustive] // To make the type non-creatable but still accessable.
5+
// To make the type non-creatable but still accessable.
6+
#[non_exhaustive]
107
pub struct InterruptTypes {
118
/// Break Interrupt
129
r#break: Interrupt,
@@ -18,16 +15,6 @@ pub struct InterruptTypes {
1815
capture_compare: Interrupt,
1916
}
2017

21-
// FIXME: This super-trait constrained makes it difficult to use this trait
22-
// without cfg(feature...)
23-
// pub trait InterruptNumber: crate::private::Sealed {
24-
// TODO: Rename, because in conflict with: use cortex_m::interrupt::InterruptNumber;
25-
pub trait InterruptNumber {
26-
type Interrupt;
27-
const INTERRUPT: Self::Interrupt;
28-
fn nvic() -> Self::Interrupt;
29-
}
30-
3118
// FIXME: Use conditional feature compilation to make this compialble for all chip families.
3219
// TODO: Check if pub is needed.
3320
pub(crate) const TIM2: Interrupt = Interrupt::TIM2;
@@ -112,12 +99,9 @@ macro_rules! single {
11299
([ $($X:literal),+ ]) => {
113100
paste::paste! {
114101
$(
115-
impl InterruptNumber for crate::pac::[<TIM $X>] {
102+
impl crate::interrupts::InterruptNumber for crate::pac::[<TIM $X>] {
116103
type Interrupt = crate::timer::interrupts::Interrupt;
117104
const INTERRUPT: Self::Interrupt = crate::timer::interrupts::[<TIM $X>];
118-
fn nvic() -> Self::Interrupt {
119-
[<TIM $X>]
120-
}
121105
}
122106
)+
123107
}
@@ -128,12 +112,9 @@ macro_rules! multi {
128112
([ $($X:literal),+ ]) => {
129113
paste::paste! {
130114
$(
131-
impl InterruptNumber for crate::pac::[<TIM $X>] {
115+
impl crate::interrupts::InterruptNumber for crate::pac::[<TIM $X>] {
132116
type Interrupt = crate::timer::interrupts::InterruptTypes;
133117
const INTERRUPT: Self::Interrupt = crate::timer::interrupts::[<TIM $X _TYPES>];
134-
fn nvic() -> Self::Interrupt {
135-
[<TIM $X _TYPES>]
136-
}
137118
}
138119
)+
139120
}

testsuite/tests/timer.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ use panic_probe as _;
88

99
use stm32f3xx_hal as hal;
1010

11+
use hal::interrupts::InterruptNumber;
1112
use hal::rcc::{Clocks, APB1};
12-
use hal::timer::{self, Event, MonoTimer, Timer};
13+
use hal::timer::{Event, MonoTimer, Timer};
1314
use hal::{interrupt, pac, prelude::*};
1415

1516
use pac::TIM2;
@@ -44,7 +45,7 @@ mod tests {
4445

4546
assert!(mono_timer.frequency() == clocks.hclk());
4647

47-
unsafe { cortex_m::peripheral::NVIC::unmask(timer.nvic()) };
48+
unsafe { cortex_m::peripheral::NVIC::unmask(timer.interrupt()) };
4849

4950
State {
5051
timer: Some(timer),
@@ -123,7 +124,7 @@ fn TIM2() {
123124
//
124125
// This is all needed, to clear the fired interrupt.
125126
assert!(cortex_m::peripheral::NVIC::is_active(
126-
<pac::TIM2 as timer::interrupts::InterruptNumber>::INTERRUPT
127+
<pac::TIM2 as InterruptNumber>::INTERRUPT
127128
));
128-
cortex_m::peripheral::NVIC::mask(<pac::TIM2 as timer::interrupts::InterruptNumber>::INTERRUPT);
129+
cortex_m::peripheral::NVIC::mask(<pac::TIM2 as InterruptNumber>::INTERRUPT);
129130
}

testsuite/tests/uart.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use enumset::EnumSet;
88
use stm32f3xx_hal as hal;
99

1010
use hal::gpio::{OpenDrain, PushPull, AF7};
11+
use hal::interrupts::InterruptNumber;
1112
use hal::pac;
1213
use hal::prelude::*;
1314
use hal::serial::{
@@ -86,10 +87,10 @@ fn trigger_event<Usart, Pins>(
8687
assert!(!serial.triggered_events().contains(event));
8788
// TODO: Is that true?: Unpend any pending interrupts - more than one could be pending,
8889
// because of the late clearing of the interrupt
89-
cortex_m::peripheral::NVIC::unpend(<pac::USART1 as Instance>::INTERRUPT);
90+
cortex_m::peripheral::NVIC::unpend(<pac::USART1 as InterruptNumber>::INTERRUPT);
9091
// Now unmask all interrupts again, which where masks in the iterrupt rountine,
9192
// as a measurement to disable all interrupts.
92-
unsafe { cortex_m::peripheral::NVIC::unmask(<pac::USART1 as Instance>::INTERRUPT) }
93+
unsafe { cortex_m::peripheral::NVIC::unmask(<pac::USART1 as InterruptNumber>::INTERRUPT) }
9394
// Clear the interrupt flag again. And make double sure, that no interrupt
9495
// fired again.
9596
INTERRUPT_FIRED.store(false, Ordering::SeqCst);
@@ -150,7 +151,7 @@ mod tests {
150151
&mut rcc.apb2,
151152
);
152153

153-
unsafe { cortex_m::peripheral::NVIC::unmask(serial1.nvic()) }
154+
unsafe { cortex_m::peripheral::NVIC::unmask(serial1.interrupt()) }
154155

155156
super::State {
156157
serial1: Some(serial1),
@@ -453,7 +454,7 @@ fn USART1_EXTI25() {
453454
//
454455
// This is all needed, to clear the fired interrupt.
455456
assert!(cortex_m::peripheral::NVIC::is_active(
456-
<pac::USART1 as Instance>::INTERRUPT
457+
<pac::USART1 as InterruptNumber>::INTERRUPT
457458
));
458-
cortex_m::peripheral::NVIC::mask(<pac::USART1 as Instance>::INTERRUPT);
459+
cortex_m::peripheral::NVIC::mask(<pac::USART1 as InterruptNumber>::INTERRUPT);
459460
}

0 commit comments

Comments
 (0)