From 30b61de2eb15978a3b80d2a2aedf30a598cc57a9 Mon Sep 17 00:00:00 2001 From: Lachezar Lechev Date: Wed, 12 Jul 2023 17:20:00 +0300 Subject: [PATCH 01/11] feat: common regs - Mode, RetryCount, RetryTime Signed-off-by: Lachezar Lechev --- src/register.rs | 174 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) diff --git a/src/register.rs b/src/register.rs index d1bfef2..d04bebe 100644 --- a/src/register.rs +++ b/src/register.rs @@ -6,13 +6,143 @@ pub mod common { use bit_field::BitArray; pub const MODE: u16 = 0x0; + + /// Register: GAR (Gateway IP Address Register) [R/W] [0x0001 – 0x0004] [0x00] pub const GATEWAY: u16 = 0x01; + + /// Register: SUBR (Subnet Mask Register) [R/W] [0x0005 – 0x0008] [0x00] pub const SUBNET_MASK: u16 = 0x05; + + /// Register: SHAR (Source Hardware Address Register) [R/W] [0x0009 – 0x000E] [0x00] pub const MAC: u16 = 0x09; + + /// Register: SIPR (Source IP Address Register) [R/W] [0x000F – 0x0012] [0x00] pub const IP: u16 = 0x0F; + + /// Register: INTLEVEL (Interrupt Low Level Timer Register) [R/W] [0x0013 – 0x0014] [0x0000] + pub const INTERRUPT_TIMER: u16 = 0x13; + + /// Register: RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] + pub const RETRY_TIME: u16 = 0x19; + + /// Register: RCR (Retry Count Register) [R/W] [0x001B] [0x08] + pub const RETRY_COUNT: u16 = 0x1B; + pub const PHY_CONFIG: u16 = 0x2E; pub const VERSION: u16 = 0x39; + /// The common register Mode. + /// + /// It differs from the [`crate::Mode`] in one key aspect - we can also + /// send a reset value to the w5500, instead of only configuring the settings. + #[derive(Debug, Clone, Copy, PartialEq, Eq)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub enum Mode { + Reset, + Mode(crate::Mode), + } + + impl Mode { + pub fn to_register(self) -> [u8; 1] { + [self.to_u8()] + } + + pub fn to_u8(self) -> u8 { + match self { + Mode::Reset => 0b10000000, + Mode::Mode(mode) => mode.to_u8(), + } + } + } + + /// A Retry Time-value + /// + /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] + /// + /// From datasheet: + /// + /// RTR configures the retransmission timeout period. The unit of timeout period is + /// 100us and the default of RTR is ‘0x07D0’ or ‘2000’. And so the default timeout period + /// is 200ms(100us X 2000). + /// During the time configured by RTR, W5500 waits for the peer response to the packet + /// that is transmitted by Sn_CR(CONNECT, DISCON, CLOSE, SEND, SEND_MAC, SEND_KEEP + /// command). If the peer does not respond within the RTR time, W5500 retransmits the + /// packet or issues timeout. + /// + /// + /// > Ex) When timeout-period is set as 400ms, RTR = (400ms / 1ms) X 10 = 4000(0x0FA0) + #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub struct RetryTime(pub(crate) u16); + + impl RetryTime { + #[inline] + pub fn to_u16(&self) -> u16 { + self.0 + } + + #[inline] + pub fn to_register(&self) -> [u8; 2] { + self.0.to_be_bytes() + } + + #[inline] + pub fn from_register(register: [u8; 2]) -> Self { + Self(u16::from_be_bytes(register)) + } + + #[inline] + pub fn from_millis(milliseconds: u16) -> Self { + Self(milliseconds * 10) + } + + #[inline] + pub fn to_millis(&self) -> u16 { + self.0 / 10 + } + } + + impl Default for RetryTime { + fn default() -> Self { + Self::from_millis(200) + } + } + + /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] + /// + /// For more details check out the rest of the datasheet documentation on the Retry count. + /// + /// From datasheet: + /// + /// RCR configures the number of time of retransmission. When retransmission occurs + /// as many as ‘RCR+1’, Timeout interrupt is issued (Sn_IR[TIMEOUT] = ‘1’). + /// + /// > Ex) RCR = 0x0007 + /// + /// The timeout of W5500 can be configurable with RTR and RCR. W5500 has two kind + /// timeout such as Address Resolution Protocol (ARP) and TCP retransmission. + /// + #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] + #[cfg_attr(feature = "defmt", derive(defmt::Format))] + pub struct RetryCount(pub u8); + + impl RetryCount { + #[inline] + pub fn to_u8(&self) -> u8 { + self.0 + } + + #[inline] + pub fn to_register(&self) -> [u8; 1] { + self.0.to_be_bytes() + } + + #[inline] + pub fn from_register(register: [u8; 1]) -> Self { + Self(register[0]) + } + } + #[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] #[repr(u8)] pub enum PhyOperationMode { @@ -119,6 +249,50 @@ pub mod common { PhyConfig([val]) } } + + #[cfg(test)] + mod test { + use super::Mode; + + #[test] + fn test_mode_register() { + let reset = Mode::Reset; + // Bit: 7 Reset (RST) should be 1 + assert_eq!(0b1000_0000, reset.to_u8()); + + let ping_respond_and_force_arp = crate::Mode { + // Bit: 7 Reset (RST) should be 0 + // Bit: 6 reserved + // Bit: 5 should be 0 - Disable WOL mode + on_wake_on_lan: crate::OnWakeOnLan::Ignore, + // Bit: 4 should be 0 - Disable Ping Block Mode + on_ping_request: crate::OnPingRequest::Respond, + // Bit: 3 should be 0 - PPoE disabled + connection_type: crate::ConnectionType::Ethernet, + // Bit: 2 reserved + // Bit: 1 should be 0 - Disabled Force ARP + arp_responses: crate::ArpResponses::Cache, + // Bit: 0 reserved + }; + assert_eq!(0b0000_0000, ping_respond_and_force_arp.to_u8()); + + let all_enabled = crate::Mode { + // Bit: 7 Reset (RST) should be 0 + // Bit: 6 reserved + // Bit: 5 should be 1 - Enable WOL mode + on_wake_on_lan: crate::OnWakeOnLan::InvokeInterrupt, + // Bit: 4 should be 0 - Disable Ping Block Mode + on_ping_request: crate::OnPingRequest::Respond, + // Bit: 3 should be 1 - PPoE enable + connection_type: crate::ConnectionType::PPoE, + // Bit: 2 reserved + // Bit: 1 should be 1 - Enable Force ARP + arp_responses: crate::ArpResponses::DropAfterUse, + // Bit: 0 reserved + }; + assert_eq!(0b0010_1010, all_enabled.to_u8()); + } + } } pub const SOCKET0: u8 = 0b000_00001; From a858bd815a2fc985d0be1f56bc4f267bcf1e1212 Mon Sep 17 00:00:00 2001 From: Lachezar Lechev Date: Wed, 12 Jul 2023 17:20:27 +0300 Subject: [PATCH 02/11] feat: Mode to register value and common mode impls - make crate no_std when not running tests Signed-off-by: Lachezar Lechev --- src/lib.rs | 60 +++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 50 insertions(+), 10 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 717c1d8..3c7d74b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,4 +1,4 @@ -#![no_std] +#![cfg_attr(not(test), no_std)] #![allow(unused)] #![deny(rustdoc::broken_intra_doc_links)] #![doc = include_str!("../README.md")] @@ -14,50 +14,68 @@ pub mod tcp; pub mod udp; mod uninitialized_device; -pub use device::{Device, DeviceRefMut, InactiveDevice}; -pub use host::{Dhcp, Host, HostConfig, Manual}; -pub use net::MacAddress; -pub use uninitialized_device::{InitializeError, UninitializedDevice}; +#[doc(inline)] +pub use self::{ + device::{Device, DeviceRefMut, InactiveDevice}, + host::{Dhcp, Host, HostConfig, Manual}, + net::MacAddress, + uninitialized_device::{InitializeError, UninitializedDevice} +}; + +use register::common; // TODO add better docs to all public items, add unit tests. /// Settings for wake on LAN. Allows the W5500 to optionally emit an interrupt upon receiving a packet #[repr(u8)] -#[derive(Copy, Clone, Debug, PartialOrd, PartialEq)] +#[derive(Copy, Clone, Debug, PartialOrd, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum OnWakeOnLan { InvokeInterrupt = 0b00100000, Ignore = 0b00000000, } +/// Ping Block Mode +/// /// Settings for ping. Allows the W5500 to respond to or ignore network ping requests #[repr(u8)] -#[derive(Copy, Clone, Debug, PartialOrd, PartialEq)] +#[derive(Copy, Clone, Debug, PartialOrd, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum OnPingRequest { + /// 0: Disable Ping block Respond = 0b00000000, + /// 1 : Enable Ping block + /// + /// If the bit is ‘1’, it blocks the response to a ping request. Ignore = 0b00010000, } /// Use [ConnectionType::PPoE] when talking /// to an ADSL modem. Otherwise use [ConnectionType::Ethernet] #[repr(u8)] -#[derive(Copy, Clone, Debug, PartialOrd, PartialEq)] +#[derive(Copy, Clone, Debug, PartialOrd, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub enum ConnectionType { PPoE = 0b00001000, Ethernet = 0b00000000, } -#[derive(Copy, Clone, Debug, PartialOrd, PartialEq)] +/// Force ARP +/// +#[derive(Copy, Clone, Debug, PartialOrd, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] #[repr(u8)] pub enum ArpResponses { + /// 0 : Disable Force ARP mode Cache = 0b00000000, + /// 1 : Enable Force ARP mode + /// + /// In Force ARP mode, It forces on sending ARP Request whenever data is + /// sent. DropAfterUse = 0b00000010, } -#[derive(Copy, Clone, Debug, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] pub struct Mode { pub on_wake_on_lan: OnWakeOnLan, @@ -66,6 +84,28 @@ pub struct Mode { pub arp_responses: ArpResponses, } +impl Mode { + pub fn to_register(self) -> [u8; 1] { + [self.to_u8()] + } + + pub fn to_u8(self) -> u8 { + let mut register = 0; + register |= self.on_wake_on_lan as u8; + register |= self.on_ping_request as u8; + register |= self.connection_type as u8; + register |= self.arp_responses as u8; + + register + } +} + +impl From for common::Mode { + fn from(value: Mode) -> Self { + Self::Mode(value) + } +} + impl Default for Mode { fn default() -> Self { Self { From 2166c39ac4e6133674e4d5d53b8ef53b9d1c206f Mon Sep 17 00:00:00 2001 From: Lachezar Lechev Date: Wed, 12 Jul 2023 17:26:42 +0300 Subject: [PATCH 03/11] feat: Bus - add default impls for common registers Signed-off-by: Lachezar Lechev --- src/bus/mod.rs | 108 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 insertions(+) diff --git a/src/bus/mod.rs b/src/bus/mod.rs index f7b7f17..eb35a61 100644 --- a/src/bus/mod.rs +++ b/src/bus/mod.rs @@ -4,6 +4,11 @@ mod four_wire; mod four_wire_ref; mod three_wire; +use crate::register::{ + self, + common::{RetryCount, RetryTime, MODE,VERSION, PhyConfig}, +}; + pub use self::four_wire::FourWire; pub use self::four_wire::FourWireError; pub use self::four_wire_ref::FourWireRef; @@ -18,6 +23,109 @@ pub trait Bus { fn read_frame(&mut self, block: u8, address: u16, data: &mut [u8]) -> Result<(), Self::Error>; fn write_frame(&mut self, block: u8, address: u16, data: &[u8]) -> Result<(), Self::Error>; + + /// Reset the device + #[inline] + fn reset(&mut self) -> Result<(), Self::Error> { + self.write_frame( + register::COMMON, + register::common::MODE, + ®ister::common::Mode::Reset.to_register(), + )?; + + Ok(()) + } + + #[inline] + fn set_mode(&mut self, mode_options: register::common::Mode) -> Result<(), Self::Error> { + self.write_frame( + register::COMMON, + register::common::MODE, + &mode_options.to_register(), + )?; + Ok(()) + } + + #[inline] + fn version(&mut self) -> Result { + let mut version_register = [0_u8]; + self.read_frame( + register::COMMON, + register::common::VERSION, + &mut version_register, + )?; + + Ok(version_register[0]) + } + + /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] + /// + /// # Example + /// ``` + /// use w5500::register::common::RetryTime; + /// + /// let default = RetryTime::from_millis(200); + /// assert_eq!(RetryTime::default(), default); + /// + /// // E.g. 4000 (register) = 400ms + /// let four_hundred_ms = RetryTime::from_millis(400); + /// assert_eq!(four_hundred_ms.to_u16(), 4000); + /// ``` + #[inline] + fn set_retry_timeout(&mut self, retry_time_value: RetryTime) -> Result<(), Self::Error> { + self.write_frame( + register::COMMON, + register::common::RETRY_TIME, + &retry_time_value.to_register(), + )?; + + Ok(()) + } + + /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] + /// + /// E.g. 4000 = 400ms + #[inline] + fn current_retry_timeout(&mut self) -> Result { + let mut retry_time_register: [u8; 2] = [0, 0]; + self.read_frame( + register::COMMON, + register::common::RETRY_TIME, + &mut retry_time_register, + )?; + + Ok(RetryTime::from_register(retry_time_register)) + } + + /// Set a new value for the Retry Count register. + /// + /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] + fn set_retry_count(&mut self, retry_count: RetryCount) -> Result<(), Self::Error> { + self.write_frame( + register::COMMON, + register::common::RETRY_COUNT, + &retry_count.to_register(), + )?; + + Ok(()) + } + + /// Get the current Retry Count value + /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] + /// + /// E.g. In case of errors it will retry for 7 times: + /// `RCR = 0x0007` + #[inline] + fn current_retry_count(&mut self) -> Result { + let mut retry_count_register: [u8; 1] = [0]; + self.read_frame( + register::COMMON, + register::common::RETRY_COUNT, + &mut retry_count_register, + )?; + + Ok(RetryCount::from_register(retry_count_register)) + } } pub struct BusRef<'a, B: Bus>(pub &'a mut B); From 1450ba01905413cf3a13639fbc4a8434a80dd17d Mon Sep 17 00:00:00 2001 From: Lachezar Lechev Date: Wed, 12 Jul 2023 17:26:48 +0300 Subject: [PATCH 04/11] feat: uninit. device - RetryCount & RetryTime Signed-off-by: Lachezar Lechev --- src/uninitialized_device.rs | 76 ++++++++++++++++++++++++++++++------- 1 file changed, 63 insertions(+), 13 deletions(-) diff --git a/src/uninitialized_device.rs b/src/uninitialized_device.rs index ae230a3..b943eb8 100644 --- a/src/uninitialized_device.rs +++ b/src/uninitialized_device.rs @@ -6,8 +6,13 @@ use crate::bus::{Bus, FourWire, ThreeWire}; use crate::device::Device; use crate::host::{Dhcp, Host, Manual}; use crate::raw_device::RawDevice; -use crate::register; -use crate::{MacAddress, Mode}; +use crate::{ + register::{ + self, + common::{RetryCount, RetryTime}, + }, + MacAddress, Mode, +}; #[derive(Debug)] #[cfg_attr(feature = "defmt", derive(defmt::Format))] @@ -92,9 +97,7 @@ impl UninitializedDevice { self.assert_chip_version(0x4)?; // RESET - let mode = [0b10000000]; - self.bus - .write_frame(register::COMMON, register::common::MODE, &mode)?; + self.reset()?; self.set_mode(mode_options)?; host.refresh(&mut self.bus)?; @@ -115,6 +118,55 @@ impl UninitializedDevice { RawDevice::new(self.bus) } + /// Get the currently set Retry Time-value Register. + /// + /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] + /// + /// E.g. 4000 = 400ms + #[inline] + pub fn current_retry_timeout(&mut self) -> Result { + self.bus.current_retry_timeout() + } + + /// Set a new value for the Retry Time-value Register. + /// + /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] + /// + /// # Example + /// ``` + /// use w5500::register::common::RetryTime; + /// + /// let default = RetryTime::from_millis(200); + /// assert_eq!(RetryTime::default(), default); + /// + /// // E.g. 4000 (register) = 400ms + /// let four_hundred_ms = RetryTime::from_millis(400); + /// assert_eq!(four_hundred_ms.to_u16(), 4000); + /// ``` + #[inline] + pub fn set_retry_timeout(&mut self, retry_time_value: RetryTime) -> Result<(), SpiBus::Error> { + self.bus.set_retry_timeout(retry_time_value) + } + + /// Get the current Retry Count Register value. + /// + /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] + /// + /// E.g. In case of errors it will retry for 7 times: + /// `RCR = 0x0007` + #[inline] + pub fn current_retry_count(&mut self) -> Result { + self.bus.current_retry_count() + } + + /// Set a new value for the Retry Count register. + /// + /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] + #[inline] + pub fn set_retry_count(&mut self, retry_count: RetryCount) -> Result<(), SpiBus::Error> { + self.bus.set_retry_count(retry_count) + } + #[cfg(not(feature = "no-chip-version-assertion"))] fn assert_chip_version( &mut self, @@ -130,15 +182,13 @@ impl UninitializedDevice { } } + /// RESET + fn reset(&mut self) -> Result<(), SpiBus::Error> { + self.bus.reset() + } + fn set_mode(&mut self, mode_options: Mode) -> Result<(), SpiBus::Error> { - let mut mode = [0]; - 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; - self.bus - .write_frame(register::COMMON, register::common::MODE, &mode)?; - Ok(()) + self.bus.set_mode(mode_options.into()) } } From a8214b83ecab48fb7a6d0344fc0055a487397e8b Mon Sep 17 00:00:00 2001 From: Lachezar Lechev Date: Wed, 12 Jul 2023 17:27:42 +0300 Subject: [PATCH 05/11] feat: device - RetryCount & RetryTime Signed-off-by: Lachezar Lechev --- src/device.rs | 103 +++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 98 insertions(+), 5 deletions(-) diff --git a/src/device.rs b/src/device.rs index bf41a7c..5de4b09 100644 --- a/src/device.rs +++ b/src/device.rs @@ -52,11 +52,8 @@ impl Device { } fn clear_mode(&mut self) -> Result<(), SpiBus::Error> { - // reset bit - let mode = [0b10000000]; - self.bus - .write_frame(register::COMMON, register::common::MODE, &mode)?; - Ok(()) + // Set RST common register of the w5500 + self.bus.reset() } #[inline] @@ -89,6 +86,53 @@ impl Device { self.as_mut().version() } + /// Get the currently set Retry Time-value Register. + /// + /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] + #[inline] + pub fn current_retry_timeout(&mut self) -> Result { + self.as_mut().current_retry_timeout() + } + + /// Set a new value for the Retry Time-value Register. + /// + /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] + /// + /// # Example + /// ``` + /// use w5500::register::common::RetryTime; + /// + /// let default = RetryTime::from_millis(200); + /// assert_eq!(RetryTime::default(), default); + /// + /// // E.g. 4000 (register) = 400ms + /// let four_hundred_ms = RetryTime::from_millis(400); + /// assert_eq!(four_hundred_ms.to_u16(), 4000); + /// ``` + #[inline] + pub fn set_retry_timeout(&mut self, retry_time_value: RetryTime) -> Result<(), SpiBus::Error> { + self.as_mut().set_retry_timeout(retry_time_value) + } + + /// Get the current Retry Count Register value. + /// + /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] + /// + /// E.g. In case of errors it will retry for 7 times: + /// `RCR = 0x0007` + #[inline] + pub fn current_retry_count(&mut self) -> Result { + self.as_mut().current_retry_count() + } + + /// Set a new value for the Retry Count register. + /// + /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] + #[inline] + pub fn set_retry_count(&mut self, retry_count: RetryCount) -> Result<(), SpiBus::Error> { + self.as_mut().set_retry_count(retry_count) + } + #[inline] pub(crate) fn as_mut(&mut self) -> DeviceRefMut<'_, BusRef<'_, SpiBus>, HostImpl> { DeviceRefMut { @@ -187,4 +231,53 @@ impl DeviceRefMut<'_, SpiBus, HostImpl> { .read_frame(register::COMMON, register::common::VERSION, &mut version)?; Ok(version[0]) } + + /// Get the currently set Retry Time-value Register. + /// + /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] + /// + /// E.g. 4000 = 400ms + #[inline] + pub fn current_retry_timeout(&mut self) -> Result { + self.bus.current_retry_timeout() + } + + /// Set a new value for the Retry Time-value Register. + /// + /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] + /// + /// # Example + /// ``` + /// use w5500::register::common::RetryTime; + /// + /// let default = RetryTime::from_millis(200); + /// assert_eq!(RetryTime::default(), default); + /// + /// // E.g. 4000 (register) = 400ms + /// let four_hundred_ms = RetryTime::from_millis(400); + /// assert_eq!(four_hundred_ms.to_u16(), 4000); + /// ``` + #[inline] + pub fn set_retry_timeout(&mut self, retry_time_value: RetryTime) -> Result<(), SpiBus::Error> { + self.bus.set_retry_timeout(retry_time_value) + } + + /// Get the current Retry Count Register value. + /// + /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] + /// + /// E.g. In case of errors it will retry for 7 times: + /// `RCR = 0x0007` + #[inline] + pub fn current_retry_count(&mut self) -> Result { + self.bus.current_retry_count() + } + + /// Set a new value for the Retry Count register. + /// + /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] + #[inline] + pub fn set_retry_count(&mut self, retry_count: RetryCount) -> Result<(), SpiBus::Error> { + self.bus.set_retry_count(retry_count) + } } From dbb9189b7f9723156da65ca70318b3280065f8d2 Mon Sep 17 00:00:00 2001 From: Lachezar Lechev Date: Wed, 12 Jul 2023 17:42:09 +0300 Subject: [PATCH 06/11] chore: uninit. device - call Bus version method Signed-off-by: Lachezar Lechev --- src/uninitialized_device.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/uninitialized_device.rs b/src/uninitialized_device.rs index b943eb8..1db4a25 100644 --- a/src/uninitialized_device.rs +++ b/src/uninitialized_device.rs @@ -172,10 +172,9 @@ impl UninitializedDevice { &mut self, expected_version: u8, ) -> Result<(), InitializeError> { - let mut version = [0]; - self.bus - .read_frame(register::COMMON, register::common::VERSION, &mut version)?; - if version[0] != expected_version { + let version = self.bus.version()?; + + if version != expected_version { Err(InitializeError::ChipNotConnected) } else { Ok(()) From 43fda7bab1a93f982ed1e8ac56aa8b2063e31e42 Mon Sep 17 00:00:00 2001 From: Lachezar Lechev Date: Wed, 12 Jul 2023 17:44:01 +0300 Subject: [PATCH 07/11] fix: device import & rustfmt Signed-off-by: Lachezar Lechev --- src/bus/mod.rs | 2 +- src/device.rs | 5 ++++- src/lib.rs | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/bus/mod.rs b/src/bus/mod.rs index eb35a61..970f878 100644 --- a/src/bus/mod.rs +++ b/src/bus/mod.rs @@ -6,7 +6,7 @@ mod three_wire; use crate::register::{ self, - common::{RetryCount, RetryTime, MODE,VERSION, PhyConfig}, + common::{PhyConfig, RetryCount, RetryTime, MODE, VERSION}, }; pub use self::four_wire::FourWire; diff --git a/src/device.rs b/src/device.rs index 5de4b09..29be4c3 100644 --- a/src/device.rs +++ b/src/device.rs @@ -6,7 +6,10 @@ use crate::host::Host; use crate::net::Ipv4Addr; use crate::socket::Socket; use crate::uninitialized_device::UninitializedDevice; -use crate::{register, MacAddress}; +use crate::{ + common::{RetryCount, RetryTime}, + register, MacAddress, +}; pub enum ResetError { SocketsNotReleased, diff --git a/src/lib.rs b/src/lib.rs index b1b58e1..a63eff5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -20,7 +20,7 @@ pub use self::{ device::{Device, DeviceRefMut, InactiveDevice}, host::{Dhcp, Host, HostConfig, Manual}, net::MacAddress, - uninitialized_device::{InitializeError, UninitializedDevice} + uninitialized_device::{InitializeError, UninitializedDevice}, }; use register::common; From 360496e4a910126c809ebb22f4fd79df7858bb32 Mon Sep 17 00:00:00 2001 From: Lachezar Lechev Date: Wed, 12 Jul 2023 17:46:03 +0300 Subject: [PATCH 08/11] chore: update changelog Signed-off-by: Lachezar Lechev --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e8becb3..eabc4e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add `defmt` features for enabling `defmt::Format` to most structs and errors by [@elpiel](https://github.com/elpiel) ([#39](https://github.com/kellerkindt/w5500/issues/39)) - Fixed an issue where internal function names were conflicting with trait names by [@ryan-summers](https://github.com/ryan-summers) ([#36](https://github.com/kellerkindt/w5500/issues/36)) +- Add `RetryTime` value and `RetryCount` registers methods and common register methods to `Bus` by [@elpiel](https://github.com/elpiel) ([#54][PR54]) ### Fixed From 29f531387da166e01836613c36bf83bee4d512e0 Mon Sep 17 00:00:00 2001 From: Lachezar Lechev Date: Thu, 13 Jul 2023 11:40:09 +0300 Subject: [PATCH 09/11] chore: Bus move default impls to device & uninit device Signed-off-by: Lachezar Lechev --- src/bus/mod.rs | 103 ------------------------------------ src/device.rs | 95 ++++++++++++++++++++++++--------- src/uninitialized_device.rs | 102 ++++++++++++++++++++++++----------- 3 files changed, 140 insertions(+), 160 deletions(-) diff --git a/src/bus/mod.rs b/src/bus/mod.rs index 970f878..7ad9a32 100644 --- a/src/bus/mod.rs +++ b/src/bus/mod.rs @@ -23,109 +23,6 @@ pub trait Bus { fn read_frame(&mut self, block: u8, address: u16, data: &mut [u8]) -> Result<(), Self::Error>; fn write_frame(&mut self, block: u8, address: u16, data: &[u8]) -> Result<(), Self::Error>; - - /// Reset the device - #[inline] - fn reset(&mut self) -> Result<(), Self::Error> { - self.write_frame( - register::COMMON, - register::common::MODE, - ®ister::common::Mode::Reset.to_register(), - )?; - - Ok(()) - } - - #[inline] - fn set_mode(&mut self, mode_options: register::common::Mode) -> Result<(), Self::Error> { - self.write_frame( - register::COMMON, - register::common::MODE, - &mode_options.to_register(), - )?; - Ok(()) - } - - #[inline] - fn version(&mut self) -> Result { - let mut version_register = [0_u8]; - self.read_frame( - register::COMMON, - register::common::VERSION, - &mut version_register, - )?; - - Ok(version_register[0]) - } - - /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] - /// - /// # Example - /// ``` - /// use w5500::register::common::RetryTime; - /// - /// let default = RetryTime::from_millis(200); - /// assert_eq!(RetryTime::default(), default); - /// - /// // E.g. 4000 (register) = 400ms - /// let four_hundred_ms = RetryTime::from_millis(400); - /// assert_eq!(four_hundred_ms.to_u16(), 4000); - /// ``` - #[inline] - fn set_retry_timeout(&mut self, retry_time_value: RetryTime) -> Result<(), Self::Error> { - self.write_frame( - register::COMMON, - register::common::RETRY_TIME, - &retry_time_value.to_register(), - )?; - - Ok(()) - } - - /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] - /// - /// E.g. 4000 = 400ms - #[inline] - fn current_retry_timeout(&mut self) -> Result { - let mut retry_time_register: [u8; 2] = [0, 0]; - self.read_frame( - register::COMMON, - register::common::RETRY_TIME, - &mut retry_time_register, - )?; - - Ok(RetryTime::from_register(retry_time_register)) - } - - /// Set a new value for the Retry Count register. - /// - /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] - fn set_retry_count(&mut self, retry_count: RetryCount) -> Result<(), Self::Error> { - self.write_frame( - register::COMMON, - register::common::RETRY_COUNT, - &retry_count.to_register(), - )?; - - Ok(()) - } - - /// Get the current Retry Count value - /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] - /// - /// E.g. In case of errors it will retry for 7 times: - /// `RCR = 0x0007` - #[inline] - fn current_retry_count(&mut self) -> Result { - let mut retry_count_register: [u8; 1] = [0]; - self.read_frame( - register::COMMON, - register::common::RETRY_COUNT, - &mut retry_count_register, - )?; - - Ok(RetryCount::from_register(retry_count_register)) - } } pub struct BusRef<'a, B: Bus>(pub &'a mut B); diff --git a/src/device.rs b/src/device.rs index 29be4c3..87cda84 100644 --- a/src/device.rs +++ b/src/device.rs @@ -56,7 +56,7 @@ impl Device { fn clear_mode(&mut self) -> Result<(), SpiBus::Error> { // Set RST common register of the w5500 - self.bus.reset() + self.as_mut().reset() } #[inline] @@ -102,6 +102,7 @@ impl Device { /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] /// /// # Example + /// /// ``` /// use w5500::register::common::RetryTime; /// @@ -228,28 +229,38 @@ impl DeviceRefMut<'_, SpiBus, HostImpl> { Ok(phy[0].into()) } - pub fn version(&mut self) -> Result { - let mut version = [0u8]; - self.bus - .read_frame(register::COMMON, register::common::VERSION, &mut version)?; - Ok(version[0]) + /// Reset the device + #[inline] + fn reset(&mut self) -> Result<(), SpiBus::Error> { + self.set_mode(register::common::Mode::Reset) } - /// Get the currently set Retry Time-value Register. - /// - /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] - /// - /// E.g. 4000 = 400ms #[inline] - pub fn current_retry_timeout(&mut self) -> Result { - self.bus.current_retry_timeout() + fn set_mode(&mut self, mode_options: register::common::Mode) -> Result<(), SpiBus::Error> { + self.bus.write_frame( + register::COMMON, + register::common::MODE, + &mode_options.to_register(), + )?; + Ok(()) + } + + #[inline] + fn version(&mut self) -> Result { + let mut version_register = [0_u8]; + self.bus.read_frame( + register::COMMON, + register::common::VERSION, + &mut version_register, + )?; + + Ok(version_register[0]) } - /// Set a new value for the Retry Time-value Register. - /// /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] /// /// # Example + /// /// ``` /// use w5500::register::common::RetryTime; /// @@ -261,26 +272,58 @@ impl DeviceRefMut<'_, SpiBus, HostImpl> { /// assert_eq!(four_hundred_ms.to_u16(), 4000); /// ``` #[inline] - pub fn set_retry_timeout(&mut self, retry_time_value: RetryTime) -> Result<(), SpiBus::Error> { - self.bus.set_retry_timeout(retry_time_value) + fn set_retry_timeout(&mut self, retry_time_value: RetryTime) -> Result<(), SpiBus::Error> { + self.bus.write_frame( + register::COMMON, + register::common::RETRY_TIME, + &retry_time_value.to_register(), + )?; + + Ok(()) } - /// Get the current Retry Count Register value. - /// - /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] + /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] /// - /// E.g. In case of errors it will retry for 7 times: - /// `RCR = 0x0007` + /// E.g. 4000 = 400ms #[inline] - pub fn current_retry_count(&mut self) -> Result { - self.bus.current_retry_count() + fn current_retry_timeout(&mut self) -> Result { + let mut retry_time_register: [u8; 2] = [0, 0]; + self.bus.read_frame( + register::COMMON, + register::common::RETRY_TIME, + &mut retry_time_register, + )?; + + Ok(RetryTime::from_register(retry_time_register)) } /// Set a new value for the Retry Count register. /// /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] + fn set_retry_count(&mut self, retry_count: RetryCount) -> Result<(), SpiBus::Error> { + self.bus.write_frame( + register::COMMON, + register::common::RETRY_COUNT, + &retry_count.to_register(), + )?; + + Ok(()) + } + + /// Get the current Retry Count value + /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] + /// + /// E.g. In case of errors it will retry for 7 times: + /// `RCR = 0x0007` #[inline] - pub fn set_retry_count(&mut self, retry_count: RetryCount) -> Result<(), SpiBus::Error> { - self.bus.set_retry_count(retry_count) + fn current_retry_count(&mut self) -> Result { + let mut retry_count_register: [u8; 1] = [0]; + self.bus.read_frame( + register::COMMON, + register::common::RETRY_COUNT, + &mut retry_count_register, + )?; + + Ok(RetryCount::from_register(retry_count_register)) } } diff --git a/src/uninitialized_device.rs b/src/uninitialized_device.rs index 1db4a25..70ecb54 100644 --- a/src/uninitialized_device.rs +++ b/src/uninitialized_device.rs @@ -99,7 +99,7 @@ impl UninitializedDevice { // RESET self.reset()?; - self.set_mode(mode_options)?; + self.set_mode(mode_options.into())?; host.refresh(&mut self.bus)?; Ok(Device::new(self.bus, host)) } @@ -118,21 +118,38 @@ impl UninitializedDevice { RawDevice::new(self.bus) } - /// Get the currently set Retry Time-value Register. - /// - /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] - /// - /// E.g. 4000 = 400ms + /// Reset the device #[inline] - pub fn current_retry_timeout(&mut self) -> Result { - self.bus.current_retry_timeout() + fn reset(&mut self) -> Result<(), SpiBus::Error> { + self.set_mode(register::common::Mode::Reset) + } + + #[inline] + fn set_mode(&mut self, mode_options: register::common::Mode) -> Result<(), SpiBus::Error> { + self.bus.write_frame( + register::COMMON, + register::common::MODE, + &mode_options.to_register(), + )?; + Ok(()) + } + + #[inline] + fn version(&mut self) -> Result { + let mut version_register = [0_u8]; + self.bus.read_frame( + register::COMMON, + register::common::VERSION, + &mut version_register, + )?; + + Ok(version_register[0]) } - /// Set a new value for the Retry Time-value Register. - /// /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] /// /// # Example + /// /// ``` /// use w5500::register::common::RetryTime; /// @@ -144,27 +161,59 @@ impl UninitializedDevice { /// assert_eq!(four_hundred_ms.to_u16(), 4000); /// ``` #[inline] - pub fn set_retry_timeout(&mut self, retry_time_value: RetryTime) -> Result<(), SpiBus::Error> { - self.bus.set_retry_timeout(retry_time_value) + fn set_retry_timeout(&mut self, retry_time_value: RetryTime) -> Result<(), SpiBus::Error> { + self.bus.write_frame( + register::COMMON, + register::common::RETRY_TIME, + &retry_time_value.to_register(), + )?; + + Ok(()) } - /// Get the current Retry Count Register value. - /// - /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] + /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] /// - /// E.g. In case of errors it will retry for 7 times: - /// `RCR = 0x0007` + /// E.g. 4000 = 400ms #[inline] - pub fn current_retry_count(&mut self) -> Result { - self.bus.current_retry_count() + fn current_retry_timeout(&mut self) -> Result { + let mut retry_time_register: [u8; 2] = [0, 0]; + self.bus.read_frame( + register::COMMON, + register::common::RETRY_TIME, + &mut retry_time_register, + )?; + + Ok(RetryTime::from_register(retry_time_register)) } /// Set a new value for the Retry Count register. /// /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] + fn set_retry_count(&mut self, retry_count: RetryCount) -> Result<(), SpiBus::Error> { + self.bus.write_frame( + register::COMMON, + register::common::RETRY_COUNT, + &retry_count.to_register(), + )?; + + Ok(()) + } + + /// Get the current Retry Count value + /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] + /// + /// E.g. In case of errors it will retry for 7 times: + /// `RCR = 0x0007` #[inline] - pub fn set_retry_count(&mut self, retry_count: RetryCount) -> Result<(), SpiBus::Error> { - self.bus.set_retry_count(retry_count) + fn current_retry_count(&mut self) -> Result { + let mut retry_count_register: [u8; 1] = [0]; + self.bus.read_frame( + register::COMMON, + register::common::RETRY_COUNT, + &mut retry_count_register, + )?; + + Ok(RetryCount::from_register(retry_count_register)) } #[cfg(not(feature = "no-chip-version-assertion"))] @@ -172,7 +221,7 @@ impl UninitializedDevice { &mut self, expected_version: u8, ) -> Result<(), InitializeError> { - let version = self.bus.version()?; + let version = self.version()?; if version != expected_version { Err(InitializeError::ChipNotConnected) @@ -180,15 +229,6 @@ impl UninitializedDevice { Ok(()) } } - - /// RESET - fn reset(&mut self) -> Result<(), SpiBus::Error> { - self.bus.reset() - } - - fn set_mode(&mut self, mode_options: Mode) -> Result<(), SpiBus::Error> { - self.bus.set_mode(mode_options.into()) - } } impl + Write, ChipSelect: OutputPin> From f726d2b9a53c72c7b2f1ddbfb6c6513415e4938d Mon Sep 17 00:00:00 2001 From: Lachezar Lechev Date: Thu, 13 Jul 2023 11:41:10 +0300 Subject: [PATCH 10/11] chore: update changelog Signed-off-by: Lachezar Lechev --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index eabc4e4..1253928 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add `defmt` features for enabling `defmt::Format` to most structs and errors by [@elpiel](https://github.com/elpiel) ([#39](https://github.com/kellerkindt/w5500/issues/39)) - Fixed an issue where internal function names were conflicting with trait names by [@ryan-summers](https://github.com/ryan-summers) ([#36](https://github.com/kellerkindt/w5500/issues/36)) -- Add `RetryTime` value and `RetryCount` registers methods and common register methods to `Bus` by [@elpiel](https://github.com/elpiel) ([#54][PR54]) +- Add `RetryTime` value and `RetryCount` registers methods and common register methods to `Device` and `UninitializedDevice` by [@elpiel](https://github.com/elpiel) ([#54][PR54]) ### Fixed From 545debf0e3b0a6f080487ca463e7f3cb7462501f Mon Sep 17 00:00:00 2001 From: Lachezar Lechev Date: Thu, 13 Jul 2023 12:10:46 +0300 Subject: [PATCH 11/11] chore: simplify Signed-off-by: Lachezar Lechev --- CHANGELOG.md | 2 +- src/bus/mod.rs | 5 -- src/device.rs | 58 +++++++++++--------- src/lib.rs | 48 ++++++++++++++--- src/register.rs | 103 ------------------------------------ src/uninitialized_device.rs | 47 +++++++++------- 6 files changed, 103 insertions(+), 160 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1253928..a26c042 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Add `defmt` features for enabling `defmt::Format` to most structs and errors by [@elpiel](https://github.com/elpiel) ([#39](https://github.com/kellerkindt/w5500/issues/39)) - Fixed an issue where internal function names were conflicting with trait names by [@ryan-summers](https://github.com/ryan-summers) ([#36](https://github.com/kellerkindt/w5500/issues/36)) -- Add `RetryTime` value and `RetryCount` registers methods and common register methods to `Device` and `UninitializedDevice` by [@elpiel](https://github.com/elpiel) ([#54][PR54]) +- Add `RetryTime` and `RetryCount` common register methods to `Device` and `UninitializedDevice` by [@elpiel](https://github.com/elpiel) ([#54][PR54]) ### Fixed diff --git a/src/bus/mod.rs b/src/bus/mod.rs index 7ad9a32..f7b7f17 100644 --- a/src/bus/mod.rs +++ b/src/bus/mod.rs @@ -4,11 +4,6 @@ mod four_wire; mod four_wire_ref; mod three_wire; -use crate::register::{ - self, - common::{PhyConfig, RetryCount, RetryTime, MODE, VERSION}, -}; - pub use self::four_wire::FourWire; pub use self::four_wire::FourWireError; pub use self::four_wire_ref::FourWireRef; diff --git a/src/device.rs b/src/device.rs index 87cda84..e7112af 100644 --- a/src/device.rs +++ b/src/device.rs @@ -7,8 +7,8 @@ use crate::net::Ipv4Addr; use crate::socket::Socket; use crate::uninitialized_device::UninitializedDevice; use crate::{ - common::{RetryCount, RetryTime}, - register, MacAddress, + register::{self, common::RetryTime}, + MacAddress, Mode, }; pub enum ResetError { @@ -56,7 +56,7 @@ impl Device { fn clear_mode(&mut self) -> Result<(), SpiBus::Error> { // Set RST common register of the w5500 - self.as_mut().reset() + self.as_mut().reset_device() } #[inline] @@ -119,21 +119,14 @@ impl Device { } /// Get the current Retry Count Register value. - /// - /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] - /// - /// E.g. In case of errors it will retry for 7 times: - /// `RCR = 0x0007` #[inline] - pub fn current_retry_count(&mut self) -> Result { + pub fn current_retry_count(&mut self) -> Result { self.as_mut().current_retry_count() } /// Set a new value for the Retry Count register. - /// - /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] #[inline] - pub fn set_retry_count(&mut self, retry_count: RetryCount) -> Result<(), SpiBus::Error> { + pub fn set_retry_count(&mut self, retry_count: u8) -> Result<(), SpiBus::Error> { self.as_mut().set_retry_count(retry_count) } @@ -229,24 +222,25 @@ impl DeviceRefMut<'_, SpiBus, HostImpl> { Ok(phy[0].into()) } - /// Reset the device #[inline] - fn reset(&mut self) -> Result<(), SpiBus::Error> { - self.set_mode(register::common::Mode::Reset) + pub fn reset_device(&mut self) -> Result<(), SpiBus::Error> { + // Set RST common register of the w5500 + let mode = [0b10000000]; + self.bus + .write_frame(register::COMMON, register::common::MODE, &mode) } #[inline] - fn set_mode(&mut self, mode_options: register::common::Mode) -> Result<(), SpiBus::Error> { + pub fn set_mode(&mut self, mode_options: Mode) -> Result<(), SpiBus::Error> { self.bus.write_frame( register::COMMON, register::common::MODE, &mode_options.to_register(), - )?; - Ok(()) + ) } #[inline] - fn version(&mut self) -> Result { + pub fn version(&mut self) -> Result { let mut version_register = [0_u8]; self.bus.read_frame( register::COMMON, @@ -272,7 +266,7 @@ impl DeviceRefMut<'_, SpiBus, HostImpl> { /// assert_eq!(four_hundred_ms.to_u16(), 4000); /// ``` #[inline] - fn set_retry_timeout(&mut self, retry_time_value: RetryTime) -> Result<(), SpiBus::Error> { + pub fn set_retry_timeout(&mut self, retry_time_value: RetryTime) -> Result<(), SpiBus::Error> { self.bus.write_frame( register::COMMON, register::common::RETRY_TIME, @@ -286,7 +280,7 @@ impl DeviceRefMut<'_, SpiBus, HostImpl> { /// /// E.g. 4000 = 400ms #[inline] - fn current_retry_timeout(&mut self) -> Result { + pub fn current_retry_timeout(&mut self) -> Result { let mut retry_time_register: [u8; 2] = [0, 0]; self.bus.read_frame( register::COMMON, @@ -300,23 +294,37 @@ impl DeviceRefMut<'_, SpiBus, HostImpl> { /// Set a new value for the Retry Count register. /// /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] - fn set_retry_count(&mut self, retry_count: RetryCount) -> Result<(), SpiBus::Error> { + /// + /// For more details check out the rest of the datasheet documentation on the Retry count. + /// + /// From datasheet: + /// + /// RCR configures the number of time of retransmission. When retransmission occurs + /// as many as ‘RCR+1’, Timeout interrupt is issued (Sn_IR[TIMEOUT] = ‘1’). + /// + /// The timeout of W5500 can be configurable with RTR and RCR. W5500 has two kind + /// timeout such as Address Resolution Protocol (ARP) and TCP retransmission. + /// + /// E.g. In case of errors it will retry for 7 times: + /// `RCR = 0x0007` + pub fn set_retry_count(&mut self, retry_count: u8) -> Result<(), SpiBus::Error> { self.bus.write_frame( register::COMMON, register::common::RETRY_COUNT, - &retry_count.to_register(), + &[retry_count], )?; Ok(()) } /// Get the current Retry Count value + /// /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] /// /// E.g. In case of errors it will retry for 7 times: /// `RCR = 0x0007` #[inline] - fn current_retry_count(&mut self) -> Result { + pub fn current_retry_count(&mut self) -> Result { let mut retry_count_register: [u8; 1] = [0]; self.bus.read_frame( register::COMMON, @@ -324,6 +332,6 @@ impl DeviceRefMut<'_, SpiBus, HostImpl> { &mut retry_count_register, )?; - Ok(RetryCount::from_register(retry_count_register)) + Ok(retry_count_register[0]) } } diff --git a/src/lib.rs b/src/lib.rs index a63eff5..124ff6d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,8 +23,6 @@ pub use self::{ uninitialized_device::{InitializeError, UninitializedDevice}, }; -use register::common; - // TODO add better docs to all public items, add unit tests. /// Settings for wake on LAN. Allows the W5500 to optionally emit an interrupt upon receiving a packet @@ -101,12 +99,6 @@ impl Mode { } } -impl From for common::Mode { - fn from(value: Mode) -> Self { - Self::Mode(value) - } -} - impl Default for Mode { fn default() -> Self { Self { @@ -117,3 +109,43 @@ impl Default for Mode { } } } + +#[cfg(test)] +mod test { + use crate::Mode; + + #[test] + fn test_mode_register() { + let ping_respond_and_force_arp = Mode { + // Bit: 7 Reset (RST) should be 0 + // Bit: 6 reserved + // Bit: 5 should be 0 - Disable WOL mode + on_wake_on_lan: crate::OnWakeOnLan::Ignore, + // Bit: 4 should be 0 - Disable Ping Block Mode + on_ping_request: crate::OnPingRequest::Respond, + // Bit: 3 should be 0 - PPoE disabled + connection_type: crate::ConnectionType::Ethernet, + // Bit: 2 reserved + // Bit: 1 should be 0 - Disabled Force ARP + arp_responses: crate::ArpResponses::Cache, + // Bit: 0 reserved + }; + assert_eq!(0b0000_0000, ping_respond_and_force_arp.to_u8()); + + let all_enabled = Mode { + // Bit: 7 Reset (RST) should be 0 + // Bit: 6 reserved + // Bit: 5 should be 1 - Enable WOL mode + on_wake_on_lan: crate::OnWakeOnLan::InvokeInterrupt, + // Bit: 4 should be 0 - Disable Ping Block Mode + on_ping_request: crate::OnPingRequest::Respond, + // Bit: 3 should be 1 - PPoE enable + connection_type: crate::ConnectionType::PPoE, + // Bit: 2 reserved + // Bit: 1 should be 1 - Enable Force ARP + arp_responses: crate::ArpResponses::DropAfterUse, + // Bit: 0 reserved + }; + assert_eq!(0b0010_1010, all_enabled.to_u8()); + } +} diff --git a/src/register.rs b/src/register.rs index d04bebe..210e4bd 100644 --- a/src/register.rs +++ b/src/register.rs @@ -31,30 +31,6 @@ pub mod common { pub const PHY_CONFIG: u16 = 0x2E; pub const VERSION: u16 = 0x39; - /// The common register Mode. - /// - /// It differs from the [`crate::Mode`] in one key aspect - we can also - /// send a reset value to the w5500, instead of only configuring the settings. - #[derive(Debug, Clone, Copy, PartialEq, Eq)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub enum Mode { - Reset, - Mode(crate::Mode), - } - - impl Mode { - pub fn to_register(self) -> [u8; 1] { - [self.to_u8()] - } - - pub fn to_u8(self) -> u8 { - match self { - Mode::Reset => 0b10000000, - Mode::Mode(mode) => mode.to_u8(), - } - } - } - /// A Retry Time-value /// /// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0] @@ -108,41 +84,6 @@ pub mod common { } } - /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] - /// - /// For more details check out the rest of the datasheet documentation on the Retry count. - /// - /// From datasheet: - /// - /// RCR configures the number of time of retransmission. When retransmission occurs - /// as many as ‘RCR+1’, Timeout interrupt is issued (Sn_IR[TIMEOUT] = ‘1’). - /// - /// > Ex) RCR = 0x0007 - /// - /// The timeout of W5500 can be configurable with RTR and RCR. W5500 has two kind - /// timeout such as Address Resolution Protocol (ARP) and TCP retransmission. - /// - #[derive(Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] - #[cfg_attr(feature = "defmt", derive(defmt::Format))] - pub struct RetryCount(pub u8); - - impl RetryCount { - #[inline] - pub fn to_u8(&self) -> u8 { - self.0 - } - - #[inline] - pub fn to_register(&self) -> [u8; 1] { - self.0.to_be_bytes() - } - - #[inline] - pub fn from_register(register: [u8; 1]) -> Self { - Self(register[0]) - } - } - #[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)] #[repr(u8)] pub enum PhyOperationMode { @@ -249,50 +190,6 @@ pub mod common { PhyConfig([val]) } } - - #[cfg(test)] - mod test { - use super::Mode; - - #[test] - fn test_mode_register() { - let reset = Mode::Reset; - // Bit: 7 Reset (RST) should be 1 - assert_eq!(0b1000_0000, reset.to_u8()); - - let ping_respond_and_force_arp = crate::Mode { - // Bit: 7 Reset (RST) should be 0 - // Bit: 6 reserved - // Bit: 5 should be 0 - Disable WOL mode - on_wake_on_lan: crate::OnWakeOnLan::Ignore, - // Bit: 4 should be 0 - Disable Ping Block Mode - on_ping_request: crate::OnPingRequest::Respond, - // Bit: 3 should be 0 - PPoE disabled - connection_type: crate::ConnectionType::Ethernet, - // Bit: 2 reserved - // Bit: 1 should be 0 - Disabled Force ARP - arp_responses: crate::ArpResponses::Cache, - // Bit: 0 reserved - }; - assert_eq!(0b0000_0000, ping_respond_and_force_arp.to_u8()); - - let all_enabled = crate::Mode { - // Bit: 7 Reset (RST) should be 0 - // Bit: 6 reserved - // Bit: 5 should be 1 - Enable WOL mode - on_wake_on_lan: crate::OnWakeOnLan::InvokeInterrupt, - // Bit: 4 should be 0 - Disable Ping Block Mode - on_ping_request: crate::OnPingRequest::Respond, - // Bit: 3 should be 1 - PPoE enable - connection_type: crate::ConnectionType::PPoE, - // Bit: 2 reserved - // Bit: 1 should be 1 - Enable Force ARP - arp_responses: crate::ArpResponses::DropAfterUse, - // Bit: 0 reserved - }; - assert_eq!(0b0010_1010, all_enabled.to_u8()); - } - } } pub const SOCKET0: u8 = 0b000_00001; diff --git a/src/uninitialized_device.rs b/src/uninitialized_device.rs index 70ecb54..1149e3d 100644 --- a/src/uninitialized_device.rs +++ b/src/uninitialized_device.rs @@ -7,10 +7,7 @@ use crate::device::Device; use crate::host::{Dhcp, Host, Manual}; use crate::raw_device::RawDevice; use crate::{ - register::{ - self, - common::{RetryCount, RetryTime}, - }, + register::{self, common::RetryTime}, MacAddress, Mode, }; @@ -99,7 +96,7 @@ impl UninitializedDevice { // RESET self.reset()?; - self.set_mode(mode_options.into())?; + self.set_mode(mode_options)?; host.refresh(&mut self.bus)?; Ok(Device::new(self.bus, host)) } @@ -120,22 +117,23 @@ impl UninitializedDevice { /// Reset the device #[inline] - fn reset(&mut self) -> Result<(), SpiBus::Error> { - self.set_mode(register::common::Mode::Reset) + pub fn reset(&mut self) -> Result<(), SpiBus::Error> { + // Set RST common register of the w5500 + let mode = [0b10000000]; + self.bus + .write_frame(register::COMMON, register::common::MODE, &mode) } - #[inline] - fn set_mode(&mut self, mode_options: register::common::Mode) -> Result<(), SpiBus::Error> { + pub fn set_mode(&mut self, mode_options: Mode) -> Result<(), SpiBus::Error> { self.bus.write_frame( register::COMMON, register::common::MODE, &mode_options.to_register(), - )?; - Ok(()) + ) } #[inline] - fn version(&mut self) -> Result { + pub fn version(&mut self) -> Result { let mut version_register = [0_u8]; self.bus.read_frame( register::COMMON, @@ -161,7 +159,7 @@ impl UninitializedDevice { /// assert_eq!(four_hundred_ms.to_u16(), 4000); /// ``` #[inline] - fn set_retry_timeout(&mut self, retry_time_value: RetryTime) -> Result<(), SpiBus::Error> { + pub fn set_retry_timeout(&mut self, retry_time_value: RetryTime) -> Result<(), SpiBus::Error> { self.bus.write_frame( register::COMMON, register::common::RETRY_TIME, @@ -175,7 +173,7 @@ impl UninitializedDevice { /// /// E.g. 4000 = 400ms #[inline] - fn current_retry_timeout(&mut self) -> Result { + pub fn current_retry_timeout(&mut self) -> Result { let mut retry_time_register: [u8; 2] = [0, 0]; self.bus.read_frame( register::COMMON, @@ -189,11 +187,24 @@ impl UninitializedDevice { /// Set a new value for the Retry Count register. /// /// RCR (Retry Count Register) [R/W] [0x001B] [0x08] - fn set_retry_count(&mut self, retry_count: RetryCount) -> Result<(), SpiBus::Error> { + /// + /// For more details check out the rest of the datasheet documentation on the Retry count. + /// + /// From datasheet: + /// + /// RCR configures the number of time of retransmission. When retransmission occurs + /// as many as ‘RCR+1’, Timeout interrupt is issued (Sn_IR[TIMEOUT] = ‘1’). + /// + /// The timeout of W5500 can be configurable with RTR and RCR. W5500 has two kind + /// timeout such as Address Resolution Protocol (ARP) and TCP retransmission. + /// + /// E.g. In case of errors it will retry for 7 times: + /// `RCR = 0x0007` + pub fn set_retry_count(&mut self, retry_count: u8) -> Result<(), SpiBus::Error> { self.bus.write_frame( register::COMMON, register::common::RETRY_COUNT, - &retry_count.to_register(), + &[retry_count], )?; Ok(()) @@ -205,7 +216,7 @@ impl UninitializedDevice { /// E.g. In case of errors it will retry for 7 times: /// `RCR = 0x0007` #[inline] - fn current_retry_count(&mut self) -> Result { + pub fn current_retry_count(&mut self) -> Result { let mut retry_count_register: [u8; 1] = [0]; self.bus.read_frame( register::COMMON, @@ -213,7 +224,7 @@ impl UninitializedDevice { &mut retry_count_register, )?; - Ok(RetryCount::from_register(retry_count_register)) + Ok(retry_count_register[0]) } #[cfg(not(feature = "no-chip-version-assertion"))]