Merge pull request #54 from LechevSpace/feat/retry-time-and-count
Feat: Retry time and count
This commit is contained in:
commit
42791c27e5
5 changed files with 430 additions and 39 deletions
|
|
@ -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` and `RetryCount` common register methods to `Device` and `UninitializedDevice` by [@elpiel](https://github.com/elpiel) ([#54][PR54])
|
||||
|
||||
### Fixed
|
||||
|
||||
|
|
|
|||
167
src/device.rs
167
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::{
|
||||
register::{self, common::RetryTime},
|
||||
MacAddress, Mode,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
|
|
@ -58,11 +61,8 @@ impl<SpiBus: Bus, HostImpl: Host> Device<SpiBus, HostImpl> {
|
|||
}
|
||||
|
||||
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.as_mut().reset_device()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
|
@ -95,6 +95,47 @@ impl<SpiBus: Bus, HostImpl: Host> Device<SpiBus, HostImpl> {
|
|||
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<RetryTime, SpiBus::Error> {
|
||||
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.
|
||||
#[inline]
|
||||
pub fn current_retry_count(&mut self) -> Result<u8, SpiBus::Error> {
|
||||
self.as_mut().current_retry_count()
|
||||
}
|
||||
|
||||
/// Set a new value for the Retry Count register.
|
||||
#[inline]
|
||||
pub fn set_retry_count(&mut self, retry_count: u8) -> 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,10 +228,116 @@ impl<SpiBus: Bus, HostImpl: Host> DeviceRefMut<'_, SpiBus, HostImpl> {
|
|||
Ok(phy[0].into())
|
||||
}
|
||||
|
||||
pub fn version(&mut self) -> Result<u8, SpiBus::Error> {
|
||||
let mut version = [0u8];
|
||||
#[inline]
|
||||
pub fn reset_device(&mut self) -> Result<(), SpiBus::Error> {
|
||||
// Set RST common register of the w5500
|
||||
let mode = [0b10000000];
|
||||
self.bus
|
||||
.read_frame(register::COMMON, register::common::VERSION, &mut version)?;
|
||||
Ok(version[0])
|
||||
.write_frame(register::COMMON, register::common::MODE, &mode)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
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(),
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn version(&mut self) -> Result<u8, SpiBus::Error> {
|
||||
let mut version_register = [0_u8];
|
||||
self.bus.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]
|
||||
pub 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(())
|
||||
}
|
||||
|
||||
/// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0]
|
||||
///
|
||||
/// E.g. 4000 = 400ms
|
||||
#[inline]
|
||||
pub fn current_retry_timeout(&mut self) -> Result<RetryTime, SpiBus::Error> {
|
||||
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]
|
||||
///
|
||||
/// 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],
|
||||
)?;
|
||||
|
||||
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 current_retry_count(&mut self) -> Result<u8, SpiBus::Error> {
|
||||
let mut retry_count_register: [u8; 1] = [0];
|
||||
self.bus.read_frame(
|
||||
register::COMMON,
|
||||
register::common::RETRY_COUNT,
|
||||
&mut retry_count_register,
|
||||
)?;
|
||||
|
||||
Ok(retry_count_register[0])
|
||||
}
|
||||
}
|
||||
|
|
|
|||
90
src/lib.rs
90
src/lib.rs
|
|
@ -15,50 +15,66 @@ 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},
|
||||
};
|
||||
|
||||
// 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,
|
||||
|
|
@ -67,6 +83,22 @@ 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 Default for Mode {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
|
|
@ -77,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());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,13 +6,84 @@ 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;
|
||||
|
||||
/// 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)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
|
||||
#[repr(u8)]
|
||||
pub enum PhyOperationMode {
|
||||
|
|
|
|||
|
|
@ -6,8 +6,10 @@ 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::RetryTime},
|
||||
MacAddress, Mode,
|
||||
};
|
||||
|
||||
#[derive(Debug)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
|
|
@ -95,9 +97,7 @@ impl<SpiBus: Bus> UninitializedDevice<SpiBus> {
|
|||
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)?;
|
||||
|
|
@ -118,31 +118,131 @@ impl<SpiBus: Bus> UninitializedDevice<SpiBus> {
|
|||
RawDevice::new(self.bus)
|
||||
}
|
||||
|
||||
/// Reset the device
|
||||
#[inline]
|
||||
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]
|
||||
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(),
|
||||
)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn version(&mut self) -> Result<u8, SpiBus::Error> {
|
||||
let mut version_register = [0_u8];
|
||||
self.bus.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]
|
||||
pub 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(())
|
||||
}
|
||||
|
||||
/// RTR (Retry Time-value Register) [R/W] [0x0019 – 0x001A] [0x07D0]
|
||||
///
|
||||
/// E.g. 4000 = 400ms
|
||||
#[inline]
|
||||
pub fn current_retry_timeout(&mut self) -> Result<RetryTime, SpiBus::Error> {
|
||||
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]
|
||||
///
|
||||
/// 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],
|
||||
)?;
|
||||
|
||||
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 current_retry_count(&mut self) -> Result<u8, SpiBus::Error> {
|
||||
let mut retry_count_register: [u8; 1] = [0];
|
||||
self.bus.read_frame(
|
||||
register::COMMON,
|
||||
register::common::RETRY_COUNT,
|
||||
&mut retry_count_register,
|
||||
)?;
|
||||
|
||||
Ok(retry_count_register[0])
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "no-chip-version-assertion"))]
|
||||
fn assert_chip_version(
|
||||
&mut self,
|
||||
expected_version: u8,
|
||||
) -> Result<(), InitializeError<SpiBus::Error>> {
|
||||
let mut version = [0];
|
||||
self.bus
|
||||
.read_frame(register::COMMON, register::common::VERSION, &mut version)?;
|
||||
if version[0] != expected_version {
|
||||
let version = self.version()?;
|
||||
|
||||
if version != expected_version {
|
||||
Err(InitializeError::ChipNotConnected)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<Spi: Transfer<u8> + Write<u8>, ChipSelect: OutputPin>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue