1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
#![no_std]
#![no_main]
#![feature(type_alias_impl_trait)]
#![feature(alloc_error_handler)]
#[path = "../example_common.rs"]
mod example_common;
use example_common::*;
use cortex_m_rt::entry;
use defmt::*;
use embassy::executor::{task, Executor};
use embassy::util::Forever;
use nrf_softdevice::interrupt;
use nrf_softdevice::Softdevice;
static EXECUTOR: Forever<Executor> = Forever::new();
#[task]
async fn softdevice_task(sd: &'static Softdevice) {
sd.run().await;
}
#[task]
async fn interrupt_task(_sd: &'static Softdevice) {
let enabled = interrupt::is_enabled(interrupt::SWI0_EGU0);
info!("enabled: {:?}", enabled);
// This would panic with "irq RADIO is reserved for the softdevice"
// interrupt::set_priority(interrupt::RADIO, interrupt::Priority::Level7);
// This would panic with "priority level Level1 is reserved for the softdevice"
// interrupt::set_priority(interrupt::SWI0_EGU0, interrupt::Priority::Level1);
// This would panic with "irq SWI0_EGU0 has priority Level0 which is reserved for the softdevice. Set another prority before enabling it.""
// interrupt::enable(interrupt::SWI0_EGU0);
// If we set a non-reserved priority first, we can enable the interrupt
interrupt::set_priority(interrupt::SWI0_EGU0, interrupt::Priority::Level7);
interrupt::enable(interrupt::SWI0_EGU0);
// Now it's enabled
let enabled = interrupt::is_enabled(interrupt::SWI0_EGU0);
info!("enabled: {:?}", enabled);
// The interrupt will trigger instantly
info!("before pend");
interrupt::pend(interrupt::SWI0_EGU0);
info!("after pend");
interrupt::free(|_| {
info!("Hello from critical section!");
// The interrupt will trigger at end of critical section
info!("before pend");
interrupt::pend(interrupt::SWI0_EGU0);
info!("after pend");
// This will print true even if we're inside a critical section
// because it reads a "backup" of the irq enabled registers.
let enabled = interrupt::is_enabled(interrupt::SWI0_EGU0);
info!("enabled: {:?}", enabled);
// You can also enable/disable interrupts inside a critical section
// They don't take effect until exiting the critical section, so it's safe.
// (they modify the "backup" register which gets restored on CS exit)
interrupt::set_priority(interrupt::SWI1_EGU1, interrupt::Priority::Level6);
interrupt::enable(interrupt::SWI1_EGU1);
interrupt::pend(interrupt::SWI1_EGU1);
info!("exiting critical section...");
});
info!("exited critical section");
}
#[interrupt]
fn SWI0_EGU0() {
info!("SWI0_EGU0 triggered!")
}
#[interrupt]
fn SWI1_EGU1() {
info!("SWI1_EGU1 triggered!")
}
#[entry]
fn main() -> ! {
info!("Hello World!");
let (sdp, _p) = take_peripherals();
let sd = Softdevice::enable(sdp, &Default::default());
let executor = EXECUTOR.put(Executor::new());
executor.run(|spawner| {
unwrap!(spawner.spawn(softdevice_task(sd)));
unwrap!(spawner.spawn(interrupt_task(sd)));
});
}
|