From 3cad9cac5753b4dfa6aa8b403a82685a2b2606cf Mon Sep 17 00:00:00 2001 From: Jonah Dahlquist Date: Thu, 19 Nov 2020 19:28:12 -0800 Subject: [PATCH] Renamed W5500 -> Device, added an Interface struct that should implement the embedded-nal traits, used it to internalize the mutability of the device --- src/{w5500.rs => device.rs} | 34 ++++++++------- src/inactive_device.rs | 34 +++++++++++++++ src/inactive_w5500.rs | 34 --------------- src/interface.rs | 21 ++++++++++ src/lib.rs | 8 ++-- src/udp.rs | 41 ++++++++++--------- ...lized_w5500.rs => uninitialized_device.rs} | 24 +++++------ 7 files changed, 113 insertions(+), 83 deletions(-) rename src/{w5500.rs => device.rs} (61%) create mode 100644 src/inactive_device.rs delete mode 100644 src/inactive_w5500.rs create mode 100644 src/interface.rs rename src/{uninitialized_w5500.rs => uninitialized_device.rs} (81%) diff --git a/src/w5500.rs b/src/device.rs similarity index 61% rename from src/w5500.rs rename to src/device.rs index 92603d0..2030c79 100644 --- a/src/w5500.rs +++ b/src/device.rs @@ -1,5 +1,5 @@ -use crate::inactive_w5500::InactiveW5500; -use crate::uninitialized_w5500::UninitializedW5500; +use crate::inactive_device::InactiveDevice; +use crate::uninitialized_device::UninitializedDevice; use bit_field::BitArray; use bus::{ActiveBus, ActiveFourWire, ActiveThreeWire, FourWire, ThreeWire}; use embedded_hal::digital::v2::OutputPin; @@ -7,8 +7,9 @@ use embedded_hal::spi::FullDuplex; use network::Network; use register; use socket::Socket; +use interface::Interface; -pub struct W5500 { +pub struct Device { pub bus: SpiBus, network: NetworkImpl, sockets: [u8; 1], @@ -25,29 +26,28 @@ impl From for ResetError { } } -impl W5500 { +impl Device { pub fn new(bus: SpiBus, network: NetworkImpl) -> Self { - W5500 { + Device { bus, network, sockets: [0b11111111], } } - pub fn reset(mut self) -> Result, ResetError> { + pub fn reset(mut self) -> Result, ResetError> { if self.sockets != [0b11111111] { Err(ResetError::SocketsNotReleased) } else { self.clear_mode()?; - Ok(UninitializedW5500::new(self.bus)) + Ok(UninitializedDevice::new(self.bus)) } } fn clear_mode(&mut self) -> Result<(), SpiBus::Error> { // reset bit let mut mode = [0b10000000]; - self.bus - .write_frame(register::COMMON, register::common::MODE, &mut mode)?; + self.bus.write_frame(register::COMMON, register::common::MODE, &mut mode)?; Ok(()) } @@ -61,6 +61,10 @@ impl W5500 { None } + pub fn into_interface(self) -> Interface { + self.into() + } + pub fn release_socket(&mut self, socket: Socket) -> () { self.sockets.set_bit(socket.index.into(), true); } @@ -71,17 +75,17 @@ impl W5500 { } impl, ChipSelect: OutputPin, NetworkImpl: Network> - W5500, NetworkImpl> + Device, NetworkImpl> { - pub fn deactivate(self) -> (InactiveW5500, NetworkImpl>, Spi) { + pub fn deactivate(self) -> (InactiveDevice, NetworkImpl>, Spi) { let (bus, spi) = self.bus.deactivate(); - (InactiveW5500::new(bus, self.network), spi) + (InactiveDevice::new(bus, self.network), spi) } } -impl, NetworkImpl: Network> W5500, NetworkImpl> { - pub fn deactivate(self) -> (InactiveW5500, Spi) { +impl, NetworkImpl: Network> Device, NetworkImpl> { + pub fn deactivate(self) -> (InactiveDevice, Spi) { let (bus, spi) = self.bus.deactivate(); - (InactiveW5500::new(bus, self.network), spi) + (InactiveDevice::new(bus, self.network), spi) } } diff --git a/src/inactive_device.rs b/src/inactive_device.rs new file mode 100644 index 0000000..9762fd4 --- /dev/null +++ b/src/inactive_device.rs @@ -0,0 +1,34 @@ +use bus::{ActiveFourWire, ActiveThreeWire, Bus, FourWire, ThreeWire}; +use embedded_hal::digital::v2::OutputPin; +use embedded_hal::spi::FullDuplex; +use network::Network; +use device::Device; + +pub struct InactiveDevice { + bus: SpiBus, + network: NetworkImpl, +} + +impl InactiveDevice { + pub fn new(bus: SpiBus, network: NetworkImpl) -> Self { + Self { bus, network } + } +} + +impl InactiveDevice, NetworkImpl> { + pub fn activate>( + self, + spi: Spi, + ) -> Device, NetworkImpl> { + Device::new(self.bus.activate(spi), self.network) + } +} + +impl InactiveDevice { + pub fn activate>( + self, + spi: Spi, + ) -> Device, NetworkImpl> { + Device::new(self.bus.activate(spi), self.network) + } +} diff --git a/src/inactive_w5500.rs b/src/inactive_w5500.rs deleted file mode 100644 index 980f2b3..0000000 --- a/src/inactive_w5500.rs +++ /dev/null @@ -1,34 +0,0 @@ -use bus::{ActiveFourWire, ActiveThreeWire, Bus, FourWire, ThreeWire}; -use embedded_hal::digital::v2::OutputPin; -use embedded_hal::spi::FullDuplex; -use network::Network; -use w5500::W5500; - -pub struct InactiveW5500 { - bus: SpiBus, - network: NetworkImpl, -} - -impl InactiveW5500 { - pub fn new(bus: SpiBus, network: NetworkImpl) -> Self { - Self { bus, network } - } -} - -impl InactiveW5500, NetworkImpl> { - pub fn activate>( - self, - spi: Spi, - ) -> W5500, NetworkImpl> { - W5500::new(self.bus.activate(spi), self.network) - } -} - -impl InactiveW5500 { - pub fn activate>( - self, - spi: Spi, - ) -> W5500, NetworkImpl> { - W5500::new(self.bus.activate(spi), self.network) - } -} diff --git a/src/interface.rs b/src/interface.rs new file mode 100644 index 0000000..8542ebc --- /dev/null +++ b/src/interface.rs @@ -0,0 +1,21 @@ +use bus::{ActiveBus}; +use device::Device; +use network::Network; +use core::cell::RefCell; + +pub struct Interface { + pub device: RefCell>, +} + +impl Interface { + fn new(device: Device) -> Self { + Self { device: RefCell::new(device) } + } +} + +impl From> for Interface { + fn from(device: Device) -> Interface { + Interface::::new(device) + } +} + diff --git a/src/lib.rs b/src/lib.rs index ebe57db..ac870c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -74,12 +74,14 @@ impl Default for Mode { } pub mod bus; -mod inactive_w5500; +mod inactive_device; mod network; pub mod register; mod socket; mod udp; -pub mod uninitialized_w5500; -mod w5500; +pub mod uninitialized_device; +mod device; +pub mod interface; pub use bus::ActiveFourWire; +pub use interface::Interface; diff --git a/src/udp.rs b/src/udp.rs index 62b5983..b302438 100644 --- a/src/udp.rs +++ b/src/udp.rs @@ -2,7 +2,7 @@ use crate::bus::ActiveBus; use crate::network::Network; use crate::register::socketn; use crate::socket::Socket; -use crate::w5500::W5500; +use crate::interface::Interface; use core::fmt::Debug; use embedded_nal::{nb, IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4, UdpServer, UdpClient}; @@ -191,19 +191,20 @@ impl From> for nb::Error { } -impl UdpClient for W5500 +impl UdpClient for Interface where SpiBus: ActiveBus, NetworkImpl: Network, { type UdpSocket = UdpSocket; type Error = UdpSocketError; - fn connect(&mut self, remote: SocketAddr) -> Result { + fn connect(&self, remote: SocketAddr) -> Result { + let mut device = self.device.borrow_mut(); if let SocketAddr::V4(remote) = remote { - if let Some(socket) = self.take_socket() { + if let Some(socket) = device.take_socket() { // TODO find a random port - let mut udp_socket = UdpSocket::new(&mut self.bus, socket, 4000)?; - udp_socket.set_destination(&mut self.bus, remote)?; + let mut udp_socket = UdpSocket::new(&mut device.bus, socket, 4000)?; + udp_socket.set_destination(&mut device.bus, remote)?; Ok(udp_socket) } else { Err(Self::Error::NoMoreSockets) @@ -212,44 +213,46 @@ where Err(Self::Error::UnsupportedAddress) } } - fn send(&mut self, socket: &mut Self::UdpSocket, buffer: &[u8]) -> nb::Result<(), Self::Error> { - socket.send(&mut self.bus, buffer)?; + fn send(&self, socket: &mut Self::UdpSocket, buffer: &[u8]) -> nb::Result<(), Self::Error> { + socket.send(&mut self.device.borrow_mut().bus, buffer)?; Ok(()) } fn receive( - &mut self, + &self, socket: &mut Self::UdpSocket, buffer: &mut [u8], ) -> nb::Result<(usize, SocketAddr), Self::Error> { - Ok(socket.receive(&mut self.bus, buffer)?) + Ok(socket.receive(&mut self.device.borrow_mut().bus, buffer)?) } - fn close(&mut self, socket: Self::UdpSocket) -> Result<(), Self::Error> { - socket.close(&mut self.bus)?; - self.release_socket(socket.socket); + fn close(&self, socket: Self::UdpSocket) -> Result<(), Self::Error> { + let mut device = self.device.borrow_mut(); + socket.close(&mut device.bus)?; + device.release_socket(socket.socket); Ok(()) } } -impl UdpServer for W5500 +impl UdpServer for Interface where SpiBus: ActiveBus, NetworkImpl: Network, { - fn bind(&mut self, local_port: u16) -> Result { - if let Some(socket) = self.take_socket() { - Ok(UdpSocket::new(&mut self.bus, socket, local_port)?) + fn bind(&self, local_port: u16) -> Result { + let mut device = self.device.borrow_mut(); + if let Some(socket) = device.take_socket() { + Ok(UdpSocket::new(&mut device.bus, socket, local_port)?) } else { Err(Self::Error::NoMoreSockets) } } fn send_to( - &mut self, + &self, socket: &mut Self::UdpSocket, remote: SocketAddr, buffer: &[u8], ) -> nb::Result<(), Self::Error> { if let SocketAddr::V4(remote) = remote { - socket.send_to(&mut self.bus, remote, buffer)?; + socket.send_to(&mut self.device.borrow_mut().bus, remote, buffer)?; Ok(()) } else { Err(nb::Error::Other(Self::Error::UnsupportedAddress)) diff --git a/src/uninitialized_w5500.rs b/src/uninitialized_device.rs similarity index 81% rename from src/uninitialized_w5500.rs rename to src/uninitialized_device.rs index f076650..bba572c 100644 --- a/src/uninitialized_w5500.rs +++ b/src/uninitialized_device.rs @@ -5,9 +5,9 @@ use embedded_hal::digital::v2::OutputPin; use embedded_hal::spi::FullDuplex; use embedded_nal::Ipv4Addr; use register; -use w5500::W5500; +use device::Device; -pub struct UninitializedW5500 { +pub struct UninitializedDevice { bus: SpiBus, } @@ -18,16 +18,16 @@ pub enum InitializeError { } // TODO add From impl and remove map_errs -impl UninitializedW5500 { - pub fn new(bus: SpiBus) -> UninitializedW5500 { - UninitializedW5500 { bus: bus } +impl UninitializedDevice { + pub fn new(bus: SpiBus) -> UninitializedDevice { + UninitializedDevice { bus: bus } } pub fn initialize( self, mac: MacAddress, mode_options: Mode, - ) -> Result, InitializeError> { + ) -> Result, InitializeError> { let network = Dhcp::new(mac); self.initialize_with_network(network, mode_options) } @@ -37,7 +37,7 @@ impl UninitializedW5500 { mac: MacAddress, ip: Ipv4Addr, mode_options: Mode, - ) -> Result, InitializeError> { + ) -> Result, InitializeError> { let mut ip_bytes = ip.octets(); ip_bytes[3] = 1; let gateway = Ipv4Addr::from(ip_bytes); @@ -52,7 +52,7 @@ impl UninitializedW5500 { gateway: Ipv4Addr, subnet: Ipv4Addr, mode_options: Mode, - ) -> Result, InitializeError> { + ) -> Result, InitializeError> { let network = Manual::new(mac, ip, gateway, subnet); self.initialize_with_network(network, mode_options) } @@ -61,7 +61,7 @@ impl UninitializedW5500 { mut self, mut network: NetworkImpl, mode_options: Mode, - ) -> Result, InitializeError> { + ) -> Result, InitializeError> { self.assert_chip_version(0x4)?; // RESET @@ -75,7 +75,7 @@ impl UninitializedW5500 { network .refresh(&mut self.bus) .map_err(|e| InitializeError::SpiError(e))?; - Ok(W5500::new(self.bus, network)) + Ok(Device::new(self.bus, network)) } fn assert_chip_version( @@ -106,7 +106,7 @@ impl UninitializedW5500 { } impl, ChipSelect: OutputPin> - UninitializedW5500> + UninitializedDevice> { pub fn deactivate(self) -> (Spi, ChipSelect) { let (bus, spi) = self.bus.deactivate(); @@ -114,7 +114,7 @@ impl, ChipSelect: OutputPin> } } -impl> UninitializedW5500> { +impl> UninitializedDevice> { pub fn deactivate(self) -> Spi { self.bus.deactivate().1 }