aboutsummaryrefslogtreecommitdiff
path: root/examples/rp235x/src/bin/ethernet_w5500_tcp_server.rs
diff options
context:
space:
mode:
Diffstat (limited to 'examples/rp235x/src/bin/ethernet_w5500_tcp_server.rs')
-rw-r--r--examples/rp235x/src/bin/ethernet_w5500_tcp_server.rs136
1 files changed, 136 insertions, 0 deletions
diff --git a/examples/rp235x/src/bin/ethernet_w5500_tcp_server.rs b/examples/rp235x/src/bin/ethernet_w5500_tcp_server.rs
new file mode 100644
index 000000000..32b3880f6
--- /dev/null
+++ b/examples/rp235x/src/bin/ethernet_w5500_tcp_server.rs
@@ -0,0 +1,136 @@
1//! This example implements a TCP echo server on port 1234 and using DHCP.
2//! Send it some data, you should see it echoed back and printed in the console.
3//!
4//! Example written for the [`WIZnet W5500-EVB-Pico2`](https://docs.wiznet.io/Product/iEthernet/W5500/w5500-evb-pico2) board.
5
6#![no_std]
7#![no_main]
8
9use defmt::*;
10use embassy_executor::Spawner;
11use embassy_futures::yield_now;
12use embassy_net::{Stack, StackResources};
13use embassy_net_wiznet::chip::W5500;
14use embassy_net_wiznet::*;
15use embassy_rp::clocks::RoscRng;
16use embassy_rp::gpio::{Input, Level, Output, Pull};
17use embassy_rp::peripherals::SPI0;
18use embassy_rp::spi::{Async, Config as SpiConfig, Spi};
19use embassy_time::{Delay, Duration};
20use embedded_hal_bus::spi::ExclusiveDevice;
21use embedded_io_async::Write;
22use static_cell::StaticCell;
23use {defmt_rtt as _, panic_probe as _};
24
25#[embassy_executor::task]
26async fn ethernet_task(
27 runner: Runner<
28 'static,
29 W5500,
30 ExclusiveDevice<Spi<'static, SPI0, Async>, Output<'static>, Delay>,
31 Input<'static>,
32 Output<'static>,
33 >,
34) -> ! {
35 runner.run().await
36}
37
38#[embassy_executor::task]
39async fn net_task(mut runner: embassy_net::Runner<'static, Device<'static>>) -> ! {
40 runner.run().await
41}
42
43#[embassy_executor::main]
44async fn main(spawner: Spawner) {
45 let p = embassy_rp::init(Default::default());
46 let mut rng = RoscRng;
47 let mut led = Output::new(p.PIN_25, Level::Low);
48
49 let mut spi_cfg = SpiConfig::default();
50 spi_cfg.frequency = 50_000_000;
51 let (miso, mosi, clk) = (p.PIN_16, p.PIN_19, p.PIN_18);
52 let spi = Spi::new(p.SPI0, clk, mosi, miso, p.DMA_CH0, p.DMA_CH1, spi_cfg);
53 let cs = Output::new(p.PIN_17, Level::High);
54 let w5500_int = Input::new(p.PIN_21, Pull::Up);
55 let w5500_reset = Output::new(p.PIN_20, Level::High);
56
57 let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00];
58 static STATE: StaticCell<State<8, 8>> = StaticCell::new();
59 let state = STATE.init(State::<8, 8>::new());
60 let (device, runner) = embassy_net_wiznet::new(
61 mac_addr,
62 state,
63 ExclusiveDevice::new(spi, cs, Delay),
64 w5500_int,
65 w5500_reset,
66 )
67 .await
68 .unwrap();
69 unwrap!(spawner.spawn(ethernet_task(runner)));
70
71 // Generate random seed
72 let seed = rng.next_u64();
73
74 // Init network stack
75 static RESOURCES: StaticCell<StackResources<3>> = StaticCell::new();
76 let (stack, runner) = embassy_net::new(
77 device,
78 embassy_net::Config::dhcpv4(Default::default()),
79 RESOURCES.init(StackResources::new()),
80 seed,
81 );
82
83 // Launch network task
84 unwrap!(spawner.spawn(net_task(runner)));
85
86 info!("Waiting for DHCP...");
87 let cfg = wait_for_config(stack).await;
88 let local_addr = cfg.address.address();
89 info!("IP address: {:?}", local_addr);
90
91 let mut rx_buffer = [0; 4096];
92 let mut tx_buffer = [0; 4096];
93 let mut buf = [0; 4096];
94 loop {
95 let mut socket = embassy_net::tcp::TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer);
96 socket.set_timeout(Some(Duration::from_secs(10)));
97
98 led.set_low();
99 info!("Listening on TCP:1234...");
100 if let Err(e) = socket.accept(1234).await {
101 warn!("accept error: {:?}", e);
102 continue;
103 }
104 info!("Received connection from {:?}", socket.remote_endpoint());
105 led.set_high();
106
107 loop {
108 let n = match socket.read(&mut buf).await {
109 Ok(0) => {
110 warn!("read EOF");
111 break;
112 }
113 Ok(n) => n,
114 Err(e) => {
115 warn!("{:?}", e);
116 break;
117 }
118 };
119 info!("rxd {}", core::str::from_utf8(&buf[..n]).unwrap());
120
121 if let Err(e) = socket.write_all(&buf[..n]).await {
122 warn!("write error: {:?}", e);
123 break;
124 }
125 }
126 }
127}
128
129async fn wait_for_config(stack: Stack<'static>) -> embassy_net::StaticConfigV4 {
130 loop {
131 if let Some(config) = stack.config_v4() {
132 return config.clone();
133 }
134 yield_now().await;
135 }
136}