aboutsummaryrefslogtreecommitdiff
path: root/examples/nrf/src
diff options
context:
space:
mode:
Diffstat (limited to 'examples/nrf/src')
-rw-r--r--examples/nrf/src/bin/blinky.rs28
-rw-r--r--examples/nrf/src/bin/buffered_uart.rs68
-rw-r--r--examples/nrf/src/bin/executor_fairness_test.rs47
-rw-r--r--examples/nrf/src/bin/gpiote_channel.rs72
-rw-r--r--examples/nrf/src/bin/gpiote_port.rs43
-rw-r--r--examples/nrf/src/bin/multiprio.rs162
-rw-r--r--examples/nrf/src/bin/ppi.rs87
-rw-r--r--examples/nrf/src/bin/pwm.rs104
-rw-r--r--examples/nrf/src/bin/qspi.rs84
-rw-r--r--examples/nrf/src/bin/qspi_lowpower.rs85
-rw-r--r--examples/nrf/src/bin/raw_spawn.rs65
-rw-r--r--examples/nrf/src/bin/spim.rs76
-rw-r--r--examples/nrf/src/bin/timer.rs37
-rw-r--r--examples/nrf/src/bin/twim.rs35
-rw-r--r--examples/nrf/src/bin/twim_lowpower.rs54
-rw-r--r--examples/nrf/src/bin/uart.rs43
-rw-r--r--examples/nrf/src/bin/uart_idle.rs46
-rw-r--r--examples/nrf/src/example_common.rs17
18 files changed, 1153 insertions, 0 deletions
diff --git a/examples/nrf/src/bin/blinky.rs b/examples/nrf/src/bin/blinky.rs
new file mode 100644
index 000000000..8f12cfda9
--- /dev/null
+++ b/examples/nrf/src/bin/blinky.rs
@@ -0,0 +1,28 @@
1#![no_std]
2#![no_main]
3#![feature(min_type_alias_impl_trait)]
4#![feature(impl_trait_in_bindings)]
5#![feature(type_alias_impl_trait)]
6#![allow(incomplete_features)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10
11use defmt::panic;
12use embassy::executor::Spawner;
13use embassy::time::{Duration, Timer};
14use embassy_nrf::gpio::{Level, Output, OutputDrive};
15use embassy_nrf::Peripherals;
16use embedded_hal::digital::v2::OutputPin;
17
18#[embassy::main]
19async fn main(_spawner: Spawner, p: Peripherals) {
20 let mut led = Output::new(p.P0_13, Level::Low, OutputDrive::Standard);
21
22 loop {
23 led.set_high().unwrap();
24 Timer::after(Duration::from_millis(300)).await;
25 led.set_low().unwrap();
26 Timer::after(Duration::from_millis(300)).await;
27 }
28}
diff --git a/examples/nrf/src/bin/buffered_uart.rs b/examples/nrf/src/bin/buffered_uart.rs
new file mode 100644
index 000000000..c800e64fc
--- /dev/null
+++ b/examples/nrf/src/bin/buffered_uart.rs
@@ -0,0 +1,68 @@
1#![no_std]
2#![no_main]
3#![feature(min_type_alias_impl_trait)]
4#![feature(impl_trait_in_bindings)]
5#![feature(type_alias_impl_trait)]
6#![allow(incomplete_features)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10
11use defmt::panic;
12use embassy::executor::Spawner;
13use embassy::io::{AsyncBufReadExt, AsyncWriteExt};
14use embassy_nrf::gpio::NoPin;
15use embassy_nrf::{buffered_uarte::BufferedUarte, interrupt, uarte, Peripherals};
16use example_common::*;
17use futures::pin_mut;
18
19#[embassy::main]
20async fn main(_spawner: Spawner, p: Peripherals) {
21 let mut config = uarte::Config::default();
22 config.parity = uarte::Parity::EXCLUDED;
23 config.baudrate = uarte::Baudrate::BAUD115200;
24
25 let mut tx_buffer = [0u8; 4096];
26 let mut rx_buffer = [0u8; 4096];
27
28 let irq = interrupt::take!(UARTE0_UART0);
29 let u = unsafe {
30 BufferedUarte::new(
31 p.UARTE0,
32 p.TIMER0,
33 p.PPI_CH0,
34 p.PPI_CH1,
35 irq,
36 p.P0_08,
37 p.P0_06,
38 NoPin,
39 NoPin,
40 config,
41 &mut rx_buffer,
42 &mut tx_buffer,
43 )
44 };
45 pin_mut!(u);
46
47 info!("uarte initialized!");
48
49 unwrap!(u.write_all(b"Hello!\r\n").await);
50 info!("wrote hello in uart!");
51
52 // Simple demo, reading 8-char chunks and echoing them back reversed.
53 loop {
54 info!("reading...");
55 let mut buf = [0u8; 8];
56 unwrap!(u.read_exact(&mut buf).await);
57 info!("read done, got {}", buf);
58
59 // Reverse buf
60 for i in 0..4 {
61 buf.swap(i, 7 - i);
62 }
63
64 info!("writing...");
65 unwrap!(u.write_all(&buf).await);
66 info!("write done");
67 }
68}
diff --git a/examples/nrf/src/bin/executor_fairness_test.rs b/examples/nrf/src/bin/executor_fairness_test.rs
new file mode 100644
index 000000000..797be4335
--- /dev/null
+++ b/examples/nrf/src/bin/executor_fairness_test.rs
@@ -0,0 +1,47 @@
1#![no_std]
2#![no_main]
3#![feature(min_type_alias_impl_trait)]
4#![feature(impl_trait_in_bindings)]
5#![feature(type_alias_impl_trait)]
6#![allow(incomplete_features)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10use example_common::*;
11
12use core::task::Poll;
13use defmt::panic;
14use embassy::executor::Spawner;
15use embassy::time::{Duration, Instant, Timer};
16use embassy_nrf::{interrupt, Peripherals};
17
18#[embassy::task]
19async fn run1() {
20 loop {
21 info!("DING DONG");
22 Timer::after(Duration::from_ticks(16000)).await;
23 }
24}
25
26#[embassy::task]
27async fn run2() {
28 loop {
29 Timer::at(Instant::from_ticks(0)).await;
30 }
31}
32
33#[embassy::task]
34async fn run3() {
35 futures::future::poll_fn(|cx| {
36 cx.waker().wake_by_ref();
37 Poll::<()>::Pending
38 })
39 .await;
40}
41
42#[embassy::main]
43async fn main(spawner: Spawner, _p: Peripherals) {
44 unwrap!(spawner.spawn(run1()));
45 unwrap!(spawner.spawn(run2()));
46 unwrap!(spawner.spawn(run3()));
47}
diff --git a/examples/nrf/src/bin/gpiote_channel.rs b/examples/nrf/src/bin/gpiote_channel.rs
new file mode 100644
index 000000000..9800aed98
--- /dev/null
+++ b/examples/nrf/src/bin/gpiote_channel.rs
@@ -0,0 +1,72 @@
1#![no_std]
2#![no_main]
3#![feature(min_type_alias_impl_trait)]
4#![feature(impl_trait_in_bindings)]
5#![feature(type_alias_impl_trait)]
6#![allow(incomplete_features)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10use example_common::*;
11
12use defmt::panic;
13use embassy::executor::Spawner;
14use embassy_nrf::gpio::{Input, Pull};
15use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity};
16use embassy_nrf::{interrupt, Peripherals};
17
18#[embassy::main]
19async fn main(_spawner: Spawner, p: Peripherals) {
20 info!("Starting!");
21
22 let ch1 = InputChannel::new(
23 p.GPIOTE_CH0,
24 Input::new(p.P0_11, Pull::Up),
25 InputChannelPolarity::HiToLo,
26 );
27 let ch2 = InputChannel::new(
28 p.GPIOTE_CH1,
29 Input::new(p.P0_12, Pull::Up),
30 InputChannelPolarity::LoToHi,
31 );
32 let ch3 = InputChannel::new(
33 p.GPIOTE_CH2,
34 Input::new(p.P0_24, Pull::Up),
35 InputChannelPolarity::Toggle,
36 );
37 let ch4 = InputChannel::new(
38 p.GPIOTE_CH3,
39 Input::new(p.P0_25, Pull::Up),
40 InputChannelPolarity::Toggle,
41 );
42
43 let button1 = async {
44 loop {
45 ch1.wait().await;
46 info!("Button 1 pressed")
47 }
48 };
49
50 let button2 = async {
51 loop {
52 ch2.wait().await;
53 info!("Button 2 released")
54 }
55 };
56
57 let button3 = async {
58 loop {
59 ch3.wait().await;
60 info!("Button 3 toggled")
61 }
62 };
63
64 let button4 = async {
65 loop {
66 ch4.wait().await;
67 info!("Button 4 toggled")
68 }
69 };
70
71 futures::join!(button1, button2, button3, button4);
72}
diff --git a/examples/nrf/src/bin/gpiote_port.rs b/examples/nrf/src/bin/gpiote_port.rs
new file mode 100644
index 000000000..4a7951cd3
--- /dev/null
+++ b/examples/nrf/src/bin/gpiote_port.rs
@@ -0,0 +1,43 @@
1#![no_std]
2#![no_main]
3#![feature(min_type_alias_impl_trait)]
4#![feature(impl_trait_in_bindings)]
5#![feature(type_alias_impl_trait)]
6#![allow(incomplete_features)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10
11use defmt::panic;
12use embassy::executor::Spawner;
13use embassy::traits::gpio::{WaitForHigh, WaitForLow};
14use embassy_nrf::gpio::{AnyPin, Input, Pin as _, Pull};
15use embassy_nrf::gpiote::PortInput;
16use embassy_nrf::interrupt;
17use embassy_nrf::Peripherals;
18use example_common::*;
19
20#[embassy::task(pool_size = 4)]
21async fn button_task(n: usize, mut pin: PortInput<'static, AnyPin>) {
22 loop {
23 pin.wait_for_low().await;
24 info!("Button {:?} pressed!", n);
25 pin.wait_for_high().await;
26 info!("Button {:?} released!", n);
27 }
28}
29
30#[embassy::main]
31async fn main(spawner: Spawner, p: Peripherals) {
32 info!("Starting!");
33
34 let btn1 = PortInput::new(Input::new(p.P0_11.degrade(), Pull::Up));
35 let btn2 = PortInput::new(Input::new(p.P0_12.degrade(), Pull::Up));
36 let btn3 = PortInput::new(Input::new(p.P0_24.degrade(), Pull::Up));
37 let btn4 = PortInput::new(Input::new(p.P0_25.degrade(), Pull::Up));
38
39 spawner.spawn(button_task(1, btn1)).unwrap();
40 spawner.spawn(button_task(2, btn2)).unwrap();
41 spawner.spawn(button_task(3, btn3)).unwrap();
42 spawner.spawn(button_task(4, btn4)).unwrap();
43}
diff --git a/examples/nrf/src/bin/multiprio.rs b/examples/nrf/src/bin/multiprio.rs
new file mode 100644
index 000000000..79fa029b3
--- /dev/null
+++ b/examples/nrf/src/bin/multiprio.rs
@@ -0,0 +1,162 @@
1//! This example showcases how to create multiple Executor instances to run tasks at
2//! different priority levels.
3//!
4//! Low priority executor runs in thread mode (not interrupt), and uses `sev` for signaling
5//! there's work in the queue, and `wfe` for waiting for work.
6//!
7//! Medium and high priority executors run in two interrupts with different priorities.
8//! Signaling work is done by pending the interrupt. No "waiting" needs to be done explicitly, since
9//! when there's work the interrupt will trigger and run the executor.
10//!
11//! Sample output below. Note that high priority ticks can interrupt everything else, and
12//! medium priority computations can interrupt low priority computations, making them to appear
13//! to take significantly longer time.
14//!
15//! ```not_rust
16//! [med] Starting long computation
17//! [med] done in 992 ms
18//! [high] tick!
19//! [low] Starting long computation
20//! [med] Starting long computation
21//! [high] tick!
22//! [high] tick!
23//! [med] done in 993 ms
24//! [med] Starting long computation
25//! [high] tick!
26//! [high] tick!
27//! [med] done in 993 ms
28//! [low] done in 3972 ms
29//! [med] Starting long computation
30//! [high] tick!
31//! [high] tick!
32//! [med] done in 993 ms
33//! ```
34//!
35//! For comparison, try changing the code so all 3 tasks get spawned on the low priority executor.
36//! You will get an output like the following. Note that no computation is ever interrupted.
37//!
38//! ```not_rust
39//! [high] tick!
40//! [med] Starting long computation
41//! [med] done in 496 ms
42//! [low] Starting long computation
43//! [low] done in 992 ms
44//! [med] Starting long computation
45//! [med] done in 496 ms
46//! [high] tick!
47//! [low] Starting long computation
48//! [low] done in 992 ms
49//! [high] tick!
50//! [med] Starting long computation
51//! [med] done in 496 ms
52//! [high] tick!
53//! ```
54//!
55
56#![no_std]
57#![no_main]
58#![feature(min_type_alias_impl_trait)]
59#![feature(impl_trait_in_bindings)]
60#![feature(type_alias_impl_trait)]
61#![allow(incomplete_features)]
62
63#[path = "../example_common.rs"]
64mod example_common;
65use example_common::*;
66
67use cortex_m_rt::entry;
68use defmt::panic;
69use embassy::executor::{Executor, InterruptExecutor};
70use embassy::interrupt::InterruptExt;
71use embassy::time::{Duration, Instant, Timer};
72use embassy::util::Forever;
73use embassy_nrf::{interrupt, peripherals, rtc};
74
75#[embassy::task]
76async fn run_high() {
77 loop {
78 info!(" [high] tick!");
79 Timer::after(Duration::from_ticks(27374)).await;
80 }
81}
82
83#[embassy::task]
84async fn run_med() {
85 loop {
86 let start = Instant::now();
87 info!(" [med] Starting long computation");
88
89 // Spin-wait to simulate a long CPU computation
90 cortex_m::asm::delay(32_000_000); // ~1 second
91
92 let end = Instant::now();
93 let ms = end.duration_since(start).as_ticks() / 33;
94 info!(" [med] done in {} ms", ms);
95
96 Timer::after(Duration::from_ticks(23421)).await;
97 }
98}
99
100#[embassy::task]
101async fn run_low() {
102 loop {
103 let start = Instant::now();
104 info!("[low] Starting long computation");
105
106 // Spin-wait to simulate a long CPU computation
107 cortex_m::asm::delay(64_000_000); // ~2 seconds
108
109 let end = Instant::now();
110 let ms = end.duration_since(start).as_ticks() / 33;
111 info!("[low] done in {} ms", ms);
112
113 Timer::after(Duration::from_ticks(32983)).await;
114 }
115}
116
117static RTC: Forever<rtc::RTC<peripherals::RTC1>> = Forever::new();
118static ALARM_HIGH: Forever<rtc::Alarm<peripherals::RTC1>> = Forever::new();
119static EXECUTOR_HIGH: Forever<InterruptExecutor<interrupt::SWI1_EGU1>> = Forever::new();
120static ALARM_MED: Forever<rtc::Alarm<peripherals::RTC1>> = Forever::new();
121static EXECUTOR_MED: Forever<InterruptExecutor<interrupt::SWI0_EGU0>> = Forever::new();
122static ALARM_LOW: Forever<rtc::Alarm<peripherals::RTC1>> = Forever::new();
123static EXECUTOR_LOW: Forever<Executor> = Forever::new();
124
125#[entry]
126fn main() -> ! {
127 info!("Hello World!");
128
129 let p = embassy_nrf::init(Default::default());
130
131 let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1)));
132 rtc.start();
133 unsafe { embassy::time::set_clock(rtc) };
134
135 // High-priority executor: SWI1_EGU1, priority level 6
136 let irq = interrupt::take!(SWI1_EGU1);
137 irq.set_priority(interrupt::Priority::P6);
138 let alarm = ALARM_HIGH.put(rtc.alarm2());
139 let executor = EXECUTOR_HIGH.put(InterruptExecutor::new(irq));
140 executor.set_alarm(alarm);
141 executor.start(|spawner| {
142 unwrap!(spawner.spawn(run_high()));
143 });
144
145 // Medium-priority executor: SWI0_EGU0, priority level 7
146 let irq = interrupt::take!(SWI0_EGU0);
147 irq.set_priority(interrupt::Priority::P7);
148 let alarm = ALARM_MED.put(rtc.alarm1());
149 let executor = EXECUTOR_MED.put(InterruptExecutor::new(irq));
150 executor.set_alarm(alarm);
151 executor.start(|spawner| {
152 unwrap!(spawner.spawn(run_med()));
153 });
154
155 // Low priority executor: runs in thread mode, using WFE/SEV
156 let alarm = ALARM_LOW.put(rtc.alarm0());
157 let executor = EXECUTOR_LOW.put(Executor::new());
158 executor.set_alarm(alarm);
159 executor.run(|spawner| {
160 unwrap!(spawner.spawn(run_low()));
161 });
162}
diff --git a/examples/nrf/src/bin/ppi.rs b/examples/nrf/src/bin/ppi.rs
new file mode 100644
index 000000000..717604b9e
--- /dev/null
+++ b/examples/nrf/src/bin/ppi.rs
@@ -0,0 +1,87 @@
1#![no_std]
2#![no_main]
3#![feature(min_type_alias_impl_trait)]
4#![feature(impl_trait_in_bindings)]
5#![feature(type_alias_impl_trait)]
6#![allow(incomplete_features)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10use example_common::*;
11
12use core::future::pending;
13use defmt::panic;
14use embassy::executor::Spawner;
15use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull};
16use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity};
17use embassy_nrf::ppi::Ppi;
18use embassy_nrf::{interrupt, Peripherals};
19use gpiote::{OutputChannel, OutputChannelPolarity};
20
21#[embassy::main]
22async fn main(_spawner: Spawner, p: Peripherals) {
23 info!("Starting!");
24
25 let button1 = InputChannel::new(
26 p.GPIOTE_CH0,
27 Input::new(p.P0_11, Pull::Up),
28 InputChannelPolarity::HiToLo,
29 );
30 let button2 = InputChannel::new(
31 p.GPIOTE_CH1,
32 Input::new(p.P0_12, Pull::Up),
33 InputChannelPolarity::HiToLo,
34 );
35 let button3 = InputChannel::new(
36 p.GPIOTE_CH2,
37 Input::new(p.P0_24, Pull::Up),
38 InputChannelPolarity::HiToLo,
39 );
40 let button4 = InputChannel::new(
41 p.GPIOTE_CH3,
42 Input::new(p.P0_25, Pull::Up),
43 InputChannelPolarity::HiToLo,
44 );
45
46 let led1 = OutputChannel::new(
47 p.GPIOTE_CH4,
48 Output::new(p.P0_13, Level::Low, OutputDrive::Standard),
49 OutputChannelPolarity::Toggle,
50 );
51
52 let led2 = OutputChannel::new(
53 p.GPIOTE_CH5,
54 Output::new(p.P0_14, Level::Low, OutputDrive::Standard),
55 OutputChannelPolarity::Toggle,
56 );
57
58 let mut ppi = Ppi::new(p.PPI_CH0);
59 ppi.set_event(button1.event_in());
60 ppi.set_task(led1.task_out());
61 ppi.enable();
62
63 let mut ppi = Ppi::new(p.PPI_CH1);
64 ppi.set_event(button2.event_in());
65 ppi.set_task(led1.task_clr());
66 ppi.enable();
67
68 let mut ppi = Ppi::new(p.PPI_CH2);
69 ppi.set_event(button3.event_in());
70 ppi.set_task(led1.task_set());
71 ppi.enable();
72
73 let mut ppi = Ppi::new(p.PPI_CH3);
74 ppi.set_event(button4.event_in());
75 ppi.set_task(led1.task_out());
76 ppi.set_fork_task(led2.task_out());
77 ppi.enable();
78
79 info!("PPI setup!");
80 info!("Press button 1 to toggle LED 1");
81 info!("Press button 2 to turn on LED 1");
82 info!("Press button 3 to turn off LED 1");
83 info!("Press button 4 to toggle LEDs 1 and 2");
84
85 // Block forever so the above drivers don't get dropped
86 pending::<()>().await;
87}
diff --git a/examples/nrf/src/bin/pwm.rs b/examples/nrf/src/bin/pwm.rs
new file mode 100644
index 000000000..d2874a29b
--- /dev/null
+++ b/examples/nrf/src/bin/pwm.rs
@@ -0,0 +1,104 @@
1#![no_std]
2#![no_main]
3#![feature(min_type_alias_impl_trait)]
4#![feature(impl_trait_in_bindings)]
5#![feature(type_alias_impl_trait)]
6#![allow(incomplete_features)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10use defmt::{panic, *};
11use embassy::executor::Spawner;
12use embassy::time::{Duration, Timer};
13use embassy_nrf::pwm::{Prescaler, Pwm};
14use embassy_nrf::{interrupt, Peripherals};
15
16// for i in range(1024): print(int((math.sin(i/512*math.pi)*0.4+0.5)**2*32767), ', ', end='')
17static DUTY: [u16; 1024] = [
18 8191, 8272, 8353, 8434, 8516, 8598, 8681, 8764, 8847, 8931, 9015, 9099, 9184, 9269, 9354, 9440,
19 9526, 9613, 9700, 9787, 9874, 9962, 10050, 10139, 10227, 10316, 10406, 10495, 10585, 10675,
20 10766, 10857, 10948, 11039, 11131, 11223, 11315, 11407, 11500, 11592, 11685, 11779, 11872,
21 11966, 12060, 12154, 12248, 12343, 12438, 12533, 12628, 12723, 12818, 12914, 13010, 13106,
22 13202, 13298, 13394, 13491, 13587, 13684, 13781, 13878, 13975, 14072, 14169, 14266, 14364,
23 14461, 14558, 14656, 14754, 14851, 14949, 15046, 15144, 15242, 15339, 15437, 15535, 15632,
24 15730, 15828, 15925, 16023, 16120, 16218, 16315, 16412, 16510, 16607, 16704, 16801, 16898,
25 16995, 17091, 17188, 17284, 17380, 17477, 17572, 17668, 17764, 17859, 17955, 18050, 18145,
26 18239, 18334, 18428, 18522, 18616, 18710, 18803, 18896, 18989, 19082, 19174, 19266, 19358,
27 19449, 19540, 19631, 19722, 19812, 19902, 19991, 20081, 20169, 20258, 20346, 20434, 20521,
28 20608, 20695, 20781, 20867, 20952, 21037, 21122, 21206, 21290, 21373, 21456, 21538, 21620,
29 21701, 21782, 21863, 21943, 22022, 22101, 22179, 22257, 22335, 22412, 22488, 22564, 22639,
30 22714, 22788, 22861, 22934, 23007, 23079, 23150, 23220, 23290, 23360, 23429, 23497, 23564,
31 23631, 23698, 23763, 23828, 23892, 23956, 24019, 24081, 24143, 24204, 24264, 24324, 24383,
32 24441, 24499, 24555, 24611, 24667, 24721, 24775, 24828, 24881, 24933, 24983, 25034, 25083,
33 25132, 25180, 25227, 25273, 25319, 25363, 25407, 25451, 25493, 25535, 25575, 25615, 25655,
34 25693, 25731, 25767, 25803, 25838, 25873, 25906, 25939, 25971, 26002, 26032, 26061, 26089,
35 26117, 26144, 26170, 26195, 26219, 26242, 26264, 26286, 26307, 26327, 26346, 26364, 26381,
36 26397, 26413, 26427, 26441, 26454, 26466, 26477, 26487, 26496, 26505, 26512, 26519, 26525,
37 26530, 26534, 26537, 26539, 26540, 26541, 26540, 26539, 26537, 26534, 26530, 26525, 26519,
38 26512, 26505, 26496, 26487, 26477, 26466, 26454, 26441, 26427, 26413, 26397, 26381, 26364,
39 26346, 26327, 26307, 26286, 26264, 26242, 26219, 26195, 26170, 26144, 26117, 26089, 26061,
40 26032, 26002, 25971, 25939, 25906, 25873, 25838, 25803, 25767, 25731, 25693, 25655, 25615,
41 25575, 25535, 25493, 25451, 25407, 25363, 25319, 25273, 25227, 25180, 25132, 25083, 25034,
42 24983, 24933, 24881, 24828, 24775, 24721, 24667, 24611, 24555, 24499, 24441, 24383, 24324,
43 24264, 24204, 24143, 24081, 24019, 23956, 23892, 23828, 23763, 23698, 23631, 23564, 23497,
44 23429, 23360, 23290, 23220, 23150, 23079, 23007, 22934, 22861, 22788, 22714, 22639, 22564,
45 22488, 22412, 22335, 22257, 22179, 22101, 22022, 21943, 21863, 21782, 21701, 21620, 21538,
46 21456, 21373, 21290, 21206, 21122, 21037, 20952, 20867, 20781, 20695, 20608, 20521, 20434,
47 20346, 20258, 20169, 20081, 19991, 19902, 19812, 19722, 19631, 19540, 19449, 19358, 19266,
48 19174, 19082, 18989, 18896, 18803, 18710, 18616, 18522, 18428, 18334, 18239, 18145, 18050,
49 17955, 17859, 17764, 17668, 17572, 17477, 17380, 17284, 17188, 17091, 16995, 16898, 16801,
50 16704, 16607, 16510, 16412, 16315, 16218, 16120, 16023, 15925, 15828, 15730, 15632, 15535,
51 15437, 15339, 15242, 15144, 15046, 14949, 14851, 14754, 14656, 14558, 14461, 14364, 14266,
52 14169, 14072, 13975, 13878, 13781, 13684, 13587, 13491, 13394, 13298, 13202, 13106, 13010,
53 12914, 12818, 12723, 12628, 12533, 12438, 12343, 12248, 12154, 12060, 11966, 11872, 11779,
54 11685, 11592, 11500, 11407, 11315, 11223, 11131, 11039, 10948, 10857, 10766, 10675, 10585,
55 10495, 10406, 10316, 10227, 10139, 10050, 9962, 9874, 9787, 9700, 9613, 9526, 9440, 9354, 9269,
56 9184, 9099, 9015, 8931, 8847, 8764, 8681, 8598, 8516, 8434, 8353, 8272, 8191, 8111, 8031, 7952,
57 7873, 7794, 7716, 7638, 7561, 7484, 7407, 7331, 7255, 7180, 7105, 7031, 6957, 6883, 6810, 6738,
58 6665, 6594, 6522, 6451, 6381, 6311, 6241, 6172, 6104, 6036, 5968, 5901, 5834, 5767, 5702, 5636,
59 5571, 5507, 5443, 5379, 5316, 5253, 5191, 5130, 5068, 5008, 4947, 4888, 4828, 4769, 4711, 4653,
60 4596, 4539, 4482, 4426, 4371, 4316, 4261, 4207, 4153, 4100, 4047, 3995, 3943, 3892, 3841, 3791,
61 3741, 3691, 3642, 3594, 3546, 3498, 3451, 3404, 3358, 3312, 3267, 3222, 3178, 3134, 3090, 3047,
62 3005, 2962, 2921, 2879, 2839, 2798, 2758, 2719, 2680, 2641, 2603, 2565, 2528, 2491, 2454, 2418,
63 2382, 2347, 2312, 2278, 2244, 2210, 2177, 2144, 2112, 2080, 2048, 2017, 1986, 1956, 1926, 1896,
64 1867, 1838, 1810, 1781, 1754, 1726, 1699, 1673, 1646, 1620, 1595, 1570, 1545, 1520, 1496, 1472,
65 1449, 1426, 1403, 1380, 1358, 1336, 1315, 1294, 1273, 1252, 1232, 1212, 1192, 1173, 1154, 1135,
66 1117, 1099, 1081, 1063, 1046, 1029, 1012, 996, 980, 964, 948, 933, 918, 903, 888, 874, 860,
67 846, 833, 819, 806, 793, 781, 768, 756, 744, 733, 721, 710, 699, 688, 677, 667, 657, 647, 637,
68 627, 618, 609, 599, 591, 582, 574, 565, 557, 549, 541, 534, 526, 519, 512, 505, 498, 492, 485,
69 479, 473, 467, 461, 455, 450, 444, 439, 434, 429, 424, 419, 415, 410, 406, 402, 398, 394, 390,
70 386, 383, 379, 376, 373, 370, 367, 364, 361, 359, 356, 354, 351, 349, 347, 345, 343, 342, 340,
71 338, 337, 336, 334, 333, 332, 331, 330, 330, 329, 328, 328, 328, 327, 327, 327, 327, 327, 328,
72 328, 328, 329, 330, 330, 331, 332, 333, 334, 336, 337, 338, 340, 342, 343, 345, 347, 349, 351,
73 354, 356, 359, 361, 364, 367, 370, 373, 376, 379, 383, 386, 390, 394, 398, 402, 406, 410, 415,
74 419, 424, 429, 434, 439, 444, 450, 455, 461, 467, 473, 479, 485, 492, 498, 505, 512, 519, 526,
75 534, 541, 549, 557, 565, 574, 582, 591, 599, 609, 618, 627, 637, 647, 657, 667, 677, 688, 699,
76 710, 721, 733, 744, 756, 768, 781, 793, 806, 819, 833, 846, 860, 874, 888, 903, 918, 933, 948,
77 964, 980, 996, 1012, 1029, 1046, 1063, 1081, 1099, 1117, 1135, 1154, 1173, 1192, 1212, 1232,
78 1252, 1273, 1294, 1315, 1336, 1358, 1380, 1403, 1426, 1449, 1472, 1496, 1520, 1545, 1570, 1595,
79 1620, 1646, 1673, 1699, 1726, 1754, 1781, 1810, 1838, 1867, 1896, 1926, 1956, 1986, 2017, 2048,
80 2080, 2112, 2144, 2177, 2210, 2244, 2278, 2312, 2347, 2382, 2418, 2454, 2491, 2528, 2565, 2603,
81 2641, 2680, 2719, 2758, 2798, 2839, 2879, 2921, 2962, 3005, 3047, 3090, 3134, 3178, 3222, 3267,
82 3312, 3358, 3404, 3451, 3498, 3546, 3594, 3642, 3691, 3741, 3791, 3841, 3892, 3943, 3995, 4047,
83 4100, 4153, 4207, 4261, 4316, 4371, 4426, 4482, 4539, 4596, 4653, 4711, 4769, 4828, 4888, 4947,
84 5008, 5068, 5130, 5191, 5253, 5316, 5379, 5443, 5507, 5571, 5636, 5702, 5767, 5834, 5901, 5968,
85 6036, 6104, 6172, 6241, 6311, 6381, 6451, 6522, 6594, 6665, 6738, 6810, 6883, 6957, 7031, 7105,
86 7180, 7255, 7331, 7407, 7484, 7561, 7638, 7716, 7794, 7873, 7952, 8031, 8111,
87];
88
89#[embassy::main]
90async fn main(_spawner: Spawner, p: Peripherals) {
91 let pwm = Pwm::new(p.PWM0, p.P0_13, p.P0_14, p.P0_16, p.P0_15);
92 pwm.set_prescaler(Prescaler::Div1);
93 info!("pwm initialized!");
94
95 let mut i = 0;
96 loop {
97 i += 1;
98 pwm.set_duty(0, DUTY[i % 1024]);
99 pwm.set_duty(1, DUTY[(i + 256) % 1024]);
100 pwm.set_duty(2, DUTY[(i + 512) % 1024]);
101 pwm.set_duty(3, DUTY[(i + 768) % 1024]);
102 Timer::after(Duration::from_millis(3)).await;
103 }
104}
diff --git a/examples/nrf/src/bin/qspi.rs b/examples/nrf/src/bin/qspi.rs
new file mode 100644
index 000000000..6e49887a4
--- /dev/null
+++ b/examples/nrf/src/bin/qspi.rs
@@ -0,0 +1,84 @@
1#![no_std]
2#![no_main]
3#![feature(min_type_alias_impl_trait)]
4#![feature(impl_trait_in_bindings)]
5#![feature(type_alias_impl_trait)]
6#![allow(incomplete_features)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10
11use defmt::{assert_eq, panic};
12use embassy::executor::Spawner;
13use embassy::traits::flash::Flash;
14use embassy_nrf::Peripherals;
15use embassy_nrf::{interrupt, qspi};
16use example_common::*;
17
18const PAGE_SIZE: usize = 4096;
19
20// Workaround for alignment requirements.
21// Nicer API will probably come in the future.
22#[repr(C, align(4))]
23struct AlignedBuf([u8; 4096]);
24
25#[embassy::main]
26async fn main(_spawner: Spawner, p: Peripherals) {
27 // Config for the MX25R64 present in the nRF52840 DK
28 let mut config = qspi::Config::default();
29 config.read_opcode = qspi::ReadOpcode::READ4IO;
30 config.write_opcode = qspi::WriteOpcode::PP4IO;
31 config.write_page_size = qspi::WritePageSize::_256BYTES;
32
33 let irq = interrupt::take!(QSPI);
34 let mut q = qspi::Qspi::new(
35 p.QSPI, irq, p.P0_19, p.P0_17, p.P0_20, p.P0_21, p.P0_22, p.P0_23, config,
36 )
37 .await;
38
39 let mut id = [1; 3];
40 q.custom_instruction(0x9F, &[], &mut id).await.unwrap();
41 info!("id: {}", id);
42
43 // Read status register
44 let mut status = [4; 1];
45 q.custom_instruction(0x05, &[], &mut status).await.unwrap();
46
47 info!("status: {:?}", status[0]);
48
49 if status[0] & 0x40 == 0 {
50 status[0] |= 0x40;
51
52 q.custom_instruction(0x01, &status, &mut []).await.unwrap();
53
54 info!("enabled quad in status");
55 }
56
57 let mut buf = AlignedBuf([0u8; PAGE_SIZE]);
58
59 let pattern = |a: u32| (a ^ (a >> 8) ^ (a >> 16) ^ (a >> 24)) as u8;
60
61 for i in 0..8 {
62 info!("page {:?}: erasing... ", i);
63 q.erase(i * PAGE_SIZE).await.unwrap();
64
65 for j in 0..PAGE_SIZE {
66 buf.0[j] = pattern((j + i * PAGE_SIZE) as u32);
67 }
68
69 info!("programming...");
70 q.write(i * PAGE_SIZE, &buf.0).await.unwrap();
71 }
72
73 for i in 0..8 {
74 info!("page {:?}: reading... ", i);
75 q.read(i * PAGE_SIZE, &mut buf.0).await.unwrap();
76
77 info!("verifying...");
78 for j in 0..PAGE_SIZE {
79 assert_eq!(buf.0[j], pattern((j + i * PAGE_SIZE) as u32));
80 }
81 }
82
83 info!("done!")
84}
diff --git a/examples/nrf/src/bin/qspi_lowpower.rs b/examples/nrf/src/bin/qspi_lowpower.rs
new file mode 100644
index 000000000..ece3243b6
--- /dev/null
+++ b/examples/nrf/src/bin/qspi_lowpower.rs
@@ -0,0 +1,85 @@
1#![no_std]
2#![no_main]
3#![feature(min_type_alias_impl_trait)]
4#![feature(impl_trait_in_bindings)]
5#![feature(type_alias_impl_trait)]
6#![allow(incomplete_features)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10
11use core::mem;
12use defmt::panic;
13use embassy::executor::Spawner;
14use embassy::time::{Duration, Timer};
15use embassy::traits::flash::Flash;
16use embassy_nrf::Peripherals;
17use embassy_nrf::{interrupt, qspi};
18use example_common::*;
19
20// Workaround for alignment requirements.
21// Nicer API will probably come in the future.
22#[repr(C, align(4))]
23struct AlignedBuf([u8; 64]);
24
25#[embassy::main]
26async fn main(_spawner: Spawner, mut p: Peripherals) {
27 let mut irq = interrupt::take!(QSPI);
28
29 loop {
30 // Config for the MX25R64 present in the nRF52840 DK
31 let mut config = qspi::Config::default();
32 config.read_opcode = qspi::ReadOpcode::READ4IO;
33 config.write_opcode = qspi::WriteOpcode::PP4IO;
34 config.write_page_size = qspi::WritePageSize::_256BYTES;
35 config.deep_power_down = Some(qspi::DeepPowerDownConfig {
36 enter_time: 3, // tDP = 30uS
37 exit_time: 3, // tRDP = 35uS
38 });
39
40 let mut q = qspi::Qspi::new(
41 &mut p.QSPI,
42 &mut irq,
43 &mut p.P0_19,
44 &mut p.P0_17,
45 &mut p.P0_20,
46 &mut p.P0_21,
47 &mut p.P0_22,
48 &mut p.P0_23,
49 config,
50 )
51 .await;
52
53 let mut id = [1; 3];
54 q.custom_instruction(0x9F, &[], &mut id).await.unwrap();
55 info!("id: {}", id);
56
57 // Read status register
58 let mut status = [4; 1];
59 q.custom_instruction(0x05, &[], &mut status).await.unwrap();
60
61 info!("status: {:?}", status[0]);
62
63 if status[0] & 0x40 == 0 {
64 status[0] |= 0x40;
65
66 q.custom_instruction(0x01, &status, &mut []).await.unwrap();
67
68 info!("enabled quad in status");
69 }
70
71 let mut buf = AlignedBuf([0u8; 64]);
72
73 info!("reading...");
74 q.read(0, &mut buf.0).await.unwrap();
75 info!("read: {=[u8]:x}", buf.0);
76
77 // Drop the QSPI instance. This disables the peripehral and deconfigures the pins.
78 // This clears the borrow on the singletons, so they can now be used again.
79 mem::drop(q);
80
81 // Sleep for 1 second. The executor ensures the core sleeps with a WFE when it has nothing to do.
82 // During this sleep, the nRF chip should only use ~3uA
83 Timer::after(Duration::from_secs(1)).await;
84 }
85}
diff --git a/examples/nrf/src/bin/raw_spawn.rs b/examples/nrf/src/bin/raw_spawn.rs
new file mode 100644
index 000000000..78de7b100
--- /dev/null
+++ b/examples/nrf/src/bin/raw_spawn.rs
@@ -0,0 +1,65 @@
1#![no_std]
2#![no_main]
3
4#[path = "../example_common.rs"]
5mod example_common;
6use example_common::*;
7
8use core::mem;
9use cortex_m_rt::entry;
10use defmt::panic;
11use embassy::executor::raw::Task;
12use embassy::executor::Executor;
13use embassy::time::{Duration, Timer};
14use embassy::util::Forever;
15use embassy_nrf::peripherals;
16use embassy_nrf::{interrupt, rtc};
17
18async fn run1() {
19 loop {
20 info!("BIG INFREQUENT TICK");
21 Timer::after(Duration::from_ticks(64000)).await;
22 }
23}
24
25async fn run2() {
26 loop {
27 info!("tick");
28 Timer::after(Duration::from_ticks(13000)).await;
29 }
30}
31
32static RTC: Forever<rtc::RTC<peripherals::RTC1>> = Forever::new();
33static ALARM: Forever<rtc::Alarm<peripherals::RTC1>> = Forever::new();
34static EXECUTOR: Forever<Executor> = Forever::new();
35
36#[entry]
37fn main() -> ! {
38 info!("Hello World!");
39
40 let p = embassy_nrf::init(Default::default());
41
42 let rtc = RTC.put(rtc::RTC::new(p.RTC1, interrupt::take!(RTC1)));
43 rtc.start();
44 unsafe { embassy::time::set_clock(rtc) };
45
46 let alarm = ALARM.put(rtc.alarm0());
47 let executor = EXECUTOR.put(Executor::new());
48 executor.set_alarm(alarm);
49
50 let run1_task = Task::new();
51 let run2_task = Task::new();
52
53 // Safety: these variables do live forever if main never returns.
54 let run1_task = unsafe { make_static(&run1_task) };
55 let run2_task = unsafe { make_static(&run2_task) };
56
57 executor.run(|spawner| {
58 unwrap!(spawner.spawn(run1_task.spawn(|| run1())));
59 unwrap!(spawner.spawn(run2_task.spawn(|| run2())));
60 });
61}
62
63unsafe fn make_static<T>(t: &T) -> &'static T {
64 mem::transmute(t)
65}
diff --git a/examples/nrf/src/bin/spim.rs b/examples/nrf/src/bin/spim.rs
new file mode 100644
index 000000000..c42cc6015
--- /dev/null
+++ b/examples/nrf/src/bin/spim.rs
@@ -0,0 +1,76 @@
1#![no_std]
2#![no_main]
3#![feature(min_type_alias_impl_trait)]
4#![feature(impl_trait_in_bindings)]
5#![feature(type_alias_impl_trait)]
6#![allow(incomplete_features)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10
11use defmt::panic;
12use embassy::executor::Spawner;
13use embassy_nrf::gpio::{Level, Output, OutputDrive};
14use embassy_nrf::Peripherals;
15use embassy_nrf::{interrupt, spim};
16use embassy_traits::spi::FullDuplex;
17use embedded_hal::digital::v2::*;
18use example_common::*;
19
20#[embassy::main]
21async fn main(_spawner: Spawner, p: Peripherals) {
22 info!("running!");
23
24 let mut config = spim::Config::default();
25 config.frequency = spim::Frequency::M16;
26
27 let irq = interrupt::take!(SPIM3);
28 let mut spim = spim::Spim::new(p.SPI3, irq, p.P0_29, p.P0_28, p.P0_30, config);
29
30 let mut ncs = Output::new(p.P0_31, Level::High, OutputDrive::Standard);
31
32 // Example on how to talk to an ENC28J60 chip
33
34 // softreset
35 cortex_m::asm::delay(10);
36 ncs.set_low().unwrap();
37 cortex_m::asm::delay(5);
38 let tx = [0xFF];
39 unwrap!(spim.read_write(&mut [], &tx).await);
40 cortex_m::asm::delay(10);
41 ncs.set_high().unwrap();
42
43 cortex_m::asm::delay(100000);
44
45 let mut rx = [0; 2];
46
47 // read ESTAT
48 cortex_m::asm::delay(5000);
49 ncs.set_low().unwrap();
50 cortex_m::asm::delay(5000);
51 let tx = [0b000_11101, 0];
52 unwrap!(spim.read_write(&mut rx, &tx).await);
53 cortex_m::asm::delay(5000);
54 ncs.set_high().unwrap();
55 info!("estat: {=[?]}", rx);
56
57 // Switch to bank 3
58 cortex_m::asm::delay(10);
59 ncs.set_low().unwrap();
60 cortex_m::asm::delay(5);
61 let tx = [0b100_11111, 0b11];
62 unwrap!(spim.read_write(&mut rx, &tx).await);
63 cortex_m::asm::delay(10);
64 ncs.set_high().unwrap();
65
66 // read EREVID
67 cortex_m::asm::delay(10);
68 ncs.set_low().unwrap();
69 cortex_m::asm::delay(5);
70 let tx = [0b000_10010, 0];
71 unwrap!(spim.read_write(&mut rx, &tx).await);
72 cortex_m::asm::delay(10);
73 ncs.set_high().unwrap();
74
75 info!("erevid: {=[?]}", rx);
76}
diff --git a/examples/nrf/src/bin/timer.rs b/examples/nrf/src/bin/timer.rs
new file mode 100644
index 000000000..43f6d76ce
--- /dev/null
+++ b/examples/nrf/src/bin/timer.rs
@@ -0,0 +1,37 @@
1#![no_std]
2#![no_main]
3#![feature(min_type_alias_impl_trait)]
4#![feature(impl_trait_in_bindings)]
5#![feature(type_alias_impl_trait)]
6#![allow(incomplete_features)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10use embassy_nrf::Peripherals;
11use example_common::*;
12
13use defmt::panic;
14use embassy::executor::Spawner;
15use embassy::time::{Duration, Timer};
16
17#[embassy::task]
18async fn run1() {
19 loop {
20 info!("BIG INFREQUENT TICK");
21 Timer::after(Duration::from_ticks(64000)).await;
22 }
23}
24
25#[embassy::task]
26async fn run2() {
27 loop {
28 info!("tick");
29 Timer::after(Duration::from_ticks(13000)).await;
30 }
31}
32
33#[embassy::main]
34async fn main(spawner: Spawner, _p: Peripherals) {
35 unwrap!(spawner.spawn(run1()));
36 unwrap!(spawner.spawn(run2()));
37}
diff --git a/examples/nrf/src/bin/twim.rs b/examples/nrf/src/bin/twim.rs
new file mode 100644
index 000000000..537cea160
--- /dev/null
+++ b/examples/nrf/src/bin/twim.rs
@@ -0,0 +1,35 @@
1//! Example on how to read a 24C/24LC i2c eeprom.
2//!
3//! Connect SDA to P0.03, SCL to P0.04
4
5#![no_std]
6#![no_main]
7#![feature(min_type_alias_impl_trait)]
8#![feature(impl_trait_in_bindings)]
9#![feature(type_alias_impl_trait)]
10#![allow(incomplete_features)]
11
12#[path = "../example_common.rs"]
13mod example_common;
14
15use defmt::{panic, *};
16use embassy::executor::Spawner;
17use embassy_nrf::twim::{self, Twim};
18use embassy_nrf::{interrupt, Peripherals};
19
20const ADDRESS: u8 = 0x50;
21
22#[embassy::main]
23async fn main(_spawner: Spawner, p: Peripherals) {
24 info!("Initializing TWI...");
25 let config = twim::Config::default();
26 let irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0);
27 let mut twi = Twim::new(p.TWISPI0, irq, p.P0_03, p.P0_04, config);
28
29 info!("Reading...");
30
31 let mut buf = [0u8; 16];
32 twi.write_then_read(ADDRESS, &mut [0x00], &mut buf).unwrap();
33
34 info!("Read: {=[u8]:x}", buf);
35}
diff --git a/examples/nrf/src/bin/twim_lowpower.rs b/examples/nrf/src/bin/twim_lowpower.rs
new file mode 100644
index 000000000..1cd66a18e
--- /dev/null
+++ b/examples/nrf/src/bin/twim_lowpower.rs
@@ -0,0 +1,54 @@
1//! Example on how to read a 24C/24LC i2c eeprom with low power consumption.
2//! The eeprom is read every 1 second, while ensuring lowest possible power while
3//! sleeping between reads.
4//!
5//! Connect SDA to P0.03, SCL to P0.04
6
7#![no_std]
8#![no_main]
9#![feature(min_type_alias_impl_trait)]
10#![feature(impl_trait_in_bindings)]
11#![feature(type_alias_impl_trait)]
12#![allow(incomplete_features)]
13
14#[path = "../example_common.rs"]
15mod example_common;
16
17use core::mem;
18
19use defmt::{panic, *};
20use embassy::executor::Spawner;
21use embassy::time::{Duration, Timer};
22use embassy_nrf::twim::{self, Twim};
23use embassy_nrf::{interrupt, Peripherals};
24
25const ADDRESS: u8 = 0x50;
26
27#[embassy::main]
28async fn main(_spawner: Spawner, mut p: Peripherals) {
29 info!("Started!");
30 let mut irq = interrupt::take!(SPIM0_SPIS0_TWIM0_TWIS0_SPI0_TWI0);
31
32 loop {
33 info!("Initializing TWI...");
34 let config = twim::Config::default();
35
36 // Create the TWIM instance with borrowed singletons, so they're not consumed.
37 let mut twi = Twim::new(&mut p.TWISPI0, &mut irq, &mut p.P0_03, &mut p.P0_04, config);
38
39 info!("Reading...");
40
41 let mut buf = [0u8; 16];
42 twi.write_then_read(ADDRESS, &mut [0x00], &mut buf).unwrap();
43
44 info!("Read: {=[u8]:x}", buf);
45
46 // Drop the TWIM instance. This disables the peripehral and deconfigures the pins.
47 // This clears the borrow on the singletons, so they can now be used again.
48 mem::drop(twi);
49
50 // Sleep for 1 second. The executor ensures the core sleeps with a WFE when it has nothing to do.
51 // During this sleep, the nRF chip should only use ~3uA
52 Timer::after(Duration::from_secs(1)).await;
53 }
54}
diff --git a/examples/nrf/src/bin/uart.rs b/examples/nrf/src/bin/uart.rs
new file mode 100644
index 000000000..e65e2fe51
--- /dev/null
+++ b/examples/nrf/src/bin/uart.rs
@@ -0,0 +1,43 @@
1#![no_std]
2#![no_main]
3#![feature(min_type_alias_impl_trait)]
4#![feature(impl_trait_in_bindings)]
5#![feature(type_alias_impl_trait)]
6#![allow(incomplete_features)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10use example_common::*;
11
12use defmt::panic;
13use embassy::executor::Spawner;
14use embassy::traits::uart::{Read, Write};
15use embassy_nrf::gpio::NoPin;
16use embassy_nrf::{interrupt, uarte, Peripherals};
17
18#[embassy::main]
19async fn main(_spawner: Spawner, p: Peripherals) {
20 let mut config = uarte::Config::default();
21 config.parity = uarte::Parity::EXCLUDED;
22 config.baudrate = uarte::Baudrate::BAUD115200;
23
24 let irq = interrupt::take!(UARTE0_UART0);
25 let mut uart =
26 unsafe { uarte::Uarte::new(p.UARTE0, irq, p.P0_08, p.P0_06, NoPin, NoPin, config) };
27
28 info!("uarte initialized!");
29
30 // Message must be in SRAM
31 let mut buf = [0; 8];
32 buf.copy_from_slice(b"Hello!\r\n");
33
34 unwrap!(uart.write(&buf).await);
35 info!("wrote hello in uart!");
36
37 loop {
38 info!("reading...");
39 unwrap!(uart.read(&mut buf).await);
40 info!("writing...");
41 unwrap!(uart.write(&buf).await);
42 }
43}
diff --git a/examples/nrf/src/bin/uart_idle.rs b/examples/nrf/src/bin/uart_idle.rs
new file mode 100644
index 000000000..dc2c73433
--- /dev/null
+++ b/examples/nrf/src/bin/uart_idle.rs
@@ -0,0 +1,46 @@
1#![no_std]
2#![no_main]
3#![feature(min_type_alias_impl_trait)]
4#![feature(impl_trait_in_bindings)]
5#![feature(type_alias_impl_trait)]
6#![allow(incomplete_features)]
7
8#[path = "../example_common.rs"]
9mod example_common;
10use embassy_traits::uart::ReadUntilIdle;
11use example_common::*;
12
13use defmt::panic;
14use embassy::executor::Spawner;
15use embassy::traits::uart::Write;
16use embassy_nrf::gpio::NoPin;
17use embassy_nrf::{interrupt, uarte, Peripherals};
18
19#[embassy::main]
20async fn main(_spawner: Spawner, p: Peripherals) {
21 let mut config = uarte::Config::default();
22 config.parity = uarte::Parity::EXCLUDED;
23 config.baudrate = uarte::Baudrate::BAUD115200;
24
25 let irq = interrupt::take!(UARTE0_UART0);
26 let mut uart = unsafe {
27 uarte::UarteWithIdle::new(
28 p.UARTE0, p.TIMER0, p.PPI_CH0, p.PPI_CH1, irq, p.P0_08, p.P0_06, NoPin, NoPin, config,
29 )
30 };
31
32 info!("uarte initialized!");
33
34 // Message must be in SRAM
35 let mut buf = [0; 8];
36 buf.copy_from_slice(b"Hello!\r\n");
37
38 unwrap!(uart.write(&buf).await);
39 info!("wrote hello in uart!");
40
41 loop {
42 info!("reading...");
43 let n = unwrap!(uart.read_until_idle(&mut buf).await);
44 info!("got {} bytes", n);
45 }
46}
diff --git a/examples/nrf/src/example_common.rs b/examples/nrf/src/example_common.rs
new file mode 100644
index 000000000..54d633837
--- /dev/null
+++ b/examples/nrf/src/example_common.rs
@@ -0,0 +1,17 @@
1#![macro_use]
2
3use defmt_rtt as _; // global logger
4use panic_probe as _;
5
6pub use defmt::*;
7
8use core::sync::atomic::{AtomicUsize, Ordering};
9
10defmt::timestamp! {"{=u64}", {
11 static COUNT: AtomicUsize = AtomicUsize::new(0);
12 // NOTE(no-CAS) `timestamps` runs with interrupts disabled
13 let n = COUNT.load(Ordering::Relaxed);
14 COUNT.store(n + 1, Ordering::Relaxed);
15 n as u64
16 }
17}