From d70994e4a8ea695f07b777fa99d7db4e5d4a7122 Mon Sep 17 00:00:00 2001 From: Dario Nieuwenhuis Date: Wed, 31 May 2023 01:01:30 +0200 Subject: [PATCH] net-w5500: integrate into main repo. --- embassy-net-w5500/Cargo.toml | 12 +---- embassy-net-w5500/src/device.rs | 33 ++++-------- embassy-net-w5500/src/lib.rs | 12 ++--- embassy-net-w5500/src/socket.rs | 53 ++++++------------- embassy-net-w5500/src/spi.rs | 17 ++---- examples/rp/Cargo.toml | 4 +- .../rp/src/bin/ethernet_w5500_multisocket.rs | 25 +++------ .../rp/src/bin/ethernet_w5500_tcp_client.rs | 13 ++--- .../rp/src/bin/ethernet_w5500_tcp_server.rs | 13 ++--- examples/rp/src/bin/ethernet_w5500_udp.rs | 22 ++------ 10 files changed, 55 insertions(+), 149 deletions(-) diff --git a/embassy-net-w5500/Cargo.toml b/embassy-net-w5500/Cargo.toml index 1921e812..3f19e3d3 100644 --- a/embassy-net-w5500/Cargo.toml +++ b/embassy-net-w5500/Cargo.toml @@ -10,17 +10,7 @@ edition = "2021" [dependencies] embedded-hal = { version = "1.0.0-alpha.10" } embedded-hal-async = { version = "=0.2.0-alpha.1" } -embassy-net-driver-channel = { version = "0.1.0" } +embassy-net-driver-channel = { version = "0.1.0", path = "../embassy-net-driver-channel"} embassy-time = { version = "0.1.0" } embassy-futures = { version = "0.1.0" } defmt = { version = "0.3", optional = true } - -[patch.crates-io] -embassy-executor = { git = "https://github.com/embassy-rs/embassy", rev = "e179e7cf85810f0aa7ef8027d8d48f6d21f64dac" } -embassy-time = { git = "https://github.com/embassy-rs/embassy", rev = "e179e7cf85810f0aa7ef8027d8d48f6d21f64dac" } -embassy-futures = { git = "https://github.com/embassy-rs/embassy", rev = "e179e7cf85810f0aa7ef8027d8d48f6d21f64dac" } -embassy-sync = { git = "https://github.com/embassy-rs/embassy", rev = "e179e7cf85810f0aa7ef8027d8d48f6d21f64dac" } -embassy-rp = { git = "https://github.com/embassy-rs/embassy", rev = "e179e7cf85810f0aa7ef8027d8d48f6d21f64dac" } -embassy-net = { git = "https://github.com/embassy-rs/embassy", rev = "e179e7cf85810f0aa7ef8027d8d48f6d21f64dac" } -embassy-net-driver = { git = "https://github.com/embassy-rs/embassy", rev = "e179e7cf85810f0aa7ef8027d8d48f6d21f64dac" } -embassy-net-driver-channel = { git = "https://github.com/embassy-rs/embassy", rev = "e179e7cf85810f0aa7ef8027d8d48f6d21f64dac" } diff --git a/embassy-net-w5500/src/device.rs b/embassy-net-w5500/src/device.rs index 8158bc98..9874df0d 100644 --- a/embassy-net-w5500/src/device.rs +++ b/embassy-net-w5500/src/device.rs @@ -1,6 +1,7 @@ +use embedded_hal_async::spi::SpiDevice; + use crate::socket; use crate::spi::SpiInterface; -use embedded_hal_async::spi::SpiDevice; pub const MODE: u16 = 0x00; pub const MAC: u16 = 0x09; @@ -27,12 +28,10 @@ impl W5500 { pub async fn new(spi: SPI, mac_addr: [u8; 6]) -> Result, SPI::Error> { let mut bus = SpiInterface(spi); // Reset device - bus.write_frame(RegisterBlock::Common, MODE, &[0x80]) - .await?; + bus.write_frame(RegisterBlock::Common, MODE, &[0x80]).await?; // Enable interrupt pin - bus.write_frame(RegisterBlock::Common, SOCKET_INTR, &[0x01]) - .await?; + bus.write_frame(RegisterBlock::Common, SOCKET_INTR, &[0x01]).await?; // Enable receive interrupt bus.write_frame( RegisterBlock::Socket0, @@ -42,8 +41,7 @@ impl W5500 { .await?; // Set MAC address - bus.write_frame(RegisterBlock::Common, MAC, &mac_addr) - .await?; + bus.write_frame(RegisterBlock::Common, MAC, &mac_addr).await?; // Set the raw socket RX/TX buffer sizes to 16KB bus.write_frame(RegisterBlock::Socket0, socket::TXBUF_SIZE, &[16]) @@ -53,8 +51,7 @@ impl W5500 { // MACRAW mode with MAC filtering. let mode: u8 = (1 << 2) | (1 << 7); - bus.write_frame(RegisterBlock::Socket0, socket::MODE, &[mode]) - .await?; + bus.write_frame(RegisterBlock::Socket0, socket::MODE, &[mode]).await?; socket::command(&mut bus, socket::Command::Open).await?; Ok(Self { bus }) @@ -70,17 +67,9 @@ impl W5500 { &mut buffer[..rx_size - offset as usize] }; - let read_ptr = socket::get_rx_read_ptr(&mut self.bus) - .await? - .wrapping_add(offset); - self.bus - .read_frame(RegisterBlock::RxBuf, read_ptr, read_buffer) - .await?; - socket::set_rx_read_ptr( - &mut self.bus, - read_ptr.wrapping_add(read_buffer.len() as u16), - ) - .await?; + let read_ptr = socket::get_rx_read_ptr(&mut self.bus).await?.wrapping_add(offset); + self.bus.read_frame(RegisterBlock::RxBuf, read_ptr, read_buffer).await?; + socket::set_rx_read_ptr(&mut self.bus, read_ptr.wrapping_add(read_buffer.len() as u16)).await?; Ok(read_buffer.len()) } @@ -125,9 +114,7 @@ impl W5500 { pub async fn write_frame(&mut self, frame: &[u8]) -> Result { while socket::get_tx_free_size(&mut self.bus).await? < frame.len() as u16 {} let write_ptr = socket::get_tx_write_ptr(&mut self.bus).await?; - self.bus - .write_frame(RegisterBlock::TxBuf, write_ptr, frame) - .await?; + self.bus.write_frame(RegisterBlock::TxBuf, write_ptr, frame).await?; socket::set_tx_write_ptr(&mut self.bus, write_ptr.wrapping_add(frame.len() as u16)).await?; socket::command(&mut self.bus, socket::Command::Send).await?; Ok(frame.len()) diff --git a/embassy-net-w5500/src/lib.rs b/embassy-net-w5500/src/lib.rs index bf14b05b..6821373e 100644 --- a/embassy-net-w5500/src/lib.rs +++ b/embassy-net-w5500/src/lib.rs @@ -4,7 +4,6 @@ mod device; mod socket; mod spi; -use crate::device::W5500; use embassy_futures::select::{select, Either}; use embassy_net_driver_channel as ch; use embassy_net_driver_channel::driver::LinkState; @@ -12,6 +11,8 @@ use embassy_time::{Duration, Timer}; use embedded_hal::digital::OutputPin; use embedded_hal_async::digital::Wait; use embedded_hal_async::spi::SpiDevice; + +use crate::device::W5500; const MTU: usize = 1514; /// Type alias for the embassy-net driver for W5500 @@ -77,14 +78,7 @@ impl<'d, SPI: SpiDevice, INT: Wait, RST: OutputPin> Runner<'d, SPI, INT, RST> { } /// Obtain a driver for using the W5500 with [`embassy-net`](crates.io/crates/embassy-net). -pub async fn new< - 'a, - const N_RX: usize, - const N_TX: usize, - SPI: SpiDevice, - INT: Wait, - RST: OutputPin, ->( +pub async fn new<'a, const N_RX: usize, const N_TX: usize, SPI: SpiDevice, INT: Wait, RST: OutputPin>( mac_addr: [u8; 6], state: &'a mut State, spi_dev: SPI, diff --git a/embassy-net-w5500/src/socket.rs b/embassy-net-w5500/src/socket.rs index 3f64d04d..3d65583c 100644 --- a/embassy-net-w5500/src/socket.rs +++ b/embassy-net-w5500/src/socket.rs @@ -1,6 +1,7 @@ +use embedded_hal_async::spi::SpiDevice; + use crate::device::RegisterBlock; use crate::spi::SpiInterface; -use embedded_hal_async::spi::SpiDevice; pub const MODE: u16 = 0x00; pub const COMMAND: u16 = 0x01; @@ -25,79 +26,55 @@ pub enum Interrupt { Receive = 0b00100_u8, } -pub async fn reset_interrupt( - bus: &mut SpiInterface, - code: Interrupt, -) -> Result<(), SPI::Error> { +pub async fn reset_interrupt(bus: &mut SpiInterface, code: Interrupt) -> Result<(), SPI::Error> { let data = [code as u8]; bus.write_frame(RegisterBlock::Socket0, INTR, &data).await } -pub async fn get_tx_write_ptr( - bus: &mut SpiInterface, -) -> Result { +pub async fn get_tx_write_ptr(bus: &mut SpiInterface) -> Result { let mut data = [0u8; 2]; bus.read_frame(RegisterBlock::Socket0, TX_DATA_WRITE_PTR, &mut data) .await?; Ok(u16::from_be_bytes(data)) } -pub async fn set_tx_write_ptr( - bus: &mut SpiInterface, - ptr: u16, -) -> Result<(), SPI::Error> { +pub async fn set_tx_write_ptr(bus: &mut SpiInterface, ptr: u16) -> Result<(), SPI::Error> { let data = ptr.to_be_bytes(); - bus.write_frame(RegisterBlock::Socket0, TX_DATA_WRITE_PTR, &data) - .await + bus.write_frame(RegisterBlock::Socket0, TX_DATA_WRITE_PTR, &data).await } -pub async fn get_rx_read_ptr( - bus: &mut SpiInterface, -) -> Result { +pub async fn get_rx_read_ptr(bus: &mut SpiInterface) -> Result { let mut data = [0u8; 2]; bus.read_frame(RegisterBlock::Socket0, RX_DATA_READ_PTR, &mut data) .await?; Ok(u16::from_be_bytes(data)) } -pub async fn set_rx_read_ptr( - bus: &mut SpiInterface, - ptr: u16, -) -> Result<(), SPI::Error> { +pub async fn set_rx_read_ptr(bus: &mut SpiInterface, ptr: u16) -> Result<(), SPI::Error> { let data = ptr.to_be_bytes(); - bus.write_frame(RegisterBlock::Socket0, RX_DATA_READ_PTR, &data) - .await + bus.write_frame(RegisterBlock::Socket0, RX_DATA_READ_PTR, &data).await } -pub async fn command( - bus: &mut SpiInterface, - command: Command, -) -> Result<(), SPI::Error> { +pub async fn command(bus: &mut SpiInterface, command: Command) -> Result<(), SPI::Error> { let data = [command as u8]; - bus.write_frame(RegisterBlock::Socket0, COMMAND, &data) - .await + bus.write_frame(RegisterBlock::Socket0, COMMAND, &data).await } pub async fn get_rx_size(bus: &mut SpiInterface) -> Result { loop { // Wait until two sequential reads are equal let mut res0 = [0u8; 2]; - bus.read_frame(RegisterBlock::Socket0, RECVD_SIZE, &mut res0) - .await?; + bus.read_frame(RegisterBlock::Socket0, RECVD_SIZE, &mut res0).await?; let mut res1 = [0u8; 2]; - bus.read_frame(RegisterBlock::Socket0, RECVD_SIZE, &mut res1) - .await?; + bus.read_frame(RegisterBlock::Socket0, RECVD_SIZE, &mut res1).await?; if res0 == res1 { break Ok(u16::from_be_bytes(res0)); } } } -pub async fn get_tx_free_size( - bus: &mut SpiInterface, -) -> Result { +pub async fn get_tx_free_size(bus: &mut SpiInterface) -> Result { let mut data = [0; 2]; - bus.read_frame(RegisterBlock::Socket0, TX_FREE_SIZE, &mut data) - .await?; + bus.read_frame(RegisterBlock::Socket0, TX_FREE_SIZE, &mut data).await?; Ok(u16::from_be_bytes(data)) } diff --git a/embassy-net-w5500/src/spi.rs b/embassy-net-w5500/src/spi.rs index 55d31188..6cd52c44 100644 --- a/embassy-net-w5500/src/spi.rs +++ b/embassy-net-w5500/src/spi.rs @@ -1,17 +1,13 @@ -use crate::device::RegisterBlock; use embedded_hal_async::spi::{Operation, SpiDevice}; +use crate::device::RegisterBlock; + #[derive(Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct SpiInterface(pub SPI); impl SpiInterface { - pub async fn read_frame( - &mut self, - block: RegisterBlock, - address: u16, - data: &mut [u8], - ) -> Result<(), SPI::Error> { + pub async fn read_frame(&mut self, block: RegisterBlock, address: u16, data: &mut [u8]) -> Result<(), SPI::Error> { let address_phase = address.to_be_bytes(); let control_phase = [(block as u8) << 3]; let operations = &mut [ @@ -22,12 +18,7 @@ impl SpiInterface { self.0.transaction(operations).await } - pub async fn write_frame( - &mut self, - block: RegisterBlock, - address: u16, - data: &[u8], - ) -> Result<(), SPI::Error> { + pub async fn write_frame(&mut self, block: RegisterBlock, address: u16, data: &[u8]) -> Result<(), SPI::Error> { let address_phase = address.to_be_bytes(); let control_phase = [(block as u8) << 3 | 0b0000_0100]; let data_phase = data; diff --git a/examples/rp/Cargo.toml b/examples/rp/Cargo.toml index f77377a6..58b70191 100644 --- a/examples/rp/Cargo.toml +++ b/examples/rp/Cargo.toml @@ -12,7 +12,8 @@ embassy-executor = { version = "0.2.0", path = "../../embassy-executor", feature embassy-time = { version = "0.1.0", path = "../../embassy-time", features = ["nightly", "unstable-traits", "defmt", "defmt-timestamp-uptime"] } embassy-rp = { version = "0.1.0", path = "../../embassy-rp", features = ["defmt", "unstable-traits", "nightly", "unstable-pac", "time-driver", "critical-section-impl"] } embassy-usb = { version = "0.1.0", path = "../../embassy-usb", features = ["defmt"] } -embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "dhcpv4", "medium-ethernet"] } +embassy-net = { version = "0.1.0", path = "../../embassy-net", features = ["defmt", "nightly", "tcp", "udp", "dhcpv4", "medium-ethernet"] } +embassy-net-w5500 = { version = "0.1.0", path = "../../embassy-net-w5500", features = ["defmt"] } embassy-futures = { version = "0.1.0", path = "../../embassy-futures" } embassy-usb-logger = { version = "0.1.0", path = "../../embassy-usb-logger" } embassy-lora = { version = "0.1.0", path = "../../embassy-lora", features = ["time", "defmt"] } @@ -48,6 +49,7 @@ static_cell = "1.0.0" log = "0.4" pio-proc = "0.2" pio = "0.2.1" +rand = { version = "0.8.5", default-features = false } [profile.release] debug = true diff --git a/examples/rp/src/bin/ethernet_w5500_multisocket.rs b/examples/rp/src/bin/ethernet_w5500_multisocket.rs index eb3b8de8..c8e6d46a 100644 --- a/examples/rp/src/bin/ethernet_w5500_multisocket.rs +++ b/examples/rp/src/bin/ethernet_w5500_multisocket.rs @@ -15,6 +15,7 @@ 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::Duration; use embedded_hal_async::spi::ExclusiveDevice; use embedded_io::asynch::Write; use rand::RngCore; @@ -62,14 +63,8 @@ async fn main(spawner: Spawner) { let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; let state = singleton!(State::<8, 8>::new()); - let (device, runner) = embassy_net_w5500::new( - mac_addr, - state, - ExclusiveDevice::new(spi, cs), - w5500_int, - w5500_reset, - ) - .await; + let (device, runner) = + embassy_net_w5500::new(mac_addr, state, ExclusiveDevice::new(spi, cs), w5500_int, w5500_reset).await; unwrap!(spawner.spawn(ethernet_task(runner))); // Generate random seed @@ -103,18 +98,14 @@ async fn listen_task(stack: &'static Stack>, id: u8, port: u16) let mut buf = [0; 4096]; loop { let mut socket = embassy_net::tcp::TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); - socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10))); + socket.set_timeout(Some(Duration::from_secs(10))); info!("SOCKET {}: Listening on TCP:{}...", id, port); if let Err(e) = socket.accept(port).await { warn!("accept error: {:?}", e); continue; } - info!( - "SOCKET {}: Received connection from {:?}", - id, - socket.remote_endpoint() - ); + info!("SOCKET {}: Received connection from {:?}", id, socket.remote_endpoint()); loop { let n = match socket.read(&mut buf).await { @@ -128,11 +119,7 @@ async fn listen_task(stack: &'static Stack>, id: u8, port: u16) break; } }; - info!( - "SOCKET {}: rxd {}", - id, - core::str::from_utf8(&buf[..n]).unwrap() - ); + info!("SOCKET {}: rxd {}", id, core::str::from_utf8(&buf[..n]).unwrap()); if let Err(e) = socket.write_all(&buf[..n]).await { warn!("write error: {:?}", e); diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs index e166e0f3..9a7c3ad1 100644 --- a/examples/rp/src/bin/ethernet_w5500_tcp_client.rs +++ b/examples/rp/src/bin/ethernet_w5500_tcp_client.rs @@ -7,6 +7,7 @@ #![feature(type_alias_impl_trait)] use core::str::FromStr; + use defmt::*; use embassy_executor::Spawner; use embassy_futures::yield_now; @@ -65,14 +66,8 @@ async fn main(spawner: Spawner) { let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; let state = singleton!(State::<8, 8>::new()); - let (device, runner) = embassy_net_w5500::new( - mac_addr, - state, - ExclusiveDevice::new(spi, cs), - w5500_int, - w5500_reset, - ) - .await; + let (device, runner) = + embassy_net_w5500::new(mac_addr, state, ExclusiveDevice::new(spi, cs), w5500_int, w5500_reset).await; unwrap!(spawner.spawn(ethernet_task(runner))); // Generate random seed @@ -98,7 +93,7 @@ async fn main(spawner: Spawner) { let mut tx_buffer = [0; 4096]; loop { let mut socket = embassy_net::tcp::TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); - socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10))); + socket.set_timeout(Some(Duration::from_secs(10))); led.set_low(); info!("Connecting..."); diff --git a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs index ffd664d1..f0254324 100644 --- a/examples/rp/src/bin/ethernet_w5500_tcp_server.rs +++ b/examples/rp/src/bin/ethernet_w5500_tcp_server.rs @@ -16,6 +16,7 @@ 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::Duration; use embedded_hal_async::spi::ExclusiveDevice; use embedded_io::asynch::Write; use rand::RngCore; @@ -64,14 +65,8 @@ async fn main(spawner: Spawner) { let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; let state = singleton!(State::<8, 8>::new()); - let (device, runner) = embassy_net_w5500::new( - mac_addr, - state, - ExclusiveDevice::new(spi, cs), - w5500_int, - w5500_reset, - ) - .await; + let (device, runner) = + embassy_net_w5500::new(mac_addr, state, ExclusiveDevice::new(spi, cs), w5500_int, w5500_reset).await; unwrap!(spawner.spawn(ethernet_task(runner))); // Generate random seed @@ -98,7 +93,7 @@ async fn main(spawner: Spawner) { let mut buf = [0; 4096]; loop { let mut socket = embassy_net::tcp::TcpSocket::new(stack, &mut rx_buffer, &mut tx_buffer); - socket.set_timeout(Some(embassy_net::SmolDuration::from_secs(10))); + socket.set_timeout(Some(Duration::from_secs(10))); led.set_low(); info!("Listening on TCP:1234..."); diff --git a/examples/rp/src/bin/ethernet_w5500_udp.rs b/examples/rp/src/bin/ethernet_w5500_udp.rs index 08ffeb24..2c54f711 100644 --- a/examples/rp/src/bin/ethernet_w5500_udp.rs +++ b/examples/rp/src/bin/ethernet_w5500_udp.rs @@ -9,8 +9,8 @@ use defmt::*; use embassy_executor::Spawner; use embassy_futures::yield_now; -use embassy_net::udp::UdpSocket; -use embassy_net::{PacketMetadata, Stack, StackResources}; +use embassy_net::udp::{PacketMetadata, UdpSocket}; +use embassy_net::{Stack, StackResources}; use embassy_net_w5500::*; use embassy_rp::clocks::RoscRng; use embassy_rp::gpio::{Input, Level, Output, Pull}; @@ -62,14 +62,8 @@ async fn main(spawner: Spawner) { let mac_addr = [0x02, 0x00, 0x00, 0x00, 0x00, 0x00]; let state = singleton!(State::<8, 8>::new()); - let (device, runner) = embassy_net_w5500::new( - mac_addr, - state, - ExclusiveDevice::new(spi, cs), - w5500_int, - w5500_reset, - ) - .await; + let (device, runner) = + embassy_net_w5500::new(mac_addr, state, ExclusiveDevice::new(spi, cs), w5500_int, w5500_reset).await; unwrap!(spawner.spawn(ethernet_task(runner))); // Generate random seed @@ -98,13 +92,7 @@ async fn main(spawner: Spawner) { let mut tx_meta = [PacketMetadata::EMPTY; 16]; let mut buf = [0; 4096]; loop { - let mut socket = UdpSocket::new( - stack, - &mut rx_meta, - &mut rx_buffer, - &mut tx_meta, - &mut tx_buffer, - ); + let mut socket = UdpSocket::new(stack, &mut rx_meta, &mut rx_buffer, &mut tx_meta, &mut tx_buffer); socket.bind(1234).unwrap(); loop {