aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authormaor1993 <[email protected]>2025-11-01 18:02:39 -0400
committerGitHub <[email protected]>2025-11-01 18:02:39 -0400
commit07549723afaea68f033aa688f1096dc46d9b192b (patch)
treea64726df1dd948ba8b18fa7276ca9cee445ddd6c /examples
parentcb0175a89f072d38393368ef380d9db8e3994740 (diff)
parentcf231d461ff4b16cf7d16e4dbc5db909212c2c89 (diff)
Merge branch 'embassy-rs:main' into main
Diffstat (limited to 'examples')
-rw-r--r--examples/lpc55s69/src/bin/pwm.rs18
-rw-r--r--examples/mspm0g3507/src/bin/i2c_target.rs63
-rw-r--r--examples/mspm0l1306/src/bin/i2c_target.rs63
-rw-r--r--examples/nrf52840/src/bin/egu.rs15
-rw-r--r--examples/nrf52840/src/bin/gpiote_channel.rs26
-rw-r--r--examples/nrf52840/src/bin/i2s_monitor.rs9
-rw-r--r--examples/nrf52840/src/bin/ppi.rs34
-rw-r--r--examples/nrf52840/src/bin/pwm.rs14
-rw-r--r--examples/nrf52840/src/bin/pwm_sequence_ppi.rs14
-rw-r--r--examples/nrf52840/src/bin/pwm_servo.rs14
-rw-r--r--examples/nrf52840/src/bin/wifi_esp_hosted.rs16
-rw-r--r--examples/nrf5340/src/bin/gpiote_channel.rs26
-rw-r--r--examples/nrf54l15/Cargo.toml7
-rw-r--r--examples/nrf54l15/src/bin/buffered_uart.rs49
-rw-r--r--examples/nrf54l15/src/bin/gpiote_channel.rs49
-rw-r--r--examples/nrf54l15/src/bin/gpiote_port.rs33
-rw-r--r--examples/nrf54l15/src/bin/pwm.rs86
-rw-r--r--examples/nrf54l15/src/bin/rtc.rs56
-rw-r--r--examples/nrf54l15/src/bin/saadc.rs28
-rw-r--r--examples/nrf54l15/src/bin/spim.rs30
-rw-r--r--examples/nrf54l15/src/bin/twim.rs37
-rw-r--r--examples/nrf54l15/src/bin/twis.rs47
-rw-r--r--examples/nrf54l15/src/bin/uart.rs37
23 files changed, 660 insertions, 111 deletions
diff --git a/examples/lpc55s69/src/bin/pwm.rs b/examples/lpc55s69/src/bin/pwm.rs
new file mode 100644
index 000000000..93b898b9d
--- /dev/null
+++ b/examples/lpc55s69/src/bin/pwm.rs
@@ -0,0 +1,18 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_nxp::pwm::{Config, Pwm};
7use embassy_time::Timer;
8use {defmt_rtt as _, panic_halt as _};
9
10#[embassy_executor::main]
11async fn main(_spawner: Spawner) {
12 let p = embassy_nxp::init(Default::default());
13 let pwm = Pwm::new_output(p.PWM_OUTPUT1, p.PIO0_18, Config::new(1_000_000_000, 2_000_000_000));
14 loop {
15 info!("Counter: {}", pwm.counter());
16 Timer::after_millis(50).await;
17 }
18}
diff --git a/examples/mspm0g3507/src/bin/i2c_target.rs b/examples/mspm0g3507/src/bin/i2c_target.rs
new file mode 100644
index 000000000..5dd718eaf
--- /dev/null
+++ b/examples/mspm0g3507/src/bin/i2c_target.rs
@@ -0,0 +1,63 @@
1//! Example of using async I2C target
2//!
3//! This uses the virtual COM port provided on the LP-MSPM0G3507 board.
4
5#![no_std]
6#![no_main]
7
8use defmt::*;
9use embassy_executor::Spawner;
10use embassy_mspm0::i2c::Config;
11use embassy_mspm0::i2c_target::{Command, Config as TargetConfig, I2cTarget, ReadStatus};
12use embassy_mspm0::peripherals::I2C1;
13use embassy_mspm0::{bind_interrupts, i2c};
14use {defmt_rtt as _, panic_halt as _};
15
16bind_interrupts!(struct Irqs {
17 I2C1 => i2c::InterruptHandler<I2C1>;
18});
19
20#[embassy_executor::main]
21async fn main(_spawner: Spawner) -> ! {
22 let p = embassy_mspm0::init(Default::default());
23
24 let instance = p.I2C1;
25 let scl = p.PB2;
26 let sda = p.PB3;
27
28 let config = Config::default();
29 let mut target_config = TargetConfig::default();
30 target_config.target_addr = 0x48;
31 target_config.general_call = true;
32 let mut i2c = I2cTarget::new(instance, scl, sda, Irqs, config, target_config).unwrap();
33
34 let mut read = [0u8; 8];
35 let data = [8u8; 2];
36 let data_wr = [9u8; 2];
37
38 loop {
39 match i2c.listen(&mut read).await {
40 Ok(Command::GeneralCall(_)) => info!("General call received"),
41 Ok(Command::Read) => {
42 info!("Read command received");
43 match i2c.respond_to_read(&data).await.unwrap() {
44 ReadStatus::Done => info!("Finished reading"),
45 ReadStatus::NeedMoreBytes => {
46 info!("Read needs more bytes - will reset");
47 i2c.reset().unwrap();
48 }
49 ReadStatus::LeftoverBytes(_) => {
50 info!("Leftover bytes received");
51 i2c.flush_tx_fifo();
52 }
53 }
54 }
55 Ok(Command::Write(_)) => info!("Write command received"),
56 Ok(Command::WriteRead(_)) => {
57 info!("Write-Read command received");
58 i2c.respond_and_fill(&data_wr, 0xFE).await.unwrap();
59 }
60 Err(e) => info!("Got error {}", e),
61 }
62 }
63}
diff --git a/examples/mspm0l1306/src/bin/i2c_target.rs b/examples/mspm0l1306/src/bin/i2c_target.rs
new file mode 100644
index 000000000..4d147d08b
--- /dev/null
+++ b/examples/mspm0l1306/src/bin/i2c_target.rs
@@ -0,0 +1,63 @@
1//! Example of using async I2C target
2//!
3//! This uses the virtual COM port provided on the LP-MSPM0L1306 board.
4
5#![no_std]
6#![no_main]
7
8use defmt::*;
9use embassy_executor::Spawner;
10use embassy_mspm0::i2c::Config;
11use embassy_mspm0::i2c_target::{Command, Config as TargetConfig, I2cTarget, ReadStatus};
12use embassy_mspm0::peripherals::I2C0;
13use embassy_mspm0::{bind_interrupts, i2c};
14use {defmt_rtt as _, panic_halt as _};
15
16bind_interrupts!(struct Irqs {
17 I2C0 => i2c::InterruptHandler<I2C0>;
18});
19
20#[embassy_executor::main]
21async fn main(_spawner: Spawner) -> ! {
22 let p = embassy_mspm0::init(Default::default());
23
24 let instance = p.I2C0;
25 let scl = p.PA1;
26 let sda = p.PA0;
27
28 let config = Config::default();
29 let mut target_config = TargetConfig::default();
30 target_config.target_addr = 0x48;
31 target_config.general_call = true;
32 let mut i2c = I2cTarget::new(instance, scl, sda, Irqs, config, target_config).unwrap();
33
34 let mut read = [0u8; 8];
35 let data = [8u8; 2];
36 let data_wr = [9u8; 2];
37
38 loop {
39 match i2c.listen(&mut read).await {
40 Ok(Command::GeneralCall(_)) => info!("General call received"),
41 Ok(Command::Read) => {
42 info!("Read command received");
43 match i2c.respond_to_read(&data).await.unwrap() {
44 ReadStatus::Done => info!("Finished reading"),
45 ReadStatus::NeedMoreBytes => {
46 info!("Read needs more bytes - will reset");
47 i2c.reset().unwrap();
48 }
49 ReadStatus::LeftoverBytes(_) => {
50 info!("Leftover bytes received");
51 i2c.flush_tx_fifo();
52 }
53 }
54 }
55 Ok(Command::Write(_)) => info!("Write command received"),
56 Ok(Command::WriteRead(_)) => {
57 info!("Write-Read command received");
58 i2c.respond_and_fill(&data_wr, 0xFE).await.unwrap();
59 }
60 Err(e) => info!("Got error {}", e),
61 }
62 }
63}
diff --git a/examples/nrf52840/src/bin/egu.rs b/examples/nrf52840/src/bin/egu.rs
index 8bf712697..36eba8084 100644
--- a/examples/nrf52840/src/bin/egu.rs
+++ b/examples/nrf52840/src/bin/egu.rs
@@ -6,7 +6,7 @@
6 6
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_nrf::egu::{Egu, TriggerNumber}; 8use embassy_nrf::egu::{Egu, TriggerNumber};
9use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; 9use embassy_nrf::gpio::{Level, OutputDrive, Pull};
10use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity, OutputChannel, OutputChannelPolarity}; 10use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity, OutputChannel, OutputChannelPolarity};
11use embassy_nrf::peripherals::{PPI_CH0, PPI_CH1, PPI_CH2}; 11use embassy_nrf::peripherals::{PPI_CH0, PPI_CH1, PPI_CH2};
12use embassy_nrf::ppi::Ppi; 12use embassy_nrf::ppi::Ppi;
@@ -17,12 +17,15 @@ use {defmt_rtt as _, panic_probe as _};
17async fn main(_spawner: Spawner) { 17async fn main(_spawner: Spawner) {
18 let p = embassy_nrf::init(Default::default()); 18 let p = embassy_nrf::init(Default::default());
19 19
20 let led1 = Output::new(p.P0_13, Level::High, OutputDrive::Standard);
21 let btn1 = Input::new(p.P0_11, Pull::Up);
22
23 let mut egu1 = Egu::new(p.EGU0); 20 let mut egu1 = Egu::new(p.EGU0);
24 let led1 = OutputChannel::new(p.GPIOTE_CH0, led1, OutputChannelPolarity::Toggle); 21 let led1 = OutputChannel::new(
25 let btn1 = InputChannel::new(p.GPIOTE_CH1, btn1, InputChannelPolarity::LoToHi); 22 p.GPIOTE_CH0,
23 p.P0_13,
24 Level::High,
25 OutputDrive::Standard,
26 OutputChannelPolarity::Toggle,
27 );
28 let btn1 = InputChannel::new(p.GPIOTE_CH1, p.P0_11, Pull::Up, InputChannelPolarity::LoToHi);
26 29
27 let trigger0 = egu1.trigger(TriggerNumber::Trigger0); 30 let trigger0 = egu1.trigger(TriggerNumber::Trigger0);
28 let trigger1 = egu1.trigger(TriggerNumber::Trigger1); 31 let trigger1 = egu1.trigger(TriggerNumber::Trigger1);
diff --git a/examples/nrf52840/src/bin/gpiote_channel.rs b/examples/nrf52840/src/bin/gpiote_channel.rs
index dcfe7723a..c7ddc1d8d 100644
--- a/examples/nrf52840/src/bin/gpiote_channel.rs
+++ b/examples/nrf52840/src/bin/gpiote_channel.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::info; 4use defmt::info;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_nrf::gpio::{Input, Pull}; 6use embassy_nrf::gpio::Pull;
7use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; 7use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity};
8use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
9 9
@@ -12,26 +12,10 @@ async fn main(_spawner: Spawner) {
12 let p = embassy_nrf::init(Default::default()); 12 let p = embassy_nrf::init(Default::default());
13 info!("Starting!"); 13 info!("Starting!");
14 14
15 let ch1 = InputChannel::new( 15 let ch1 = InputChannel::new(p.GPIOTE_CH0, p.P0_11, Pull::Up, InputChannelPolarity::HiToLo);
16 p.GPIOTE_CH0, 16 let ch2 = InputChannel::new(p.GPIOTE_CH1, p.P0_12, Pull::Up, InputChannelPolarity::LoToHi);
17 Input::new(p.P0_11, Pull::Up), 17 let ch3 = InputChannel::new(p.GPIOTE_CH2, p.P0_24, Pull::Up, InputChannelPolarity::Toggle);
18 InputChannelPolarity::HiToLo, 18 let ch4 = InputChannel::new(p.GPIOTE_CH3, p.P0_25, Pull::Up, InputChannelPolarity::Toggle);
19 );
20 let ch2 = InputChannel::new(
21 p.GPIOTE_CH1,
22 Input::new(p.P0_12, Pull::Up),
23 InputChannelPolarity::LoToHi,
24 );
25 let ch3 = InputChannel::new(
26 p.GPIOTE_CH2,
27 Input::new(p.P0_24, Pull::Up),
28 InputChannelPolarity::Toggle,
29 );
30 let ch4 = InputChannel::new(
31 p.GPIOTE_CH3,
32 Input::new(p.P0_25, Pull::Up),
33 InputChannelPolarity::Toggle,
34 );
35 19
36 let button1 = async { 20 let button1 = async {
37 loop { 21 loop {
diff --git a/examples/nrf52840/src/bin/i2s_monitor.rs b/examples/nrf52840/src/bin/i2s_monitor.rs
index 66b429b09..a54659101 100644
--- a/examples/nrf52840/src/bin/i2s_monitor.rs
+++ b/examples/nrf52840/src/bin/i2s_monitor.rs
@@ -4,7 +4,7 @@
4use defmt::{debug, error, info}; 4use defmt::{debug, error, info};
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_nrf::i2s::{self, Channels, Config, DoubleBuffering, I2S, MasterClock, Sample as _, SampleWidth}; 6use embassy_nrf::i2s::{self, Channels, Config, DoubleBuffering, I2S, MasterClock, Sample as _, SampleWidth};
7use embassy_nrf::pwm::{Prescaler, SimplePwm}; 7use embassy_nrf::pwm::{DutyCycle, Prescaler, SimplePwm};
8use embassy_nrf::{bind_interrupts, peripherals}; 8use embassy_nrf::{bind_interrupts, peripherals};
9use {defmt_rtt as _, panic_probe as _}; 9use {defmt_rtt as _, panic_probe as _};
10 10
@@ -34,7 +34,7 @@ async fn main(_spawner: Spawner) {
34 I2S::new_master(p.I2S, Irqs, p.P0_25, p.P0_26, p.P0_27, master_clock, config).input(p.P0_29, buffers); 34 I2S::new_master(p.I2S, Irqs, p.P0_25, p.P0_26, p.P0_27, master_clock, config).input(p.P0_29, buffers);
35 35
36 // Configure the PWM to use the pins corresponding to the RGB leds 36 // Configure the PWM to use the pins corresponding to the RGB leds
37 let mut pwm = SimplePwm::new_3ch(p.PWM0, p.P0_23, p.P0_22, p.P0_24); 37 let mut pwm = SimplePwm::new_3ch(p.PWM0, p.P0_23, p.P0_22, p.P0_24, &Default::default());
38 pwm.set_prescaler(Prescaler::Div1); 38 pwm.set_prescaler(Prescaler::Div1);
39 pwm.set_max_duty(255); 39 pwm.set_max_duty(255);
40 40
@@ -47,9 +47,8 @@ async fn main(_spawner: Spawner) {
47 let rgb = rgb_from_rms(rms); 47 let rgb = rgb_from_rms(rms);
48 48
49 debug!("RMS: {}, RGB: {:?}", rms, rgb); 49 debug!("RMS: {}, RGB: {:?}", rms, rgb);
50 for i in 0..3 { 50 let duties = rgb.map(|byte| DutyCycle::normal(u16::from(byte)));
51 pwm.set_duty(i, rgb[i].into()); 51 pwm.set_all_duties([duties[0], duties[1], duties[2], DutyCycle::normal(0)]);
52 }
53 52
54 if let Err(err) = input_stream.receive().await { 53 if let Err(err) = input_stream.receive().await {
55 error!("{}", err); 54 error!("{}", err);
diff --git a/examples/nrf52840/src/bin/ppi.rs b/examples/nrf52840/src/bin/ppi.rs
index 129ad06e7..177f6a06d 100644
--- a/examples/nrf52840/src/bin/ppi.rs
+++ b/examples/nrf52840/src/bin/ppi.rs
@@ -5,7 +5,7 @@ use core::future::pending;
5 5
6use defmt::info; 6use defmt::info;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_nrf::gpio::{Input, Level, Output, OutputDrive, Pull}; 8use embassy_nrf::gpio::{Level, OutputDrive, Pull};
9use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity}; 9use embassy_nrf::gpiote::{self, InputChannel, InputChannelPolarity};
10use embassy_nrf::ppi::Ppi; 10use embassy_nrf::ppi::Ppi;
11use gpiote::{OutputChannel, OutputChannelPolarity}; 11use gpiote::{OutputChannel, OutputChannelPolarity};
@@ -16,36 +16,24 @@ async fn main(_spawner: Spawner) {
16 let p = embassy_nrf::init(Default::default()); 16 let p = embassy_nrf::init(Default::default());
17 info!("Starting!"); 17 info!("Starting!");
18 18
19 let button1 = InputChannel::new( 19 let button1 = InputChannel::new(p.GPIOTE_CH0, p.P0_11, Pull::Up, InputChannelPolarity::HiToLo);
20 p.GPIOTE_CH0, 20 let button2 = InputChannel::new(p.GPIOTE_CH1, p.P0_12, Pull::Up, InputChannelPolarity::HiToLo);
21 Input::new(p.P0_11, Pull::Up), 21 let button3 = InputChannel::new(p.GPIOTE_CH2, p.P0_24, Pull::Up, InputChannelPolarity::HiToLo);
22 InputChannelPolarity::HiToLo, 22 let button4 = InputChannel::new(p.GPIOTE_CH3, p.P0_25, Pull::Up, InputChannelPolarity::HiToLo);
23 );
24 let button2 = InputChannel::new(
25 p.GPIOTE_CH1,
26 Input::new(p.P0_12, Pull::Up),
27 InputChannelPolarity::HiToLo,
28 );
29 let button3 = InputChannel::new(
30 p.GPIOTE_CH2,
31 Input::new(p.P0_24, Pull::Up),
32 InputChannelPolarity::HiToLo,
33 );
34 let button4 = InputChannel::new(
35 p.GPIOTE_CH3,
36 Input::new(p.P0_25, Pull::Up),
37 InputChannelPolarity::HiToLo,
38 );
39 23
40 let led1 = OutputChannel::new( 24 let led1 = OutputChannel::new(
41 p.GPIOTE_CH4, 25 p.GPIOTE_CH4,
42 Output::new(p.P0_13, Level::Low, OutputDrive::Standard), 26 p.P0_13,
27 Level::Low,
28 OutputDrive::Standard,
43 OutputChannelPolarity::Toggle, 29 OutputChannelPolarity::Toggle,
44 ); 30 );
45 31
46 let led2 = OutputChannel::new( 32 let led2 = OutputChannel::new(
47 p.GPIOTE_CH5, 33 p.GPIOTE_CH5,
48 Output::new(p.P0_14, Level::Low, OutputDrive::Standard), 34 p.P0_14,
35 Level::Low,
36 OutputDrive::Standard,
49 OutputChannelPolarity::Toggle, 37 OutputChannelPolarity::Toggle,
50 ); 38 );
51 39
diff --git a/examples/nrf52840/src/bin/pwm.rs b/examples/nrf52840/src/bin/pwm.rs
index a5bb1347a..02f9b4191 100644
--- a/examples/nrf52840/src/bin/pwm.rs
+++ b/examples/nrf52840/src/bin/pwm.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_nrf::pwm::{Prescaler, SimplePwm}; 6use embassy_nrf::pwm::{DutyCycle, Prescaler, SimplePwm};
7use embassy_time::Timer; 7use embassy_time::Timer;
8use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
9 9
@@ -71,7 +71,7 @@ static DUTY: [u16; 1024] = [
71#[embassy_executor::main] 71#[embassy_executor::main]
72async fn main(_spawner: Spawner) { 72async fn main(_spawner: Spawner) {
73 let p = embassy_nrf::init(Default::default()); 73 let p = embassy_nrf::init(Default::default());
74 let mut pwm = SimplePwm::new_4ch(p.PWM0, p.P0_13, p.P0_14, p.P0_16, p.P0_15); 74 let mut pwm = SimplePwm::new_4ch(p.PWM0, p.P0_13, p.P0_14, p.P0_16, p.P0_15, &Default::default());
75 pwm.set_prescaler(Prescaler::Div1); 75 pwm.set_prescaler(Prescaler::Div1);
76 pwm.set_max_duty(32767); 76 pwm.set_max_duty(32767);
77 info!("pwm initialized!"); 77 info!("pwm initialized!");
@@ -79,10 +79,12 @@ async fn main(_spawner: Spawner) {
79 let mut i = 0; 79 let mut i = 0;
80 loop { 80 loop {
81 i += 1; 81 i += 1;
82 pwm.set_duty(0, DUTY[i % 1024]); 82 pwm.set_all_duties([
83 pwm.set_duty(1, DUTY[(i + 256) % 1024]); 83 DutyCycle::normal(DUTY[i % 1024]),
84 pwm.set_duty(2, DUTY[(i + 512) % 1024]); 84 DutyCycle::normal(DUTY[(i + 256) % 1024]),
85 pwm.set_duty(3, DUTY[(i + 768) % 1024]); 85 DutyCycle::normal(DUTY[(i + 512) % 1024]),
86 DutyCycle::normal(DUTY[(i + 768) % 1024]),
87 ]);
86 Timer::after_millis(3).await; 88 Timer::after_millis(3).await;
87 } 89 }
88} 90}
diff --git a/examples/nrf52840/src/bin/pwm_sequence_ppi.rs b/examples/nrf52840/src/bin/pwm_sequence_ppi.rs
index 60ea712b5..fff7decb2 100644
--- a/examples/nrf52840/src/bin/pwm_sequence_ppi.rs
+++ b/examples/nrf52840/src/bin/pwm_sequence_ppi.rs
@@ -5,7 +5,7 @@ use core::future::pending;
5 5
6use defmt::*; 6use defmt::*;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_nrf::gpio::{Input, Pull}; 8use embassy_nrf::gpio::Pull;
9use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; 9use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity};
10use embassy_nrf::ppi::Ppi; 10use embassy_nrf::ppi::Ppi;
11use embassy_nrf::pwm::{Config, Prescaler, SequenceConfig, SequencePwm, SingleSequenceMode, SingleSequencer}; 11use embassy_nrf::pwm::{Config, Prescaler, SequenceConfig, SequencePwm, SingleSequenceMode, SingleSequencer};
@@ -30,17 +30,9 @@ async fn main(_spawner: Spawner) {
30 // pwm.stop() deconfigures pins, and then the task_start_seq0 task cant work 30 // pwm.stop() deconfigures pins, and then the task_start_seq0 task cant work
31 // so its going to have to start running in order load the configuration 31 // so its going to have to start running in order load the configuration
32 32
33 let button1 = InputChannel::new( 33 let button1 = InputChannel::new(p.GPIOTE_CH0, p.P0_11, Pull::Up, InputChannelPolarity::HiToLo);
34 p.GPIOTE_CH0,
35 Input::new(p.P0_11, Pull::Up),
36 InputChannelPolarity::HiToLo,
37 );
38 34
39 let button2 = InputChannel::new( 35 let button2 = InputChannel::new(p.GPIOTE_CH1, p.P0_12, Pull::Up, InputChannelPolarity::HiToLo);
40 p.GPIOTE_CH1,
41 Input::new(p.P0_12, Pull::Up),
42 InputChannelPolarity::HiToLo,
43 );
44 36
45 // messing with the pwm tasks is ill advised 37 // messing with the pwm tasks is ill advised
46 // Times::Ininite and Times even are seq0, Times odd is seq1 38 // Times::Ininite and Times even are seq0, Times odd is seq1
diff --git a/examples/nrf52840/src/bin/pwm_servo.rs b/examples/nrf52840/src/bin/pwm_servo.rs
index d772d2f5d..93cb984e6 100644
--- a/examples/nrf52840/src/bin/pwm_servo.rs
+++ b/examples/nrf52840/src/bin/pwm_servo.rs
@@ -3,14 +3,14 @@
3 3
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_nrf::pwm::{Prescaler, SimplePwm}; 6use embassy_nrf::pwm::{DutyCycle, Prescaler, SimplePwm};
7use embassy_time::Timer; 7use embassy_time::Timer;
8use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
9 9
10#[embassy_executor::main] 10#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 11async fn main(_spawner: Spawner) {
12 let p = embassy_nrf::init(Default::default()); 12 let p = embassy_nrf::init(Default::default());
13 let mut pwm = SimplePwm::new_1ch(p.PWM0, p.P0_05); 13 let mut pwm = SimplePwm::new_1ch(p.PWM0, p.P0_05, &Default::default());
14 // sg90 microervo requires 50hz or 20ms period 14 // sg90 microervo requires 50hz or 20ms period
15 // set_period can only set down to 125khz so we cant use it directly 15 // set_period can only set down to 125khz so we cant use it directly
16 // Div128 is 125khz or 0.000008s or 0.008ms, 20/0.008 is 2500 is top 16 // Div128 is 125khz or 0.000008s or 0.008ms, 20/0.008 is 2500 is top
@@ -24,23 +24,23 @@ async fn main(_spawner: Spawner) {
24 loop { 24 loop {
25 info!("45 deg"); 25 info!("45 deg");
26 // poor mans inverting, subtract our value from max_duty 26 // poor mans inverting, subtract our value from max_duty
27 pwm.set_duty(0, 2500 - 156); 27 pwm.set_duty(0, DutyCycle::normal(2500 - 156));
28 Timer::after_millis(5000).await; 28 Timer::after_millis(5000).await;
29 29
30 info!("90 deg"); 30 info!("90 deg");
31 pwm.set_duty(0, 2500 - 187); 31 pwm.set_duty(0, DutyCycle::normal(2500 - 187));
32 Timer::after_millis(5000).await; 32 Timer::after_millis(5000).await;
33 33
34 info!("135 deg"); 34 info!("135 deg");
35 pwm.set_duty(0, 2500 - 218); 35 pwm.set_duty(0, DutyCycle::normal(2500 - 218));
36 Timer::after_millis(5000).await; 36 Timer::after_millis(5000).await;
37 37
38 info!("180 deg"); 38 info!("180 deg");
39 pwm.set_duty(0, 2500 - 250); 39 pwm.set_duty(0, DutyCycle::normal(2500 - 250));
40 Timer::after_millis(5000).await; 40 Timer::after_millis(5000).await;
41 41
42 info!("0 deg"); 42 info!("0 deg");
43 pwm.set_duty(0, 2500 - 125); 43 pwm.set_duty(0, DutyCycle::normal(2500 - 125));
44 Timer::after_millis(5000).await; 44 Timer::after_millis(5000).await;
45 } 45 }
46} 46}
diff --git a/examples/nrf52840/src/bin/wifi_esp_hosted.rs b/examples/nrf52840/src/bin/wifi_esp_hosted.rs
index 07752ffc4..2f9c06b56 100644
--- a/examples/nrf52840/src/bin/wifi_esp_hosted.rs
+++ b/examples/nrf52840/src/bin/wifi_esp_hosted.rs
@@ -27,14 +27,12 @@ bind_interrupts!(struct Irqs {
27async fn wifi_task( 27async fn wifi_task(
28 runner: hosted::Runner< 28 runner: hosted::Runner<
29 'static, 29 'static,
30 ExclusiveDevice<Spim<'static>, Output<'static>, Delay>, 30 hosted::SpiInterface<ExclusiveDevice<Spim<'static>, Output<'static>, Delay>, Input<'static>>,
31 Input<'static>,
32 Output<'static>, 31 Output<'static>,
33 >, 32 >,
34) -> ! { 33) -> ! {
35 runner.run().await 34 runner.run().await
36} 35}
37
38#[embassy_executor::task] 36#[embassy_executor::task]
39async fn net_task(mut runner: embassy_net::Runner<'static, hosted::NetDriver<'static>>) -> ! { 37async fn net_task(mut runner: embassy_net::Runner<'static, hosted::NetDriver<'static>>) -> ! {
40 runner.run().await 38 runner.run().await
@@ -60,15 +58,11 @@ async fn main(spawner: Spawner) {
60 let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config); 58 let spi = spim::Spim::new(p.SPI3, Irqs, sck, miso, mosi, config);
61 let spi = ExclusiveDevice::new(spi, cs, Delay); 59 let spi = ExclusiveDevice::new(spi, cs, Delay);
62 60
61 let iface = hosted::SpiInterface::new(spi, handshake, ready);
62
63 static ESP_STATE: StaticCell<embassy_net_esp_hosted::State> = StaticCell::new(); 63 static ESP_STATE: StaticCell<embassy_net_esp_hosted::State> = StaticCell::new();
64 let (device, mut control, runner) = embassy_net_esp_hosted::new( 64 let (device, mut control, runner) =
65 ESP_STATE.init(embassy_net_esp_hosted::State::new()), 65 embassy_net_esp_hosted::new(ESP_STATE.init(embassy_net_esp_hosted::State::new()), iface, reset).await;
66 spi,
67 handshake,
68 ready,
69 reset,
70 )
71 .await;
72 66
73 spawner.spawn(unwrap!(wifi_task(runner))); 67 spawner.spawn(unwrap!(wifi_task(runner)));
74 68
diff --git a/examples/nrf5340/src/bin/gpiote_channel.rs b/examples/nrf5340/src/bin/gpiote_channel.rs
index 23f6fca98..a085310ce 100644
--- a/examples/nrf5340/src/bin/gpiote_channel.rs
+++ b/examples/nrf5340/src/bin/gpiote_channel.rs
@@ -3,7 +3,7 @@
3 3
4use defmt::info; 4use defmt::info;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_nrf::gpio::{Input, Pull}; 6use embassy_nrf::gpio::Pull;
7use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity}; 7use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity};
8use {defmt_rtt as _, panic_probe as _}; 8use {defmt_rtt as _, panic_probe as _};
9 9
@@ -12,26 +12,10 @@ async fn main(_spawner: Spawner) {
12 let p = embassy_nrf::init(Default::default()); 12 let p = embassy_nrf::init(Default::default());
13 info!("Starting!"); 13 info!("Starting!");
14 14
15 let ch1 = InputChannel::new( 15 let ch1 = InputChannel::new(p.GPIOTE_CH0, p.P0_23, Pull::Up, InputChannelPolarity::HiToLo);
16 p.GPIOTE_CH0, 16 let ch2 = InputChannel::new(p.GPIOTE_CH1, p.P0_24, Pull::Up, InputChannelPolarity::LoToHi);
17 Input::new(p.P0_23, Pull::Up), 17 let ch3 = InputChannel::new(p.GPIOTE_CH2, p.P0_08, Pull::Up, InputChannelPolarity::Toggle);
18 InputChannelPolarity::HiToLo, 18 let ch4 = InputChannel::new(p.GPIOTE_CH3, p.P0_09, Pull::Up, InputChannelPolarity::Toggle);
19 );
20 let ch2 = InputChannel::new(
21 p.GPIOTE_CH1,
22 Input::new(p.P0_24, Pull::Up),
23 InputChannelPolarity::LoToHi,
24 );
25 let ch3 = InputChannel::new(
26 p.GPIOTE_CH2,
27 Input::new(p.P0_08, Pull::Up),
28 InputChannelPolarity::Toggle,
29 );
30 let ch4 = InputChannel::new(
31 p.GPIOTE_CH3,
32 Input::new(p.P0_09, Pull::Up),
33 InputChannelPolarity::Toggle,
34 );
35 19
36 let button1 = async { 20 let button1 = async {
37 loop { 21 loop {
diff --git a/examples/nrf54l15/Cargo.toml b/examples/nrf54l15/Cargo.toml
index a053dd0ec..14a80efe7 100644
--- a/examples/nrf54l15/Cargo.toml
+++ b/examples/nrf54l15/Cargo.toml
@@ -6,9 +6,13 @@ license = "MIT OR Apache-2.0"
6publish = false 6publish = false
7 7
8[dependencies] 8[dependencies]
9embassy-futures = { version = "0.1.2", path = "../../embassy-futures" }
9embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] } 10embassy-executor = { version = "0.9.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "executor-interrupt", "defmt"] }
10embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] } 11embassy-time = { version = "0.5.0", path = "../../embassy-time", features = ["defmt", "defmt-timestamp-uptime"] }
12embassy-sync = { version = "0.7.2", path = "../../embassy-sync", features = ["defmt"] }
11embassy-nrf = { version = "0.8.0", path = "../../embassy-nrf", features = ["defmt", "nrf54l15-app-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] } 13embassy-nrf = { version = "0.8.0", path = "../../embassy-nrf", features = ["defmt", "nrf54l15-app-s", "time-driver-rtc1", "gpiote", "unstable-pac", "time"] }
14embedded-io = { version = "0.6.0", features = ["defmt-03"] }
15embedded-io-async = { version = "0.6.1", features = ["defmt-03"] }
12 16
13defmt = "1.0.1" 17defmt = "1.0.1"
14defmt-rtt = "1.0.0" 18defmt-rtt = "1.0.0"
@@ -18,6 +22,9 @@ cortex-m = { version = "0.7.6", features = ["inline-asm", "critical-section-sing
18cortex-m-rt = "0.7.0" 22cortex-m-rt = "0.7.0"
19 23
20embedded-storage = "0.3.1" 24embedded-storage = "0.3.1"
25portable-atomic = "1"
26
27static_cell = "2"
21 28
22[profile.release] 29[profile.release]
23debug = 2 30debug = 2
diff --git a/examples/nrf54l15/src/bin/buffered_uart.rs b/examples/nrf54l15/src/bin/buffered_uart.rs
new file mode 100644
index 000000000..41fa1ca4e
--- /dev/null
+++ b/examples/nrf54l15/src/bin/buffered_uart.rs
@@ -0,0 +1,49 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_nrf::buffered_uarte::{self, BufferedUarte};
7use embassy_nrf::{bind_interrupts, peripherals, uarte};
8use embedded_io_async::Write;
9use {defmt_rtt as _, panic_probe as _};
10
11bind_interrupts!(struct Irqs {
12 SERIAL20 => buffered_uarte::InterruptHandler<peripherals::SERIAL20>;
13});
14
15#[embassy_executor::main]
16async fn main(_spawner: Spawner) {
17 let p = embassy_nrf::init(Default::default());
18 let mut config = uarte::Config::default();
19 config.parity = uarte::Parity::EXCLUDED;
20 config.baudrate = uarte::Baudrate::BAUD115200;
21
22 let mut tx_buffer = [0u8; 4096];
23 let mut rx_buffer = [0u8; 4096];
24
25 let mut u = BufferedUarte::new(
26 p.SERIAL20,
27 p.P1_12,
28 p.P1_13,
29 Irqs,
30 config,
31 &mut rx_buffer,
32 &mut tx_buffer,
33 );
34
35 info!("uarte initialized!");
36
37 unwrap!(u.write_all(b"Hello!\r\n").await);
38 info!("wrote hello in uart!");
39
40 loop {
41 info!("reading...");
42 let buf = unwrap!(u.fill_buf().await);
43 info!("read done, got {}", buf);
44
45 // Read bytes have to be explicitly consumed, otherwise fill_buf() will return them again
46 let n = buf.len();
47 u.consume(n);
48 }
49}
diff --git a/examples/nrf54l15/src/bin/gpiote_channel.rs b/examples/nrf54l15/src/bin/gpiote_channel.rs
new file mode 100644
index 000000000..6333250ba
--- /dev/null
+++ b/examples/nrf54l15/src/bin/gpiote_channel.rs
@@ -0,0 +1,49 @@
1#![no_std]
2#![no_main]
3
4use defmt::info;
5use embassy_executor::Spawner;
6use embassy_nrf::gpio::Pull;
7use embassy_nrf::gpiote::{InputChannel, InputChannelPolarity};
8use {defmt_rtt as _, panic_probe as _};
9
10#[embassy_executor::main]
11async fn main(_spawner: Spawner) {
12 let p = embassy_nrf::init(Default::default());
13 info!("Starting!");
14
15 let ch1 = InputChannel::new(p.GPIOTE20_CH0, p.P1_13, Pull::Up, InputChannelPolarity::HiToLo);
16 let ch2 = InputChannel::new(p.GPIOTE20_CH1, p.P1_09, Pull::Up, InputChannelPolarity::LoToHi);
17 let ch3 = InputChannel::new(p.GPIOTE20_CH2, p.P1_08, Pull::Up, InputChannelPolarity::Toggle);
18 let ch4 = InputChannel::new(p.GPIOTE30_CH0, p.P0_04, Pull::Up, InputChannelPolarity::Toggle);
19
20 let button1 = async {
21 loop {
22 ch1.wait().await;
23 info!("Button 1 pressed")
24 }
25 };
26
27 let button2 = async {
28 loop {
29 ch2.wait().await;
30 info!("Button 2 released")
31 }
32 };
33
34 let button3 = async {
35 loop {
36 ch3.wait().await;
37 info!("Button 3 toggled")
38 }
39 };
40
41 let button4 = async {
42 loop {
43 ch4.wait().await;
44 info!("Button 4 toggled")
45 }
46 };
47
48 embassy_futures::join::join4(button1, button2, button3, button4).await;
49}
diff --git a/examples/nrf54l15/src/bin/gpiote_port.rs b/examples/nrf54l15/src/bin/gpiote_port.rs
new file mode 100644
index 000000000..620cb2435
--- /dev/null
+++ b/examples/nrf54l15/src/bin/gpiote_port.rs
@@ -0,0 +1,33 @@
1#![no_std]
2#![no_main]
3
4use defmt::{info, unwrap};
5use embassy_executor::Spawner;
6use embassy_nrf::gpio::{Input, Pull};
7use {defmt_rtt as _, panic_probe as _};
8
9#[embassy_executor::task(pool_size = 4)]
10async fn button_task(n: usize, mut pin: Input<'static>) {
11 loop {
12 pin.wait_for_low().await;
13 info!("Button {:?} pressed!", n);
14 pin.wait_for_high().await;
15 info!("Button {:?} released!", n);
16 }
17}
18
19#[embassy_executor::main]
20async fn main(spawner: Spawner) {
21 let p = embassy_nrf::init(Default::default());
22 info!("Starting!");
23
24 let btn1 = Input::new(p.P1_13, Pull::Up);
25 let btn2 = Input::new(p.P1_09, Pull::Up);
26 let btn3 = Input::new(p.P1_08, Pull::Up);
27 let btn4 = Input::new(p.P0_04, Pull::Up);
28
29 spawner.spawn(unwrap!(button_task(1, btn1)));
30 spawner.spawn(unwrap!(button_task(2, btn2)));
31 spawner.spawn(unwrap!(button_task(3, btn3)));
32 spawner.spawn(unwrap!(button_task(4, btn4)));
33}
diff --git a/examples/nrf54l15/src/bin/pwm.rs b/examples/nrf54l15/src/bin/pwm.rs
new file mode 100644
index 000000000..b438978f1
--- /dev/null
+++ b/examples/nrf54l15/src/bin/pwm.rs
@@ -0,0 +1,86 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_nrf::pwm::{DutyCycle, Prescaler, SimplePwm};
7use embassy_time::Timer;
8use {defmt_rtt as _, panic_probe as _};
9
10// for i in range(1024): print(int((math.sin(i/512*math.pi)*0.4+0.5)**2*32767), ', ', end='')
11static DUTY: [u16; 1024] = [
12 8191, 8272, 8353, 8434, 8516, 8598, 8681, 8764, 8847, 8931, 9015, 9099, 9184, 9269, 9354, 9440, 9526, 9613, 9700,
13 9787, 9874, 9962, 10050, 10139, 10227, 10316, 10406, 10495, 10585, 10675, 10766, 10857, 10948, 11039, 11131, 11223,
14 11315, 11407, 11500, 11592, 11685, 11779, 11872, 11966, 12060, 12154, 12248, 12343, 12438, 12533, 12628, 12723,
15 12818, 12914, 13010, 13106, 13202, 13298, 13394, 13491, 13587, 13684, 13781, 13878, 13975, 14072, 14169, 14266,
16 14364, 14461, 14558, 14656, 14754, 14851, 14949, 15046, 15144, 15242, 15339, 15437, 15535, 15632, 15730, 15828,
17 15925, 16023, 16120, 16218, 16315, 16412, 16510, 16607, 16704, 16801, 16898, 16995, 17091, 17188, 17284, 17380,
18 17477, 17572, 17668, 17764, 17859, 17955, 18050, 18145, 18239, 18334, 18428, 18522, 18616, 18710, 18803, 18896,
19 18989, 19082, 19174, 19266, 19358, 19449, 19540, 19631, 19722, 19812, 19902, 19991, 20081, 20169, 20258, 20346,
20 20434, 20521, 20608, 20695, 20781, 20867, 20952, 21037, 21122, 21206, 21290, 21373, 21456, 21538, 21620, 21701,
21 21782, 21863, 21943, 22022, 22101, 22179, 22257, 22335, 22412, 22488, 22564, 22639, 22714, 22788, 22861, 22934,
22 23007, 23079, 23150, 23220, 23290, 23360, 23429, 23497, 23564, 23631, 23698, 23763, 23828, 23892, 23956, 24019,
23 24081, 24143, 24204, 24264, 24324, 24383, 24441, 24499, 24555, 24611, 24667, 24721, 24775, 24828, 24881, 24933,
24 24983, 25034, 25083, 25132, 25180, 25227, 25273, 25319, 25363, 25407, 25451, 25493, 25535, 25575, 25615, 25655,
25 25693, 25731, 25767, 25803, 25838, 25873, 25906, 25939, 25971, 26002, 26032, 26061, 26089, 26117, 26144, 26170,
26 26195, 26219, 26242, 26264, 26286, 26307, 26327, 26346, 26364, 26381, 26397, 26413, 26427, 26441, 26454, 26466,
27 26477, 26487, 26496, 26505, 26512, 26519, 26525, 26530, 26534, 26537, 26539, 26540, 26541, 26540, 26539, 26537,
28 26534, 26530, 26525, 26519, 26512, 26505, 26496, 26487, 26477, 26466, 26454, 26441, 26427, 26413, 26397, 26381,
29 26364, 26346, 26327, 26307, 26286, 26264, 26242, 26219, 26195, 26170, 26144, 26117, 26089, 26061, 26032, 26002,
30 25971, 25939, 25906, 25873, 25838, 25803, 25767, 25731, 25693, 25655, 25615, 25575, 25535, 25493, 25451, 25407,
31 25363, 25319, 25273, 25227, 25180, 25132, 25083, 25034, 24983, 24933, 24881, 24828, 24775, 24721, 24667, 24611,
32 24555, 24499, 24441, 24383, 24324, 24264, 24204, 24143, 24081, 24019, 23956, 23892, 23828, 23763, 23698, 23631,
33 23564, 23497, 23429, 23360, 23290, 23220, 23150, 23079, 23007, 22934, 22861, 22788, 22714, 22639, 22564, 22488,
34 22412, 22335, 22257, 22179, 22101, 22022, 21943, 21863, 21782, 21701, 21620, 21538, 21456, 21373, 21290, 21206,
35 21122, 21037, 20952, 20867, 20781, 20695, 20608, 20521, 20434, 20346, 20258, 20169, 20081, 19991, 19902, 19812,
36 19722, 19631, 19540, 19449, 19358, 19266, 19174, 19082, 18989, 18896, 18803, 18710, 18616, 18522, 18428, 18334,
37 18239, 18145, 18050, 17955, 17859, 17764, 17668, 17572, 17477, 17380, 17284, 17188, 17091, 16995, 16898, 16801,
38 16704, 16607, 16510, 16412, 16315, 16218, 16120, 16023, 15925, 15828, 15730, 15632, 15535, 15437, 15339, 15242,
39 15144, 15046, 14949, 14851, 14754, 14656, 14558, 14461, 14364, 14266, 14169, 14072, 13975, 13878, 13781, 13684,
40 13587, 13491, 13394, 13298, 13202, 13106, 13010, 12914, 12818, 12723, 12628, 12533, 12438, 12343, 12248, 12154,
41 12060, 11966, 11872, 11779, 11685, 11592, 11500, 11407, 11315, 11223, 11131, 11039, 10948, 10857, 10766, 10675,
42 10585, 10495, 10406, 10316, 10227, 10139, 10050, 9962, 9874, 9787, 9700, 9613, 9526, 9440, 9354, 9269, 9184, 9099,
43 9015, 8931, 8847, 8764, 8681, 8598, 8516, 8434, 8353, 8272, 8191, 8111, 8031, 7952, 7873, 7794, 7716, 7638, 7561,
44 7484, 7407, 7331, 7255, 7180, 7105, 7031, 6957, 6883, 6810, 6738, 6665, 6594, 6522, 6451, 6381, 6311, 6241, 6172,
45 6104, 6036, 5968, 5901, 5834, 5767, 5702, 5636, 5571, 5507, 5443, 5379, 5316, 5253, 5191, 5130, 5068, 5008, 4947,
46 4888, 4828, 4769, 4711, 4653, 4596, 4539, 4482, 4426, 4371, 4316, 4261, 4207, 4153, 4100, 4047, 3995, 3943, 3892,
47 3841, 3791, 3741, 3691, 3642, 3594, 3546, 3498, 3451, 3404, 3358, 3312, 3267, 3222, 3178, 3134, 3090, 3047, 3005,
48 2962, 2921, 2879, 2839, 2798, 2758, 2719, 2680, 2641, 2603, 2565, 2528, 2491, 2454, 2418, 2382, 2347, 2312, 2278,
49 2244, 2210, 2177, 2144, 2112, 2080, 2048, 2017, 1986, 1956, 1926, 1896, 1867, 1838, 1810, 1781, 1754, 1726, 1699,
50 1673, 1646, 1620, 1595, 1570, 1545, 1520, 1496, 1472, 1449, 1426, 1403, 1380, 1358, 1336, 1315, 1294, 1273, 1252,
51 1232, 1212, 1192, 1173, 1154, 1135, 1117, 1099, 1081, 1063, 1046, 1029, 1012, 996, 980, 964, 948, 933, 918, 903,
52 888, 874, 860, 846, 833, 819, 806, 793, 781, 768, 756, 744, 733, 721, 710, 699, 688, 677, 667, 657, 647, 637, 627,
53 618, 609, 599, 591, 582, 574, 565, 557, 549, 541, 534, 526, 519, 512, 505, 498, 492, 485, 479, 473, 467, 461, 455,
54 450, 444, 439, 434, 429, 424, 419, 415, 410, 406, 402, 398, 394, 390, 386, 383, 379, 376, 373, 370, 367, 364, 361,
55 359, 356, 354, 351, 349, 347, 345, 343, 342, 340, 338, 337, 336, 334, 333, 332, 331, 330, 330, 329, 328, 328, 328,
56 327, 327, 327, 327, 327, 328, 328, 328, 329, 330, 330, 331, 332, 333, 334, 336, 337, 338, 340, 342, 343, 345, 347,
57 349, 351, 354, 356, 359, 361, 364, 367, 370, 373, 376, 379, 383, 386, 390, 394, 398, 402, 406, 410, 415, 419, 424,
58 429, 434, 439, 444, 450, 455, 461, 467, 473, 479, 485, 492, 498, 505, 512, 519, 526, 534, 541, 549, 557, 565, 574,
59 582, 591, 599, 609, 618, 627, 637, 647, 657, 667, 677, 688, 699, 710, 721, 733, 744, 756, 768, 781, 793, 806, 819,
60 833, 846, 860, 874, 888, 903, 918, 933, 948, 964, 980, 996, 1012, 1029, 1046, 1063, 1081, 1099, 1117, 1135, 1154,
61 1173, 1192, 1212, 1232, 1252, 1273, 1294, 1315, 1336, 1358, 1380, 1403, 1426, 1449, 1472, 1496, 1520, 1545, 1570,
62 1595, 1620, 1646, 1673, 1699, 1726, 1754, 1781, 1810, 1838, 1867, 1896, 1926, 1956, 1986, 2017, 2048, 2080, 2112,
63 2144, 2177, 2210, 2244, 2278, 2312, 2347, 2382, 2418, 2454, 2491, 2528, 2565, 2603, 2641, 2680, 2719, 2758, 2798,
64 2839, 2879, 2921, 2962, 3005, 3047, 3090, 3134, 3178, 3222, 3267, 3312, 3358, 3404, 3451, 3498, 3546, 3594, 3642,
65 3691, 3741, 3791, 3841, 3892, 3943, 3995, 4047, 4100, 4153, 4207, 4261, 4316, 4371, 4426, 4482, 4539, 4596, 4653,
66 4711, 4769, 4828, 4888, 4947, 5008, 5068, 5130, 5191, 5253, 5316, 5379, 5443, 5507, 5571, 5636, 5702, 5767, 5834,
67 5901, 5968, 6036, 6104, 6172, 6241, 6311, 6381, 6451, 6522, 6594, 6665, 6738, 6810, 6883, 6957, 7031, 7105, 7180,
68 7255, 7331, 7407, 7484, 7561, 7638, 7716, 7794, 7873, 7952, 8031, 8111,
69];
70
71#[embassy_executor::main]
72async fn main(_spawner: Spawner) {
73 let p = embassy_nrf::init(Default::default());
74 let mut pwm = SimplePwm::new_2ch(p.PWM20, p.P1_10, p.P1_14, &Default::default());
75 pwm.set_prescaler(Prescaler::Div1);
76 pwm.set_max_duty(32767);
77 info!("pwm initialized!");
78
79 let mut i = 0;
80 loop {
81 i += 1;
82 pwm.set_duty(0, DutyCycle::normal(DUTY[i % 1024]));
83 pwm.set_duty(1, DutyCycle::normal(DUTY[(i + 512) % 1024]));
84 Timer::after_millis(3).await;
85 }
86}
diff --git a/examples/nrf54l15/src/bin/rtc.rs b/examples/nrf54l15/src/bin/rtc.rs
new file mode 100644
index 000000000..a45aaca52
--- /dev/null
+++ b/examples/nrf54l15/src/bin/rtc.rs
@@ -0,0 +1,56 @@
1#![no_std]
2#![no_main]
3
4use core::cell::RefCell;
5
6use embassy_executor::Spawner;
7use embassy_nrf::gpio::{Level, Output, OutputDrive};
8use embassy_nrf::interrupt;
9use embassy_nrf::rtc::Rtc;
10use embassy_sync::blocking_mutex::Mutex;
11use embassy_sync::blocking_mutex::raw::CriticalSectionRawMutex;
12use portable_atomic::AtomicU64;
13use {defmt_rtt as _, panic_probe as _};
14
15// 64 bit counter which will never overflow.
16static TICK_COUNTER: AtomicU64 = AtomicU64::new(0);
17static RTC: Mutex<CriticalSectionRawMutex, RefCell<Option<Rtc<'static>>>> = Mutex::new(RefCell::new(None));
18
19#[embassy_executor::main]
20async fn main(_spawner: Spawner) {
21 defmt::println!("nRF54L15 RTC example");
22 let p = embassy_nrf::init(Default::default());
23 let mut led = Output::new(p.P2_09, Level::High, OutputDrive::Standard);
24 // Counter resolution is 125 ms.
25 let mut rtc = Rtc::new(p.RTC10, (1 << 12) - 1).unwrap();
26 rtc.enable_interrupt(embassy_nrf::rtc::Interrupt::Tick, true);
27 rtc.enable_event(embassy_nrf::rtc::Interrupt::Tick);
28 rtc.enable();
29 RTC.lock(|r| {
30 let mut rtc_borrow = r.borrow_mut();
31 *rtc_borrow = Some(rtc);
32 });
33
34 let mut last_counter_val = 0;
35 loop {
36 let current = TICK_COUNTER.load(core::sync::atomic::Ordering::Relaxed);
37 if current != last_counter_val {
38 led.toggle();
39 last_counter_val = current;
40 }
41 }
42}
43
44#[interrupt]
45fn RTC10() {
46 // For 64-bit, we do not need to worry about overflowing, at least not for realistic program
47 // lifetimes.
48 TICK_COUNTER.fetch_add(1, core::sync::atomic::Ordering::Relaxed);
49 RTC.lock(|r| {
50 let mut rtc_borrow = r.borrow_mut();
51 rtc_borrow
52 .as_mut()
53 .unwrap()
54 .reset_event(embassy_nrf::rtc::Interrupt::Tick);
55 });
56}
diff --git a/examples/nrf54l15/src/bin/saadc.rs b/examples/nrf54l15/src/bin/saadc.rs
new file mode 100644
index 000000000..567177894
--- /dev/null
+++ b/examples/nrf54l15/src/bin/saadc.rs
@@ -0,0 +1,28 @@
1#![no_std]
2#![no_main]
3
4use defmt::info;
5use embassy_executor::Spawner;
6use embassy_nrf::saadc::{ChannelConfig, Config, Saadc};
7use embassy_nrf::{bind_interrupts, saadc};
8use embassy_time::Timer;
9use {defmt_rtt as _, panic_probe as _};
10
11bind_interrupts!(struct Irqs {
12 SAADC => saadc::InterruptHandler;
13});
14
15#[embassy_executor::main]
16async fn main(_p: Spawner) {
17 let mut p = embassy_nrf::init(Default::default());
18 let config = Config::default();
19 let channel_config = ChannelConfig::single_ended(p.P1_04.reborrow());
20 let mut saadc = Saadc::new(p.SAADC, Irqs, config, [channel_config]);
21
22 loop {
23 let mut buf = [0; 1];
24 saadc.sample(&mut buf).await;
25 info!("sample: {=i16}", &buf[0]);
26 Timer::after_millis(100).await;
27 }
28}
diff --git a/examples/nrf54l15/src/bin/spim.rs b/examples/nrf54l15/src/bin/spim.rs
new file mode 100644
index 000000000..3f5980647
--- /dev/null
+++ b/examples/nrf54l15/src/bin/spim.rs
@@ -0,0 +1,30 @@
1#![no_std]
2#![no_main]
3
4use embassy_executor::Spawner;
5use embassy_nrf::{bind_interrupts, peripherals, spim};
6use {defmt_rtt as _, panic_probe as _};
7
8bind_interrupts!(struct Irqs {
9 SERIAL00 => spim::InterruptHandler<peripherals::SERIAL00>;
10});
11
12#[embassy_executor::main]
13async fn main(_spawner: Spawner) {
14 let p = embassy_nrf::init(Default::default());
15 let mut config = spim::Config::default();
16 config.frequency = spim::Frequency::M32;
17 let mut spim = spim::Spim::new(p.SERIAL00, Irqs, p.P2_05, p.P2_09, p.P2_08, config.clone());
18 let data = [
19 0x42, 0x43, 0x44, 0x45, 0x66, 0x12, 0x23, 0x34, 0x45, 0x19, 0x91, 0xaa, 0xff, 0xa5, 0x5a, 0x77,
20 ];
21 let mut buf = [0u8; 16];
22
23 buf.fill(0);
24 spim.blocking_transfer(&mut buf, &data).unwrap();
25 assert_eq!(data, buf);
26
27 buf.fill(0);
28 spim.transfer(&mut buf, &data).await.unwrap();
29 assert_eq!(data, buf);
30}
diff --git a/examples/nrf54l15/src/bin/twim.rs b/examples/nrf54l15/src/bin/twim.rs
new file mode 100644
index 000000000..53b85034e
--- /dev/null
+++ b/examples/nrf54l15/src/bin/twim.rs
@@ -0,0 +1,37 @@
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
8use defmt::*;
9use embassy_executor::Spawner;
10use embassy_nrf::twim::{self, Twim};
11use embassy_nrf::{bind_interrupts, peripherals};
12use static_cell::ConstStaticCell;
13use {defmt_rtt as _, panic_probe as _};
14
15const ADDRESS: u8 = 0x18;
16const WHOAMI: u8 = 0x0F;
17
18bind_interrupts!(struct Irqs {
19 SERIAL20 => twim::InterruptHandler<peripherals::SERIAL20>;
20});
21
22#[embassy_executor::main]
23async fn main(_spawner: Spawner) {
24 let p = embassy_nrf::init(Default::default());
25 info!("Initializing TWI...");
26 let config = twim::Config::default();
27 static RAM_BUFFER: ConstStaticCell<[u8; 16]> = ConstStaticCell::new([0; 16]);
28 let mut twi = Twim::new(p.SERIAL20, Irqs, p.P1_13, p.P1_12, config, RAM_BUFFER.take());
29
30 info!("Reading...");
31
32 let mut data = [0u8; 1];
33 match twi.write_read(ADDRESS, &[WHOAMI], &mut data).await {
34 Ok(()) => info!("Whoami: {}", data[0]),
35 Err(e) => error!("I2c Error: {:?}", e),
36 }
37}
diff --git a/examples/nrf54l15/src/bin/twis.rs b/examples/nrf54l15/src/bin/twis.rs
new file mode 100644
index 000000000..34c04aee3
--- /dev/null
+++ b/examples/nrf54l15/src/bin/twis.rs
@@ -0,0 +1,47 @@
1//! TWIS example
2
3#![no_std]
4#![no_main]
5
6use defmt::*;
7use embassy_executor::Spawner;
8use embassy_nrf::twis::{self, Command, Twis};
9use embassy_nrf::{bind_interrupts, peripherals};
10use {defmt_rtt as _, panic_probe as _};
11
12bind_interrupts!(struct Irqs {
13 SERIAL20 => twis::InterruptHandler<peripherals::SERIAL20>;
14});
15
16#[embassy_executor::main]
17async fn main(_spawner: Spawner) {
18 let p = embassy_nrf::init(Default::default());
19
20 let mut config = twis::Config::default();
21 config.address0 = 0x55; // Set i2c address
22 let mut i2c = Twis::new(p.SERIAL20, Irqs, p.P0_03, p.P0_04, config);
23
24 info!("Listening...");
25 loop {
26 let response = [1, 2, 3, 4, 5, 6, 7, 8];
27 // This buffer is used if the i2c master performs a Write or WriteRead
28 let mut buf = [0u8; 16];
29 match i2c.listen(&mut buf).await {
30 Ok(Command::Read) => {
31 info!("Got READ command. Respond with data:\n{:?}\n", response);
32 if let Err(e) = i2c.respond_to_read(&response).await {
33 error!("{:?}", e);
34 }
35 }
36 Ok(Command::Write(n)) => info!("Got WRITE command with data:\n{:?}\n", buf[..n]),
37 Ok(Command::WriteRead(n)) => {
38 info!("Got WRITE/READ command with data:\n{:?}", buf[..n]);
39 info!("Respond with data:\n{:?}\n", response);
40 if let Err(e) = i2c.respond_to_read(&response).await {
41 error!("{:?}", e);
42 }
43 }
44 Err(e) => error!("{:?}", e),
45 }
46 }
47}
diff --git a/examples/nrf54l15/src/bin/uart.rs b/examples/nrf54l15/src/bin/uart.rs
new file mode 100644
index 000000000..cc6528a6f
--- /dev/null
+++ b/examples/nrf54l15/src/bin/uart.rs
@@ -0,0 +1,37 @@
1#![no_std]
2#![no_main]
3
4use defmt::*;
5use embassy_executor::Spawner;
6use embassy_nrf::{bind_interrupts, peripherals, uarte};
7use {defmt_rtt as _, panic_probe as _};
8
9bind_interrupts!(struct Irqs {
10 SERIAL20 => uarte::InterruptHandler<peripherals::SERIAL20>;
11});
12
13#[embassy_executor::main]
14async fn main(_spawner: Spawner) {
15 let p = embassy_nrf::init(Default::default());
16 let mut config = uarte::Config::default();
17 config.parity = uarte::Parity::EXCLUDED;
18 config.baudrate = uarte::Baudrate::BAUD115200;
19
20 let mut uart = uarte::Uarte::new(p.SERIAL20, p.P1_12, p.P1_13, Irqs, config);
21
22 info!("uarte initialized!");
23
24 // Message must be in SRAM
25 let mut buf = [0; 8];
26 buf.copy_from_slice(b"Hello!\r\n");
27
28 unwrap!(uart.write(&buf).await);
29 info!("wrote hello in uart!");
30
31 loop {
32 info!("reading...");
33 unwrap!(uart.read(&mut buf).await);
34 info!("writing...");
35 unwrap!(uart.write(&buf).await);
36 }
37}