diff --git a/src/inactive_w5500.rs b/src/inactive_w5500.rs index 3bc7f7f..3aa68ad 100644 --- a/src/inactive_w5500.rs +++ b/src/inactive_w5500.rs @@ -1,26 +1,28 @@ use bus::{ActiveFourWire, ActiveThreeWire, Bus, FourWire, ThreeWire}; +use network::Network; use embedded_hal::digital::v2::OutputPin; use embedded_hal::spi::FullDuplex; use w5500::W5500; -pub struct InactiveW5500 { +pub struct InactiveW5500 { bus: SpiBus, + network: NetworkImpl } -impl InactiveW5500 { - pub fn new(bus: SpiBus) -> Self { - Self { bus } +impl InactiveW5500 { + pub fn new(bus: SpiBus, network: NetworkImpl) -> Self { + Self { bus, network } } } -impl InactiveW5500> { - pub fn activate>(self, spi: Spi) -> W5500> { - W5500::new(self.bus.activate(spi)) +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> { - W5500::new(self.bus.activate(spi)) +impl InactiveW5500 { + pub fn activate>(self, spi: Spi) -> W5500, NetworkImpl> { + W5500::new(self.bus.activate(spi), self.network) } } diff --git a/src/lib.rs b/src/lib.rs index 5c94d26..5689b1e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -945,3 +945,4 @@ pub mod inactive_w5500; pub mod uninitialized_w5500; pub mod w5500; mod register; +mod network; diff --git a/src/network/dhcp.rs b/src/network/dhcp.rs new file mode 100644 index 0000000..e1dddea --- /dev/null +++ b/src/network/dhcp.rs @@ -0,0 +1,29 @@ +use crate::bus::ActiveBus; +use crate::network::{Network,NetworkSettings}; +use crate::MacAddress; + +pub struct Dhcp { + settings: NetworkSettings, + current: NetworkSettings, +} + +impl Dhcp { + pub fn new(mac: MacAddress) -> Self { + let settings = NetworkSettings { + mac, + ..NetworkSettings::default() + }; + Self { + settings, + current: NetworkSettings::default(), + } + } +} + +impl Network for Dhcp { + /// Gets (if necessary) and sets the network settings on the chip + fn refresh(&mut self, _bus: &mut SpiBus) -> Result<(), SpiBus::Error> { + // TODO actually negotiate settings from DHCP + Ok(()) + } +} diff --git a/src/network/manual.rs b/src/network/manual.rs new file mode 100644 index 0000000..979fb79 --- /dev/null +++ b/src/network/manual.rs @@ -0,0 +1,36 @@ +use crate::network::NetworkSettings; +use crate::network::Network; +use crate::bus::ActiveBus; +use crate::{MacAddress, IpAddress}; + +pub struct Manual { + is_setup: bool, + settings: NetworkSettings, + current: NetworkSettings, +} + +impl Manual { + pub fn new(mac: MacAddress, ip: IpAddress, gateway: IpAddress, subnet: IpAddress) -> Self { + Self { + is_setup: false, + settings: NetworkSettings { + mac, + ip, + gateway, + subnet, + }, + current: NetworkSettings::default() + } + } +} + +impl Network for Manual { + /// Gets (if necessary) and sets the network settings on the chip + fn refresh(&mut self, bus: &mut SpiBus) -> Result<(), SpiBus::Error> { + if !self.is_setup { + Self::write_settings(bus, &mut self.current, &self.settings)?; + self.is_setup = true; + } + Ok(()) + } +} diff --git a/src/network/mod.rs b/src/network/mod.rs new file mode 100644 index 0000000..4f698f4 --- /dev/null +++ b/src/network/mod.rs @@ -0,0 +1,49 @@ +mod dhcp; +mod manual; + +use crate::{MacAddress,IpAddress}; +use crate::bus::ActiveBus; +use crate::register; +pub use self::dhcp::Dhcp; +pub use self::manual::Manual; + +#[derive(Default)] +pub struct NetworkSettings { + mac: MacAddress, + ip: IpAddress, + gateway: IpAddress, + subnet: IpAddress, +} + +pub trait Network { + /// Gets (if necessary) and sets the network settings on the chip + fn refresh(&mut self, bus: &mut SpiBus) -> Result<(), SpiBus:: Error>; + + /// Write changed settings to chip + /// + /// Will check all settings and write any new ones to the chip. Will update the settings returned by `current` + /// with any changes. + fn write_settings(bus: &mut SpiBus, current: &mut NetworkSettings, settings: &NetworkSettings) -> Result<(), SpiBus::Error> { + if settings.gateway != current.gateway { + let mut address = settings.gateway.address; + block!(bus.transfer_frame(register::COMMON, register::common::GATEWAY, true, &mut address))?; + current.gateway = settings.gateway; + } + if settings.subnet != current.subnet { + let mut address = settings.subnet.address; + block!(bus.transfer_frame(register::COMMON, register::common::SUBNET_MASK, true, &mut address))?; + current.subnet = settings.subnet; + } + if settings.mac != current.mac { + let mut address = settings.mac.address; + block!(bus.transfer_frame(register::COMMON, register::common::MAC, true, &mut address))?; + current.mac = settings.mac; + } + if settings.ip != current.ip { + let mut address = settings.ip.address; + block!(bus.transfer_frame(register::COMMON, register::common::IP, true, &mut address))?; + current.ip = settings.ip; + } + Ok(()) + } +} diff --git a/src/register.rs b/src/register.rs index 043056a..1c5147a 100644 --- a/src/register.rs +++ b/src/register.rs @@ -2,5 +2,10 @@ pub const COMMON: u8 = 0; pub mod common { - pub const MODE: u16 = 0; + pub const MODE: u16 = 0x0; + pub const GATEWAY: u16 = 0x1; + pub const SUBNET_MASK: u16 = 0x5; + pub const MAC: u16 = 0x9; + pub const IP: u16 = 0xF; + pub const VERSION: u16 = 0x39; } diff --git a/src/w5500.rs b/src/w5500.rs index d159927..8cf7864 100644 --- a/src/w5500.rs +++ b/src/w5500.rs @@ -1,17 +1,19 @@ use crate::inactive_w5500::InactiveW5500; use crate::uninitialized_w5500::UninitializedW5500; use bus::{ActiveBus, ActiveFourWire, ActiveThreeWire, FourWire, ThreeWire}; +use network::Network; use embedded_hal::digital::v2::OutputPin; use embedded_hal::spi::FullDuplex; use register; -pub struct W5500 { +pub struct W5500 { bus: SpiBus, + network: NetworkImpl, } -impl W5500 { - pub fn new(bus: SpiBus) -> Self { - W5500 { bus } +impl W5500 { + pub fn new(bus: SpiBus, network: NetworkImpl) -> Self { + W5500 { bus, network } } pub fn reset(mut self) -> Result, SpiBus::Error> { // TODO accept all sockets back @@ -29,16 +31,16 @@ impl W5500 { //TODO open_udp_socket } -impl, ChipSelect: OutputPin> W5500> { - pub fn deactivate(self) -> (InactiveW5500>, Spi) { +impl, ChipSelect: OutputPin, NetworkImpl: Network> W5500, NetworkImpl> { + pub fn deactivate(self) -> (InactiveW5500, NetworkImpl>, Spi) { let (bus, spi) = self.bus.deactivate(); - (InactiveW5500::new(bus), spi) + (InactiveW5500::new(bus, self.network), spi) } } -impl> W5500> { - pub fn deactivate(self) -> (InactiveW5500, Spi) { +impl, NetworkImpl: Network> W5500, NetworkImpl> { + pub fn deactivate(self) -> (InactiveW5500, Spi) { let (bus, spi) = self.bus.deactivate(); - (InactiveW5500::new(bus), spi) + (InactiveW5500::new(bus, self.network), spi) } }