Renamed W5500 -> Device, added an Interface struct that should implement the embedded-nal traits, used it to internalize the mutability of the device
This commit is contained in:
parent
f546ff2011
commit
3cad9cac57
7 changed files with 113 additions and 83 deletions
|
|
@ -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<SpiBus: ActiveBus, NetworkImpl: Network> {
|
||||
pub struct Device<SpiBus: ActiveBus, NetworkImpl: Network> {
|
||||
pub bus: SpiBus,
|
||||
network: NetworkImpl,
|
||||
sockets: [u8; 1],
|
||||
|
|
@ -25,29 +26,28 @@ impl<E> From<E> for ResetError<E> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<SpiBus: ActiveBus, NetworkImpl: Network> W5500<SpiBus, NetworkImpl> {
|
||||
impl<SpiBus: ActiveBus, NetworkImpl: Network> Device<SpiBus, NetworkImpl> {
|
||||
pub fn new(bus: SpiBus, network: NetworkImpl) -> Self {
|
||||
W5500 {
|
||||
Device {
|
||||
bus,
|
||||
network,
|
||||
sockets: [0b11111111],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reset(mut self) -> Result<UninitializedW5500<SpiBus>, ResetError<SpiBus::Error>> {
|
||||
pub fn reset(mut self) -> Result<UninitializedDevice<SpiBus>, ResetError<SpiBus::Error>> {
|
||||
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<SpiBus: ActiveBus, NetworkImpl: Network> W5500<SpiBus, NetworkImpl> {
|
|||
None
|
||||
}
|
||||
|
||||
pub fn into_interface(self) -> Interface<SpiBus, NetworkImpl> {
|
||||
self.into()
|
||||
}
|
||||
|
||||
pub fn release_socket(&mut self, socket: Socket) -> () {
|
||||
self.sockets.set_bit(socket.index.into(), true);
|
||||
}
|
||||
|
|
@ -71,17 +75,17 @@ impl<SpiBus: ActiveBus, NetworkImpl: Network> W5500<SpiBus, NetworkImpl> {
|
|||
}
|
||||
|
||||
impl<Spi: FullDuplex<u8>, ChipSelect: OutputPin, NetworkImpl: Network>
|
||||
W5500<ActiveFourWire<Spi, ChipSelect>, NetworkImpl>
|
||||
Device<ActiveFourWire<Spi, ChipSelect>, NetworkImpl>
|
||||
{
|
||||
pub fn deactivate(self) -> (InactiveW5500<FourWire<ChipSelect>, NetworkImpl>, Spi) {
|
||||
pub fn deactivate(self) -> (InactiveDevice<FourWire<ChipSelect>, NetworkImpl>, Spi) {
|
||||
let (bus, spi) = self.bus.deactivate();
|
||||
(InactiveW5500::new(bus, self.network), spi)
|
||||
(InactiveDevice::new(bus, self.network), spi)
|
||||
}
|
||||
}
|
||||
|
||||
impl<Spi: FullDuplex<u8>, NetworkImpl: Network> W5500<ActiveThreeWire<Spi>, NetworkImpl> {
|
||||
pub fn deactivate(self) -> (InactiveW5500<ThreeWire, NetworkImpl>, Spi) {
|
||||
impl<Spi: FullDuplex<u8>, NetworkImpl: Network> Device<ActiveThreeWire<Spi>, NetworkImpl> {
|
||||
pub fn deactivate(self) -> (InactiveDevice<ThreeWire, NetworkImpl>, Spi) {
|
||||
let (bus, spi) = self.bus.deactivate();
|
||||
(InactiveW5500::new(bus, self.network), spi)
|
||||
(InactiveDevice::new(bus, self.network), spi)
|
||||
}
|
||||
}
|
||||
34
src/inactive_device.rs
Normal file
34
src/inactive_device.rs
Normal file
|
|
@ -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<SpiBus: Bus, NetworkImpl: Network> {
|
||||
bus: SpiBus,
|
||||
network: NetworkImpl,
|
||||
}
|
||||
|
||||
impl<SpiBus: Bus, NetworkImpl: Network> InactiveDevice<SpiBus, NetworkImpl> {
|
||||
pub fn new(bus: SpiBus, network: NetworkImpl) -> Self {
|
||||
Self { bus, network }
|
||||
}
|
||||
}
|
||||
|
||||
impl<ChipSelect: OutputPin, NetworkImpl: Network> InactiveDevice<FourWire<ChipSelect>, NetworkImpl> {
|
||||
pub fn activate<Spi: FullDuplex<u8>>(
|
||||
self,
|
||||
spi: Spi,
|
||||
) -> Device<ActiveFourWire<Spi, ChipSelect>, NetworkImpl> {
|
||||
Device::new(self.bus.activate(spi), self.network)
|
||||
}
|
||||
}
|
||||
|
||||
impl<NetworkImpl: Network> InactiveDevice<ThreeWire, NetworkImpl> {
|
||||
pub fn activate<Spi: FullDuplex<u8>>(
|
||||
self,
|
||||
spi: Spi,
|
||||
) -> Device<ActiveThreeWire<Spi>, NetworkImpl> {
|
||||
Device::new(self.bus.activate(spi), self.network)
|
||||
}
|
||||
}
|
||||
|
|
@ -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<SpiBus: Bus, NetworkImpl: Network> {
|
||||
bus: SpiBus,
|
||||
network: NetworkImpl,
|
||||
}
|
||||
|
||||
impl<SpiBus: Bus, NetworkImpl: Network> InactiveW5500<SpiBus, NetworkImpl> {
|
||||
pub fn new(bus: SpiBus, network: NetworkImpl) -> Self {
|
||||
Self { bus, network }
|
||||
}
|
||||
}
|
||||
|
||||
impl<ChipSelect: OutputPin, NetworkImpl: Network> InactiveW5500<FourWire<ChipSelect>, NetworkImpl> {
|
||||
pub fn activate<Spi: FullDuplex<u8>>(
|
||||
self,
|
||||
spi: Spi,
|
||||
) -> W5500<ActiveFourWire<Spi, ChipSelect>, NetworkImpl> {
|
||||
W5500::new(self.bus.activate(spi), self.network)
|
||||
}
|
||||
}
|
||||
|
||||
impl<NetworkImpl: Network> InactiveW5500<ThreeWire, NetworkImpl> {
|
||||
pub fn activate<Spi: FullDuplex<u8>>(
|
||||
self,
|
||||
spi: Spi,
|
||||
) -> W5500<ActiveThreeWire<Spi>, NetworkImpl> {
|
||||
W5500::new(self.bus.activate(spi), self.network)
|
||||
}
|
||||
}
|
||||
21
src/interface.rs
Normal file
21
src/interface.rs
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
use bus::{ActiveBus};
|
||||
use device::Device;
|
||||
use network::Network;
|
||||
use core::cell::RefCell;
|
||||
|
||||
pub struct Interface<SpiBus: ActiveBus, NetworkImpl: Network> {
|
||||
pub device: RefCell<Device<SpiBus, NetworkImpl>>,
|
||||
}
|
||||
|
||||
impl<SpiBus: ActiveBus, NetworkImpl: Network> Interface<SpiBus, NetworkImpl> {
|
||||
fn new(device: Device<SpiBus, NetworkImpl>) -> Self {
|
||||
Self { device: RefCell::new(device) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<SpiBus: ActiveBus, NetworkImpl: Network> From<Device<SpiBus, NetworkImpl>> for Interface<SpiBus, NetworkImpl> {
|
||||
fn from(device: Device<SpiBus, NetworkImpl>) -> Interface<SpiBus, NetworkImpl> {
|
||||
Interface::<SpiBus, NetworkImpl>::new(device)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
41
src/udp.rs
41
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<E: Debug> From<NbError<E>> for nb::Error<E> {
|
|||
}
|
||||
|
||||
|
||||
impl<SpiBus, NetworkImpl> UdpClient for W5500<SpiBus, NetworkImpl>
|
||||
impl<SpiBus, NetworkImpl> UdpClient for Interface<SpiBus, NetworkImpl>
|
||||
where
|
||||
SpiBus: ActiveBus,
|
||||
NetworkImpl: Network,
|
||||
{
|
||||
type UdpSocket = UdpSocket;
|
||||
type Error = UdpSocketError<SpiBus::Error>;
|
||||
fn connect(&mut self, remote: SocketAddr) -> Result<Self::UdpSocket, Self::Error> {
|
||||
fn connect(&self, remote: SocketAddr) -> Result<Self::UdpSocket, Self::Error> {
|
||||
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<SpiBus, NetworkImpl> UdpServer for W5500<SpiBus, NetworkImpl>
|
||||
impl<SpiBus, NetworkImpl> UdpServer for Interface<SpiBus, NetworkImpl>
|
||||
where
|
||||
SpiBus: ActiveBus,
|
||||
NetworkImpl: Network,
|
||||
{
|
||||
fn bind(&mut self, local_port: u16) -> Result<Self::UdpSocket, Self::Error> {
|
||||
if let Some(socket) = self.take_socket() {
|
||||
Ok(UdpSocket::new(&mut self.bus, socket, local_port)?)
|
||||
fn bind(&self, local_port: u16) -> Result<Self::UdpSocket, Self::Error> {
|
||||
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))
|
||||
|
|
|
|||
|
|
@ -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<SpiBus: ActiveBus> {
|
||||
pub struct UninitializedDevice<SpiBus: ActiveBus> {
|
||||
bus: SpiBus,
|
||||
}
|
||||
|
||||
|
|
@ -18,16 +18,16 @@ pub enum InitializeError<SpiError> {
|
|||
}
|
||||
// TODO add From impl and remove map_errs
|
||||
|
||||
impl<SpiBus: ActiveBus> UninitializedW5500<SpiBus> {
|
||||
pub fn new(bus: SpiBus) -> UninitializedW5500<SpiBus> {
|
||||
UninitializedW5500 { bus: bus }
|
||||
impl<SpiBus: ActiveBus> UninitializedDevice<SpiBus> {
|
||||
pub fn new(bus: SpiBus) -> UninitializedDevice<SpiBus> {
|
||||
UninitializedDevice { bus: bus }
|
||||
}
|
||||
|
||||
pub fn initialize(
|
||||
self,
|
||||
mac: MacAddress,
|
||||
mode_options: Mode,
|
||||
) -> Result<W5500<SpiBus, Dhcp>, InitializeError<SpiBus::Error>> {
|
||||
) -> Result<Device<SpiBus, Dhcp>, InitializeError<SpiBus::Error>> {
|
||||
let network = Dhcp::new(mac);
|
||||
self.initialize_with_network(network, mode_options)
|
||||
}
|
||||
|
|
@ -37,7 +37,7 @@ impl<SpiBus: ActiveBus> UninitializedW5500<SpiBus> {
|
|||
mac: MacAddress,
|
||||
ip: Ipv4Addr,
|
||||
mode_options: Mode,
|
||||
) -> Result<W5500<SpiBus, Manual>, InitializeError<SpiBus::Error>> {
|
||||
) -> Result<Device<SpiBus, Manual>, InitializeError<SpiBus::Error>> {
|
||||
let mut ip_bytes = ip.octets();
|
||||
ip_bytes[3] = 1;
|
||||
let gateway = Ipv4Addr::from(ip_bytes);
|
||||
|
|
@ -52,7 +52,7 @@ impl<SpiBus: ActiveBus> UninitializedW5500<SpiBus> {
|
|||
gateway: Ipv4Addr,
|
||||
subnet: Ipv4Addr,
|
||||
mode_options: Mode,
|
||||
) -> Result<W5500<SpiBus, Manual>, InitializeError<SpiBus::Error>> {
|
||||
) -> Result<Device<SpiBus, Manual>, InitializeError<SpiBus::Error>> {
|
||||
let network = Manual::new(mac, ip, gateway, subnet);
|
||||
self.initialize_with_network(network, mode_options)
|
||||
}
|
||||
|
|
@ -61,7 +61,7 @@ impl<SpiBus: ActiveBus> UninitializedW5500<SpiBus> {
|
|||
mut self,
|
||||
mut network: NetworkImpl,
|
||||
mode_options: Mode,
|
||||
) -> Result<W5500<SpiBus, NetworkImpl>, InitializeError<SpiBus::Error>> {
|
||||
) -> Result<Device<SpiBus, NetworkImpl>, InitializeError<SpiBus::Error>> {
|
||||
self.assert_chip_version(0x4)?;
|
||||
|
||||
// RESET
|
||||
|
|
@ -75,7 +75,7 @@ impl<SpiBus: ActiveBus> UninitializedW5500<SpiBus> {
|
|||
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<SpiBus: ActiveBus> UninitializedW5500<SpiBus> {
|
|||
}
|
||||
|
||||
impl<Spi: FullDuplex<u8>, ChipSelect: OutputPin>
|
||||
UninitializedW5500<ActiveFourWire<Spi, ChipSelect>>
|
||||
UninitializedDevice<ActiveFourWire<Spi, ChipSelect>>
|
||||
{
|
||||
pub fn deactivate(self) -> (Spi, ChipSelect) {
|
||||
let (bus, spi) = self.bus.deactivate();
|
||||
|
|
@ -114,7 +114,7 @@ impl<Spi: FullDuplex<u8>, ChipSelect: OutputPin>
|
|||
}
|
||||
}
|
||||
|
||||
impl<Spi: FullDuplex<u8>> UninitializedW5500<ActiveThreeWire<Spi>> {
|
||||
impl<Spi: FullDuplex<u8>> UninitializedDevice<ActiveThreeWire<Spi>> {
|
||||
pub fn deactivate(self) -> Spi {
|
||||
self.bus.deactivate().1
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue