This commit is contained in:
Jonah Dahlquist 2019-08-09 17:26:14 -05:00 committed by Jonah Dahlquist
commit d2fb6b9996
8 changed files with 104 additions and 46 deletions

View file

@ -1,12 +1,12 @@
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 network::Network;
use w5500::W5500; use w5500::W5500;
pub struct InactiveW5500<SpiBus: Bus, NetworkImpl: Network> { pub struct InactiveW5500<SpiBus: Bus, NetworkImpl: Network> {
bus: SpiBus, bus: SpiBus,
network: NetworkImpl network: NetworkImpl,
} }
impl<SpiBus: Bus, NetworkImpl: Network> InactiveW5500<SpiBus, NetworkImpl> { impl<SpiBus: Bus, NetworkImpl: Network> InactiveW5500<SpiBus, NetworkImpl> {
@ -16,13 +16,19 @@ impl<SpiBus: Bus, NetworkImpl: Network> InactiveW5500<SpiBus, NetworkImpl> {
} }
impl<ChipSelect: OutputPin, NetworkImpl: Network> InactiveW5500<FourWire<ChipSelect>, NetworkImpl> { impl<ChipSelect: OutputPin, NetworkImpl: Network> InactiveW5500<FourWire<ChipSelect>, NetworkImpl> {
pub fn activate<Spi: FullDuplex<u8>>(self, spi: Spi) -> W5500<ActiveFourWire<Spi, ChipSelect>, NetworkImpl> { pub fn activate<Spi: FullDuplex<u8>>(
self,
spi: Spi,
) -> W5500<ActiveFourWire<Spi, ChipSelect>, NetworkImpl> {
W5500::new(self.bus.activate(spi), self.network) W5500::new(self.bus.activate(spi), self.network)
} }
} }
impl<NetworkImpl: Network> InactiveW5500<ThreeWire, NetworkImpl> { impl<NetworkImpl: Network> InactiveW5500<ThreeWire, NetworkImpl> {
pub fn activate<Spi: FullDuplex<u8>>(self, spi: Spi) -> W5500<ActiveThreeWire<Spi>, NetworkImpl> { pub fn activate<Spi: FullDuplex<u8>>(
self,
spi: Spi,
) -> W5500<ActiveThreeWire<Spi>, NetworkImpl> {
W5500::new(self.bus.activate(spi), self.network) W5500::new(self.bus.activate(spi), self.network)
} }
} }

View file

@ -942,7 +942,7 @@ impl Default for Mode {
pub mod bus; pub mod bus;
pub mod inactive_w5500; pub mod inactive_w5500;
mod network;
mod register;
pub mod uninitialized_w5500; pub mod uninitialized_w5500;
pub mod w5500; pub mod w5500;
mod register;
mod network;

View file

@ -1,5 +1,5 @@
use crate::bus::ActiveBus; use crate::bus::ActiveBus;
use crate::network::{Network,NetworkSettings}; use crate::network::{Network, NetworkSettings};
use crate::MacAddress; use crate::MacAddress;
pub struct Dhcp { pub struct Dhcp {

View file

@ -1,7 +1,7 @@
use crate::network::NetworkSettings;
use crate::network::Network;
use crate::bus::ActiveBus; use crate::bus::ActiveBus;
use crate::{MacAddress, IpAddress}; use crate::network::Network;
use crate::network::NetworkSettings;
use crate::{IpAddress, MacAddress};
pub struct Manual { pub struct Manual {
is_setup: bool, is_setup: bool,
@ -19,7 +19,7 @@ impl Manual {
gateway, gateway,
subnet, subnet,
}, },
current: NetworkSettings::default() current: NetworkSettings::default(),
} }
} }
} }

View file

@ -1,11 +1,11 @@
mod dhcp; mod dhcp;
mod manual; mod manual;
use crate::{MacAddress,IpAddress};
use crate::bus::ActiveBus;
use crate::register;
pub use self::dhcp::Dhcp; pub use self::dhcp::Dhcp;
pub use self::manual::Manual; pub use self::manual::Manual;
use crate::bus::ActiveBus;
use crate::register;
use crate::{IpAddress, MacAddress};
#[derive(Default)] #[derive(Default)]
pub struct NetworkSettings { pub struct NetworkSettings {
@ -17,26 +17,45 @@ pub struct NetworkSettings {
pub trait Network { pub trait Network {
/// Gets (if necessary) and sets the network settings on the chip /// Gets (if necessary) and sets the network settings on the chip
fn refresh<SpiBus: ActiveBus>(&mut self, bus: &mut SpiBus) -> Result<(), SpiBus:: Error>; fn refresh<SpiBus: ActiveBus>(&mut self, bus: &mut SpiBus) -> Result<(), SpiBus::Error>;
/// Write changed settings to chip /// Write changed settings to chip
/// ///
/// Will check all settings and write any new ones to the chip. Will update the settings returned by `current` /// Will check all settings and write any new ones to the chip. Will update the settings returned by `current`
/// with any changes. /// with any changes.
fn write_settings<SpiBus: ActiveBus>(bus: &mut SpiBus, current: &mut NetworkSettings, settings: &NetworkSettings) -> Result<(), SpiBus::Error> { fn write_settings<SpiBus: ActiveBus>(
bus: &mut SpiBus,
current: &mut NetworkSettings,
settings: &NetworkSettings,
) -> Result<(), SpiBus::Error> {
if settings.gateway != current.gateway { if settings.gateway != current.gateway {
let mut address = settings.gateway.address; let mut address = settings.gateway.address;
block!(bus.transfer_frame(register::COMMON, register::common::GATEWAY, true, &mut address))?; block!(bus.transfer_frame(
register::COMMON,
register::common::GATEWAY,
true,
&mut address
))?;
current.gateway = settings.gateway; current.gateway = settings.gateway;
} }
if settings.subnet != current.subnet { if settings.subnet != current.subnet {
let mut address = settings.subnet.address; let mut address = settings.subnet.address;
block!(bus.transfer_frame(register::COMMON, register::common::SUBNET_MASK, true, &mut address))?; block!(bus.transfer_frame(
register::COMMON,
register::common::SUBNET_MASK,
true,
&mut address
))?;
current.subnet = settings.subnet; current.subnet = settings.subnet;
} }
if settings.mac != current.mac { if settings.mac != current.mac {
let mut address = settings.mac.address; let mut address = settings.mac.address;
block!(bus.transfer_frame(register::COMMON, register::common::MAC, true, &mut address))?; block!(bus.transfer_frame(
register::COMMON,
register::common::MAC,
true,
&mut address
))?;
current.mac = settings.mac; current.mac = settings.mac;
} }
if settings.ip != current.ip { if settings.ip != current.ip {

View file

@ -1,11 +1,10 @@
pub const COMMON: u8 = 0; pub const COMMON: u8 = 0;
pub mod common { pub mod common {
pub const MODE: u16 = 0x0; pub const MODE: u16 = 0x0;
pub const GATEWAY: u16 = 0x1; pub const GATEWAY: u16 = 0x1;
pub const SUBNET_MASK: u16 = 0x5; pub const SUBNET_MASK: u16 = 0x5;
pub const MAC: u16 = 0x9; pub const MAC: u16 = 0x9;
pub const IP: u16 = 0xF; pub const IP: u16 = 0xF;
pub const VERSION: u16 = 0x39; pub const VERSION: u16 = 0x39;
} }

View file

@ -1,10 +1,10 @@
use crate::network::{Dhcp, Manual, Network};
use crate::{IpAddress, MacAddress, Mode};
use bus::{ActiveBus, ActiveFourWire, ActiveThreeWire}; use bus::{ActiveBus, ActiveFourWire, ActiveThreeWire};
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 crate::{Mode, IpAddress, MacAddress};
use crate::network::{Network,Manual,Dhcp};
use register; use register;
use w5500::W5500;
pub struct UninitializedW5500<SpiBus: ActiveBus> { pub struct UninitializedW5500<SpiBus: ActiveBus> {
bus: SpiBus, bus: SpiBus,
@ -17,38 +17,69 @@ pub enum InitializeError<SpiError> {
impl<SpiBus: ActiveBus> UninitializedW5500<SpiBus> { impl<SpiBus: ActiveBus> UninitializedW5500<SpiBus> {
pub fn new(bus: SpiBus) -> UninitializedW5500<SpiBus> { pub fn new(bus: SpiBus) -> UninitializedW5500<SpiBus> {
UninitializedW5500 { bus: bus } UninitializedW5500 { bus: bus }
} }
pub fn initialize(self, mac: MacAddress, mode_options: Mode) -> Result<W5500<SpiBus, Dhcp>, InitializeError<SpiBus::Error>> { pub fn initialize(
self,
mac: MacAddress,
mode_options: Mode,
) -> Result<W5500<SpiBus, Dhcp>, InitializeError<SpiBus::Error>> {
let network = Dhcp::new(mac); let network = Dhcp::new(mac);
self.initialize_with_network(network, mode_options) self.initialize_with_network(network, mode_options)
} }
pub fn initialize_manual(self, mac: MacAddress, ip: IpAddress, mode_options: Mode) -> Result<W5500<SpiBus, Manual>, InitializeError<SpiBus::Error>> { pub fn initialize_manual(
self,
mac: MacAddress,
ip: IpAddress,
mode_options: Mode,
) -> Result<W5500<SpiBus, Manual>, InitializeError<SpiBus::Error>> {
let mut gateway = ip; let mut gateway = ip;
gateway.address[3] = 1; gateway.address[3] = 1;
let subnet = IpAddress::new(255, 255, 255, 0); let subnet = IpAddress::new(255, 255, 255, 0);
self.initialize_advanced(mac, ip, gateway, subnet, mode_options) self.initialize_advanced(mac, ip, gateway, subnet, mode_options)
} }
pub fn initialize_advanced(self, mac: MacAddress, ip: IpAddress, gateway: IpAddress, subnet: IpAddress, mode_options: Mode) -> Result<W5500<SpiBus, Manual>, InitializeError<SpiBus::Error>>{ pub fn initialize_advanced(
self,
mac: MacAddress,
ip: IpAddress,
gateway: IpAddress,
subnet: IpAddress,
mode_options: Mode,
) -> Result<W5500<SpiBus, Manual>, InitializeError<SpiBus::Error>> {
let network = Manual::new(mac, ip, gateway, subnet); let network = Manual::new(mac, ip, gateway, subnet);
self.initialize_with_network(network, mode_options) self.initialize_with_network(network, mode_options)
} }
fn initialize_with_network<NetworkImpl: Network>(mut self, mut network: NetworkImpl, mode_options: Mode) -> Result<W5500<SpiBus, NetworkImpl>, InitializeError<SpiBus::Error>> { fn initialize_with_network<NetworkImpl: Network>(
mut self,
mut network: NetworkImpl,
mode_options: Mode,
) -> Result<W5500<SpiBus, NetworkImpl>, InitializeError<SpiBus::Error>> {
self.assert_chip_version(0x4)?; self.assert_chip_version(0x4)?;
self.set_mode(mode_options).map_err(|e| InitializeError::SpiError(e))?; self.set_mode(mode_options)
network.refresh(&mut self.bus).map_err(|e| InitializeError::SpiError(e))?; .map_err(|e| InitializeError::SpiError(e))?;
network
.refresh(&mut self.bus)
.map_err(|e| InitializeError::SpiError(e))?;
Ok(W5500::new(self.bus, network)) Ok(W5500::new(self.bus, network))
// TODO give ownership of all sockets // TODO give ownership of all sockets
} }
fn assert_chip_version(&mut self, expected_version: u8) -> Result<(), InitializeError<SpiBus::Error>> { fn assert_chip_version(
&mut self,
expected_version: u8,
) -> Result<(), InitializeError<SpiBus::Error>> {
let mut version = [0]; let mut version = [0];
block!(self.bus.transfer_frame(register::COMMON, register::common::VERSION, false, &mut version)).map_err(|e| InitializeError::SpiError(e))?; block!(self.bus.transfer_frame(
register::COMMON,
register::common::VERSION,
false,
&mut version
))
.map_err(|e| InitializeError::SpiError(e))?;
if version[0] != expected_version { if version[0] != expected_version {
Err(InitializeError::ChipNotConnected) Err(InitializeError::ChipNotConnected)
} else { } else {
@ -56,16 +87,15 @@ impl<SpiBus: ActiveBus> UninitializedW5500<SpiBus> {
} }
} }
fn set_mode( fn set_mode(&mut self, mode_options: Mode) -> Result<(), SpiBus::Error> {
&mut self,
mode_options: Mode,
) -> Result<(), SpiBus::Error> {
let mut mode = [0]; let mut mode = [0];
mode[0] |= mode_options.on_wake_on_lan as u8; mode[0] |= mode_options.on_wake_on_lan as u8;
mode[0] |= mode_options.on_ping_request as u8; mode[0] |= mode_options.on_ping_request as u8;
mode[0] |= mode_options.connection_type as u8; mode[0] |= mode_options.connection_type as u8;
mode[0] |= mode_options.arp_responses as u8; mode[0] |= mode_options.arp_responses as u8;
block!(self.bus.transfer_frame(register::COMMON, register::common::MODE, true, &mut mode))?; block!(self
.bus
.transfer_frame(register::COMMON, register::common::MODE, true, &mut mode))?;
Ok(()) Ok(())
} }
} }

View file

@ -1,9 +1,9 @@
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 network::Network;
use register; use register;
pub struct W5500<SpiBus: ActiveBus, NetworkImpl: Network> { pub struct W5500<SpiBus: ActiveBus, NetworkImpl: Network> {
@ -24,14 +24,18 @@ impl<SpiBus: ActiveBus, NetworkImpl: Network> W5500<SpiBus, NetworkImpl> {
fn clear_mode(&mut self) -> Result<(), SpiBus::Error> { fn clear_mode(&mut self) -> Result<(), SpiBus::Error> {
// reset bit // reset bit
let mut mode = [0b10000000]; let mut mode = [0b10000000];
block!(self.bus.transfer_frame(register::COMMON, register::common::MODE, true, &mut mode))?; block!(self
.bus
.transfer_frame(register::COMMON, register::common::MODE, true, &mut mode))?;
Ok(()) Ok(())
} }
//TODO open_udp_socket //TODO open_udp_socket
} }
impl<Spi: FullDuplex<u8>, ChipSelect: OutputPin, NetworkImpl: Network> W5500<ActiveFourWire<Spi, ChipSelect>, NetworkImpl> { impl<Spi: FullDuplex<u8>, ChipSelect: OutputPin, NetworkImpl: Network>
W5500<ActiveFourWire<Spi, ChipSelect>, NetworkImpl>
{
pub fn deactivate(self) -> (InactiveW5500<FourWire<ChipSelect>, NetworkImpl>, 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, self.network), spi) (InactiveW5500::new(bus, self.network), spi)