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"))]