diff --git a/src/register.rs b/src/register.rs index 3421a5d..114b870 100644 --- a/src/register.rs +++ b/src/register.rs @@ -68,5 +68,4 @@ pub mod socketn { pub const RECEIVED_SIZE: u16 = 0x26; pub const RX_DATA_READ_POINTER: u16 = 0x28; - pub const RX_DATA_WRITE_POINTER: u16 = 0x2A; } diff --git a/src/socket/mod.rs b/src/socket/mod.rs index 3872ee7..86b48d2 100644 --- a/src/socket/mod.rs +++ b/src/socket/mod.rs @@ -9,6 +9,7 @@ pub trait Socket { fn register(&self) -> u8; fn tx_buffer(&self) -> u8; fn rx_buffer(&self) -> u8; + fn set_mode( &self, bus: &mut SpiBus, @@ -18,6 +19,7 @@ pub trait Socket { block!(bus.transfer_frame(self.register(), socketn::MODE, true, &mut mode))?; Ok(()) } + fn reset_interrupt( &self, bus: &mut SpiBus, @@ -27,6 +29,7 @@ pub trait Socket { block!(bus.transfer_frame(self.register(), socketn::INTERRUPT, true, &mut data))?; Ok(()) } + fn set_source_port( &self, bus: &mut SpiBus, @@ -37,6 +40,7 @@ pub trait Socket { block!(bus.transfer_frame(self.register(), socketn::SOURCE_PORT, true, &mut data))?; Ok(()) } + fn has_received( &self, bus: &mut SpiBus, @@ -68,6 +72,19 @@ pub trait Socket { block!(bus.transfer_frame(self.register(), socketn::COMMAND, true, &mut data))?; Ok(()) } + + fn get_receive_size(&self, bus: &mut SpiBus) -> Result { + loop { + // Section 4.2 of datasheet, Sn_TX_FSR address docs indicate that read must be repeated until two sequential reads are stable + let mut sample_0 = [0u8; 2]; + block!(bus.transfer_frame(self.register(), socketn::RECEIVED_SIZE, false, &mut sample_0))?; + let mut sample_1 = [0u8; 2]; + block!(bus.transfer_frame(self.register(), socketn::RECEIVED_SIZE, false, &mut sample_1))?; + if sample_0 == sample_1 && sample_0[0] >= 8 { + break Ok(BigEndian::read_u16(&sample_0)); + } + } + } } pub type OwnedSockets = ( diff --git a/src/udp/packet.rs b/src/udp/packet.rs index cf36f6e..a64318b 100644 --- a/src/udp/packet.rs +++ b/src/udp/packet.rs @@ -17,7 +17,9 @@ pub struct UdpPacket { impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> UdpPacket> { pub fn new(mut udp_socket: UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>) -> Result { - let receive_size = Self::block_until_receive_size_known(&mut udp_socket)?; + let receive_size = udp_socket.socket.get_receive_size(&mut udp_socket.bus)?; + + // Packet frame, as described in W5200 docs sectino 5.2.2.1 // |<-- read_pointer read_pointer + received_size -->| // |Destination IP Address | Destination Port | Byte Size of DATA | Actual DATA ... | // | --- 4 Bytes --- | --- 2 Bytes --- | --- 2 Bytes --- | .... | @@ -53,17 +55,6 @@ impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> UdpPacket< Ok(self.udp_socket) } - fn block_until_receive_size_known(udp_socket: &mut UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>) -> Result { - loop { - let mut sample_0 = [0u8; 2]; - block!(udp_socket.bus.transfer_frame(udp_socket.socket.register(), socketn::RECEIVED_SIZE, false, &mut sample_0))?; - let mut sample_1 = [0u8; 2]; - block!(udp_socket.bus.transfer_frame(udp_socket.socket.register(), socketn::RECEIVED_SIZE, false, &mut sample_1))?; - if sample_0 == sample_1 && sample_0[0] >= 8 { - break Ok(BigEndian::read_u16(&sample_0)); - } - } - } } impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> Iterator for UdpPacket> {