From 7dd4c04fe46bd1d68219543ffe8c57cc7b7fbd80 Mon Sep 17 00:00:00 2001 From: Jonah Dahlquist Date: Fri, 9 Aug 2019 17:21:30 -0500 Subject: [PATCH] Renamed Settings to Mode since it only applies to network mode byte --- src/lib.rs | 6 ++-- src/uninitialized_w5500.rs | 60 ++++++++++++++++++++++++++++++-------- 2 files changed, 51 insertions(+), 15 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 919223c..5c94d26 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -136,14 +136,14 @@ pub enum ArpResponses { } #[derive(Copy, Clone, PartialEq)] -pub struct Settings { +pub struct Mode { on_wake_on_lan: OnWakeOnLan, on_ping_request: OnPingRequest, connection_type: ConnectionType, - arp_responses: ArpResponses + arp_responses: ArpResponses, } -impl Default for Settings { +impl Default for Mode { fn default() -> Self { Self { on_wake_on_lan: OnWakeOnLan::Ignore, diff --git a/src/uninitialized_w5500.rs b/src/uninitialized_w5500.rs index 34157b8..5316e04 100644 --- a/src/uninitialized_w5500.rs +++ b/src/uninitialized_w5500.rs @@ -2,33 +2,69 @@ use bus::{ActiveBus, ActiveFourWire, ActiveThreeWire}; use embedded_hal::digital::v2::OutputPin; use embedded_hal::spi::FullDuplex; use w5500::W5500; -use crate::Settings; +use crate::{Mode, IpAddress, MacAddress}; +use crate::network::{Network,Manual,Dhcp}; use register; pub struct UninitializedW5500 { bus: SpiBus, } +pub enum InitializeError { + SpiError(SpiError), + ChipNotConnected, +} + impl UninitializedW5500 { - pub fn initialize(mut self, settings: Settings) -> Result, SpiBus::Error> { - self.set_mode(settings)?; - // TODO set up IP/etc - // TODO give ownership of all sockets - Ok(W5500::new(self.bus)) - } pub fn new(bus: SpiBus) -> UninitializedW5500 { + UninitializedW5500 { bus: bus } } + pub fn initialize(self, mac: MacAddress, mode_options: Mode) -> Result, InitializeError> { + let network = Dhcp::new(mac); + self.initialize_with_network(network, mode_options) + } + + pub fn initialize_manual(self, mac: MacAddress, ip: IpAddress, mode_options: Mode) -> Result, InitializeError> { + let mut gateway = ip; + gateway.address[3] = 1; + let subnet = IpAddress::new(255, 255, 255, 0); + 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, InitializeError>{ + let network = Manual::new(mac, ip, gateway, subnet); + self.initialize_with_network(network, mode_options) + } + + fn initialize_with_network(mut self, mut network: NetworkImpl, mode_options: Mode) -> Result, InitializeError> { + self.assert_chip_version(0x4)?; + self.set_mode(mode_options).map_err(|e| InitializeError::SpiError(e))?; + network.refresh(&mut self.bus).map_err(|e| InitializeError::SpiError(e))?; + Ok(W5500::new(self.bus, network)) + // TODO give ownership of all sockets + } + + fn assert_chip_version(&mut self, expected_version: u8) -> Result<(), InitializeError> { + let mut version = [0]; + block!(self.bus.transfer_frame(register::COMMON, register::common::VERSION, false, &mut version)).map_err(|e| InitializeError::SpiError(e))?; + if version[0] != expected_version { + Err(InitializeError::ChipNotConnected) + } else { + Ok(()) + } + } + fn set_mode( &mut self, - settings: Settings, + mode_options: Mode, ) -> Result<(), SpiBus::Error> { let mut mode = [0]; - mode[0] |= settings.on_wake_on_lan as u8; - mode[0] |= settings.on_ping_request as u8; - mode[0] |= settings.connection_type as u8; - mode[0] |= settings.arp_responses 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.connection_type as u8; + mode[0] |= mode_options.arp_responses as u8; block!(self.bus.transfer_frame(register::COMMON, register::common::MODE, true, &mut mode))?; Ok(()) }