diff --git a/tests/rp/Cargo.toml b/tests/rp/Cargo.toml index c69bf7a8..6a3df4b9 100644 --- a/tests/rp/Cargo.toml +++ b/tests/rp/Cargo.toml @@ -9,10 +9,11 @@ teleprobe-meta = "1.1" embassy-sync = { version = "0.2.0", path = "../../embassy-sync", features = ["defmt"] } embassy-executor = { version = "0.2.0", path = "../../embassy-executor", features = ["nightly", "arch-cortex-m", "executor-thread", "defmt", "integrated-timers"] } -embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt"] } +embassy-time = { version = "0.1.2", path = "../../embassy-time", features = ["defmt", "nightly", "unstable-traits"] } embassy-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"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } +embassy-net-wiznet = { version = "0.1.0", path = "../../embassy-net-wiznet", features = ["defmt"] } cyw43 = { path = "../../cyw43", features = ["defmt", "firmware-logs"] } cyw43-pio = { path = "../../cyw43-pio", features = ["defmt", "overclock"] } @@ -24,6 +25,7 @@ cortex-m-rt = "0.7.0" embedded-hal = "0.2.6" embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-rc.1" } embedded-hal-async = { version = "=1.0.0-rc.1" } +embedded-hal-bus = { version = "=0.1.0-rc.1", features = ["async"] } panic-probe = { version = "0.3.0", features = ["print-defmt"] } futures = { version = "0.3.17", default-features = false, features = ["async-await"] } embedded-io-async = { version = "0.5.0" } @@ -31,6 +33,7 @@ embedded-storage = { version = "0.3" } static_cell = { version = "1.1", features = ["nightly"]} pio = "0.2" pio-proc = "0.2" +rand = { version = "0.8.5", default-features = false } [profile.dev] debug = 2 diff --git a/tests/rp/src/bin/adc.rs b/tests/rp/src/bin/adc.rs index b29a3a7c..0250fd5f 100644 --- a/tests/rp/src/bin/adc.rs +++ b/tests/rp/src/bin/adc.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use defmt::*; use embassy_executor::Spawner; diff --git a/tests/rp/src/bin/cyw43-perf.rs b/tests/rp/src/bin/cyw43-perf.rs index fffdabc9..1c665f95 100644 --- a/tests/rp/src/bin/cyw43-perf.rs +++ b/tests/rp/src/bin/cyw43-perf.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use cyw43_pio::PioSpi; use defmt::{assert, panic, *}; diff --git a/tests/rp/src/bin/dma_copy_async.rs b/tests/rp/src/bin/dma_copy_async.rs index 2c0b559a..b071ed9d 100644 --- a/tests/rp/src/bin/dma_copy_async.rs +++ b/tests/rp/src/bin/dma_copy_async.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use defmt::{assert_eq, *}; use embassy_executor::Spawner; diff --git a/tests/rp/src/bin/ethernet_w5100s_perf.rs b/tests/rp/src/bin/ethernet_w5100s_perf.rs new file mode 100644 index 00000000..faa8638c --- /dev/null +++ b/tests/rp/src/bin/ethernet_w5100s_perf.rs @@ -0,0 +1,249 @@ +#![no_std] +#![no_main] +#![feature(type_alias_impl_trait)] +teleprobe_meta::target!(b"w5100s-evb-pico"); +teleprobe_meta::timeout!(120); + +use defmt::{assert, *}; +use embassy_executor::Spawner; +use embassy_futures::join::join; +use embassy_net::tcp::TcpSocket; +use embassy_net::{Ipv4Address, Stack, StackResources}; +use embassy_net_wiznet::chip::W5100S; +use embassy_net_wiznet::*; +use embassy_rp::clocks::RoscRng; +use embassy_rp::gpio::{Input, Level, Output, Pull}; +use embassy_rp::peripherals::{PIN_17, PIN_20, PIN_21, SPI0}; +use embassy_rp::spi::{Async, Config as SpiConfig, Spi}; +use embassy_time::{with_timeout, Delay, Duration, Timer}; +use embedded_hal_bus::spi::ExclusiveDevice; +use rand::RngCore; +use static_cell::make_static; +use {defmt_rtt as _, panic_probe as _}; + +#[embassy_executor::task] +async fn ethernet_task( + runner: Runner< + 'static, + W5100S, + ExclusiveDevice, Output<'static, PIN_17>, Delay>, + Input<'static, PIN_21>, + Output<'static, PIN_20>, + >, +) -> ! { + runner.run().await +} + +#[embassy_executor::task] +async fn net_task(stack: &'static Stack>) -> ! { + stack.run().await +} + +#[embassy_executor::main] +async fn main(spawner: Spawner) { + let p = embassy_rp::init(Default::default()); + let mut rng = RoscRng; + + let mut spi_cfg = SpiConfig::default(); + spi_cfg.frequency = 50_000_000; + let (miso, mosi, clk) = (p.PIN_16, p.PIN_19, p.PIN_18); + let spi = Spi::new(p.SPI0, clk, mosi, miso, p.DMA_CH0, p.DMA_CH1, spi_cfg); + let cs = Output::new(p.PIN_17, Level::High); + let w5500_int = Input::new(p.PIN_21, Pull::Up); + let w5500_reset = Output::new(p.PIN_20, Level::High); + + let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; + let state = make_static!(State::<8, 8>::new()); + let (device, runner) = embassy_net_wiznet::new( + mac_addr, + state, + ExclusiveDevice::new(spi, cs, Delay), + w5500_int, + w5500_reset, + ) + .await; + unwrap!(spawner.spawn(ethernet_task(runner))); + + // Generate random seed + let seed = rng.next_u64(); + + // Init network stack + let stack = &*make_static!(Stack::new( + device, + embassy_net::Config::dhcpv4(Default::default()), + make_static!(StackResources::<2>::new()), + seed + )); + + // Launch network task + unwrap!(spawner.spawn(net_task(&stack))); + + info!("Waiting for DHCP up..."); + while stack.config_v4().is_none() { + Timer::after(Duration::from_millis(100)).await; + } + info!("IP addressing up!"); + + let down = test_download(stack).await; + let up = test_upload(stack).await; + let updown = test_upload_download(stack).await; + + assert!(down > TEST_EXPECTED_DOWNLOAD_KBPS); + assert!(up > TEST_EXPECTED_UPLOAD_KBPS); + assert!(updown > TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS); + + info!("Test OK"); + cortex_m::asm::bkpt(); +} + +const TEST_DURATION: usize = 10; +const TEST_EXPECTED_DOWNLOAD_KBPS: usize = 500; +const TEST_EXPECTED_UPLOAD_KBPS: usize = 500; +const TEST_EXPECTED_UPLOAD_DOWNLOAD_KBPS: usize = 300; +const RX_BUFFER_SIZE: usize = 4096; +const TX_BUFFER_SIZE: usize = 4096; +const SERVER_ADDRESS: Ipv4Address = Ipv4Address::new(192, 168, 2, 2); +const DOWNLOAD_PORT: u16 = 4321; +const UPLOAD_PORT: u16 = 4322; +const UPLOAD_DOWNLOAD_PORT: u16 = 4323; + +async fn test_download(stack: &'static Stack>) -> usize { + info!("Testing download..."); + + let mut rx_buffer = [0; RX_BUFFER_SIZE]; + let mut tx_buffer = [0; TX_BUFFER_SIZE]; + let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); + socket.set_timeout(Some(Duration::from_secs(10))); + + info!("connecting to {:?}:{}...", SERVER_ADDRESS, DOWNLOAD_PORT); + if let Err(e) = socket.connect((SERVER_ADDRESS, DOWNLOAD_PORT)).await { + error!("connect error: {:?}", e); + return 0; + } + info!("connected, testing..."); + + let mut rx_buf = [0; 4096]; + let mut total: usize = 0; + with_timeout(Duration::from_secs(TEST_DURATION as _), async { + loop { + match socket.read(&mut rx_buf).await { + Ok(0) => { + error!("read EOF"); + return 0; + } + Ok(n) => total += n, + Err(e) => { + error!("read error: {:?}", e); + return 0; + } + } + } + }) + .await + .ok(); + + let kbps = (total + 512) / 1024 / TEST_DURATION; + info!("download: {} kB/s", kbps); + kbps +} + +async fn test_upload(stack: &'static Stack>) -> usize { + info!("Testing upload..."); + + let mut rx_buffer = [0; RX_BUFFER_SIZE]; + let mut tx_buffer = [0; TX_BUFFER_SIZE]; + let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); + socket.set_timeout(Some(Duration::from_secs(10))); + + info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_PORT); + if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_PORT)).await { + error!("connect error: {:?}", e); + return 0; + } + info!("connected, testing..."); + + let buf = [0; 4096]; + let mut total: usize = 0; + with_timeout(Duration::from_secs(TEST_DURATION as _), async { + loop { + match socket.write(&buf).await { + Ok(0) => { + error!("write zero?!??!?!"); + return 0; + } + Ok(n) => total += n, + Err(e) => { + error!("write error: {:?}", e); + return 0; + } + } + } + }) + .await + .ok(); + + let kbps = (total + 512) / 1024 / TEST_DURATION; + info!("upload: {} kB/s", kbps); + kbps +} + +async fn test_upload_download(stack: &'static Stack>) -> usize { + info!("Testing upload+download..."); + + let mut rx_buffer = [0; RX_BUFFER_SIZE]; + let mut tx_buffer = [0; TX_BUFFER_SIZE]; + let mut socket = TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); + socket.set_timeout(Some(Duration::from_secs(10))); + + info!("connecting to {:?}:{}...", SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT); + if let Err(e) = socket.connect((SERVER_ADDRESS, UPLOAD_DOWNLOAD_PORT)).await { + error!("connect error: {:?}", e); + return 0; + } + info!("connected, testing..."); + + let (mut reader, mut writer) = socket.split(); + + let tx_buf = [0; 4096]; + let mut rx_buf = [0; 4096]; + let mut total: usize = 0; + let tx_fut = async { + loop { + match writer.write(&tx_buf).await { + Ok(0) => { + error!("write zero?!??!?!"); + return 0; + } + Ok(_) => {} + Err(e) => { + error!("write error: {:?}", e); + return 0; + } + } + } + }; + + let rx_fut = async { + loop { + match reader.read(&mut rx_buf).await { + Ok(0) => { + error!("read EOF"); + return 0; + } + Ok(n) => total += n, + Err(e) => { + error!("read error: {:?}", e); + return 0; + } + } + } + }; + + with_timeout(Duration::from_secs(TEST_DURATION as _), join(tx_fut, rx_fut)) + .await + .ok(); + + let kbps = (total + 512) / 1024 / TEST_DURATION; + info!("upload+download: {} kB/s", kbps); + kbps +} diff --git a/tests/rp/src/bin/flash.rs b/tests/rp/src/bin/flash.rs index c31d6dec..6e65fbdc 100644 --- a/tests/rp/src/bin/flash.rs +++ b/tests/rp/src/bin/flash.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use defmt::*; use embassy_executor::Spawner; diff --git a/tests/rp/src/bin/float.rs b/tests/rp/src/bin/float.rs index 0e0de85f..2874aa91 100644 --- a/tests/rp/src/bin/float.rs +++ b/tests/rp/src/bin/float.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use defmt::*; use embassy_executor::Spawner; diff --git a/tests/rp/src/bin/gpio.rs b/tests/rp/src/bin/gpio.rs index 946b7dc8..1a43a928 100644 --- a/tests/rp/src/bin/gpio.rs +++ b/tests/rp/src/bin/gpio.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use defmt::{assert, *}; use embassy_executor::Spawner; diff --git a/tests/rp/src/bin/gpio_async.rs b/tests/rp/src/bin/gpio_async.rs index 532494de..60c65b7a 100644 --- a/tests/rp/src/bin/gpio_async.rs +++ b/tests/rp/src/bin/gpio_async.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use defmt::{assert, *}; use embassy_executor::Spawner; diff --git a/tests/rp/src/bin/gpio_multicore.rs b/tests/rp/src/bin/gpio_multicore.rs index 780112bc..22be7824 100644 --- a/tests/rp/src/bin/gpio_multicore.rs +++ b/tests/rp/src/bin/gpio_multicore.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use defmt::{info, unwrap}; use embassy_executor::Executor; diff --git a/tests/rp/src/bin/multicore.rs b/tests/rp/src/bin/multicore.rs index 114889de..ec794c48 100644 --- a/tests/rp/src/bin/multicore.rs +++ b/tests/rp/src/bin/multicore.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use defmt::{info, unwrap}; use embassy_executor::Executor; diff --git a/tests/rp/src/bin/pio_irq.rs b/tests/rp/src/bin/pio_irq.rs index bdea63ea..c71e55d9 100644 --- a/tests/rp/src/bin/pio_irq.rs +++ b/tests/rp/src/bin/pio_irq.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use defmt::info; use embassy_executor::Spawner; diff --git a/tests/rp/src/bin/pio_multi_load.rs b/tests/rp/src/bin/pio_multi_load.rs index 356f1679..6343ff3a 100644 --- a/tests/rp/src/bin/pio_multi_load.rs +++ b/tests/rp/src/bin/pio_multi_load.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use defmt::info; use embassy_executor::Spawner; diff --git a/tests/rp/src/bin/pwm.rs b/tests/rp/src/bin/pwm.rs index c71d21ef..8c02b844 100644 --- a/tests/rp/src/bin/pwm.rs +++ b/tests/rp/src/bin/pwm.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use defmt::{assert, assert_eq, assert_ne, *}; use embassy_executor::Spawner; diff --git a/tests/rp/src/bin/spi.rs b/tests/rp/src/bin/spi.rs index 84dfa5a2..f347b80c 100644 --- a/tests/rp/src/bin/spi.rs +++ b/tests/rp/src/bin/spi.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use defmt::{assert_eq, *}; use embassy_executor::Spawner; diff --git a/tests/rp/src/bin/spi_async.rs b/tests/rp/src/bin/spi_async.rs index a4080b03..80d5a714 100644 --- a/tests/rp/src/bin/spi_async.rs +++ b/tests/rp/src/bin/spi_async.rs @@ -4,8 +4,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use defmt::{assert_eq, *}; use embassy_executor::Spawner; diff --git a/tests/rp/src/bin/uart.rs b/tests/rp/src/bin/uart.rs index 2331c7d3..00f3e194 100644 --- a/tests/rp/src/bin/uart.rs +++ b/tests/rp/src/bin/uart.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use defmt::{assert_eq, *}; use embassy_executor::Spawner; diff --git a/tests/rp/src/bin/uart_buffered.rs b/tests/rp/src/bin/uart_buffered.rs index edabf55b..6ab7de29 100644 --- a/tests/rp/src/bin/uart_buffered.rs +++ b/tests/rp/src/bin/uart_buffered.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use defmt::{assert_eq, panic, *}; use embassy_executor::Spawner; diff --git a/tests/rp/src/bin/uart_dma.rs b/tests/rp/src/bin/uart_dma.rs index fee6c825..cd4af1ef 100644 --- a/tests/rp/src/bin/uart_dma.rs +++ b/tests/rp/src/bin/uart_dma.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use defmt::{assert_eq, *}; use embassy_executor::Spawner; diff --git a/tests/rp/src/bin/uart_upgrade.rs b/tests/rp/src/bin/uart_upgrade.rs index effd0bc4..c07fc08c 100644 --- a/tests/rp/src/bin/uart_upgrade.rs +++ b/tests/rp/src/bin/uart_upgrade.rs @@ -1,8 +1,7 @@ #![no_std] #![no_main] #![feature(type_alias_impl_trait)] -#[path = "../common.rs"] -mod common; +teleprobe_meta::target!(b"rpi-pico"); use defmt::{assert_eq, *}; use embassy_executor::Spawner; diff --git a/tests/rp/src/common.rs b/tests/rp/src/common.rs deleted file mode 100644 index 955674f2..00000000 --- a/tests/rp/src/common.rs +++ /dev/null @@ -1 +0,0 @@ -teleprobe_meta::target!(b"rpi-pico");