aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/nrf/.cargo/config.toml2
-rw-r--r--tests/nrf/Cargo.toml7
-rw-r--r--tests/nrf/src/bin/ethernet_enc28j60_perf.rs182
-rw-r--r--tests/nrf/src/bin/wifi_esp_hosted_perf.rs190
-rw-r--r--tests/perf-client/Cargo.toml12
-rw-r--r--tests/perf-client/src/lib.rs179
-rw-r--r--tests/riscv32/Cargo.toml4
-rw-r--r--tests/rp/.cargo/config.toml2
-rw-r--r--tests/rp/Cargo.toml5
-rw-r--r--tests/rp/src/bin/cyw43-perf.rs189
-rw-r--r--tests/rp/src/bin/ethernet_w5100s_perf.rs182
-rw-r--r--tests/rp/src/bin/i2c.rs212
-rw-r--r--tests/stm32/.cargo/config.toml7
-rw-r--r--tests/stm32/Cargo.toml18
-rw-r--r--tests/stm32/build.rs3
-rw-r--r--tests/stm32/src/bin/gpio.rs20
-rw-r--r--tests/stm32/src/bin/rtc.rs7
-rw-r--r--tests/stm32/src/bin/spi.rs22
-rw-r--r--tests/stm32/src/bin/spi_dma.rs24
-rw-r--r--tests/stm32/src/bin/stop.rs71
-rw-r--r--tests/stm32/src/bin/usart.rs95
-rw-r--r--tests/stm32/src/bin/usart_dma.rs53
-rw-r--r--tests/stm32/src/bin/usart_rx_ringbuffered.rs105
-rw-r--r--tests/stm32/src/common.rs205
24 files changed, 828 insertions, 968 deletions
diff --git a/tests/nrf/.cargo/config.toml b/tests/nrf/.cargo/config.toml
index 03995f963..9d6b0313a 100644
--- a/tests/nrf/.cargo/config.toml
+++ b/tests/nrf/.cargo/config.toml
@@ -6,4 +6,4 @@ runner = "teleprobe client run"
6target = "thumbv7em-none-eabi" 6target = "thumbv7em-none-eabi"
7 7
8[env] 8[env]
9DEFMT_LOG = "trace" 9DEFMT_LOG = "trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,smoltcp=info"
diff --git a/tests/nrf/Cargo.toml b/tests/nrf/Cargo.toml
index 4e31bed59..08fe1a4b5 100644
--- a/tests/nrf/Cargo.toml
+++ b/tests/nrf/Cargo.toml
@@ -8,9 +8,9 @@ license = "MIT OR Apache-2.0"
8teleprobe-meta = "1" 8teleprobe-meta = "1"
9 9
10embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 10embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
11embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt", "nightly"] } 11embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt", "nightly"] }
12embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "nightly", "integrated-timers"] } 12embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-cortex-m", "executor-thread", "defmt", "nightly", "integrated-timers"] }
13embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits", "defmt-timestamp-uptime"] } 13embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits", "defmt-timestamp-uptime"] }
14embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nightly", "unstable-traits", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] } 14embassy-nrf = { version = "0.1.0", path = "../../embassy-nrf", features = ["defmt", "nightly", "unstable-traits", "nrf52840", "time-driver-rtc1", "gpiote", "unstable-pac"] }
15embedded-io-async = { version = "0.5.0" } 15embedded-io-async = { version = "0.5.0" }
16embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] } 16embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4", "medium-ethernet", "nightly"] }
@@ -19,10 +19,11 @@ embassy-net-enc28j60 = { version = "0.1.0", path = "../../embassy-net-enc28j60",
19embedded-hal-async = { version = "1.0.0-rc.1" } 19embedded-hal-async = { version = "1.0.0-rc.1" }
20embedded-hal-bus = { version = "0.1.0-rc.1", features = ["async"] } 20embedded-hal-bus = { version = "0.1.0-rc.1", features = ["async"] }
21static_cell = { version = "1.1", features = [ "nightly" ] } 21static_cell = { version = "1.1", features = [ "nightly" ] }
22perf-client = { path = "../perf-client" }
22 23
23defmt = "0.3" 24defmt = "0.3"
24defmt-rtt = "0.4" 25defmt-rtt = "0.4"
25 26
26cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] } 27cortex-m = { version = "0.7.6", features = ["critical-section-single-core"] }
27cortex-m-rt = "0.7.0" 28cortex-m-rt = "0.7.0"
28panic-probe = { version = "0.3", features = ["print-defmt"] } \ No newline at end of file 29panic-probe = { version = "0.3", features = ["print-defmt"] }
diff --git a/tests/nrf/src/bin/ethernet_enc28j60_perf.rs b/tests/nrf/src/bin/ethernet_enc28j60_perf.rs
index 0446d39ac..60d30a2ff 100644
--- a/tests/nrf/src/bin/ethernet_enc28j60_perf.rs
+++ b/tests/nrf/src/bin/ethernet_enc28j60_perf.rs
@@ -4,17 +4,15 @@
4teleprobe_meta::target!(b"ak-gwe-r7"); 4teleprobe_meta::target!(b"ak-gwe-r7");
5teleprobe_meta::timeout!(120); 5teleprobe_meta::timeout!(120);
6 6
7use defmt::{error, info, unwrap}; 7use defmt::{info, unwrap};
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_futures::join::join; 9use embassy_net::{Stack, StackResources};
10use embassy_net::tcp::TcpSocket;
11use embassy_net::{Ipv4Address, Stack, StackResources};
12use embassy_net_enc28j60::Enc28j60; 10use embassy_net_enc28j60::Enc28j60;
13use embassy_nrf::gpio::{Level, Output, OutputDrive}; 11use embassy_nrf::gpio::{Level, Output, OutputDrive};
14use embassy_nrf::rng::Rng; 12use embassy_nrf::rng::Rng;
15use embassy_nrf::spim::{self, Spim}; 13use embassy_nrf::spim::{self, Spim};
16use embassy_nrf::{bind_interrupts, peripherals}; 14use embassy_nrf::{bind_interrupts, peripherals};
17use embassy_time::{with_timeout, Delay, Duration, Timer}; 15use embassy_time::Delay;
18use embedded_hal_bus::spi::ExclusiveDevice; 16use embedded_hal_bus::spi::ExclusiveDevice;
19use static_cell::make_static; 17use static_cell::make_static;
20use {defmt_rtt as _, panic_probe as _}; 18use {defmt_rtt as _, panic_probe as _};
@@ -79,172 +77,16 @@ async fn main(spawner: Spawner) {
79 77
80 unwrap!(spawner.spawn(net_task(stack))); 78 unwrap!(spawner.spawn(net_task(stack)));
81 79
82 info!("Waiting for DHCP up..."); 80 perf_client::run(
83 while stack.config_v4().is_none() { 81 stack,
84 Timer::after(Duration::from_millis(100)).await; 82 perf_client::Expected {
85 } 83 down_kbps: 200,
86 info!("IP addressing up!"); 84 up_kbps: 200,
87 85 updown_kbps: 150,
88 let down = test_download(stack).await; 86 },
89 let up = test_upload(stack).await; 87 )
90 let updown = test_upload_download(stack).await; 88 .await;
91
92 assert!(down > TEST_EXPECTED_DOWNLOAD_KBPS);
93 assert!(up > TEST_EXPECTED_UPLOAD_KBPS);
94 assert!(updown > TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS);
95 89
96 info!("Test OK"); 90 info!("Test OK");
97 cortex_m::asm::bkpt(); 91 cortex_m::asm::bkpt();
98} 92}
99
100const TEST_DURATION: usize = 10;
101const TEST_EXPECTED_DOWNLOAD_KBPS: usize = 200;
102const TEST_EXPECTED_UPLOAD_KBPS: usize = 200;
103const TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS: usize = 150;
104const RX_BUFFER_SIZE: usize = 4096;
105const TX_BUFFER_SIZE: usize = 4096;
106const SERVER_ADDRESS: Ipv4Address = Ipv4Address::new(192, 168, 2, 2);
107const DOWNLOAD_PORT: u16 = 4321;
108const UPLOAD_PORT: u16 = 4322;
109const UPLOAD_DOWNLOAD_PORT: u16 = 4323;
110
111async fn test_download(stack: &'static Stack<MyDriver>) -> usize {
112 info!("Testing download...");
113
114 let mut rx_buffer = [0; RX_BUFFER_SIZE];
115 let mut tx_buffer = [0; TX_BUFFER_SIZE];
116 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
117 socket.set_timeout(Some(Duration::from_secs(10)));
118
119 info!("connecting to {:?}:{}...", SERVER_ADDRESS, DOWNLOAD_PORT);
120 if let Err(e) = socket.connect((SERVER_ADDRESS, DOWNLOAD_PORT)).await {
121 error!("connect error: {:?}", e);
122 return 0;
123 }
124 info!("connected, testing...");
125
126 let mut rx_buf = [0; 4096];
127 let mut total: usize = 0;
128 with_timeout(Duration::from_secs(TEST_DURATION as _), async {
129 loop {
130 match socket.read(&mut rx_buf).await {
131 Ok(0) => {
132 error!("read EOF");
133 return 0;
134 }
135 Ok(n) => total += n,
136 Err(e) => {
137 error!("read error: {:?}", e);
138 return 0;
139 }
140 }
141 }
142 })
143 .await
144 .ok();
145
146 let kbps = (total + 512) / 1024 / TEST_DURATION;
147 info!("download: {} kB/s", kbps);
148 kbps
149}
150
151async fn test_upload(stack: &'static Stack<MyDriver>) -> usize {
152 info!("Testing upload...");
153
154 let mut rx_buffer = [0; RX_BUFFER_SIZE];
155 let mut tx_buffer = [0; TX_BUFFER_SIZE];
156 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
157 socket.set_timeout(Some(Duration::from_secs(10)));
158
159 info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_PORT);
160 if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_PORT)).await {
161 error!("connect error: {:?}", e);
162 return 0;
163 }
164 info!("connected, testing...");
165
166 let buf = [0; 4096];
167 let mut total: usize = 0;
168 with_timeout(Duration::from_secs(TEST_DURATION as _), async {
169 loop {
170 match socket.write(&buf).await {
171 Ok(0) => {
172 error!("write zero?!??!?!");
173 return 0;
174 }
175 Ok(n) => total += n,
176 Err(e) => {
177 error!("write error: {:?}", e);
178 return 0;
179 }
180 }
181 }
182 })
183 .await
184 .ok();
185
186 let kbps = (total + 512) / 1024 / TEST_DURATION;
187 info!("upload: {} kB/s", kbps);
188 kbps
189}
190
191async fn test_upload_download(stack: &'static Stack<MyDriver>) -> usize {
192 info!("Testing upload+download...");
193
194 let mut rx_buffer = [0; RX_BUFFER_SIZE];
195 let mut tx_buffer = [0; TX_BUFFER_SIZE];
196 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
197 socket.set_timeout(Some(Duration::from_secs(10)));
198
199 info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT);
200 if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT)).await {
201 error!("connect error: {:?}", e);
202 return 0;
203 }
204 info!("connected, testing...");
205
206 let (mut reader, mut writer) = socket.split();
207
208 let tx_buf = [0; 4096];
209 let mut rx_buf = [0; 4096];
210 let mut total: usize = 0;
211 let tx_fut = async {
212 loop {
213 match writer.write(&tx_buf).await {
214 Ok(0) => {
215 error!("write zero?!??!?!");
216 return 0;
217 }
218 Ok(_) => {}
219 Err(e) => {
220 error!("write error: {:?}", e);
221 return 0;
222 }
223 }
224 }
225 };
226
227 let rx_fut = async {
228 loop {
229 match reader.read(&mut rx_buf).await {
230 Ok(0) => {
231 error!("read EOF");
232 return 0;
233 }
234 Ok(n) => total += n,
235 Err(e) => {
236 error!("read error: {:?}", e);
237 return 0;
238 }
239 }
240 }
241 };
242
243 with_timeout(Duration::from_secs(TEST_DURATION as _), join(tx_fut, rx_fut))
244 .await
245 .ok();
246
247 let kbps = (total + 512) / 1024 / TEST_DURATION;
248 info!("upload+download: {} kB/s", kbps);
249 kbps
250}
diff --git a/tests/nrf/src/bin/wifi_esp_hosted_perf.rs b/tests/nrf/src/bin/wifi_esp_hosted_perf.rs
index 97ebafec8..9eee39ccf 100644
--- a/tests/nrf/src/bin/wifi_esp_hosted_perf.rs
+++ b/tests/nrf/src/bin/wifi_esp_hosted_perf.rs
@@ -4,16 +4,14 @@
4teleprobe_meta::target!(b"nrf52840-dk"); 4teleprobe_meta::target!(b"nrf52840-dk");
5teleprobe_meta::timeout!(120); 5teleprobe_meta::timeout!(120);
6 6
7use defmt::{error, info, unwrap}; 7use defmt::{info, unwrap};
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_futures::join::join; 9use embassy_net::{Config, Stack, StackResources};
10use embassy_net::tcp::TcpSocket;
11use embassy_net::{Config, Ipv4Address, Stack, StackResources};
12use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin, Pull}; 10use embassy_nrf::gpio::{AnyPin, Input, Level, Output, OutputDrive, Pin, Pull};
13use embassy_nrf::rng::Rng; 11use embassy_nrf::rng::Rng;
14use embassy_nrf::spim::{self, Spim}; 12use embassy_nrf::spim::{self, Spim};
15use embassy_nrf::{bind_interrupts, peripherals}; 13use embassy_nrf::{bind_interrupts, peripherals};
16use embassy_time::{with_timeout, Delay, Duration, Timer}; 14use embassy_time::Delay;
17use embedded_hal_bus::spi::ExclusiveDevice; 15use embedded_hal_bus::spi::ExclusiveDevice;
18use static_cell::make_static; 16use static_cell::make_static;
19use {defmt_rtt as _, embassy_net_esp_hosted as hosted, panic_probe as _}; 17use {defmt_rtt as _, embassy_net_esp_hosted as hosted, panic_probe as _};
@@ -23,6 +21,10 @@ bind_interrupts!(struct Irqs {
23 RNG => embassy_nrf::rng::InterruptHandler<peripherals::RNG>; 21 RNG => embassy_nrf::rng::InterruptHandler<peripherals::RNG>;
24}); 22});
25 23
24// Test-only wifi network, no internet access!
25const WIFI_NETWORK: &str = "EmbassyTest";
26const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud";
27
26#[embassy_executor::task] 28#[embassy_executor::task]
27async fn wifi_task( 29async fn wifi_task(
28 runner: hosted::Runner< 30 runner: hosted::Runner<
@@ -92,176 +94,16 @@ async fn main(spawner: Spawner) {
92 94
93 unwrap!(spawner.spawn(net_task(stack))); 95 unwrap!(spawner.spawn(net_task(stack)));
94 96
95 info!("Waiting for DHCP up..."); 97 perf_client::run(
96 while stack.config_v4().is_none() { 98 stack,
97 Timer::after(Duration::from_millis(100)).await; 99 perf_client::Expected {
98 } 100 down_kbps: 50,
99 info!("IP addressing up!"); 101 up_kbps: 50,
100 102 updown_kbps: 50,
101 let down = test_download(stack).await; 103 },
102 let up = test_upload(stack).await; 104 )
103 let updown = test_upload_download(stack).await; 105 .await;
104
105 assert!(down > TEST_EXPECTED_DOWNLOAD_KBPS);
106 assert!(up > TEST_EXPECTED_UPLOAD_KBPS);
107 assert!(updown > TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS);
108 106
109 info!("Test OK"); 107 info!("Test OK");
110 cortex_m::asm::bkpt(); 108 cortex_m::asm::bkpt();
111} 109}
112
113// Test-only wifi network, no internet access!
114const WIFI_NETWORK: &str = "EmbassyTest";
115const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud";
116
117const TEST_DURATION: usize = 10;
118const TEST_EXPECTED_DOWNLOAD_KBPS: usize = 50;
119const TEST_EXPECTED_UPLOAD_KBPS: usize = 50;
120const TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS: usize = 50;
121const RX_BUFFER_SIZE: usize = 4096;
122const TX_BUFFER_SIZE: usize = 4096;
123const SERVER_ADDRESS: Ipv4Address = Ipv4Address::new(192, 168, 2, 2);
124const DOWNLOAD_PORT: u16 = 4321;
125const UPLOAD_PORT: u16 = 4322;
126const UPLOAD_DOWNLOAD_PORT: u16 = 4323;
127
128async fn test_download(stack: &'static Stack<MyDriver>) -> usize {
129 info!("Testing download...");
130
131 let mut rx_buffer = [0; RX_BUFFER_SIZE];
132 let mut tx_buffer = [0; TX_BUFFER_SIZE];
133 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
134 socket.set_timeout(Some(Duration::from_secs(10)));
135
136 info!("connecting to {:?}:{}...", SERVER_ADDRESS, DOWNLOAD_PORT);
137 if let Err(e) = socket.connect((SERVER_ADDRESS, DOWNLOAD_PORT)).await {
138 error!("connect error: {:?}", e);
139 return 0;
140 }
141 info!("connected, testing...");
142
143 let mut rx_buf = [0; 4096];
144 let mut total: usize = 0;
145 with_timeout(Duration::from_secs(TEST_DURATION as _), async {
146 loop {
147 match socket.read(&mut rx_buf).await {
148 Ok(0) => {
149 error!("read EOF");
150 return 0;
151 }
152 Ok(n) => total += n,
153 Err(e) => {
154 error!("read error: {:?}", e);
155 return 0;
156 }
157 }
158 }
159 })
160 .await
161 .ok();
162
163 let kbps = (total + 512) / 1024 / TEST_DURATION;
164 info!("download: {} kB/s", kbps);
165 kbps
166}
167
168async fn test_upload(stack: &'static Stack<MyDriver>) -> usize {
169 info!("Testing upload...");
170
171 let mut rx_buffer = [0; RX_BUFFER_SIZE];
172 let mut tx_buffer = [0; TX_BUFFER_SIZE];
173 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
174 socket.set_timeout(Some(Duration::from_secs(10)));
175
176 info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_PORT);
177 if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_PORT)).await {
178 error!("connect error: {:?}", e);
179 return 0;
180 }
181 info!("connected, testing...");
182
183 let buf = [0; 4096];
184 let mut total: usize = 0;
185 with_timeout(Duration::from_secs(TEST_DURATION as _), async {
186 loop {
187 match socket.write(&buf).await {
188 Ok(0) => {
189 error!("write zero?!??!?!");
190 return 0;
191 }
192 Ok(n) => total += n,
193 Err(e) => {
194 error!("write error: {:?}", e);
195 return 0;
196 }
197 }
198 }
199 })
200 .await
201 .ok();
202
203 let kbps = (total + 512) / 1024 / TEST_DURATION;
204 info!("upload: {} kB/s", kbps);
205 kbps
206}
207
208async fn test_upload_download(stack: &'static Stack<MyDriver>) -> usize {
209 info!("Testing upload+download...");
210
211 let mut rx_buffer = [0; RX_BUFFER_SIZE];
212 let mut tx_buffer = [0; TX_BUFFER_SIZE];
213 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
214 socket.set_timeout(Some(Duration::from_secs(10)));
215
216 info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT);
217 if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT)).await {
218 error!("connect error: {:?}", e);
219 return 0;
220 }
221 info!("connected, testing...");
222
223 let (mut reader, mut writer) = socket.split();
224
225 let tx_buf = [0; 4096];
226 let mut rx_buf = [0; 4096];
227 let mut total: usize = 0;
228 let tx_fut = async {
229 loop {
230 match writer.write(&tx_buf).await {
231 Ok(0) => {
232 error!("write zero?!??!?!");
233 return 0;
234 }
235 Ok(_) => {}
236 Err(e) => {
237 error!("write error: {:?}", e);
238 return 0;
239 }
240 }
241 }
242 };
243
244 let rx_fut = async {
245 loop {
246 match reader.read(&mut rx_buf).await {
247 Ok(0) => {
248 error!("read EOF");
249 return 0;
250 }
251 Ok(n) => total += n,
252 Err(e) => {
253 error!("read error: {:?}", e);
254 return 0;
255 }
256 }
257 }
258 };
259
260 with_timeout(Duration::from_secs(TEST_DURATION as _), join(tx_fut, rx_fut))
261 .await
262 .ok();
263
264 let kbps = (total + 512) / 1024 / TEST_DURATION;
265 info!("upload+download: {} kB/s", kbps);
266 kbps
267}
diff --git a/tests/perf-client/Cargo.toml b/tests/perf-client/Cargo.toml
new file mode 100644
index 000000000..3284664d9
--- /dev/null
+++ b/tests/perf-client/Cargo.toml
@@ -0,0 +1,12 @@
1[package]
2name = "perf-client"
3version = "0.1.0"
4edition = "2021"
5
6# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7
8[dependencies]
9embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "tcp", "dhcpv4"] }
10embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits"] }
11embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
12defmt = "0.3.0"
diff --git a/tests/perf-client/src/lib.rs b/tests/perf-client/src/lib.rs
new file mode 100644
index 000000000..a36147dbb
--- /dev/null
+++ b/tests/perf-client/src/lib.rs
@@ -0,0 +1,179 @@
1#![no_std]
2
3use defmt::{assert, *};
4use embassy_futures::join::join;
5use embassy_net::driver::Driver;
6use embassy_net::tcp::TcpSocket;
7use embassy_net::{Ipv4Address, Stack};
8use embassy_time::{with_timeout, Duration, Timer};
9
10pub struct Expected {
11 pub down_kbps: usize,
12 pub up_kbps: usize,
13 pub updown_kbps: usize,
14}
15
16pub async fn run<D: Driver>(stack: &Stack<D>, expected: Expected) {
17 info!("Waiting for DHCP up...");
18 while stack.config_v4().is_none() {
19 Timer::after(Duration::from_millis(100)).await;
20 }
21 info!("IP addressing up!");
22
23 let down = test_download(stack).await;
24 let up = test_upload(stack).await;
25 let updown = test_upload_download(stack).await;
26
27 assert!(down > expected.down_kbps);
28 assert!(up > expected.up_kbps);
29 assert!(updown > expected.updown_kbps);
30}
31
32const TEST_DURATION: usize = 10;
33const RX_BUFFER_SIZE: usize = 4096;
34const TX_BUFFER_SIZE: usize = 4096;
35const SERVER_ADDRESS: Ipv4Address = Ipv4Address::new(192, 168, 2, 2);
36const DOWNLOAD_PORT: u16 = 4321;
37const UPLOAD_PORT: u16 = 4322;
38const UPLOAD_DOWNLOAD_PORT: u16 = 4323;
39
40async fn test_download<D: Driver>(stack: &Stack<D>) -> usize {
41 info!("Testing download...");
42
43 let mut rx_buffer = [0; RX_BUFFER_SIZE];
44 let mut tx_buffer = [0; TX_BUFFER_SIZE];
45 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
46 socket.set_timeout(Some(Duration::from_secs(10)));
47
48 info!("connecting to {:?}:{}...", SERVER_ADDRESS, DOWNLOAD_PORT);
49 if let Err(e) = socket.connect((SERVER_ADDRESS, DOWNLOAD_PORT)).await {
50 error!("connect error: {:?}", e);
51 return 0;
52 }
53 info!("connected, testing...");
54
55 let mut rx_buf = [0; 4096];
56 let mut total: usize = 0;
57 with_timeout(Duration::from_secs(TEST_DURATION as _), async {
58 loop {
59 match socket.read(&mut rx_buf).await {
60 Ok(0) => {
61 error!("read EOF");
62 return 0;
63 }
64 Ok(n) => total += n,
65 Err(e) => {
66 error!("read error: {:?}", e);
67 return 0;
68 }
69 }
70 }
71 })
72 .await
73 .ok();
74
75 let kbps = (total + 512) / 1024 / TEST_DURATION;
76 info!("download: {} kB/s", kbps);
77 kbps
78}
79
80async fn test_upload<D: Driver>(stack: &Stack<D>) -> usize {
81 info!("Testing upload...");
82
83 let mut rx_buffer = [0; RX_BUFFER_SIZE];
84 let mut tx_buffer = [0; TX_BUFFER_SIZE];
85 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
86 socket.set_timeout(Some(Duration::from_secs(10)));
87
88 info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_PORT);
89 if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_PORT)).await {
90 error!("connect error: {:?}", e);
91 return 0;
92 }
93 info!("connected, testing...");
94
95 let buf = [0; 4096];
96 let mut total: usize = 0;
97 with_timeout(Duration::from_secs(TEST_DURATION as _), async {
98 loop {
99 match socket.write(&buf).await {
100 Ok(0) => {
101 error!("write zero?!??!?!");
102 return 0;
103 }
104 Ok(n) => total += n,
105 Err(e) => {
106 error!("write error: {:?}", e);
107 return 0;
108 }
109 }
110 }
111 })
112 .await
113 .ok();
114
115 let kbps = (total + 512) / 1024 / TEST_DURATION;
116 info!("upload: {} kB/s", kbps);
117 kbps
118}
119
120async fn test_upload_download<D: Driver>(stack: &Stack<D>) -> usize {
121 info!("Testing upload+download...");
122
123 let mut rx_buffer = [0; RX_BUFFER_SIZE];
124 let mut tx_buffer = [0; TX_BUFFER_SIZE];
125 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
126 socket.set_timeout(Some(Duration::from_secs(10)));
127
128 info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT);
129 if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT)).await {
130 error!("connect error: {:?}", e);
131 return 0;
132 }
133 info!("connected, testing...");
134
135 let (mut reader, mut writer) = socket.split();
136
137 let tx_buf = [0; 4096];
138 let mut rx_buf = [0; 4096];
139 let mut total: usize = 0;
140 let tx_fut = async {
141 loop {
142 match writer.write(&tx_buf).await {
143 Ok(0) => {
144 error!("write zero?!??!?!");
145 return 0;
146 }
147 Ok(_) => {}
148 Err(e) => {
149 error!("write error: {:?}", e);
150 return 0;
151 }
152 }
153 }
154 };
155
156 let rx_fut = async {
157 loop {
158 match reader.read(&mut rx_buf).await {
159 Ok(0) => {
160 error!("read EOF");
161 return 0;
162 }
163 Ok(n) => total += n,
164 Err(e) => {
165 error!("read error: {:?}", e);
166 return 0;
167 }
168 }
169 }
170 };
171
172 with_timeout(Duration::from_secs(TEST_DURATION as _), join(tx_fut, rx_fut))
173 .await
174 .ok();
175
176 let kbps = (total + 512) / 1024 / TEST_DURATION;
177 info!("upload+download: {} kB/s", kbps);
178 kbps
179}
diff --git a/tests/riscv32/Cargo.toml b/tests/riscv32/Cargo.toml
index be610b1c5..490f037b9 100644
--- a/tests/riscv32/Cargo.toml
+++ b/tests/riscv32/Cargo.toml
@@ -6,9 +6,9 @@ license = "MIT OR Apache-2.0"
6 6
7[dependencies] 7[dependencies]
8critical-section = { version = "1.1.1", features = ["restore-state-bool"] } 8critical-section = { version = "1.1.1", features = ["restore-state-bool"] }
9embassy-sync = { version = "0.2.0", path = "../../embassy-sync" } 9embassy-sync = { version = "0.3.0", path = "../../embassy-sync" }
10embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-riscv32", "nightly", "executor-thread"] } 10embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["arch-riscv32", "nightly", "executor-thread"] }
11embassy-time = { version = "0.1.2", path = "../../embassy-time" } 11embassy-time = { version = "0.1.3", path = "../../embassy-time" }
12embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 12embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
13 13
14riscv-rt = "0.11" 14riscv-rt = "0.11"
diff --git a/tests/rp/.cargo/config.toml b/tests/rp/.cargo/config.toml
index bc92e788b..40b5d7000 100644
--- a/tests/rp/.cargo/config.toml
+++ b/tests/rp/.cargo/config.toml
@@ -19,4 +19,4 @@ rustflags = [
19target = "thumbv6m-none-eabi" 19target = "thumbv6m-none-eabi"
20 20
21[env] 21[env]
22DEFMT_LOG = "trace" 22DEFMT_LOG = "trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,cyw43=info,cyw43_pio=info,smoltcp=info"
diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml
index c494b66ee..8bb0de6c6 100644
--- a/tests/rp/Cargo.toml
+++ b/tests/rp/Cargo.toml
@@ -7,15 +7,16 @@ license = "MIT OR Apache-2.0"
7[dependencies] 7[dependencies]
8teleprobe-meta = "1.1" 8teleprobe-meta = "1.1"
9 9
10embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 10embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] }
11embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 11embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
12embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits"] } 12embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits"] }
13embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] } 13embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["nightly", "defmt", "unstable-pac", "unstable-traits", "time-driver", "critical-section-impl", "intrinsics", "rom-v2-intrinsics", "run-from-ram"] }
14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 14embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
15embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } 15embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] }
16embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } 16embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] }
17cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } 17cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] }
18cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] } 18cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] }
19perf-client = { path = "../perf-client" }
19 20
20defmt = "0.3.0" 21defmt = "0.3.0"
21defmt-rtt = "0.4" 22defmt-rtt = "0.4"
diff --git a/tests/rp/src/bin/cyw43-perf.rs b/tests/rp/src/bin/cyw43-perf.rs
index 1c665f95d..de29c06dd 100644
--- a/tests/rp/src/bin/cyw43-perf.rs
+++ b/tests/rp/src/bin/cyw43-perf.rs
@@ -4,16 +4,13 @@
4teleprobe_meta::target!(b"rpi-pico"); 4teleprobe_meta::target!(b"rpi-pico");
5 5
6use cyw43_pio::PioSpi; 6use cyw43_pio::PioSpi;
7use defmt::{assert, panic, *}; 7use defmt::{panic, *};
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_futures::join::join; 9use embassy_net::{Config, Stack, StackResources};
10use embassy_net::tcp::TcpSocket;
11use embassy_net::{Config, Ipv4Address, Stack, StackResources};
12use embassy_rp::gpio::{Level, Output}; 10use embassy_rp::gpio::{Level, Output};
13use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0}; 11use embassy_rp::peripherals::{DMA_CH0, PIN_23, PIN_25, PIO0};
14use embassy_rp::pio::{InterruptHandler, Pio}; 12use embassy_rp::pio::{InterruptHandler, Pio};
15use embassy_rp::{bind_interrupts, rom_data}; 13use embassy_rp::{bind_interrupts, rom_data};
16use embassy_time::{with_timeout, Duration, Timer};
17use static_cell::make_static; 14use static_cell::make_static;
18use {defmt_rtt as _, panic_probe as _}; 15use {defmt_rtt as _, panic_probe as _};
19 16
@@ -23,6 +20,10 @@ bind_interrupts!(struct Irqs {
23 20
24teleprobe_meta::timeout!(120); 21teleprobe_meta::timeout!(120);
25 22
23// Test-only wifi network, no internet access!
24const WIFI_NETWORK: &str = "EmbassyTest";
25const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud";
26
26#[embassy_executor::task] 27#[embassy_executor::task]
27async fn wifi_task( 28async fn wifi_task(
28 runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>, 29 runner: cyw43::Runner<'static, Output<'static, PIN_23>, PioSpi<'static, PIN_25, PIO0, 0, DMA_CH0>>,
@@ -88,176 +89,16 @@ async fn main(spawner: Spawner) {
88 } 89 }
89 } 90 }
90 91
91 info!("Waiting for DHCP up..."); 92 perf_client::run(
92 while stack.config_v4().is_none() { 93 stack,
93 Timer::after(Duration::from_millis(100)).await; 94 perf_client::Expected {
94 } 95 down_kbps: 300,
95 info!("IP addressing up!"); 96 up_kbps: 300,
96 97 updown_kbps: 300,
97 let down = test_download(stack).await; 98 },
98 let up = test_upload(stack).await; 99 )
99 let updown = test_upload_download(stack).await; 100 .await;
100
101 assert!(down > TEST_EXPECTED_DOWNLOAD_KBPS);
102 assert!(up > TEST_EXPECTED_UPLOAD_KBPS);
103 assert!(updown > TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS);
104 101
105 info!("Test OK"); 102 info!("Test OK");
106 cortex_m::asm::bkpt(); 103 cortex_m::asm::bkpt();
107} 104}
108
109// Test-only wifi network, no internet access!
110const WIFI_NETWORK: &str = "EmbassyTest";
111const WIFI_PASSWORD: &str = "V8YxhKt5CdIAJFud";
112
113const TEST_DURATION: usize = 10;
114const TEST_EXPECTED_DOWNLOAD_KBPS: usize = 300;
115const TEST_EXPECTED_UPLOAD_KBPS: usize = 300;
116const TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS: usize = 300;
117const RX_BUFFER_SIZE: usize = 4096;
118const TX_BUFFER_SIZE: usize = 4096;
119const SERVER_ADDRESS: Ipv4Address = Ipv4Address::new(192, 168, 2, 2);
120const DOWNLOAD_PORT: u16 = 4321;
121const UPLOAD_PORT: u16 = 4322;
122const UPLOAD_DOWNLOAD_PORT: u16 = 4323;
123
124async fn test_download(stack: &'static Stack<cyw43::NetDriver<'static>>) -> usize {
125 info!("Testing download...");
126
127 let mut rx_buffer = [0; RX_BUFFER_SIZE];
128 let mut tx_buffer = [0; TX_BUFFER_SIZE];
129 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
130 socket.set_timeout(Some(Duration::from_secs(10)));
131
132 info!("connecting to {:?}:{}...", SERVER_ADDRESS, DOWNLOAD_PORT);
133 if let Err(e) = socket.connect((SERVER_ADDRESS, DOWNLOAD_PORT)).await {
134 error!("connect error: {:?}", e);
135 return 0;
136 }
137 info!("connected, testing...");
138
139 let mut rx_buf = [0; 4096];
140 let mut total: usize = 0;
141 with_timeout(Duration::from_secs(TEST_DURATION as _), async {
142 loop {
143 match socket.read(&mut rx_buf).await {
144 Ok(0) => {
145 error!("read EOF");
146 return 0;
147 }
148 Ok(n) => total += n,
149 Err(e) => {
150 error!("read error: {:?}", e);
151 return 0;
152 }
153 }
154 }
155 })
156 .await
157 .ok();
158
159 let kbps = (total + 512) / 1024 / TEST_DURATION;
160 info!("download: {} kB/s", kbps);
161 kbps
162}
163
164async fn test_upload(stack: &'static Stack<cyw43::NetDriver<'static>>) -> usize {
165 info!("Testing upload...");
166
167 let mut rx_buffer = [0; RX_BUFFER_SIZE];
168 let mut tx_buffer = [0; TX_BUFFER_SIZE];
169 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
170 socket.set_timeout(Some(Duration::from_secs(10)));
171
172 info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_PORT);
173 if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_PORT)).await {
174 error!("connect error: {:?}", e);
175 return 0;
176 }
177 info!("connected, testing...");
178
179 let buf = [0; 4096];
180 let mut total: usize = 0;
181 with_timeout(Duration::from_secs(TEST_DURATION as _), async {
182 loop {
183 match socket.write(&buf).await {
184 Ok(0) => {
185 error!("write zero?!??!?!");
186 return 0;
187 }
188 Ok(n) => total += n,
189 Err(e) => {
190 error!("write error: {:?}", e);
191 return 0;
192 }
193 }
194 }
195 })
196 .await
197 .ok();
198
199 let kbps = (total + 512) / 1024 / TEST_DURATION;
200 info!("upload: {} kB/s", kbps);
201 kbps
202}
203
204async fn test_upload_download(stack: &'static Stack<cyw43::NetDriver<'static>>) -> usize {
205 info!("Testing upload+download...");
206
207 let mut rx_buffer = [0; RX_BUFFER_SIZE];
208 let mut tx_buffer = [0; TX_BUFFER_SIZE];
209 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
210 socket.set_timeout(Some(Duration::from_secs(10)));
211
212 info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT);
213 if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT)).await {
214 error!("connect error: {:?}", e);
215 return 0;
216 }
217 info!("connected, testing...");
218
219 let (mut reader, mut writer) = socket.split();
220
221 let tx_buf = [0; 4096];
222 let mut rx_buf = [0; 4096];
223 let mut total: usize = 0;
224 let tx_fut = async {
225 loop {
226 match writer.write(&tx_buf).await {
227 Ok(0) => {
228 error!("write zero?!??!?!");
229 return 0;
230 }
231 Ok(_) => {}
232 Err(e) => {
233 error!("write error: {:?}", e);
234 return 0;
235 }
236 }
237 }
238 };
239
240 let rx_fut = async {
241 loop {
242 match reader.read(&mut rx_buf).await {
243 Ok(0) => {
244 error!("read EOF");
245 return 0;
246 }
247 Ok(n) => total += n,
248 Err(e) => {
249 error!("read error: {:?}", e);
250 return 0;
251 }
252 }
253 }
254 };
255
256 with_timeout(Duration::from_secs(TEST_DURATION as _), join(tx_fut, rx_fut))
257 .await
258 .ok();
259
260 let kbps = (total + 512) / 1024 / TEST_DURATION;
261 info!("upload+download: {} kB/s", kbps);
262 kbps
263}
diff --git a/tests/rp/src/bin/ethernet_w5100s_perf.rs b/tests/rp/src/bin/ethernet_w5100s_perf.rs
index faa8638c0..a4d253b3c 100644
--- a/tests/rp/src/bin/ethernet_w5100s_perf.rs
+++ b/tests/rp/src/bin/ethernet_w5100s_perf.rs
@@ -4,18 +4,16 @@
4teleprobe_meta::target!(b"w5100s-evb-pico"); 4teleprobe_meta::target!(b"w5100s-evb-pico");
5teleprobe_meta::timeout!(120); 5teleprobe_meta::timeout!(120);
6 6
7use defmt::{assert, *}; 7use defmt::*;
8use embassy_executor::Spawner; 8use embassy_executor::Spawner;
9use embassy_futures::join::join; 9use embassy_net::{Stack, StackResources};
10use embassy_net::tcp::TcpSocket;
11use embassy_net::{Ipv4Address, Stack, StackResources};
12use embassy_net_wiznet::chip::W5100S; 10use embassy_net_wiznet::chip::W5100S;
13use embassy_net_wiznet::*; 11use embassy_net_wiznet::*;
14use embassy_rp::clocks::RoscRng; 12use embassy_rp::clocks::RoscRng;
15use embassy_rp::gpio::{Input, Level, Output, Pull}; 13use embassy_rp::gpio::{Input, Level, Output, Pull};
16use embassy_rp::peripherals::{PIN_17, PIN_20, PIN_21, SPI0}; 14use embassy_rp::peripherals::{PIN_17, PIN_20, PIN_21, SPI0};
17use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; 15use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
18use embassy_time::{with_timeout, Delay, Duration, Timer}; 16use embassy_time::Delay;
19use embedded_hal_bus::spi::ExclusiveDevice; 17use embedded_hal_bus::spi::ExclusiveDevice;
20use rand::RngCore; 18use rand::RngCore;
21use static_cell::make_static; 19use static_cell::make_static;
@@ -78,172 +76,16 @@ async fn main(spawner: Spawner) {
78 // Launch network task 76 // Launch network task
79 unwrap!(spawner.spawn(net_task(&stack))); 77 unwrap!(spawner.spawn(net_task(&stack)));
80 78
81 info!("Waiting for DHCP up..."); 79 perf_client::run(
82 while stack.config_v4().is_none() { 80 stack,
83 Timer::after(Duration::from_millis(100)).await; 81 perf_client::Expected {
84 } 82 down_kbps: 500,
85 info!("IP addressing up!"); 83 up_kbps: 500,
86 84 updown_kbps: 300,
87 let down = test_download(stack).await; 85 },
88 let up = test_upload(stack).await; 86 )
89 let updown = test_upload_download(stack).await; 87 .await;
90
91 assert!(down > TEST_EXPECTED_DOWNLOAD_KBPS);
92 assert!(up > TEST_EXPECTED_UPLOAD_KBPS);
93 assert!(updown > TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS);
94 88
95 info!("Test OK"); 89 info!("Test OK");
96 cortex_m::asm::bkpt(); 90 cortex_m::asm::bkpt();
97} 91}
98
99const TEST_DURATION: usize = 10;
100const TEST_EXPECTED_DOWNLOAD_KBPS: usize = 500;
101const TEST_EXPECTED_UPLOAD_KBPS: usize = 500;
102const TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS: usize = 300;
103const RX_BUFFER_SIZE: usize = 4096;
104const TX_BUFFER_SIZE: usize = 4096;
105const SERVER_ADDRESS: Ipv4Address = Ipv4Address::new(192, 168, 2, 2);
106const DOWNLOAD_PORT: u16 = 4321;
107const UPLOAD_PORT: u16 = 4322;
108const UPLOAD_DOWNLOAD_PORT: u16 = 4323;
109
110async fn test_download(stack: &'static Stack<cyw43::NetDriver<'static>>) -> usize {
111 info!("Testing download...");
112
113 let mut rx_buffer = [0; RX_BUFFER_SIZE];
114 let mut tx_buffer = [0; TX_BUFFER_SIZE];
115 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
116 socket.set_timeout(Some(Duration::from_secs(10)));
117
118 info!("connecting to {:?}:{}...", SERVER_ADDRESS, DOWNLOAD_PORT);
119 if let Err(e) = socket.connect((SERVER_ADDRESS, DOWNLOAD_PORT)).await {
120 error!("connect error: {:?}", e);
121 return 0;
122 }
123 info!("connected, testing...");
124
125 let mut rx_buf = [0; 4096];
126 let mut total: usize = 0;
127 with_timeout(Duration::from_secs(TEST_DURATION as _), async {
128 loop {
129 match socket.read(&mut rx_buf).await {
130 Ok(0) => {
131 error!("read EOF");
132 return 0;
133 }
134 Ok(n) => total += n,
135 Err(e) => {
136 error!("read error: {:?}", e);
137 return 0;
138 }
139 }
140 }
141 })
142 .await
143 .ok();
144
145 let kbps = (total + 512) / 1024 / TEST_DURATION;
146 info!("download: {} kB/s", kbps);
147 kbps
148}
149
150async fn test_upload(stack: &'static Stack<cyw43::NetDriver<'static>>) -> usize {
151 info!("Testing upload...");
152
153 let mut rx_buffer = [0; RX_BUFFER_SIZE];
154 let mut tx_buffer = [0; TX_BUFFER_SIZE];
155 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
156 socket.set_timeout(Some(Duration::from_secs(10)));
157
158 info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_PORT);
159 if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_PORT)).await {
160 error!("connect error: {:?}", e);
161 return 0;
162 }
163 info!("connected, testing...");
164
165 let buf = [0; 4096];
166 let mut total: usize = 0;
167 with_timeout(Duration::from_secs(TEST_DURATION as _), async {
168 loop {
169 match socket.write(&buf).await {
170 Ok(0) => {
171 error!("write zero?!??!?!");
172 return 0;
173 }
174 Ok(n) => total += n,
175 Err(e) => {
176 error!("write error: {:?}", e);
177 return 0;
178 }
179 }
180 }
181 })
182 .await
183 .ok();
184
185 let kbps = (total + 512) / 1024 / TEST_DURATION;
186 info!("upload: {} kB/s", kbps);
187 kbps
188}
189
190async fn test_upload_download(stack: &'static Stack<cyw43::NetDriver<'static>>) -> usize {
191 info!("Testing upload+download...");
192
193 let mut rx_buffer = [0; RX_BUFFER_SIZE];
194 let mut tx_buffer = [0; TX_BUFFER_SIZE];
195 let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
196 socket.set_timeout(Some(Duration::from_secs(10)));
197
198 info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT);
199 if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT)).await {
200 error!("connect error: {:?}", e);
201 return 0;
202 }
203 info!("connected, testing...");
204
205 let (mut reader, mut writer) = socket.split();
206
207 let tx_buf = [0; 4096];
208 let mut rx_buf = [0; 4096];
209 let mut total: usize = 0;
210 let tx_fut = async {
211 loop {
212 match writer.write(&tx_buf).await {
213 Ok(0) => {
214 error!("write zero?!??!?!");
215 return 0;
216 }
217 Ok(_) => {}
218 Err(e) => {
219 error!("write error: {:?}", e);
220 return 0;
221 }
222 }
223 }
224 };
225
226 let rx_fut = async {
227 loop {
228 match reader.read(&mut rx_buf).await {
229 Ok(0) => {
230 error!("read EOF");
231 return 0;
232 }
233 Ok(n) => total += n,
234 Err(e) => {
235 error!("read error: {:?}", e);
236 return 0;
237 }
238 }
239 }
240 };
241
242 with_timeout(Duration::from_secs(TEST_DURATION as _), join(tx_fut, rx_fut))
243 .await
244 .ok();
245
246 let kbps = (total + 512) / 1024 / TEST_DURATION;
247 info!("upload+download: {} kB/s", kbps);
248 kbps
249}
diff --git a/tests/rp/src/bin/i2c.rs b/tests/rp/src/bin/i2c.rs
new file mode 100644
index 000000000..425f2d086
--- /dev/null
+++ b/tests/rp/src/bin/i2c.rs
@@ -0,0 +1,212 @@
1#![no_std]
2#![no_main]
3#![feature(type_alias_impl_trait)]
4teleprobe_meta::target!(b"rpi-pico");
5
6use defmt::{assert_eq, info, panic, unwrap};
7use embassy_executor::Executor;
8use embassy_executor::_export::StaticCell;
9use embassy_rp::multicore::{spawn_core1, Stack};
10use embassy_rp::peripherals::{I2C0, I2C1};
11use embassy_rp::{bind_interrupts, i2c, i2c_slave};
12use embedded_hal_1::i2c::Operation;
13use embedded_hal_async::i2c::I2c;
14use {defmt_rtt as _, panic_probe as _, panic_probe as _, panic_probe as _};
15
16static mut CORE1_STACK: Stack<1024> = Stack::new();
17static EXECUTOR0: StaticCell<Executor> = StaticCell::new();
18static EXECUTOR1: StaticCell<Executor> = StaticCell::new();
19
20use crate::i2c::AbortReason;
21
22bind_interrupts!(struct Irqs {
23 I2C0_IRQ => i2c::InterruptHandler<I2C0>;
24 I2C1_IRQ => i2c::InterruptHandler<I2C1>;
25});
26
27const DEV_ADDR: u8 = 0x42;
28
29#[embassy_executor::task]
30async fn device_task(mut dev: i2c_slave::I2cSlave<'static, I2C1>) -> ! {
31 info!("Device start");
32
33 let mut count = 0xD0;
34
35 loop {
36 let mut buf = [0u8; 128];
37 match dev.listen(&mut buf).await {
38 Ok(i2c_slave::Command::GeneralCall(len)) => {
39 assert_eq!(buf[..len], [0xCA, 0x11], "recieving the general call failed");
40 info!("General Call - OK");
41 }
42 Ok(i2c_slave::Command::Read) => {
43 loop {
44 match dev.respond_to_read(&[count]).await {
45 Ok(x) => match x {
46 i2c_slave::ReadStatus::Done => break,
47 i2c_slave::ReadStatus::NeedMoreBytes => count += 1,
48 i2c_slave::ReadStatus::LeftoverBytes(x) => {
49 info!("tried to write {} extra bytes", x);
50 break;
51 }
52 },
53 Err(e) => match e {
54 embassy_rp::i2c_slave::Error::Abort(AbortReason::Other(n)) => panic!("Other {:b}", n),
55 _ => panic!("{}", e),
56 },
57 }
58 }
59 count += 1;
60 }
61 Ok(i2c_slave::Command::Write(len)) => match len {
62 1 => {
63 assert_eq!(buf[..len], [0xAA], "recieving a single byte failed");
64 info!("Single Byte Write - OK")
65 }
66 4 => {
67 assert_eq!(buf[..len], [0xAA, 0xBB, 0xCC, 0xDD], "recieving 4 bytes failed");
68 info!("4 Byte Write - OK")
69 }
70 32 => {
71 assert_eq!(
72 buf[..len],
73 [
74 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
75 25, 26, 27, 28, 29, 30, 31
76 ],
77 "recieving 32 bytes failed"
78 );
79 info!("32 Byte Write - OK")
80 }
81 _ => panic!("Invalid write length {}", len),
82 },
83 Ok(i2c_slave::Command::WriteRead(len)) => {
84 info!("device recieved write read: {:x}", buf[..len]);
85 match buf[0] {
86 0xC2 => {
87 let resp_buff = [0xD1, 0xD2, 0xD3, 0xD4];
88 dev.respond_to_read(&resp_buff).await.unwrap();
89 }
90 0xC8 => {
91 let mut resp_buff = [0u8; 32];
92 for i in 0..32 {
93 resp_buff[i] = i as u8;
94 }
95 dev.respond_to_read(&resp_buff).await.unwrap();
96 }
97 x => panic!("Invalid Write Read {:x}", x),
98 }
99 }
100 Err(e) => match e {
101 embassy_rp::i2c_slave::Error::Abort(AbortReason::Other(n)) => panic!("Other {:b}", n),
102 _ => panic!("{}", e),
103 },
104 }
105 }
106}
107
108#[embassy_executor::task]
109async fn controller_task(mut con: i2c::I2c<'static, I2C0, i2c::Async>) {
110 info!("Device start");
111
112 {
113 let buf = [0xCA, 0x11];
114 con.write(0u16, &buf).await.unwrap();
115 info!("Controler general call write");
116 embassy_futures::yield_now().await;
117 }
118
119 {
120 let mut buf = [0u8];
121 con.read(DEV_ADDR, &mut buf).await.unwrap();
122 assert_eq!(buf, [0xD0], "single byte read failed");
123 info!("single byte read - OK");
124 embassy_futures::yield_now().await;
125 }
126
127 {
128 let mut buf = [0u8; 4];
129 con.read(DEV_ADDR, &mut buf).await.unwrap();
130 assert_eq!(buf, [0xD1, 0xD2, 0xD3, 0xD4], "single byte read failed");
131 info!("4 byte read - OK");
132 embassy_futures::yield_now().await;
133 }
134
135 {
136 let buf = [0xAA];
137 con.write(DEV_ADDR, &buf).await.unwrap();
138 info!("Controler single byte write");
139 embassy_futures::yield_now().await;
140 }
141
142 {
143 let buf = [0xAA, 0xBB, 0xCC, 0xDD];
144 con.write(DEV_ADDR, &buf).await.unwrap();
145 info!("Controler 4 byte write");
146 embassy_futures::yield_now().await;
147 }
148
149 {
150 let mut buf = [0u8; 32];
151 for i in 0..32 {
152 buf[i] = i as u8;
153 }
154 con.write(DEV_ADDR, &buf).await.unwrap();
155 info!("Controler 32 byte write");
156 embassy_futures::yield_now().await;
157 }
158
159 {
160 let mut buf = [0u8; 4];
161 let mut ops = [Operation::Write(&[0xC2]), Operation::Read(&mut buf)];
162 con.transaction(DEV_ADDR, &mut ops).await.unwrap();
163 assert_eq!(buf, [0xD1, 0xD2, 0xD3, 0xD4], "write_read failed");
164 info!("write_read - OK");
165 embassy_futures::yield_now().await;
166 }
167
168 {
169 let mut buf = [0u8; 32];
170 let mut ops = [Operation::Write(&[0xC8]), Operation::Read(&mut buf)];
171 con.transaction(DEV_ADDR, &mut ops).await.unwrap();
172 assert_eq!(
173 buf,
174 [
175 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
176 28, 29, 30, 31
177 ],
178 "write_read of 32 bytes failed"
179 );
180 info!("large write_read - OK")
181 }
182
183 info!("Test OK");
184 cortex_m::asm::bkpt();
185}
186
187#[cortex_m_rt::entry]
188fn main() -> ! {
189 let p = embassy_rp::init(Default::default());
190 info!("Hello World!");
191
192 let d_sda = p.PIN_19;
193 let d_scl = p.PIN_18;
194 let mut config = i2c_slave::Config::default();
195 config.addr = DEV_ADDR as u16;
196 let device = i2c_slave::I2cSlave::new(p.I2C1, d_sda, d_scl, Irqs, config);
197
198 spawn_core1(p.CORE1, unsafe { &mut CORE1_STACK }, move || {
199 let executor1 = EXECUTOR1.init(Executor::new());
200 executor1.run(|spawner| unwrap!(spawner.spawn(device_task(device))));
201 });
202
203 let executor0 = EXECUTOR0.init(Executor::new());
204
205 let c_sda = p.PIN_21;
206 let c_scl = p.PIN_20;
207 let mut config = i2c::Config::default();
208 config.frequency = 5_000;
209 let controller = i2c::I2c::new_async(p.I2C0, c_sda, c_scl, Irqs, config);
210
211 executor0.run(|spawner| unwrap!(spawner.spawn(controller_task(controller))));
212}
diff --git a/tests/stm32/.cargo/config.toml b/tests/stm32/.cargo/config.toml
index 07761b01c..2e3f055d4 100644
--- a/tests/stm32/.cargo/config.toml
+++ b/tests/stm32/.cargo/config.toml
@@ -14,7 +14,10 @@ rustflags = [
14] 14]
15 15
16[build] 16[build]
17target = "thumbv7m-none-eabi" 17target = "thumbv6m-none-eabi"
18#target = "thumbv7m-none-eabi"
19#target = "thumbv7em-none-eabi"
20#target = "thumbv8m.main-none-eabihf"
18 21
19[env] 22[env]
20DEFMT_LOG = "trace" \ No newline at end of file 23DEFMT_LOG = "trace,embassy_hal_internal=debug,embassy_net_esp_hosted=debug,smoltcp=info" \ No newline at end of file
diff --git a/tests/stm32/Cargo.toml b/tests/stm32/Cargo.toml
index 754356cb5..bfe5bc823 100644
--- a/tests/stm32/Cargo.toml
+++ b/tests/stm32/Cargo.toml
@@ -7,7 +7,7 @@ autobins = false
7 7
8[features] 8[features]
9stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] # Blue Pill 9stm32f103c8 = ["embassy-stm32/stm32f103c8", "not-gpdma"] # Blue Pill
10stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "can", "not-gpdma", "dac-adc-pin"] # Nucleo "sdmmc" 10stm32f429zi = ["embassy-stm32/stm32f429zi", "chrono", "stop", "can", "not-gpdma", "dac-adc-pin"] # Nucleo "sdmmc"
11stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] # Nucleo 11stm32g071rb = ["embassy-stm32/stm32g071rb", "not-gpdma", "dac-adc-pin"] # Nucleo
12stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo 12stm32c031c6 = ["embassy-stm32/stm32c031c6", "not-gpdma"] # Nucleo
13stm32g491re = ["embassy-stm32/stm32g491re", "not-gpdma"] # Nucleo 13stm32g491re = ["embassy-stm32/stm32g491re", "not-gpdma"] # Nucleo
@@ -15,8 +15,14 @@ stm32h755zi = ["embassy-stm32/stm32h755zi-cm7", "not-gpdma", "dac-adc-pin"] # Nu
15stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma", "ble", "mac" ] # Nucleo 15stm32wb55rg = ["embassy-stm32/stm32wb55rg", "not-gpdma", "ble", "mac" ] # Nucleo
16stm32h563zi = ["embassy-stm32/stm32h563zi"] # Nucleo 16stm32h563zi = ["embassy-stm32/stm32h563zi"] # Nucleo
17stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board 17stm32u585ai = ["embassy-stm32/stm32u585ai"] # IoT board
18stm32l073rz = ["embassy-stm32/stm32l073rz", "not-gpdma"] # Nucleo
19stm32l152re = ["embassy-stm32/stm32l152re", "not-gpdma"] # Nucleo
20stm32l4a6zg = ["embassy-stm32/stm32l4a6zg", "not-gpdma"] # Nucleo
21stm32l4r5zi = ["embassy-stm32/stm32l4r5zi", "not-gpdma"] # Nucleo
22stm32l552ze = ["embassy-stm32/stm32l552ze", "not-gpdma"] # Nucleo
18 23
19sdmmc = [] 24sdmmc = []
25stop = ["embassy-stm32/low-power"]
20chrono = ["embassy-stm32/chrono", "dep:chrono"] 26chrono = ["embassy-stm32/chrono", "dep:chrono"]
21can = [] 27can = []
22ble = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/ble"] 28ble = ["dep:embassy-stm32-wpan", "embassy-stm32-wpan/ble"]
@@ -28,9 +34,9 @@ dac-adc-pin = []
28[dependencies] 34[dependencies]
29teleprobe-meta = "1" 35teleprobe-meta = "1"
30 36
31embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } 37embassy-sync = { version = "0.3.0", path = "../../embassy-sync", features = ["defmt"] }
32embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } 38embassy-executor = { version = "0.3.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] }
33embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "tick-hz-32_768", "defmt-timestamp-uptime"] } 39embassy-time = { version = "0.1.3", path = "../../embassy-time", features = ["defmt", "tick-hz-32_768", "defmt-timestamp-uptime"] }
34embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "memory-x", "time-driver-any"] } 40embassy-stm32 = { version = "0.1.0", path = "../../embassy-stm32", features = ["nightly", "defmt", "unstable-pac", "memory-x", "time-driver-any"] }
35embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } 41embassy-futures = { version = "0.1.0", path = "../../embassy-futures" }
36embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] } 42embassy-stm32-wpan = { version = "0.1.0", path = "../../embassy-stm32-wpan", optional = true, features = ["defmt", "stm32wb55rg", "ble"] }
@@ -47,6 +53,7 @@ micromath = "2.0.0"
47panic-probe = { version = "0.3.0", features = ["print-defmt"] } 53panic-probe = { version = "0.3.0", features = ["print-defmt"] }
48rand_core = { version = "0.6", default-features = false } 54rand_core = { version = "0.6", default-features = false }
49rand_chacha = { version = "0.3", default-features = false } 55rand_chacha = { version = "0.3", default-features = false }
56static_cell = {version = "1.1", features = ["nightly"] }
50 57
51chrono = { version = "^0.4", default-features = false, optional = true} 58chrono = { version = "^0.4", default-features = false, optional = true}
52 59
@@ -88,6 +95,11 @@ path = "src/bin/spi_dma.rs"
88required-features = [] 95required-features = []
89 96
90[[bin]] 97[[bin]]
98name = "stop"
99path = "src/bin/stop.rs"
100required-features = [ "stop", "chrono",]
101
102[[bin]]
91name = "timer" 103name = "timer"
92path = "src/bin/timer.rs" 104path = "src/bin/timer.rs"
93required-features = [] 105required-features = []
diff --git a/tests/stm32/build.rs b/tests/stm32/build.rs
index 2e71954d7..9aabf8541 100644
--- a/tests/stm32/build.rs
+++ b/tests/stm32/build.rs
@@ -12,7 +12,8 @@ fn main() -> Result<(), Box<dyn Error>> {
12 if cfg!(any( 12 if cfg!(any(
13 feature = "stm32f103c8", 13 feature = "stm32f103c8",
14 feature = "stm32c031c6", 14 feature = "stm32c031c6",
15 feature = "stm32wb55rg" 15 feature = "stm32wb55rg",
16 feature = "stm32l073rz",
16 )) { 17 )) {
17 println!("cargo:rustc-link-arg-bins=-Tlink.x"); 18 println!("cargo:rustc-link-arg-bins=-Tlink.x");
18 println!("cargo:rerun-if-changed=link.x"); 19 println!("cargo:rerun-if-changed=link.x");
diff --git a/tests/stm32/src/bin/gpio.rs b/tests/stm32/src/bin/gpio.rs
index aad174431..49d9a60f7 100644
--- a/tests/stm32/src/bin/gpio.rs
+++ b/tests/stm32/src/bin/gpio.rs
@@ -16,24 +16,8 @@ async fn main(_spawner: Spawner) {
16 16
17 // Arduino pins D0 and D1 17 // Arduino pins D0 and D1
18 // They're connected together with a 1K resistor. 18 // They're connected together with a 1K resistor.
19 #[cfg(feature = "stm32f103c8")] 19 let mut a = peri!(p, UART_RX);
20 let (mut a, mut b) = (p.PA9, p.PA10); 20 let mut b = peri!(p, UART_TX);
21 #[cfg(feature = "stm32g491re")]
22 let (mut a, mut b) = (p.PC4, p.PC5);
23 #[cfg(feature = "stm32g071rb")]
24 let (mut a, mut b) = (p.PC4, p.PC5);
25 #[cfg(feature = "stm32f429zi")]
26 let (mut a, mut b) = (p.PG14, p.PG9);
27 #[cfg(feature = "stm32wb55rg")]
28 let (mut a, mut b) = (p.PA3, p.PA2);
29 #[cfg(feature = "stm32h755zi")]
30 let (mut a, mut b) = (p.PB6, p.PB7);
31 #[cfg(feature = "stm32u585ai")]
32 let (mut a, mut b) = (p.PD9, p.PD8);
33 #[cfg(feature = "stm32h563zi")]
34 let (mut a, mut b) = (p.PB6, p.PB7);
35 #[cfg(feature = "stm32c031c6")]
36 let (mut a, mut b) = (p.PB6, p.PB7);
37 21
38 // Test initial output 22 // Test initial output
39 { 23 {
diff --git a/tests/stm32/src/bin/rtc.rs b/tests/stm32/src/bin/rtc.rs
index 7df415b44..22be6fac5 100644
--- a/tests/stm32/src/bin/rtc.rs
+++ b/tests/stm32/src/bin/rtc.rs
@@ -10,14 +10,17 @@ use chrono::{NaiveDate, NaiveDateTime};
10use common::*; 10use common::*;
11use defmt::assert; 11use defmt::assert;
12use embassy_executor::Spawner; 12use embassy_executor::Spawner;
13use embassy_stm32::rtc::{Rtc, RtcClockSource, RtcConfig}; 13use embassy_stm32::rcc::RtcClockSource;
14use embassy_stm32::rtc::{Rtc, RtcConfig};
15use embassy_stm32::time::Hertz;
14use embassy_time::{Duration, Timer}; 16use embassy_time::{Duration, Timer};
15 17
16#[embassy_executor::main] 18#[embassy_executor::main]
17async fn main(_spawner: Spawner) { 19async fn main(_spawner: Spawner) {
18 let mut config = config(); 20 let mut config = config();
19 21
20 config.rcc.rtc = Some(RtcClockSource::LSI); 22 config.rcc.lse = Some(Hertz(32_768));
23 config.rcc.rtc = Some(RtcClockSource::LSE);
21 24
22 let p = embassy_stm32::init(config); 25 let p = embassy_stm32::init(config);
23 info!("Hello World!"); 26 info!("Hello World!");
diff --git a/tests/stm32/src/bin/spi.rs b/tests/stm32/src/bin/spi.rs
index e51dd5bf2..b0fb75d69 100644
--- a/tests/stm32/src/bin/spi.rs
+++ b/tests/stm32/src/bin/spi.rs
@@ -16,24 +16,10 @@ async fn main(_spawner: Spawner) {
16 let p = embassy_stm32::init(config()); 16 let p = embassy_stm32::init(config());
17 info!("Hello World!"); 17 info!("Hello World!");
18 18
19 #[cfg(feature = "stm32f103c8")] 19 let spi = peri!(p, SPI);
20 let (spi, sck, mosi, miso) = (p.SPI1, p.PA5, p.PA7, p.PA6); 20 let sck = peri!(p, SPI_SCK);
21 #[cfg(feature = "stm32f429zi")] 21 let mosi = peri!(p, SPI_MOSI);
22 let (spi, sck, mosi, miso) = (p.SPI1, p.PA5, p.PA7, p.PA6); 22 let miso = peri!(p, SPI_MISO);
23 #[cfg(feature = "stm32h755zi")]
24 let (spi, sck, mosi, miso) = (p.SPI1, p.PA5, p.PB5, p.PA6);
25 #[cfg(feature = "stm32g491re")]
26 let (spi, sck, mosi, miso) = (p.SPI1, p.PA5, p.PA7, p.PA6);
27 #[cfg(feature = "stm32g071rb")]
28 let (spi, sck, mosi, miso) = (p.SPI1, p.PA5, p.PA7, p.PA6);
29 #[cfg(feature = "stm32wb55rg")]
30 let (spi, sck, mosi, miso) = (p.SPI1, p.PA5, p.PA7, p.PA6);
31 #[cfg(feature = "stm32u585ai")]
32 let (spi, sck, mosi, miso) = (p.SPI1, p.PE13, p.PE15, p.PE14);
33 #[cfg(feature = "stm32h563zi")]
34 let (spi, sck, mosi, miso) = (p.SPI4, p.PE12, p.PE14, p.PE13);
35 #[cfg(feature = "stm32c031c6")]
36 let (spi, sck, mosi, miso) = (p.SPI1, p.PA5, p.PA7, p.PA6);
37 23
38 let mut spi_config = spi::Config::default(); 24 let mut spi_config = spi::Config::default();
39 spi_config.frequency = Hertz(1_000_000); 25 spi_config.frequency = Hertz(1_000_000);
diff --git a/tests/stm32/src/bin/spi_dma.rs b/tests/stm32/src/bin/spi_dma.rs
index d45cbe45b..212cfae5d 100644
--- a/tests/stm32/src/bin/spi_dma.rs
+++ b/tests/stm32/src/bin/spi_dma.rs
@@ -15,24 +15,12 @@ async fn main(_spawner: Spawner) {
15 let p = embassy_stm32::init(config()); 15 let p = embassy_stm32::init(config());
16 info!("Hello World!"); 16 info!("Hello World!");
17 17
18 #[cfg(feature = "stm32f103c8")] 18 let spi = peri!(p, SPI);
19 let (spi, sck, mosi, miso, tx_dma, rx_dma) = (p.SPI1, p.PA5, p.PA7, p.PA6, p.DMA1_CH3, p.DMA1_CH2); 19 let sck = peri!(p, SPI_SCK);
20 #[cfg(feature = "stm32f429zi")] 20 let mosi = peri!(p, SPI_MOSI);
21 let (spi, sck, mosi, miso, tx_dma, rx_dma) = (p.SPI1, p.PA5, p.PA7, p.PA6, p.DMA2_CH3, p.DMA2_CH2); 21 let miso = peri!(p, SPI_MISO);
22 #[cfg(feature = "stm32h755zi")] 22 let tx_dma = peri!(p, SPI_TX_DMA);
23 let (spi, sck, mosi, miso, tx_dma, rx_dma) = (p.SPI1, p.PA5, p.PB5, p.PA6, p.DMA1_CH0, p.DMA1_CH1); 23 let rx_dma = peri!(p, SPI_RX_DMA);
24 #[cfg(feature = "stm32g491re")]
25 let (spi, sck, mosi, miso, tx_dma, rx_dma) = (p.SPI1, p.PA5, p.PA7, p.PA6, p.DMA1_CH1, p.DMA1_CH2);
26 #[cfg(feature = "stm32g071rb")]
27 let (spi, sck, mosi, miso, tx_dma, rx_dma) = (p.SPI1, p.PA5, p.PA7, p.PA6, p.DMA1_CH1, p.DMA1_CH2);
28 #[cfg(feature = "stm32wb55rg")]
29 let (spi, sck, mosi, miso, tx_dma, rx_dma) = (p.SPI1, p.PA5, p.PA7, p.PA6, p.DMA1_CH1, p.DMA1_CH2);
30 #[cfg(feature = "stm32u585ai")]
31 let (spi, sck, mosi, miso, tx_dma, rx_dma) = (p.SPI1, p.PE13, p.PE15, p.PE14, p.GPDMA1_CH0, p.GPDMA1_CH1);
32 #[cfg(feature = "stm32h563zi")]
33 let (spi, sck, mosi, miso, tx_dma, rx_dma) = (p.SPI4, p.PE12, p.PE14, p.PE13, p.GPDMA1_CH0, p.GPDMA1_CH1);
34 #[cfg(feature = "stm32c031c6")]
35 let (spi, sck, mosi, miso, tx_dma, rx_dma) = (p.SPI1, p.PA5, p.PA7, p.PA6, p.DMA1_CH1, p.DMA1_CH2);
36 24
37 let mut spi_config = spi::Config::default(); 25 let mut spi_config = spi::Config::default();
38 spi_config.frequency = Hertz(1_000_000); 26 spi_config.frequency = Hertz(1_000_000);
diff --git a/tests/stm32/src/bin/stop.rs b/tests/stm32/src/bin/stop.rs
new file mode 100644
index 000000000..48d59b794
--- /dev/null
+++ b/tests/stm32/src/bin/stop.rs
@@ -0,0 +1,71 @@
1// required-features: stop,chrono
2
3#![no_std]
4#![no_main]
5#![feature(type_alias_impl_trait)]
6#[path = "../common.rs"]
7mod common;
8
9use chrono::NaiveDate;
10use common::*;
11use cortex_m_rt::entry;
12use embassy_executor::Spawner;
13use embassy_stm32::low_power::{stop_with_rtc, Executor};
14use embassy_stm32::rcc::RtcClockSource;
15use embassy_stm32::rtc::{Rtc, RtcConfig};
16use embassy_stm32::time::Hertz;
17use embassy_time::{Duration, Timer};
18use static_cell::make_static;
19
20#[entry]
21fn main() -> ! {
22 Executor::take().run(|spawner| {
23 unwrap!(spawner.spawn(async_main(spawner)));
24 });
25}
26
27#[embassy_executor::task]
28async fn task_1() {
29 for _ in 0..9 {
30 info!("task 1: waiting for 500ms...");
31 Timer::after(Duration::from_millis(500)).await;
32 }
33}
34
35#[embassy_executor::task]
36async fn task_2() {
37 for _ in 0..5 {
38 info!("task 2: waiting for 1000ms...");
39 Timer::after(Duration::from_millis(1000)).await;
40 }
41
42 info!("Test OK");
43 cortex_m::asm::bkpt();
44}
45
46#[embassy_executor::task]
47async fn async_main(spawner: Spawner) {
48 let mut config = config();
49
50 config.rcc.lse = Some(Hertz(32_768));
51 config.rcc.rtc = Some(RtcClockSource::LSE);
52
53 let p = embassy_stm32::init(config);
54 info!("Hello World!");
55
56 let now = NaiveDate::from_ymd_opt(2020, 5, 15)
57 .unwrap()
58 .and_hms_opt(10, 30, 15)
59 .unwrap();
60
61 let mut rtc = Rtc::new(p.RTC, RtcConfig::default());
62
63 rtc.set_datetime(now.into()).expect("datetime not set");
64
65 let rtc = make_static!(rtc);
66
67 stop_with_rtc(rtc);
68
69 spawner.spawn(task_1()).unwrap();
70 spawner.spawn(task_2()).unwrap();
71}
diff --git a/tests/stm32/src/bin/usart.rs b/tests/stm32/src/bin/usart.rs
index 394005b82..74a81b4ec 100644
--- a/tests/stm32/src/bin/usart.rs
+++ b/tests/stm32/src/bin/usart.rs
@@ -5,38 +5,11 @@
5mod common; 5mod common;
6 6
7use common::*; 7use common::*;
8use defmt::assert_eq; 8use defmt::{assert, assert_eq, unreachable};
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_stm32::dma::NoDma; 10use embassy_stm32::dma::NoDma;
11use embassy_stm32::usart::{Config, Error, Uart}; 11use embassy_stm32::usart::{Config, ConfigError, Error, Uart};
12use embassy_stm32::{bind_interrupts, peripherals, usart}; 12use embassy_time::{block_for, Duration, Instant};
13use embassy_time::{Duration, Instant};
14
15#[cfg(any(
16 feature = "stm32f103c8",
17 feature = "stm32g491re",
18 feature = "stm32g071rb",
19 feature = "stm32h755zi",
20 feature = "stm32c031c6",
21))]
22bind_interrupts!(struct Irqs {
23 USART1 => usart::InterruptHandler<peripherals::USART1>;
24});
25
26#[cfg(feature = "stm32u585ai")]
27bind_interrupts!(struct Irqs {
28 USART3 => usart::InterruptHandler<peripherals::USART3>;
29});
30
31#[cfg(feature = "stm32f429zi")]
32bind_interrupts!(struct Irqs {
33 USART6 => usart::InterruptHandler<peripherals::USART6>;
34});
35
36#[cfg(any(feature = "stm32wb55rg", feature = "stm32h563zi"))]
37bind_interrupts!(struct Irqs {
38 LPUART1 => usart::InterruptHandler<peripherals::LPUART1>;
39});
40 13
41#[embassy_executor::main] 14#[embassy_executor::main]
42async fn main(_spawner: Spawner) { 15async fn main(_spawner: Spawner) {
@@ -45,28 +18,14 @@ async fn main(_spawner: Spawner) {
45 18
46 // Arduino pins D0 and D1 19 // Arduino pins D0 and D1
47 // They're connected together with a 1K resistor. 20 // They're connected together with a 1K resistor.
48 #[cfg(feature = "stm32f103c8")] 21 let mut usart = peri!(p, UART);
49 let (mut tx, mut rx, mut usart) = (p.PA9, p.PA10, p.USART1); 22 let mut rx = peri!(p, UART_RX);
50 #[cfg(feature = "stm32g491re")] 23 let mut tx = peri!(p, UART_TX);
51 let (mut tx, mut rx, mut usart) = (p.PC4, p.PC5, p.USART1); 24 let irq = irqs!(UART);
52 #[cfg(feature = "stm32g071rb")]
53 let (mut tx, mut rx, mut usart) = (p.PC4, p.PC5, p.USART1);
54 #[cfg(feature = "stm32f429zi")]
55 let (mut tx, mut rx, mut usart) = (p.PG14, p.PG9, p.USART6);
56 #[cfg(feature = "stm32wb55rg")]
57 let (mut tx, mut rx, mut usart) = (p.PA2, p.PA3, p.LPUART1);
58 #[cfg(feature = "stm32h755zi")]
59 let (mut tx, mut rx, mut usart) = (p.PB6, p.PB7, p.USART1);
60 #[cfg(feature = "stm32u585ai")]
61 let (mut tx, mut rx, mut usart) = (p.PD8, p.PD9, p.USART3);
62 #[cfg(feature = "stm32h563zi")]
63 let (mut tx, mut rx, mut usart) = (p.PB6, p.PB7, p.LPUART1);
64 #[cfg(feature = "stm32c031c6")]
65 let (mut tx, mut rx, mut usart) = (p.PB6, p.PB7, p.USART1);
66 25
67 { 26 {
68 let config = Config::default(); 27 let config = Config::default();
69 let mut usart = Uart::new(&mut usart, &mut rx, &mut tx, Irqs, NoDma, NoDma, config); 28 let mut usart = Uart::new(&mut usart, &mut rx, &mut tx, irq, NoDma, NoDma, config).unwrap();
70 29
71 // We can't send too many bytes, they have to fit in the FIFO. 30 // We can't send too many bytes, they have to fit in the FIFO.
72 // This is because we aren't sending+receiving at the same time. 31 // This is because we aren't sending+receiving at the same time.
@@ -82,13 +41,19 @@ async fn main(_spawner: Spawner) {
82 // Test error handling with with an overflow error 41 // Test error handling with with an overflow error
83 { 42 {
84 let config = Config::default(); 43 let config = Config::default();
85 let mut usart = Uart::new(&mut usart, &mut rx, &mut tx, Irqs, NoDma, NoDma, config); 44 let mut usart = Uart::new(&mut usart, &mut rx, &mut tx, irq, NoDma, NoDma, config).unwrap();
86 45
87 // Send enough bytes to fill the RX FIFOs off all USART versions. 46 // Send enough bytes to fill the RX FIFOs off all USART versions.
88 let data = [0xC0, 0xDE, 0x12, 0x23, 0x34]; 47 let data = [0; 64];
89 usart.blocking_write(&data).unwrap(); 48 usart.blocking_write(&data).unwrap();
90 usart.blocking_flush().unwrap(); 49 usart.blocking_flush().unwrap();
91 50
51 // USART can still take up to 1 bit time (?) to receive the last byte
52 // that we just flushed, so wait a bit.
53 // otherwise, we might clear the overrun flag from an *earlier* byte and
54 // it gets set again when receiving the last byte is done.
55 block_for(Duration::from_millis(1));
56
92 // The error should be reported first. 57 // The error should be reported first.
93 let mut buf = [0; 1]; 58 let mut buf = [0; 1];
94 let err = usart.blocking_read(&mut buf); 59 let err = usart.blocking_read(&mut buf);
@@ -101,22 +66,25 @@ async fn main(_spawner: Spawner) {
101 66
102 // Test that baudrate divider is calculated correctly. 67 // Test that baudrate divider is calculated correctly.
103 // Do it by comparing the time it takes to send a known number of bytes. 68 // Do it by comparing the time it takes to send a known number of bytes.
104 for baudrate in [ 69 for baudrate in [300, 9600, 115200, 250_000, 337_934, 1_000_000, 2_000_000] {
105 300,
106 9600,
107 115200,
108 250_000,
109 337_934,
110 #[cfg(not(feature = "stm32f103c8"))]
111 1_000_000,
112 #[cfg(not(feature = "stm32f103c8"))]
113 2_000_000,
114 ] {
115 info!("testing baudrate {}", baudrate); 70 info!("testing baudrate {}", baudrate);
116 71
117 let mut config = Config::default(); 72 let mut config = Config::default();
118 config.baudrate = baudrate; 73 config.baudrate = baudrate;
119 let mut usart = Uart::new(&mut usart, &mut rx, &mut tx, Irqs, NoDma, NoDma, config); 74 let mut usart = match Uart::new(&mut usart, &mut rx, &mut tx, irq, NoDma, NoDma, config) {
75 Ok(x) => x,
76 Err(ConfigError::BaudrateTooHigh) => {
77 info!("baudrate too high");
78 assert!(baudrate >= 1_000_000);
79 continue;
80 }
81 Err(ConfigError::BaudrateTooLow) => {
82 info!("baudrate too low");
83 assert!(baudrate <= 300);
84 continue;
85 }
86 Err(_) => unreachable!(),
87 };
120 88
121 let n = (baudrate as usize / 100).max(64); 89 let n = (baudrate as usize / 100).max(64);
122 90
@@ -124,6 +92,7 @@ async fn main(_spawner: Spawner) {
124 for _ in 0..n { 92 for _ in 0..n {
125 usart.blocking_write(&[0x00]).unwrap(); 93 usart.blocking_write(&[0x00]).unwrap();
126 } 94 }
95 usart.blocking_flush().unwrap();
127 let dur = Instant::now() - start; 96 let dur = Instant::now() - start;
128 let want_dur = Duration::from_micros(n as u64 * 10 * 1_000_000 / (baudrate as u64)); 97 let want_dur = Duration::from_micros(n as u64 * 10 * 1_000_000 / (baudrate as u64));
129 let fuzz = want_dur / 5; 98 let fuzz = want_dur / 5;
diff --git a/tests/stm32/src/bin/usart_dma.rs b/tests/stm32/src/bin/usart_dma.rs
index c34d9574b..1421f6605 100644
--- a/tests/stm32/src/bin/usart_dma.rs
+++ b/tests/stm32/src/bin/usart_dma.rs
@@ -9,33 +9,6 @@ use defmt::assert_eq;
9use embassy_executor::Spawner; 9use embassy_executor::Spawner;
10use embassy_futures::join::join; 10use embassy_futures::join::join;
11use embassy_stm32::usart::{Config, Uart}; 11use embassy_stm32::usart::{Config, Uart};
12use embassy_stm32::{bind_interrupts, peripherals, usart};
13
14#[cfg(any(
15 feature = "stm32f103c8",
16 feature = "stm32g491re",
17 feature = "stm32g071rb",
18 feature = "stm32h755zi",
19 feature = "stm32c031c6",
20))]
21bind_interrupts!(struct Irqs {
22 USART1 => usart::InterruptHandler<peripherals::USART1>;
23});
24
25#[cfg(feature = "stm32u585ai")]
26bind_interrupts!(struct Irqs {
27 USART3 => usart::InterruptHandler<peripherals::USART3>;
28});
29
30#[cfg(feature = "stm32f429zi")]
31bind_interrupts!(struct Irqs {
32 USART6 => usart::InterruptHandler<peripherals::USART6>;
33});
34
35#[cfg(any(feature = "stm32wb55rg", feature = "stm32h563zi"))]
36bind_interrupts!(struct Irqs {
37 LPUART1 => usart::InterruptHandler<peripherals::LPUART1>;
38});
39 12
40#[embassy_executor::main] 13#[embassy_executor::main]
41async fn main(_spawner: Spawner) { 14async fn main(_spawner: Spawner) {
@@ -44,27 +17,15 @@ async fn main(_spawner: Spawner) {
44 17
45 // Arduino pins D0 and D1 18 // Arduino pins D0 and D1
46 // They're connected together with a 1K resistor. 19 // They're connected together with a 1K resistor.
47 #[cfg(feature = "stm32f103c8")] 20 let usart = peri!(p, UART);
48 let (tx, rx, usart, irq, tx_dma, rx_dma) = (p.PA9, p.PA10, p.USART1, Irqs, p.DMA1_CH4, p.DMA1_CH5); 21 let rx = peri!(p, UART_RX);
49 #[cfg(feature = "stm32g491re")] 22 let tx = peri!(p, UART_TX);
50 let (tx, rx, usart, irq, tx_dma, rx_dma) = (p.PC4, p.PC5, p.USART1, Irqs, p.DMA1_CH1, p.DMA1_CH2); 23 let rx_dma = peri!(p, UART_RX_DMA);
51 #[cfg(feature = "stm32g071rb")] 24 let tx_dma = peri!(p, UART_TX_DMA);
52 let (tx, rx, usart, irq, tx_dma, rx_dma) = (p.PC4, p.PC5, p.USART1, Irqs, p.DMA1_CH1, p.DMA1_CH2); 25 let irq = irqs!(UART);
53 #[cfg(feature = "stm32f429zi")]
54 let (tx, rx, usart, irq, tx_dma, rx_dma) = (p.PG14, p.PG9, p.USART6, Irqs, p.DMA2_CH6, p.DMA2_CH1);
55 #[cfg(feature = "stm32wb55rg")]
56 let (tx, rx, usart, irq, tx_dma, rx_dma) = (p.PA2, p.PA3, p.LPUART1, Irqs, p.DMA1_CH1, p.DMA1_CH2);
57 #[cfg(feature = "stm32h755zi")]
58 let (tx, rx, usart, irq, tx_dma, rx_dma) = (p.PB6, p.PB7, p.USART1, Irqs, p.DMA1_CH0, p.DMA1_CH1);
59 #[cfg(feature = "stm32u585ai")]
60 let (tx, rx, usart, irq, tx_dma, rx_dma) = (p.PD8, p.PD9, p.USART3, Irqs, p.GPDMA1_CH0, p.GPDMA1_CH1);
61 #[cfg(feature = "stm32h563zi")]
62 let (tx, rx, usart, irq, tx_dma, rx_dma) = (p.PB6, p.PB7, p.LPUART1, Irqs, p.GPDMA1_CH0, p.GPDMA1_CH1);
63 #[cfg(feature = "stm32c031c6")]
64 let (tx, rx, usart, irq, tx_dma, rx_dma) = (p.PB6, p.PB7, p.USART1, Irqs, p.DMA1_CH1, p.DMA1_CH2);
65 26
66 let config = Config::default(); 27 let config = Config::default();
67 let usart = Uart::new(usart, rx, tx, irq, tx_dma, rx_dma, config); 28 let usart = Uart::new(usart, rx, tx, irq, tx_dma, rx_dma, config).unwrap();
68 29
69 const LEN: usize = 128; 30 const LEN: usize = 128;
70 let mut tx_buf = [0; LEN]; 31 let mut tx_buf = [0; LEN];
diff --git a/tests/stm32/src/bin/usart_rx_ringbuffered.rs b/tests/stm32/src/bin/usart_rx_ringbuffered.rs
index c8dd2643b..1ee7e596d 100644
--- a/tests/stm32/src/bin/usart_rx_ringbuffered.rs
+++ b/tests/stm32/src/bin/usart_rx_ringbuffered.rs
@@ -10,87 +10,10 @@ use common::*;
10use defmt::{assert_eq, panic}; 10use defmt::{assert_eq, panic};
11use embassy_executor::Spawner; 11use embassy_executor::Spawner;
12use embassy_stm32::usart::{Config, DataBits, Parity, RingBufferedUartRx, StopBits, Uart, UartTx}; 12use embassy_stm32::usart::{Config, DataBits, Parity, RingBufferedUartRx, StopBits, Uart, UartTx};
13use embassy_stm32::{bind_interrupts, peripherals, usart};
14use embassy_time::{Duration, Timer}; 13use embassy_time::{Duration, Timer};
15use rand_chacha::ChaCha8Rng; 14use rand_chacha::ChaCha8Rng;
16use rand_core::{RngCore, SeedableRng}; 15use rand_core::{RngCore, SeedableRng};
17 16
18#[cfg(any(
19 feature = "stm32f103c8",
20 feature = "stm32g491re",
21 feature = "stm32g071rb",
22 feature = "stm32h755zi",
23 feature = "stm32c031c6",
24))]
25bind_interrupts!(struct Irqs {
26 USART1 => usart::InterruptHandler<peripherals::USART1>;
27});
28
29#[cfg(feature = "stm32u585ai")]
30bind_interrupts!(struct Irqs {
31 USART3 => usart::InterruptHandler<peripherals::USART3>;
32});
33
34#[cfg(feature = "stm32f429zi")]
35bind_interrupts!(struct Irqs {
36 USART1 => usart::InterruptHandler<peripherals::USART1>;
37 USART6 => usart::InterruptHandler<peripherals::USART6>;
38});
39
40#[cfg(any(feature = "stm32wb55rg", feature = "stm32h563zi"))]
41bind_interrupts!(struct Irqs {
42 LPUART1 => usart::InterruptHandler<peripherals::LPUART1>;
43});
44
45#[cfg(feature = "stm32f103c8")]
46mod board {
47 pub type Uart = embassy_stm32::peripherals::USART1;
48 pub type TxDma = embassy_stm32::peripherals::DMA1_CH4;
49 pub type RxDma = embassy_stm32::peripherals::DMA1_CH5;
50}
51#[cfg(feature = "stm32g491re")]
52mod board {
53 pub type Uart = embassy_stm32::peripherals::USART1;
54 pub type TxDma = embassy_stm32::peripherals::DMA1_CH1;
55 pub type RxDma = embassy_stm32::peripherals::DMA1_CH2;
56}
57#[cfg(feature = "stm32g071rb")]
58mod board {
59 pub type Uart = embassy_stm32::peripherals::USART1;
60 pub type TxDma = embassy_stm32::peripherals::DMA1_CH1;
61 pub type RxDma = embassy_stm32::peripherals::DMA1_CH2;
62}
63#[cfg(feature = "stm32f429zi")]
64mod board {
65 pub type Uart = embassy_stm32::peripherals::USART6;
66 pub type TxDma = embassy_stm32::peripherals::DMA2_CH6;
67 pub type RxDma = embassy_stm32::peripherals::DMA2_CH1;
68}
69#[cfg(feature = "stm32wb55rg")]
70mod board {
71 pub type Uart = embassy_stm32::peripherals::LPUART1;
72 pub type TxDma = embassy_stm32::peripherals::DMA1_CH1;
73 pub type RxDma = embassy_stm32::peripherals::DMA1_CH2;
74}
75#[cfg(feature = "stm32h755zi")]
76mod board {
77 pub type Uart = embassy_stm32::peripherals::USART1;
78 pub type TxDma = embassy_stm32::peripherals::DMA1_CH0;
79 pub type RxDma = embassy_stm32::peripherals::DMA1_CH1;
80}
81#[cfg(feature = "stm32u585ai")]
82mod board {
83 pub type Uart = embassy_stm32::peripherals::USART3;
84 pub type TxDma = embassy_stm32::peripherals::GPDMA1_CH0;
85 pub type RxDma = embassy_stm32::peripherals::GPDMA1_CH1;
86}
87#[cfg(feature = "stm32c031c6")]
88mod board {
89 pub type Uart = embassy_stm32::peripherals::USART1;
90 pub type TxDma = embassy_stm32::peripherals::DMA1_CH1;
91 pub type RxDma = embassy_stm32::peripherals::DMA1_CH2;
92}
93
94const DMA_BUF_SIZE: usize = 256; 17const DMA_BUF_SIZE: usize = 256;
95 18
96#[embassy_executor::main] 19#[embassy_executor::main]
@@ -100,22 +23,12 @@ async fn main(spawner: Spawner) {
100 23
101 // Arduino pins D0 and D1 24 // Arduino pins D0 and D1
102 // They're connected together with a 1K resistor. 25 // They're connected together with a 1K resistor.
103 #[cfg(feature = "stm32f103c8")] 26 let usart = peri!(p, UART);
104 let (tx, rx, usart, tx_dma, rx_dma) = (p.PA9, p.PA10, p.USART1, p.DMA1_CH4, p.DMA1_CH5); 27 let rx = peri!(p, UART_RX);
105 #[cfg(feature = "stm32g491re")] 28 let tx = peri!(p, UART_TX);
106 let (tx, rx, usart, tx_dma, rx_dma) = (p.PC4, p.PC5, p.USART1, p.DMA1_CH1, p.DMA1_CH2); 29 let rx_dma = peri!(p, UART_RX_DMA);
107 #[cfg(feature = "stm32g071rb")] 30 let tx_dma = peri!(p, UART_TX_DMA);
108 let (tx, rx, usart, tx_dma, rx_dma) = (p.PC4, p.PC5, p.USART1, p.DMA1_CH1, p.DMA1_CH2); 31 let irq = irqs!(UART);
109 #[cfg(feature = "stm32f429zi")]
110 let (tx, rx, usart, tx_dma, rx_dma) = (p.PG14, p.PG9, p.USART6, p.DMA2_CH6, p.DMA2_CH1);
111 #[cfg(feature = "stm32wb55rg")]
112 let (tx, rx, usart, tx_dma, rx_dma) = (p.PA2, p.PA3, p.LPUART1, p.DMA1_CH1, p.DMA1_CH2);
113 #[cfg(feature = "stm32h755zi")]
114 let (tx, rx, usart, tx_dma, rx_dma) = (p.PB6, p.PB7, p.USART1, p.DMA1_CH0, p.DMA1_CH1);
115 #[cfg(feature = "stm32u585ai")]
116 let (tx, rx, usart, tx_dma, rx_dma) = (p.PD8, p.PD9, p.USART3, p.GPDMA1_CH0, p.GPDMA1_CH1);
117 #[cfg(feature = "stm32c031c6")]
118 let (tx, rx, usart, tx_dma, rx_dma) = (p.PB6, p.PB7, p.USART1, p.DMA1_CH1, p.DMA1_CH2);
119 32
120 // To run this test, use the saturating_serial test utility to saturate the serial port 33 // To run this test, use the saturating_serial test utility to saturate the serial port
121 34
@@ -127,7 +40,7 @@ async fn main(spawner: Spawner) {
127 config.stop_bits = StopBits::STOP1; 40 config.stop_bits = StopBits::STOP1;
128 config.parity = Parity::ParityNone; 41 config.parity = Parity::ParityNone;
129 42
130 let usart = Uart::new(usart, rx, tx, Irqs, tx_dma, rx_dma, config); 43 let usart = Uart::new(usart, rx, tx, irq, tx_dma, rx_dma, config).unwrap();
131 let (tx, rx) = usart.split(); 44 let (tx, rx) = usart.split();
132 static mut DMA_BUF: [u8; DMA_BUF_SIZE] = [0; DMA_BUF_SIZE]; 45 static mut DMA_BUF: [u8; DMA_BUF_SIZE] = [0; DMA_BUF_SIZE];
133 let dma_buf = unsafe { DMA_BUF.as_mut() }; 46 let dma_buf = unsafe { DMA_BUF.as_mut() };
@@ -139,7 +52,7 @@ async fn main(spawner: Spawner) {
139} 52}
140 53
141#[embassy_executor::task] 54#[embassy_executor::task]
142async fn transmit_task(mut tx: UartTx<'static, board::Uart, board::TxDma>) { 55async fn transmit_task(mut tx: UartTx<'static, peris::UART, peris::UART_TX_DMA>) {
143 // workaround https://github.com/embassy-rs/embassy/issues/1426 56 // workaround https://github.com/embassy-rs/embassy/issues/1426
144 Timer::after(Duration::from_millis(100) as _).await; 57 Timer::after(Duration::from_millis(100) as _).await;
145 58
@@ -162,7 +75,7 @@ async fn transmit_task(mut tx: UartTx<'static, board::Uart, board::TxDma>) {
162} 75}
163 76
164#[embassy_executor::task] 77#[embassy_executor::task]
165async fn receive_task(mut rx: RingBufferedUartRx<'static, board::Uart, board::RxDma>) { 78async fn receive_task(mut rx: RingBufferedUartRx<'static, peris::UART, peris::UART_RX_DMA>) {
166 info!("Ready to receive..."); 79 info!("Ready to receive...");
167 80
168 let mut rng = ChaCha8Rng::seed_from_u64(1337); 81 let mut rng = ChaCha8Rng::seed_from_u64(1337);
diff --git a/tests/stm32/src/common.rs b/tests/stm32/src/common.rs
index ca5cb43ac..9c0b8c39e 100644
--- a/tests/stm32/src/common.rs
+++ b/tests/stm32/src/common.rs
@@ -24,6 +24,131 @@ teleprobe_meta::target!(b"iot-stm32u585ai");
24teleprobe_meta::target!(b"nucleo-stm32h563zi"); 24teleprobe_meta::target!(b"nucleo-stm32h563zi");
25#[cfg(feature = "stm32c031c6")] 25#[cfg(feature = "stm32c031c6")]
26teleprobe_meta::target!(b"nucleo-stm32c031c6"); 26teleprobe_meta::target!(b"nucleo-stm32c031c6");
27#[cfg(feature = "stm32l073rz")]
28teleprobe_meta::target!(b"nucleo-stm32l073rz");
29#[cfg(feature = "stm32l152re")]
30teleprobe_meta::target!(b"nucleo-stm32l152re");
31#[cfg(feature = "stm32l4a6zg")]
32teleprobe_meta::target!(b"nucleo-stm32l4a6zg");
33#[cfg(feature = "stm32l4r5zi")]
34teleprobe_meta::target!(b"nucleo-stm32l4r5zi");
35#[cfg(feature = "stm32l552ze")]
36teleprobe_meta::target!(b"nucleo-stm32l552ze");
37
38macro_rules! define_peris {
39 ($($name:ident = $peri:ident,)* $(@irq $irq_name:ident = $irq_code:tt,)*) => {
40 #[allow(unused_macros)]
41 macro_rules! peri {
42 $(
43 ($p:expr, $name) => {
44 $p.$peri
45 };
46 )*
47 }
48 #[allow(unused_macros)]
49 macro_rules! irqs {
50 $(
51 ($irq_name) => {{
52 embassy_stm32::bind_interrupts!(struct Irqs $irq_code);
53 Irqs
54 }};
55 )*
56 }
57
58 #[allow(unused)]
59 #[allow(non_camel_case_types)]
60 pub mod peris {
61 $(
62 pub type $name = embassy_stm32::peripherals::$peri;
63 )*
64 }
65 };
66}
67
68#[cfg(feature = "stm32f103c8")]
69define_peris!(
70 UART = USART1, UART_TX = PA9, UART_RX = PA10, UART_TX_DMA = DMA1_CH4, UART_RX_DMA = DMA1_CH5,
71 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2,
72 @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;},
73);
74#[cfg(feature = "stm32g491re")]
75define_peris!(
76 UART = USART1, UART_TX = PC4, UART_RX = PC5, UART_TX_DMA = DMA1_CH1, UART_RX_DMA = DMA1_CH2,
77 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH1, SPI_RX_DMA = DMA1_CH2,
78 @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;},
79);
80#[cfg(feature = "stm32g071rb")]
81define_peris!(
82 UART = USART1, UART_TX = PC4, UART_RX = PC5, UART_TX_DMA = DMA1_CH1, UART_RX_DMA = DMA1_CH2,
83 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH1, SPI_RX_DMA = DMA1_CH2,
84 @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;},
85);
86#[cfg(feature = "stm32f429zi")]
87define_peris!(
88 UART = USART6, UART_TX = PG14, UART_RX = PG9, UART_TX_DMA = DMA2_CH6, UART_RX_DMA = DMA2_CH1,
89 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA2_CH3, SPI_RX_DMA = DMA2_CH2,
90 @irq UART = {USART6 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART6>;},
91);
92#[cfg(feature = "stm32wb55rg")]
93define_peris!(
94 UART = LPUART1, UART_TX = PA2, UART_RX = PA3, UART_TX_DMA = DMA1_CH1, UART_RX_DMA = DMA1_CH2,
95 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH1, SPI_RX_DMA = DMA1_CH2,
96 @irq UART = {LPUART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::LPUART1>;},
97);
98#[cfg(feature = "stm32h755zi")]
99define_peris!(
100 UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH0, UART_RX_DMA = DMA1_CH1,
101 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PB5, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH0, SPI_RX_DMA = DMA1_CH1,
102 @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;},
103);
104#[cfg(feature = "stm32u585ai")]
105define_peris!(
106 UART = USART3, UART_TX = PD8, UART_RX = PD9, UART_TX_DMA = GPDMA1_CH0, UART_RX_DMA = GPDMA1_CH1,
107 SPI = SPI1, SPI_SCK = PE13, SPI_MOSI = PE15, SPI_MISO = PE14, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1,
108 @irq UART = {USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;},
109);
110#[cfg(feature = "stm32h563zi")]
111define_peris!(
112 UART = LPUART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = GPDMA1_CH0, UART_RX_DMA = GPDMA1_CH1,
113 SPI = SPI4, SPI_SCK = PE12, SPI_MOSI = PE14, SPI_MISO = PE13, SPI_TX_DMA = GPDMA1_CH0, SPI_RX_DMA = GPDMA1_CH1,
114 @irq UART = {LPUART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::LPUART1>;},
115);
116#[cfg(feature = "stm32c031c6")]
117define_peris!(
118 UART = USART1, UART_TX = PB6, UART_RX = PB7, UART_TX_DMA = DMA1_CH1, UART_RX_DMA = DMA1_CH2,
119 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH1, SPI_RX_DMA = DMA1_CH2,
120 @irq UART = {USART1 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART1>;},
121);
122#[cfg(feature = "stm32l4a6zg")]
123define_peris!(
124 UART = USART3, UART_TX = PD8, UART_RX = PD9, UART_TX_DMA = DMA1_CH2, UART_RX_DMA = DMA1_CH3,
125 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2,
126 @irq UART = {USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;},
127);
128#[cfg(feature = "stm32l4r5zi")]
129define_peris!(
130 UART = USART3, UART_TX = PD8, UART_RX = PD9, UART_TX_DMA = DMA1_CH1, UART_RX_DMA = DMA1_CH2,
131 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH1, SPI_RX_DMA = DMA1_CH2,
132 @irq UART = {USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;},
133);
134#[cfg(feature = "stm32l073rz")]
135define_peris!(
136 UART = USART4, UART_TX = PA0, UART_RX = PA1, UART_TX_DMA = DMA1_CH3, UART_RX_DMA = DMA1_CH2,
137 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2,
138 @irq UART = {USART4_5 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART4>;},
139);
140#[cfg(feature = "stm32l152re")]
141define_peris!(
142 UART = USART3, UART_TX = PB10, UART_RX = PB11, UART_TX_DMA = DMA1_CH2, UART_RX_DMA = DMA1_CH3,
143 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH3, SPI_RX_DMA = DMA1_CH2,
144 @irq UART = {USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;},
145);
146#[cfg(feature = "stm32l552ze")]
147define_peris!(
148 UART = USART3, UART_TX = PD8, UART_RX = PD9, UART_TX_DMA = DMA1_CH1, UART_RX_DMA = DMA1_CH2,
149 SPI = SPI1, SPI_SCK = PA5, SPI_MOSI = PA7, SPI_MISO = PA6, SPI_TX_DMA = DMA1_CH1, SPI_RX_DMA = DMA1_CH2,
150 @irq UART = {USART3 => embassy_stm32::usart::InterruptHandler<embassy_stm32::peripherals::USART3>;},
151);
27 152
28pub fn config() -> Config { 153pub fn config() -> Config {
29 #[allow(unused_mut)] 154 #[allow(unused_mut)]
@@ -31,14 +156,86 @@ pub fn config() -> Config {
31 156
32 #[cfg(feature = "stm32h755zi")] 157 #[cfg(feature = "stm32h755zi")]
33 { 158 {
34 config.rcc.sys_ck = Some(Hertz(400_000_000)); 159 use embassy_stm32::rcc::*;
35 config.rcc.pll1.q_ck = Some(Hertz(100_000_000)); 160 config.rcc.hsi = Some(Hsi::Mhz64);
36 config.rcc.adc_clock_source = embassy_stm32::rcc::AdcClockSource::PerCk; 161 config.rcc.csi = true;
162 config.rcc.pll_src = PllSource::Hsi;
163 config.rcc.pll1 = Some(Pll {
164 prediv: 4,
165 mul: 50,
166 divp: Some(2),
167 divq: Some(8), // SPI1 cksel defaults to pll1_q
168 divr: None,
169 });
170 config.rcc.pll2 = Some(Pll {
171 prediv: 4,
172 mul: 50,
173 divp: Some(8), // 100mhz
174 divq: None,
175 divr: None,
176 });
177 config.rcc.sys = Sysclk::Pll1P; // 400 Mhz
178 config.rcc.ahb_pre = AHBPrescaler::DIV2; // 200 Mhz
179 config.rcc.apb1_pre = APBPrescaler::DIV2; // 100 Mhz
180 config.rcc.apb2_pre = APBPrescaler::DIV2; // 100 Mhz
181 config.rcc.apb3_pre = APBPrescaler::DIV2; // 100 Mhz
182 config.rcc.apb4_pre = APBPrescaler::DIV2; // 100 Mhz
183 config.rcc.voltage_scale = VoltageScale::Scale1;
184 config.rcc.adc_clock_source = AdcClockSource::PLL2_P;
185 }
186
187 #[cfg(any(feature = "stm32l4a6zg", feature = "stm32l4r5zi"))]
188 {
189 use embassy_stm32::rcc::*;
190 config.rcc.mux = ClockSrc::PLL(
191 // 72Mhz clock (16 / 1 * 18 / 4)
192 PLLSource::HSI16,
193 PLLClkDiv::Div4,
194 PLLSrcDiv::Div1,
195 PLLMul::Mul18,
196 Some(PLLClkDiv::Div6), // 48Mhz (16 / 1 * 18 / 6)
197 );
198 }
199
200 #[cfg(any(feature = "stm32l552ze"))]
201 {
202 use embassy_stm32::rcc::*;
203 config.rcc.mux = ClockSrc::PLL(
204 // 110Mhz clock (16 / 4 * 55 / 2)
205 PLLSource::HSI16,
206 PLLClkDiv::Div2,
207 PLLSrcDiv::Div4,
208 PLLMul::Mul55,
209 None,
210 );
37 } 211 }
38 212
39 #[cfg(feature = "stm32u585ai")] 213 #[cfg(feature = "stm32u585ai")]
40 { 214 {
41 config.rcc.mux = embassy_stm32::rcc::ClockSrc::MSI(embassy_stm32::rcc::MSIRange::Range48mhz); 215 use embassy_stm32::rcc::*;
216 config.rcc.mux = ClockSrc::MSI(MSIRange::Range48mhz);
217 }
218
219 #[cfg(feature = "stm32l073rz")]
220 {
221 use embassy_stm32::rcc::*;
222 config.rcc.mux = ClockSrc::PLL(
223 // 32Mhz clock (16 * 4 / 2)
224 PLLSource::HSI16,
225 PLLMul::Mul4,
226 PLLDiv::Div2,
227 );
228 }
229
230 #[cfg(any(feature = "stm32l152re"))]
231 {
232 use embassy_stm32::rcc::*;
233 config.rcc.mux = ClockSrc::PLL(
234 // 32Mhz clock (16 * 4 / 2)
235 PLLSource::HSI,
236 PLLMul::Mul4,
237 PLLDiv::Div2,
238 );
42 } 239 }
43 240
44 config 241 config