Skip to content

Commit b7c3ebc

Browse files
committed
Add new InterruptNumber trait
1 parent 32634e4 commit b7c3ebc

File tree

2 files changed

+41
-27
lines changed

2 files changed

+41
-27
lines changed

src/interrupt.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,22 @@
11
//! Interrupts
22
3-
// use core::sync::atomic::{self, Ordering};
3+
pub use bare_metal::{CriticalSection, Mutex};
44

5-
pub use bare_metal::{CriticalSection, Mutex, Nr};
5+
/// Trait for enums of external interrupt numbers.
6+
///
7+
/// This trait should be implemented by a peripheral access crate (PAC)
8+
/// on its enum of available external interrupts for a specific device.
9+
/// Each variant must convert to a u16 of its interrupt number,
10+
/// which is its exception number - 16.
11+
///
12+
/// # Safety
13+
///
14+
/// This trait must only be implemented on enums of device interrupts. Each
15+
/// enum variant must represent a distinct value (no duplicates are permitted),
16+
/// and must always return the same value (do not change at runtime).
17+
///
18+
/// These requirements ensure safe nesting of critical sections.
19+
pub unsafe trait InterruptNumber: Into<u16> {}
620

721
/// Disables all interrupts
822
#[inline]

src/peripheral/nvic.rs

+25-25
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use volatile_register::RW;
44
#[cfg(not(armv6m))]
55
use volatile_register::{RO, WO};
66

7-
use crate::interrupt::Nr;
7+
use crate::interrupt::InterruptNumber;
88
use crate::peripheral::NVIC;
99

1010
/// Register block
@@ -86,9 +86,9 @@ impl NVIC {
8686
#[inline]
8787
pub fn request<I>(&mut self, interrupt: I)
8888
where
89-
I: Nr,
89+
I: InterruptNumber,
9090
{
91-
let nr = interrupt.nr();
91+
let nr = interrupt.into();
9292

9393
unsafe {
9494
self.stir.write(u32::from(nr));
@@ -99,9 +99,9 @@ impl NVIC {
9999
#[inline]
100100
pub fn mask<I>(interrupt: I)
101101
where
102-
I: Nr,
102+
I: InterruptNumber,
103103
{
104-
let nr = interrupt.nr();
104+
let nr = interrupt.into();
105105
// NOTE(unsafe) this is a write to a stateless register
106106
unsafe { (*Self::ptr()).icer[usize::from(nr / 32)].write(1 << (nr % 32)) }
107107
}
@@ -112,9 +112,9 @@ impl NVIC {
112112
#[inline]
113113
pub unsafe fn unmask<I>(interrupt: I)
114114
where
115-
I: Nr,
115+
I: InterruptNumber,
116116
{
117-
let nr = interrupt.nr();
117+
let nr = interrupt.into();
118118
// NOTE(ptr) this is a write to a stateless register
119119
(*Self::ptr()).iser[usize::from(nr / 32)].write(1 << (nr % 32))
120120
}
@@ -127,11 +127,11 @@ impl NVIC {
127127
#[inline]
128128
pub fn get_priority<I>(interrupt: I) -> u8
129129
where
130-
I: Nr,
130+
I: InterruptNumber,
131131
{
132132
#[cfg(not(armv6m))]
133133
{
134-
let nr = interrupt.nr();
134+
let nr = interrupt.into();
135135
// NOTE(unsafe) atomic read with no side effects
136136
unsafe { (*Self::ptr()).ipr[usize::from(nr)].read() }
137137
}
@@ -150,9 +150,9 @@ impl NVIC {
150150
#[inline]
151151
pub fn is_active<I>(interrupt: I) -> bool
152152
where
153-
I: Nr,
153+
I: InterruptNumber,
154154
{
155-
let nr = interrupt.nr();
155+
let nr = interrupt.into();
156156
let mask = 1 << (nr % 32);
157157

158158
// NOTE(unsafe) atomic read with no side effects
@@ -163,9 +163,9 @@ impl NVIC {
163163
#[inline]
164164
pub fn is_enabled<I>(interrupt: I) -> bool
165165
where
166-
I: Nr,
166+
I: InterruptNumber,
167167
{
168-
let nr = interrupt.nr();
168+
let nr = interrupt.into();
169169
let mask = 1 << (nr % 32);
170170

171171
// NOTE(unsafe) atomic read with no side effects
@@ -176,9 +176,9 @@ impl NVIC {
176176
#[inline]
177177
pub fn is_pending<I>(interrupt: I) -> bool
178178
where
179-
I: Nr,
179+
I: InterruptNumber,
180180
{
181-
let nr = interrupt.nr();
181+
let nr = interrupt.into();
182182
let mask = 1 << (nr % 32);
183183

184184
// NOTE(unsafe) atomic read with no side effects
@@ -189,9 +189,9 @@ impl NVIC {
189189
#[inline]
190190
pub fn pend<I>(interrupt: I)
191191
where
192-
I: Nr,
192+
I: InterruptNumber,
193193
{
194-
let nr = interrupt.nr();
194+
let nr = interrupt.into();
195195

196196
// NOTE(unsafe) atomic stateless write; ICPR doesn't store any state
197197
unsafe { (*Self::ptr()).ispr[usize::from(nr / 32)].write(1 << (nr % 32)) }
@@ -212,11 +212,11 @@ impl NVIC {
212212
#[inline]
213213
pub unsafe fn set_priority<I>(&mut self, interrupt: I, prio: u8)
214214
where
215-
I: Nr,
215+
I: InterruptNumber,
216216
{
217217
#[cfg(not(armv6m))]
218218
{
219-
let nr = interrupt.nr();
219+
let nr = interrupt.into();
220220
self.ipr[usize::from(nr)].write(prio)
221221
}
222222

@@ -235,9 +235,9 @@ impl NVIC {
235235
#[inline]
236236
pub fn unpend<I>(interrupt: I)
237237
where
238-
I: Nr,
238+
I: InterruptNumber,
239239
{
240-
let nr = interrupt.nr();
240+
let nr = interrupt.into();
241241

242242
// NOTE(unsafe) atomic stateless write; ICPR doesn't store any state
243243
unsafe { (*Self::ptr()).icpr[usize::from(nr / 32)].write(1 << (nr % 32)) }
@@ -247,17 +247,17 @@ impl NVIC {
247247
#[inline]
248248
fn ipr_index<I>(interrupt: &I) -> usize
249249
where
250-
I: Nr,
250+
I: InterruptNumber,
251251
{
252-
usize::from(interrupt.nr()) / 4
252+
usize::from(interrupt.into()) / 4
253253
}
254254

255255
#[cfg(armv6m)]
256256
#[inline]
257257
fn ipr_shift<I>(interrupt: &I) -> usize
258258
where
259-
I: Nr,
259+
I: InterruptNumber,
260260
{
261-
(usize::from(interrupt.nr()) % 4) * 8
261+
(usize::from(interrupt.into()) % 4) * 8
262262
}
263263
}

0 commit comments

Comments
 (0)