Skip to content

Commit b5ad45c

Browse files
committed
Add new InterruptNumber trait
1 parent 9021bcd commit b5ad45c

File tree

2 files changed

+53
-34
lines changed

2 files changed

+53
-34
lines changed

src/interrupt.rs

+21-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,27 @@
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: Copy {
20+
/// Return the interrupt number associated with this variant.
21+
///
22+
/// See trait documentation for safety requirements.
23+
fn number(self) -> u16;
24+
}
625

726
/// Disables all interrupts
827
#[inline]

src/peripheral/nvic.rs

+32-32
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.number();
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.number();
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.number();
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,20 +127,20 @@ 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.number();
135135
// NOTE(unsafe) atomic read with no side effects
136136
unsafe { (*Self::ptr()).ipr[usize::from(nr)].read() }
137137
}
138138

139139
#[cfg(armv6m)]
140140
{
141141
// NOTE(unsafe) atomic read with no side effects
142-
let ipr_n = unsafe { (*Self::ptr()).ipr[Self::ipr_index(&interrupt)].read() };
143-
let prio = (ipr_n >> Self::ipr_shift(&interrupt)) & 0x0000_00ff;
142+
let ipr_n = unsafe { (*Self::ptr()).ipr[Self::ipr_index(interrupt)].read() };
143+
let prio = (ipr_n >> Self::ipr_shift(interrupt)) & 0x0000_00ff;
144144
prio as u8
145145
}
146146
}
@@ -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.number();
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.number();
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.number();
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.number();
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,19 +212,19 @@ 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.number();
220220
self.ipr[usize::from(nr)].write(prio)
221221
}
222222

223223
#[cfg(armv6m)]
224224
{
225-
self.ipr[Self::ipr_index(&interrupt)].modify(|value| {
226-
let mask = 0x0000_00ff << Self::ipr_shift(&interrupt);
227-
let prio = u32::from(prio) << Self::ipr_shift(&interrupt);
225+
self.ipr[Self::ipr_index(interrupt)].modify(|value| {
226+
let mask = 0x0000_00ff << Self::ipr_shift(interrupt);
227+
let prio = u32::from(prio) << Self::ipr_shift(interrupt);
228228

229229
(value & !mask) | prio
230230
})
@@ -235,29 +235,29 @@ 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.number();
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)) }
244244
}
245245

246246
#[cfg(armv6m)]
247247
#[inline]
248-
fn ipr_index<I>(interrupt: &I) -> usize
248+
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.number()) / 4
253253
}
254254

255255
#[cfg(armv6m)]
256256
#[inline]
257-
fn ipr_shift<I>(interrupt: &I) -> usize
257+
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.number()) % 4) * 8
262262
}
263263
}

0 commit comments

Comments
 (0)