aboutsummaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorxoviat <[email protected]>2025-11-18 10:00:16 -0600
committerGitHub <[email protected]>2025-11-18 10:00:16 -0600
commit0102bc3f82a4a92f3ba7594bc788f6345acc8d17 (patch)
tree604068e12694e9f3cb6e449b2544c38b6a17620b /examples
parenteb18f8482dceb644a626002d070359f997f1e474 (diff)
parentaad02db7c59467374526ffbb484dbacf2a7b6e5e (diff)
Merge branch 'main' into sma
Diffstat (limited to 'examples')
-rw-r--r--examples/lpc55s69/src/bin/pwm.rs2
-rw-r--r--examples/lpc55s69/src/bin/usart_async.rs4
-rw-r--r--examples/nrf52840/src/bin/gpiote_channel.rs8
-rw-r--r--examples/nrf5340/src/bin/gpiote_channel.rs8
-rw-r--r--examples/nrf54l15/memory.x2
-rw-r--r--examples/nrf54l15/src/bin/gpiote_channel.rs8
-rw-r--r--examples/rp/src/bin/wifi_webrequest.rs90
-rw-r--r--examples/stm32h5/src/bin/adc_dma.rs9
-rw-r--r--examples/stm32h5/src/bin/stop.rs12
-rw-r--r--examples/stm32h723/src/bin/spdifrx.rs2
-rw-r--r--examples/stm32l5/src/bin/stop.rs12
-rw-r--r--examples/stm32wb/src/bin/mac_ffd_net.rs185
-rw-r--r--examples/stm32wle5/src/bin/adc.rs12
-rw-r--r--examples/stm32wle5/src/bin/blinky.rs12
-rw-r--r--examples/stm32wle5/src/bin/button_exti.rs12
-rw-r--r--examples/stm32wle5/src/bin/i2c.rs13
16 files changed, 175 insertions, 216 deletions
diff --git a/examples/lpc55s69/src/bin/pwm.rs b/examples/lpc55s69/src/bin/pwm.rs
index 93b898b9d..8a9894b94 100644
--- a/examples/lpc55s69/src/bin/pwm.rs
+++ b/examples/lpc55s69/src/bin/pwm.rs
@@ -10,7 +10,7 @@ use {defmt_rtt as _, panic_halt as _};
10#[embassy_executor::main] 10#[embassy_executor::main]
11async fn main(_spawner: Spawner) { 11async fn main(_spawner: Spawner) {
12 let p = embassy_nxp::init(Default::default()); 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)); 13 let pwm = Pwm::new_output(p.SCT0_OUT1, p.PIO0_18, Config::new(1_000_000_000, 2_000_000_000));
14 loop { 14 loop {
15 info!("Counter: {}", pwm.counter()); 15 info!("Counter: {}", pwm.counter());
16 Timer::after_millis(50).await; 16 Timer::after_millis(50).await;
diff --git a/examples/lpc55s69/src/bin/usart_async.rs b/examples/lpc55s69/src/bin/usart_async.rs
index b06abd477..a9815b920 100644
--- a/examples/lpc55s69/src/bin/usart_async.rs
+++ b/examples/lpc55s69/src/bin/usart_async.rs
@@ -38,8 +38,8 @@ async fn main(spawner: Spawner) {
38 p.PIO0_27, 38 p.PIO0_27,
39 p.PIO1_24, 39 p.PIO1_24,
40 Irqs, 40 Irqs,
41 p.DMA_CH11, 41 p.DMA0_CH11,
42 p.DMA_CH10, 42 p.DMA0_CH10,
43 Config::default(), 43 Config::default(),
44 ); 44 );
45 let led = Output::new(p.PIO1_6, Level::Low); 45 let led = Output::new(p.PIO1_6, Level::Low);
diff --git a/examples/nrf52840/src/bin/gpiote_channel.rs b/examples/nrf52840/src/bin/gpiote_channel.rs
index c7ddc1d8d..e358779b2 100644
--- a/examples/nrf52840/src/bin/gpiote_channel.rs
+++ b/examples/nrf52840/src/bin/gpiote_channel.rs
@@ -12,10 +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(p.GPIOTE_CH0, p.P0_11, Pull::Up, InputChannelPolarity::HiToLo); 15 let mut ch1 = InputChannel::new(p.GPIOTE_CH0, p.P0_11, Pull::Up, InputChannelPolarity::HiToLo);
16 let ch2 = InputChannel::new(p.GPIOTE_CH1, p.P0_12, Pull::Up, InputChannelPolarity::LoToHi); 16 let mut ch2 = InputChannel::new(p.GPIOTE_CH1, p.P0_12, Pull::Up, InputChannelPolarity::LoToHi);
17 let ch3 = InputChannel::new(p.GPIOTE_CH2, p.P0_24, Pull::Up, InputChannelPolarity::Toggle); 17 let mut ch3 = InputChannel::new(p.GPIOTE_CH2, p.P0_24, Pull::Up, InputChannelPolarity::Toggle);
18 let ch4 = InputChannel::new(p.GPIOTE_CH3, p.P0_25, Pull::Up, InputChannelPolarity::Toggle); 18 let mut ch4 = InputChannel::new(p.GPIOTE_CH3, p.P0_25, Pull::Up, InputChannelPolarity::Toggle);
19 19
20 let button1 = async { 20 let button1 = async {
21 loop { 21 loop {
diff --git a/examples/nrf5340/src/bin/gpiote_channel.rs b/examples/nrf5340/src/bin/gpiote_channel.rs
index a085310ce..41ee732c3 100644
--- a/examples/nrf5340/src/bin/gpiote_channel.rs
+++ b/examples/nrf5340/src/bin/gpiote_channel.rs
@@ -12,10 +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(p.GPIOTE_CH0, p.P0_23, Pull::Up, InputChannelPolarity::HiToLo); 15 let mut ch1 = InputChannel::new(p.GPIOTE_CH0, p.P0_23, Pull::Up, InputChannelPolarity::HiToLo);
16 let ch2 = InputChannel::new(p.GPIOTE_CH1, p.P0_24, Pull::Up, InputChannelPolarity::LoToHi); 16 let mut ch2 = InputChannel::new(p.GPIOTE_CH1, p.P0_24, Pull::Up, InputChannelPolarity::LoToHi);
17 let ch3 = InputChannel::new(p.GPIOTE_CH2, p.P0_08, Pull::Up, InputChannelPolarity::Toggle); 17 let mut ch3 = InputChannel::new(p.GPIOTE_CH2, p.P0_08, Pull::Up, InputChannelPolarity::Toggle);
18 let ch4 = InputChannel::new(p.GPIOTE_CH3, p.P0_09, Pull::Up, InputChannelPolarity::Toggle); 18 let mut ch4 = InputChannel::new(p.GPIOTE_CH3, p.P0_09, Pull::Up, InputChannelPolarity::Toggle);
19 19
20 let button1 = async { 20 let button1 = async {
21 loop { 21 loop {
diff --git a/examples/nrf54l15/memory.x b/examples/nrf54l15/memory.x
index 1064c8a5c..332200828 100644
--- a/examples/nrf54l15/memory.x
+++ b/examples/nrf54l15/memory.x
@@ -1,5 +1,5 @@
1MEMORY 1MEMORY
2{ 2{
3 FLASH : ORIGIN = 0x00000000, LENGTH = 1536K 3 FLASH : ORIGIN = 0x00000000, LENGTH = 1524K
4 RAM : ORIGIN = 0x20000000, LENGTH = 256K 4 RAM : ORIGIN = 0x20000000, LENGTH = 256K
5} 5}
diff --git a/examples/nrf54l15/src/bin/gpiote_channel.rs b/examples/nrf54l15/src/bin/gpiote_channel.rs
index 6333250ba..cac8823f8 100644
--- a/examples/nrf54l15/src/bin/gpiote_channel.rs
+++ b/examples/nrf54l15/src/bin/gpiote_channel.rs
@@ -12,10 +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(p.GPIOTE20_CH0, p.P1_13, Pull::Up, InputChannelPolarity::HiToLo); 15 let mut 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); 16 let mut 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); 17 let mut 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); 18 let mut ch4 = InputChannel::new(p.GPIOTE30_CH0, p.P0_04, Pull::Up, InputChannelPolarity::Toggle);
19 19
20 let button1 = async { 20 let button1 = async {
21 loop { 21 loop {
diff --git a/examples/rp/src/bin/wifi_webrequest.rs b/examples/rp/src/bin/wifi_webrequest.rs
index b618d2b38..ce85f4b9a 100644
--- a/examples/rp/src/bin/wifi_webrequest.rs
+++ b/examples/rp/src/bin/wifi_webrequest.rs
@@ -1,9 +1,8 @@
1//! This example uses the RP Pico W board Wifi chip (cyw43). 1//! This example uses the RP Pico W board Wifi chip (cyw43).
2//! Connects to Wifi network and makes a web request to get the current time. 2//! Connects to Wifi network and makes a web request to httpbin.org.
3 3
4#![no_std] 4#![no_std]
5#![no_main] 5#![no_main]
6#![allow(async_fn_in_trait)]
7 6
8use core::str::from_utf8; 7use core::str::from_utf8;
9 8
@@ -20,11 +19,14 @@ use embassy_rp::gpio::{Level, Output};
20use embassy_rp::peripherals::{DMA_CH0, PIO0}; 19use embassy_rp::peripherals::{DMA_CH0, PIO0};
21use embassy_rp::pio::{InterruptHandler, Pio}; 20use embassy_rp::pio::{InterruptHandler, Pio};
22use embassy_time::{Duration, Timer}; 21use embassy_time::{Duration, Timer};
23use reqwless::client::{HttpClient, TlsConfig, TlsVerify}; 22use reqwless::client::HttpClient;
23// Uncomment these for TLS requests:
24// use reqwless::client::{HttpClient, TlsConfig, TlsVerify};
24use reqwless::request::Method; 25use reqwless::request::Method;
25use serde::Deserialize; 26use serde::Deserialize;
27use serde_json_core::from_slice;
26use static_cell::StaticCell; 28use static_cell::StaticCell;
27use {defmt_rtt as _, panic_probe as _, serde_json_core}; 29use {defmt_rtt as _, panic_probe as _};
28 30
29bind_interrupts!(struct Irqs { 31bind_interrupts!(struct Irqs {
30 PIO0_IRQ_0 => InterruptHandler<PIO0>; 32 PIO0_IRQ_0 => InterruptHandler<PIO0>;
@@ -119,64 +121,90 @@ async fn main(spawner: Spawner) {
119 // And now we can use it! 121 // And now we can use it!
120 122
121 loop { 123 loop {
122 let mut rx_buffer = [0; 8192]; 124 let mut rx_buffer = [0; 4096];
123 let mut tls_read_buffer = [0; 16640]; 125 // Uncomment these for TLS requests:
124 let mut tls_write_buffer = [0; 16640]; 126 // let mut tls_read_buffer = [0; 16640];
127 // let mut tls_write_buffer = [0; 16640];
125 128
126 let client_state = TcpClientState::<1, 1024, 1024>::new(); 129 let client_state = TcpClientState::<1, 4096, 4096>::new();
127 let tcp_client = TcpClient::new(stack, &client_state); 130 let tcp_client = TcpClient::new(stack, &client_state);
128 let dns_client = DnsSocket::new(stack); 131 let dns_client = DnsSocket::new(stack);
129 let tls_config = TlsConfig::new(seed, &mut tls_read_buffer, &mut tls_write_buffer, TlsVerify::None); 132 // Uncomment these for TLS requests:
133 // let tls_config = TlsConfig::new(seed, &mut tls_read_buffer, &mut tls_write_buffer, TlsVerify::None);
130 134
131 let mut http_client = HttpClient::new_with_tls(&tcp_client, &dns_client, tls_config); 135 // Using non-TLS HTTP for this example
132 let url = "https://worldtimeapi.org/api/timezone/Europe/Berlin"; 136 let mut http_client = HttpClient::new(&tcp_client, &dns_client);
133 // for non-TLS requests, use this instead: 137 let url = "http://httpbin.org/json";
134 // let mut http_client = HttpClient::new(&tcp_client, &dns_client); 138 // For TLS requests, use this instead:
135 // let url = "http://worldtimeapi.org/api/timezone/Europe/Berlin"; 139 // let mut http_client = HttpClient::new_with_tls(&tcp_client, &dns_client, tls_config);
140 // let url = "https://httpbin.org/json";
136 141
137 info!("connecting to {}", &url); 142 info!("connecting to {}", &url);
138 143
139 let mut request = match http_client.request(Method::GET, &url).await { 144 let mut request = match http_client.request(Method::GET, url).await {
140 Ok(req) => req, 145 Ok(req) => req,
141 Err(e) => { 146 Err(e) => {
142 error!("Failed to make HTTP request: {:?}", e); 147 error!("Failed to make HTTP request: {:?}", e);
143 return; // handle the error 148 Timer::after(Duration::from_secs(5)).await;
149 continue;
144 } 150 }
145 }; 151 };
146 152
147 let response = match request.send(&mut rx_buffer).await { 153 let response = match request.send(&mut rx_buffer).await {
148 Ok(resp) => resp, 154 Ok(resp) => resp,
149 Err(_e) => { 155 Err(e) => {
150 error!("Failed to send HTTP request"); 156 error!("Failed to send HTTP request: {:?}", e);
151 return; // handle the error; 157 Timer::after(Duration::from_secs(5)).await;
158 continue;
152 } 159 }
153 }; 160 };
154 161
155 let body = match from_utf8(response.body().read_to_end().await.unwrap()) { 162 info!("Response status: {}", response.status.0);
163
164 let body_bytes = match response.body().read_to_end().await {
156 Ok(b) => b, 165 Ok(b) => b,
157 Err(_e) => { 166 Err(_e) => {
158 error!("Failed to read response body"); 167 error!("Failed to read response body");
159 return; // handle the error 168 Timer::after(Duration::from_secs(5)).await;
169 continue;
170 }
171 };
172
173 let body = match from_utf8(body_bytes) {
174 Ok(b) => b,
175 Err(_e) => {
176 error!("Failed to parse response body as UTF-8");
177 Timer::after(Duration::from_secs(5)).await;
178 continue;
160 } 179 }
161 }; 180 };
162 info!("Response body: {:?}", &body); 181 info!("Response body length: {} bytes", body.len());
163 182
164 // parse the response body and update the RTC 183 // Parse the JSON response from httpbin.org/json
184 #[derive(Deserialize)]
185 struct SlideShow<'a> {
186 author: &'a str,
187 title: &'a str,
188 }
165 189
166 #[derive(Deserialize)] 190 #[derive(Deserialize)]
167 struct ApiResponse<'a> { 191 struct HttpBinResponse<'a> {
168 datetime: &'a str, 192 #[serde(borrow)]
169 // other fields as needed 193 slideshow: SlideShow<'a>,
170 } 194 }
171 195
172 let bytes = body.as_bytes(); 196 let bytes = body.as_bytes();
173 match serde_json_core::de::from_slice::<ApiResponse>(bytes) { 197 match from_slice::<HttpBinResponse>(bytes) {
174 Ok((output, _used)) => { 198 Ok((output, _used)) => {
175 info!("Datetime: {:?}", output.datetime); 199 info!("Successfully parsed JSON response!");
200 info!("Slideshow title: {:?}", output.slideshow.title);
201 info!("Slideshow author: {:?}", output.slideshow.author);
176 } 202 }
177 Err(_e) => { 203 Err(e) => {
178 error!("Failed to parse response body"); 204 error!("Failed to parse JSON response: {}", Debug2Format(&e));
179 return; // handle the error 205 // Log preview of response for debugging
206 let preview = if body.len() > 200 { &body[..200] } else { body };
207 info!("Response preview: {:?}", preview);
180 } 208 }
181 } 209 }
182 210
diff --git a/examples/stm32h5/src/bin/adc_dma.rs b/examples/stm32h5/src/bin/adc_dma.rs
index fb9fcbc5c..2138257f7 100644
--- a/examples/stm32h5/src/bin/adc_dma.rs
+++ b/examples/stm32h5/src/bin/adc_dma.rs
@@ -6,7 +6,7 @@ use embassy_executor::Spawner;
6use embassy_stm32::adc::{self, Adc, AdcChannel, RxDma, SampleTime}; 6use embassy_stm32::adc::{self, Adc, AdcChannel, RxDma, SampleTime};
7use embassy_stm32::peripherals::{ADC1, ADC2, GPDMA1_CH0, GPDMA1_CH1, PA0, PA1, PA2, PA3}; 7use embassy_stm32::peripherals::{ADC1, ADC2, GPDMA1_CH0, GPDMA1_CH1, PA0, PA1, PA2, PA3};
8use embassy_stm32::{Config, Peri}; 8use embassy_stm32::{Config, Peri};
9use embassy_time::Instant; 9use embassy_time::{Duration, Instant, Ticker};
10use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
11 11
12#[embassy_executor::main] 12#[embassy_executor::main]
@@ -76,6 +76,9 @@ async fn adc_task<'a, T: adc::Instance>(
76 let mut pin1 = pin1.degrade_adc(); 76 let mut pin1 = pin1.degrade_adc();
77 let mut pin2 = pin2.degrade_adc(); 77 let mut pin2 = pin2.degrade_adc();
78 78
79 info!("adc init");
80
81 let mut ticker = Ticker::every(Duration::from_millis(500));
79 let mut tic = Instant::now(); 82 let mut tic = Instant::now();
80 let mut buffer = [0u16; 512]; 83 let mut buffer = [0u16; 512];
81 loop { 84 loop {
@@ -84,11 +87,13 @@ async fn adc_task<'a, T: adc::Instance>(
84 adc.read( 87 adc.read(
85 dma.reborrow(), 88 dma.reborrow(),
86 [(&mut pin1, SampleTime::CYCLES2_5), (&mut pin2, SampleTime::CYCLES2_5)].into_iter(), 89 [(&mut pin1, SampleTime::CYCLES2_5), (&mut pin2, SampleTime::CYCLES2_5)].into_iter(),
87 &mut buffer, 90 &mut buffer[0..2],
88 ) 91 )
89 .await; 92 .await;
90 let toc = Instant::now(); 93 let toc = Instant::now();
91 info!("\n adc1: {} dt = {}", buffer[0..16], (toc - tic).as_micros()); 94 info!("\n adc1: {} dt = {}", buffer[0..16], (toc - tic).as_micros());
92 tic = toc; 95 tic = toc;
96
97 ticker.next().await;
93 } 98 }
94} 99}
diff --git a/examples/stm32h5/src/bin/stop.rs b/examples/stm32h5/src/bin/stop.rs
index caebc9daf..8d5456b80 100644
--- a/examples/stm32h5/src/bin/stop.rs
+++ b/examples/stm32h5/src/bin/stop.rs
@@ -7,20 +7,12 @@
7use defmt::*; 7use defmt::*;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_stm32::gpio::{AnyPin, Level, Output, Speed}; 9use embassy_stm32::gpio::{AnyPin, Level, Output, Speed};
10use embassy_stm32::low_power::Executor;
11use embassy_stm32::rcc::{HSIPrescaler, LsConfig}; 10use embassy_stm32::rcc::{HSIPrescaler, LsConfig};
12use embassy_stm32::{Config, Peri}; 11use embassy_stm32::{Config, Peri, low_power};
13use embassy_time::Timer; 12use embassy_time::Timer;
14use {defmt_rtt as _, panic_probe as _}; 13use {defmt_rtt as _, panic_probe as _};
15 14
16#[cortex_m_rt::entry] 15#[embassy_executor::main(executor = "low_power::Executor")]
17fn main() -> ! {
18 Executor::take().run(|spawner| {
19 spawner.spawn(unwrap!(async_main(spawner)));
20 })
21}
22
23#[embassy_executor::task]
24async fn async_main(spawner: Spawner) { 16async fn async_main(spawner: Spawner) {
25 defmt::info!("Program Start"); 17 defmt::info!("Program Start");
26 18
diff --git a/examples/stm32h723/src/bin/spdifrx.rs b/examples/stm32h723/src/bin/spdifrx.rs
index cdbd69b89..5c29602c6 100644
--- a/examples/stm32h723/src/bin/spdifrx.rs
+++ b/examples/stm32h723/src/bin/spdifrx.rs
@@ -167,7 +167,7 @@ fn new_sai_transmitter<'d>(
167 sai_config.slot_count = hal::sai::word::U4(CHANNEL_COUNT as u8); 167 sai_config.slot_count = hal::sai::word::U4(CHANNEL_COUNT as u8);
168 sai_config.slot_enable = 0xFFFF; // All slots 168 sai_config.slot_enable = 0xFFFF; // All slots
169 sai_config.data_size = sai::DataSize::Data32; 169 sai_config.data_size = sai::DataSize::Data32;
170 sai_config.frame_length = (CHANNEL_COUNT * 32) as u8; 170 sai_config.frame_length = (CHANNEL_COUNT * 32) as u16;
171 sai_config.master_clock_divider = None; 171 sai_config.master_clock_divider = None;
172 172
173 let (sub_block_tx, _) = hal::sai::split_subblocks(sai); 173 let (sub_block_tx, _) = hal::sai::split_subblocks(sai);
diff --git a/examples/stm32l5/src/bin/stop.rs b/examples/stm32l5/src/bin/stop.rs
index 3d119f90f..fde804fb7 100644
--- a/examples/stm32l5/src/bin/stop.rs
+++ b/examples/stm32l5/src/bin/stop.rs
@@ -4,20 +4,12 @@
4use defmt::*; 4use defmt::*;
5use embassy_executor::Spawner; 5use embassy_executor::Spawner;
6use embassy_stm32::gpio::{AnyPin, Level, Output, Speed}; 6use embassy_stm32::gpio::{AnyPin, Level, Output, Speed};
7use embassy_stm32::low_power::Executor;
8use embassy_stm32::rcc::LsConfig; 7use embassy_stm32::rcc::LsConfig;
9use embassy_stm32::{Config, Peri}; 8use embassy_stm32::{Config, Peri, low_power};
10use embassy_time::Timer; 9use embassy_time::Timer;
11use {defmt_rtt as _, panic_probe as _}; 10use {defmt_rtt as _, panic_probe as _};
12 11
13#[cortex_m_rt::entry] 12#[embassy_executor::main(executor = "low_power::Executor")]
14fn main() -> ! {
15 Executor::take().run(|spawner| {
16 spawner.spawn(unwrap!(async_main(spawner)));
17 })
18}
19
20#[embassy_executor::task]
21async fn async_main(spawner: Spawner) { 13async fn async_main(spawner: Spawner) {
22 let mut config = Config::default(); 14 let mut config = Config::default();
23 config.rcc.ls = LsConfig::default_lsi(); 15 config.rcc.ls = LsConfig::default_lsi();
diff --git a/examples/stm32wb/src/bin/mac_ffd_net.rs b/examples/stm32wb/src/bin/mac_ffd_net.rs
index 5296943a1..5d946b35b 100644
--- a/examples/stm32wb/src/bin/mac_ffd_net.rs
+++ b/examples/stm32wb/src/bin/mac_ffd_net.rs
@@ -1,32 +1,44 @@
1#![no_std] 1#![no_std]
2#![no_main] 2#![no_main]
3 3
4use core::net::Ipv6Addr;
5
4use defmt::*; 6use defmt::*;
5use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_net::udp::{PacketMetadata, UdpSocket};
9use embassy_net::{Ipv6Cidr, StackResources, StaticConfigV6};
6use embassy_stm32::bind_interrupts; 10use embassy_stm32::bind_interrupts;
7use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler}; 11use embassy_stm32::ipcc::{Config, ReceiveInterruptHandler, TransmitInterruptHandler};
12use embassy_stm32::peripherals::RNG;
8use embassy_stm32::rcc::WPAN_DEFAULT; 13use embassy_stm32::rcc::WPAN_DEFAULT;
14use embassy_stm32::rng::InterruptHandler as RngInterruptHandler;
9use embassy_stm32_wpan::TlMbox; 15use embassy_stm32_wpan::TlMbox;
10use embassy_stm32_wpan::mac::commands::{ResetRequest, SetRequest, StartRequest}; 16use embassy_stm32_wpan::mac::{Driver, DriverState, Runner};
11use embassy_stm32_wpan::mac::typedefs::{MacChannel, PanId, PibId};
12use embassy_stm32_wpan::mac::{self, Runner};
13use embassy_stm32_wpan::sub::mm; 17use embassy_stm32_wpan::sub::mm;
18use embassy_time::{Duration, Timer};
19use heapless::Vec;
14use static_cell::StaticCell; 20use static_cell::StaticCell;
15use {defmt_rtt as _, panic_probe as _}; 21use {defmt_rtt as _, panic_probe as _};
16 22
17bind_interrupts!(struct Irqs{ 23bind_interrupts!(struct Irqs{
18 IPCC_C1_RX => ReceiveInterruptHandler; 24 IPCC_C1_RX => ReceiveInterruptHandler;
19 IPCC_C1_TX => TransmitInterruptHandler; 25 IPCC_C1_TX => TransmitInterruptHandler;
26 RNG => RngInterruptHandler<RNG>;
20}); 27});
21 28
22#[embassy_executor::task] 29#[embassy_executor::task]
23async fn run_mm_queue(memory_manager: mm::MemoryManager) { 30async fn run_mm_queue(memory_manager: mm::MemoryManager) -> ! {
24 memory_manager.run_queue().await; 31 memory_manager.run_queue().await
32}
33
34#[embassy_executor::task]
35async fn run_mac(runner: &'static Runner<'static>) -> ! {
36 runner.run().await
25} 37}
26 38
27#[embassy_executor::task] 39#[embassy_executor::task]
28async fn run_mac(runner: &'static Runner<'static>) { 40async fn run_net(mut runner: embassy_net::Runner<'static, Driver<'static>>) -> ! {
29 runner.run().await; 41 runner.run().await
30} 42}
31 43
32#[embassy_executor::main] 44#[embassy_executor::main]
@@ -72,106 +84,69 @@ async fn main(spawner: Spawner) {
72 let result = mbox.sys_subsystem.shci_c2_mac_802_15_4_init().await; 84 let result = mbox.sys_subsystem.shci_c2_mac_802_15_4_init().await;
73 info!("initialized mac: {}", result); 85 info!("initialized mac: {}", result);
74 86
75 info!("resetting"); 87 static DRIVER_STATE: StaticCell<DriverState> = StaticCell::new();
76 mbox.mac_subsystem
77 .send_command(&ResetRequest {
78 set_default_pib: true,
79 ..Default::default()
80 })
81 .await
82 .unwrap();
83 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap());
84
85 info!("setting extended address");
86 let extended_address: u64 = 0xACDE480000000001;
87 mbox.mac_subsystem
88 .send_command(&SetRequest {
89 pib_attribute_ptr: &extended_address as *const _ as *const u8,
90 pib_attribute: PibId::ExtendedAddress,
91 })
92 .await
93 .unwrap();
94 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap());
95
96 info!("setting short address");
97 let short_address: u16 = 0x1122;
98 mbox.mac_subsystem
99 .send_command(&SetRequest {
100 pib_attribute_ptr: &short_address as *const _ as *const u8,
101 pib_attribute: PibId::ShortAddress,
102 })
103 .await
104 .unwrap();
105 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap());
106
107 info!("setting association permit");
108 let association_permit: bool = true;
109 mbox.mac_subsystem
110 .send_command(&SetRequest {
111 pib_attribute_ptr: &association_permit as *const _ as *const u8,
112 pib_attribute: PibId::AssociationPermit,
113 })
114 .await
115 .unwrap();
116 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap());
117
118 info!("setting TX power");
119 let transmit_power: i8 = 2;
120 mbox.mac_subsystem
121 .send_command(&SetRequest {
122 pib_attribute_ptr: &transmit_power as *const _ as *const u8,
123 pib_attribute: PibId::TransmitPower,
124 })
125 .await
126 .unwrap();
127 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap());
128
129 info!("starting FFD device");
130 mbox.mac_subsystem
131 .send_command(&StartRequest {
132 pan_id: PanId([0x1A, 0xAA]),
133 channel_number: MacChannel::Channel16,
134 beacon_order: 0x0F,
135 superframe_order: 0x0F,
136 pan_coordinator: true,
137 battery_life_extension: false,
138 ..Default::default()
139 })
140 .await
141 .unwrap();
142 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap());
143
144 info!("setting RX on when idle");
145 let rx_on_while_idle: bool = true;
146 mbox.mac_subsystem
147 .send_command(&SetRequest {
148 pib_attribute_ptr: &rx_on_while_idle as *const _ as *const u8,
149 pib_attribute: PibId::RxOnWhenIdle,
150 })
151 .await
152 .unwrap();
153 defmt::info!("{:#x}", mbox.mac_subsystem.read().await.unwrap());
154
155 static TX1: StaticCell<[u8; 127]> = StaticCell::new();
156 static TX2: StaticCell<[u8; 127]> = StaticCell::new();
157 static TX3: StaticCell<[u8; 127]> = StaticCell::new();
158 static TX4: StaticCell<[u8; 127]> = StaticCell::new();
159 static TX5: StaticCell<[u8; 127]> = StaticCell::new();
160 let tx_queue = [
161 TX1.init([0u8; 127]),
162 TX2.init([0u8; 127]),
163 TX3.init([0u8; 127]),
164 TX4.init([0u8; 127]),
165 TX5.init([0u8; 127]),
166 ];
167
168 static RUNNER: StaticCell<Runner> = StaticCell::new(); 88 static RUNNER: StaticCell<Runner> = StaticCell::new();
169 let runner = RUNNER.init(Runner::new(mbox.mac_subsystem, tx_queue)); 89 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
90
91 let driver_state = DRIVER_STATE.init(DriverState::new(mbox.mac_subsystem));
92
93 let (driver, mac_runner, mut control) = Driver::new(
94 driver_state,
95 0x1122u16.to_be_bytes().try_into().unwrap(),
96 0xACDE480000000001u64.to_be_bytes().try_into().unwrap(),
97 );
98
99 // TODO: rng does not work for some reason
100 // Generate random seed.
101 // let mut rng = Rng::new(p.RNG, Irqs);
102 let seed = [0; 8];
103 // let _ = rng.async_fill_bytes(&mut seed).await;
104 let seed = u64::from_le_bytes(seed);
105
106 info!("seed generated");
107
108 // Init network stack
109 let ipv6_addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff);
110
111 let config = embassy_net::Config::ipv6_static(StaticConfigV6 {
112 address: Ipv6Cidr::new(ipv6_addr, 104),
113 gateway: None,
114 dns_servers: Vec::new(),
115 });
116
117 let (stack, eth_runner) = embassy_net::new(driver, config, RESOURCES.init(StackResources::new()), seed);
118
119 // wpan runner
120 spawner.spawn(run_mac(RUNNER.init(mac_runner)).unwrap());
121
122 // Launch network task
123 spawner.spawn(unwrap!(run_net(eth_runner)));
124
125 info!("Network task initialized");
126
127 control.init_link([0x1A, 0xAA]).await;
128
129 // Ensure DHCP configuration is up before trying connect
130 stack.wait_config_up().await;
131
132 info!("Network up");
133
134 // Then we can use it!
135 let mut rx_meta = [PacketMetadata::EMPTY];
136 let mut rx_buffer = [0; 4096];
137 let mut tx_meta = [PacketMetadata::EMPTY];
138 let mut tx_buffer = [0; 4096];
139
140 let mut socket = UdpSocket::new(stack, &mut rx_meta, &mut rx_buffer, &mut tx_meta, &mut tx_buffer);
141
142 let remote_endpoint = (Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2fb), 8000);
143
144 let send_buf = [0u8; 20];
170 145
171 spawner.spawn(run_mac(runner).unwrap()); 146 socket.bind((ipv6_addr, 8000)).unwrap();
147 socket.send_to(&send_buf, remote_endpoint).await.unwrap();
172 148
173 let (driver, control) = mac::new(runner).await; 149 Timer::after(Duration::from_secs(2)).await;
174 150
175 let _ = driver; 151 cortex_m::asm::bkpt();
176 let _ = control;
177} 152}
diff --git a/examples/stm32wle5/src/bin/adc.rs b/examples/stm32wle5/src/bin/adc.rs
index 4e0574d97..ea91fb063 100644
--- a/examples/stm32wle5/src/bin/adc.rs
+++ b/examples/stm32wle5/src/bin/adc.rs
@@ -6,20 +6,12 @@ use defmt::*;
6use defmt_rtt as _; 6use defmt_rtt as _;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_stm32::adc::{Adc, SampleTime}; 8use embassy_stm32::adc::{Adc, SampleTime};
9use embassy_stm32::low_power::Executor; 9use embassy_stm32::low_power;
10use embassy_time::Timer; 10use embassy_time::Timer;
11use panic_probe as _; 11use panic_probe as _;
12use static_cell::StaticCell; 12use static_cell::StaticCell;
13 13
14#[cortex_m_rt::entry] 14#[embassy_executor::main(executor = "low_power::Executor")]
15fn main() -> ! {
16 info!("main: Starting!");
17 Executor::take().run(|spawner| {
18 spawner.spawn(unwrap!(async_main(spawner)));
19 });
20}
21
22#[embassy_executor::task]
23async fn async_main(_spawner: Spawner) { 15async fn async_main(_spawner: Spawner) {
24 let mut config = embassy_stm32::Config::default(); 16 let mut config = embassy_stm32::Config::default();
25 // enable HSI clock 17 // enable HSI clock
diff --git a/examples/stm32wle5/src/bin/blinky.rs b/examples/stm32wle5/src/bin/blinky.rs
index b2745fdaf..9f0c04672 100644
--- a/examples/stm32wle5/src/bin/blinky.rs
+++ b/examples/stm32wle5/src/bin/blinky.rs
@@ -6,20 +6,12 @@ use defmt::*;
6use defmt_rtt as _; 6use defmt_rtt as _;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_stm32::gpio::{Level, Output, Speed}; 8use embassy_stm32::gpio::{Level, Output, Speed};
9use embassy_stm32::low_power::Executor; 9use embassy_stm32::low_power;
10use embassy_time::Timer; 10use embassy_time::Timer;
11use panic_probe as _; 11use panic_probe as _;
12use static_cell::StaticCell; 12use static_cell::StaticCell;
13 13
14#[cortex_m_rt::entry] 14#[embassy_executor::main(executor = "low_power::Executor")]
15fn main() -> ! {
16 info!("main: Starting!");
17 Executor::take().run(|spawner| {
18 spawner.spawn(unwrap!(async_main(spawner)));
19 });
20}
21
22#[embassy_executor::task]
23async fn async_main(_spawner: Spawner) { 15async fn async_main(_spawner: Spawner) {
24 let mut config = embassy_stm32::Config::default(); 16 let mut config = embassy_stm32::Config::default();
25 // enable HSI clock 17 // enable HSI clock
diff --git a/examples/stm32wle5/src/bin/button_exti.rs b/examples/stm32wle5/src/bin/button_exti.rs
index db1bff0be..878eca7d0 100644
--- a/examples/stm32wle5/src/bin/button_exti.rs
+++ b/examples/stm32wle5/src/bin/button_exti.rs
@@ -7,19 +7,11 @@ use defmt_rtt as _;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_stm32::exti::ExtiInput; 8use embassy_stm32::exti::ExtiInput;
9use embassy_stm32::gpio::Pull; 9use embassy_stm32::gpio::Pull;
10use embassy_stm32::low_power::Executor; 10use embassy_stm32::low_power;
11use panic_probe as _; 11use panic_probe as _;
12use static_cell::StaticCell; 12use static_cell::StaticCell;
13 13
14#[cortex_m_rt::entry] 14#[embassy_executor::main(executor = "low_power::Executor")]
15fn main() -> ! {
16 info!("main: Starting!");
17 Executor::take().run(|spawner| {
18 spawner.spawn(unwrap!(async_main(spawner)));
19 });
20}
21
22#[embassy_executor::task]
23async fn async_main(_spawner: Spawner) { 15async fn async_main(_spawner: Spawner) {
24 let mut config = embassy_stm32::Config::default(); 16 let mut config = embassy_stm32::Config::default();
25 // enable HSI clock 17 // enable HSI clock
diff --git a/examples/stm32wle5/src/bin/i2c.rs b/examples/stm32wle5/src/bin/i2c.rs
index c31c673c9..68c17a672 100644
--- a/examples/stm32wle5/src/bin/i2c.rs
+++ b/examples/stm32wle5/src/bin/i2c.rs
@@ -6,9 +6,8 @@ use defmt::*;
6use defmt_rtt as _; 6use defmt_rtt as _;
7use embassy_executor::Spawner; 7use embassy_executor::Spawner;
8use embassy_stm32::i2c::I2c; 8use embassy_stm32::i2c::I2c;
9use embassy_stm32::low_power::Executor;
10use embassy_stm32::time::Hertz; 9use embassy_stm32::time::Hertz;
11use embassy_stm32::{bind_interrupts, i2c, peripherals}; 10use embassy_stm32::{bind_interrupts, i2c, low_power, peripherals};
12use embassy_time::{Duration, Timer}; 11use embassy_time::{Duration, Timer};
13use panic_probe as _; 12use panic_probe as _;
14use static_cell::StaticCell; 13use static_cell::StaticCell;
@@ -18,15 +17,7 @@ bind_interrupts!(struct IrqsI2C{
18 I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>; 17 I2C2_ER => i2c::ErrorInterruptHandler<peripherals::I2C2>;
19}); 18});
20 19
21#[cortex_m_rt::entry] 20#[embassy_executor::main(executor = "low_power::Executor")]
22fn main() -> ! {
23 info!("main: Starting!");
24 Executor::take().run(|spawner| {
25 spawner.spawn(unwrap!(async_main(spawner)));
26 });
27}
28
29#[embassy_executor::task]
30async fn async_main(_spawner: Spawner) { 21async fn async_main(_spawner: Spawner) {
31 let mut config = embassy_stm32::Config::default(); 22 let mut config = embassy_stm32::Config::default();
32 // enable HSI clock 23 // enable HSI clock