Added Network trait that keeps track of network settings and has DHCP/Manual options for setting up options

This commit is contained in:
Jonah Dahlquist 2019-08-09 17:24:51 -05:00 committed by Jonah Dahlquist
commit fd9e861dde
7 changed files with 145 additions and 21 deletions

View file

@ -1,26 +1,28 @@
use bus::{ActiveFourWire, ActiveThreeWire, Bus, FourWire, ThreeWire}; use bus::{ActiveFourWire, ActiveThreeWire, Bus, FourWire, ThreeWire};
use network::Network;
use embedded_hal::digital::v2::OutputPin; use embedded_hal::digital::v2::OutputPin;
use embedded_hal::spi::FullDuplex; use embedded_hal::spi::FullDuplex;
use w5500::W5500; use w5500::W5500;
pub struct InactiveW5500<SpiBus: Bus> { pub struct InactiveW5500<SpiBus: Bus, NetworkImpl: Network> {
bus: SpiBus, bus: SpiBus,
network: NetworkImpl
} }
impl<SpiBus: Bus> InactiveW5500<SpiBus> { impl<SpiBus: Bus, NetworkImpl: Network> InactiveW5500<SpiBus, NetworkImpl> {
pub fn new(bus: SpiBus) -> Self { pub fn new(bus: SpiBus, network: NetworkImpl) -> Self {
Self { bus } Self { bus, network }
} }
} }
impl<ChipSelect: OutputPin> InactiveW5500<FourWire<ChipSelect>> { impl<ChipSelect: OutputPin, NetworkImpl: Network> InactiveW5500<FourWire<ChipSelect>, NetworkImpl> {
pub fn activate<Spi: FullDuplex<u8>>(self, spi: Spi) -> W5500<ActiveFourWire<Spi, ChipSelect>> { pub fn activate<Spi: FullDuplex<u8>>(self, spi: Spi) -> W5500<ActiveFourWire<Spi, ChipSelect>, NetworkImpl> {
W5500::new(self.bus.activate(spi)) W5500::new(self.bus.activate(spi), self.network)
} }
} }
impl InactiveW5500<ThreeWire> { impl<NetworkImpl: Network> InactiveW5500<ThreeWire, NetworkImpl> {
pub fn activate<Spi: FullDuplex<u8>>(self, spi: Spi) -> W5500<ActiveThreeWire<Spi>> { pub fn activate<Spi: FullDuplex<u8>>(self, spi: Spi) -> W5500<ActiveThreeWire<Spi>, NetworkImpl> {
W5500::new(self.bus.activate(spi)) W5500::new(self.bus.activate(spi), self.network)
} }
} }

View file

@ -945,3 +945,4 @@ pub mod inactive_w5500;
pub mod uninitialized_w5500; pub mod uninitialized_w5500;
pub mod w5500; pub mod w5500;
mod register; mod register;
mod network;

29
src/network/dhcp.rs Normal file
View file

@ -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<SpiBus: ActiveBus>(&mut self, _bus: &mut SpiBus) -> Result<(), SpiBus::Error> {
// TODO actually negotiate settings from DHCP
Ok(())
}
}

36
src/network/manual.rs Normal file
View file

@ -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<SpiBus: ActiveBus>(&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(())
}
}

49
src/network/mod.rs Normal file
View file

@ -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<SpiBus: ActiveBus>(&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<SpiBus: ActiveBus>(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(())
}
}

View file

@ -2,5 +2,10 @@
pub const COMMON: u8 = 0; pub const COMMON: u8 = 0;
pub mod common { 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;
} }

View file

@ -1,17 +1,19 @@
use crate::inactive_w5500::InactiveW5500; use crate::inactive_w5500::InactiveW5500;
use crate::uninitialized_w5500::UninitializedW5500; use crate::uninitialized_w5500::UninitializedW5500;
use bus::{ActiveBus, ActiveFourWire, ActiveThreeWire, FourWire, ThreeWire}; use bus::{ActiveBus, ActiveFourWire, ActiveThreeWire, FourWire, ThreeWire};
use network::Network;
use embedded_hal::digital::v2::OutputPin; use embedded_hal::digital::v2::OutputPin;
use embedded_hal::spi::FullDuplex; use embedded_hal::spi::FullDuplex;
use register; use register;
pub struct W5500<SpiBus: ActiveBus> { pub struct W5500<SpiBus: ActiveBus, NetworkImpl: Network> {
bus: SpiBus, bus: SpiBus,
network: NetworkImpl,
} }
impl<SpiBus: ActiveBus> W5500<SpiBus> { impl<SpiBus: ActiveBus, NetworkImpl: Network> W5500<SpiBus, NetworkImpl> {
pub fn new(bus: SpiBus) -> Self { pub fn new(bus: SpiBus, network: NetworkImpl) -> Self {
W5500 { bus } W5500 { bus, network }
} }
pub fn reset(mut self) -> Result<UninitializedW5500<SpiBus>, SpiBus::Error> { pub fn reset(mut self) -> Result<UninitializedW5500<SpiBus>, SpiBus::Error> {
// TODO accept all sockets back // TODO accept all sockets back
@ -29,16 +31,16 @@ impl<SpiBus: ActiveBus> W5500<SpiBus> {
//TODO open_udp_socket //TODO open_udp_socket
} }
impl<Spi: FullDuplex<u8>, ChipSelect: OutputPin> W5500<ActiveFourWire<Spi, ChipSelect>> { impl<Spi: FullDuplex<u8>, ChipSelect: OutputPin, NetworkImpl: Network> W5500<ActiveFourWire<Spi, ChipSelect>, NetworkImpl> {
pub fn deactivate(self) -> (InactiveW5500<FourWire<ChipSelect>>, Spi) { pub fn deactivate(self) -> (InactiveW5500<FourWire<ChipSelect>, NetworkImpl>, Spi) {
let (bus, spi) = self.bus.deactivate(); let (bus, spi) = self.bus.deactivate();
(InactiveW5500::new(bus), spi) (InactiveW5500::new(bus, self.network), spi)
} }
} }
impl<Spi: FullDuplex<u8>> W5500<ActiveThreeWire<Spi>> { impl<Spi: FullDuplex<u8>, NetworkImpl: Network> W5500<ActiveThreeWire<Spi>, NetworkImpl> {
pub fn deactivate(self) -> (InactiveW5500<ThreeWire>, Spi) { pub fn deactivate(self) -> (InactiveW5500<ThreeWire, NetworkImpl>, Spi) {
let (bus, spi) = self.bus.deactivate(); let (bus, spi) = self.bus.deactivate();
(InactiveW5500::new(bus), spi) (InactiveW5500::new(bus, self.network), spi)
} }
} }