Removed socket ownership checking, giving up on that effort for now

This commit is contained in:
Jonah Dahlquist 2019-09-19 10:00:36 -05:00 committed by Jonah Dahlquist
commit b6a52cbf8e
10 changed files with 81 additions and 171 deletions

View file

@ -51,14 +51,14 @@ impl<Spi: FullDuplex<u8>, ChipSelect: OutputPin> ActiveBus for ActiveFourWire<Sp
self.cs
.set_high()
.map_err(|e| Self::Error::ChipSelectError(e))?;
.map_err(|e| FourWireError::ChipSelectError(e))?;
block!(Self::transfer_bytes(&mut self.spi, &mut address_phase)
.and_then(|_| Self::transfer_byte(&mut self.spi, &mut control_phase))
.and_then(|_| Self::transfer_bytes(&mut self.spi, data_phase)))
.map_err(|e| Self::Error::SpiError(e))?;
.map_err(|e| FourWireError::SpiError(e))?;
self.cs
.set_low()
.map_err(|e| Self::Error::ChipSelectError(e))?;
.map_err(|e| FourWireError::ChipSelectError(e))?;
Ok(data_phase)
}

View file

@ -2,22 +2,16 @@ use bus::{ActiveFourWire, ActiveThreeWire, Bus, FourWire, ThreeWire};
use embedded_hal::digital::v2::OutputPin;
use embedded_hal::spi::FullDuplex;
use network::Network;
use socket::OwnedSockets;
use w5500::W5500;
pub struct InactiveW5500<SpiBus: Bus, NetworkImpl: Network> {
bus: SpiBus,
network: NetworkImpl,
sockets: OwnedSockets,
}
impl<SpiBus: Bus, NetworkImpl: Network> InactiveW5500<SpiBus, NetworkImpl> {
pub fn new(bus: SpiBus, network: NetworkImpl, sockets: OwnedSockets) -> Self {
Self {
bus,
network,
sockets,
}
pub fn new(bus: SpiBus, network: NetworkImpl) -> Self {
Self { bus, network }
}
}
@ -26,7 +20,7 @@ impl<ChipSelect: OutputPin, NetworkImpl: Network> InactiveW5500<FourWire<ChipSel
self,
spi: Spi,
) -> W5500<ActiveFourWire<Spi, ChipSelect>, NetworkImpl> {
W5500::new(self.bus.activate(spi), self.network, self.sockets)
W5500::new(self.bus.activate(spi), self.network)
}
}
@ -35,6 +29,6 @@ impl<NetworkImpl: Network> InactiveW5500<ThreeWire, NetworkImpl> {
self,
spi: Spi,
) -> W5500<ActiveThreeWire<Spi>, NetworkImpl> {
W5500::new(self.bus.activate(spi), self.network, self.sockets)
W5500::new(self.bus.activate(spi), self.network)
}
}

View file

@ -940,7 +940,7 @@ impl Default for Mode {
// }
// }
mod bus;
pub mod bus;
mod inactive_w5500;
mod network;
mod register;
@ -948,3 +948,5 @@ mod socket;
mod udp;
pub mod uninitialized_w5500;
mod w5500;
pub use bus::ActiveFourWire;

View file

@ -6,7 +6,6 @@ use crate::register::socketn;
use crate::IpAddress;
pub trait Socket {
fn is_owned_by(&self, sockets: &OwnedSockets) -> bool;
fn register(&self) -> u8;
fn tx_buffer(&self) -> u8;
fn rx_buffer(&self) -> u8;
@ -181,22 +180,9 @@ pub type OwnedSockets = (
Socket6,
Socket7,
);
pub type Sockets<'a> = (
&'a mut Socket0,
&'a mut Socket1,
&'a mut Socket2,
&'a mut Socket3,
&'a mut Socket4,
&'a mut Socket5,
&'a mut Socket6,
&'a mut Socket7,
);
pub struct Socket0 {}
impl Socket for Socket0 {
fn is_owned_by(&self, sockets: &OwnedSockets) -> bool {
self as *const _ == &sockets.0 as *const _
}
fn register(&self) -> u8 {
register::SOCKET0
}
@ -209,9 +195,6 @@ impl Socket for Socket0 {
}
pub struct Socket1 {}
impl Socket for Socket1 {
fn is_owned_by(&self, sockets: &OwnedSockets) -> bool {
self as *const _ == &sockets.1 as *const _
}
fn register(&self) -> u8 {
register::SOCKET1
}
@ -224,9 +207,6 @@ impl Socket for Socket1 {
}
pub struct Socket2 {}
impl Socket for Socket2 {
fn is_owned_by(&self, sockets: &OwnedSockets) -> bool {
self as *const _ == &sockets.2 as *const _
}
fn register(&self) -> u8 {
register::SOCKET2
}
@ -239,9 +219,6 @@ impl Socket for Socket2 {
}
pub struct Socket3 {}
impl Socket for Socket3 {
fn is_owned_by(&self, sockets: &OwnedSockets) -> bool {
self as *const _ == &sockets.3 as *const _
}
fn register(&self) -> u8 {
register::SOCKET3
}
@ -254,9 +231,6 @@ impl Socket for Socket3 {
}
pub struct Socket4 {}
impl Socket for Socket4 {
fn is_owned_by(&self, sockets: &OwnedSockets) -> bool {
self as *const _ == &sockets.4 as *const _
}
fn register(&self) -> u8 {
register::SOCKET4
}
@ -269,9 +243,6 @@ impl Socket for Socket4 {
}
pub struct Socket5 {}
impl Socket for Socket5 {
fn is_owned_by(&self, sockets: &OwnedSockets) -> bool {
self as *const _ == &sockets.5 as *const _
}
fn register(&self) -> u8 {
register::SOCKET5
}
@ -284,9 +255,6 @@ impl Socket for Socket5 {
}
pub struct Socket6 {}
impl Socket for Socket6 {
fn is_owned_by(&self, sockets: &OwnedSockets) -> bool {
self as *const _ == &sockets.6 as *const _
}
fn register(&self) -> u8 {
register::SOCKET6
}
@ -299,9 +267,6 @@ impl Socket for Socket6 {
}
pub struct Socket7 {}
impl Socket for Socket7 {
fn is_owned_by(&self, sockets: &OwnedSockets) -> bool {
self as *const _ == &sockets.7 as *const _
}
fn register(&self) -> u8 {
register::SOCKET7
}

View file

@ -2,32 +2,24 @@ use crate::bus::ActiveBus;
use crate::network::Network;
use crate::socket::Socket;
use crate::udp::UdpSocket;
use crate::w5500::ForeignSocketError;
use crate::w5500::W5500;
pub struct InactiveUdpSocket<'a, SocketImpl: Socket> {
socket: &'a mut SocketImpl,
pub struct InactiveUdpSocket<SocketImpl: Socket> {
socket: SocketImpl,
}
impl<'a, SocketImpl: Socket> InactiveUdpSocket<'a, SocketImpl> {
pub fn new(socket: &'a mut SocketImpl) -> Self {
impl<SocketImpl: Socket> InactiveUdpSocket<SocketImpl> {
pub fn new(socket: SocketImpl) -> Self {
InactiveUdpSocket { socket }
}
pub fn activate<SpiBus: ActiveBus, NetworkImpl: Network>(
self,
w5500: W5500<SpiBus, NetworkImpl>,
) -> Result<UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>, ForeignSocketError> {
let (bus, network, sockets) = w5500.release();
if self.socket.is_owned_by(&sockets) {
Ok(UdpSocket {
bus,
network,
sockets,
socket: self.socket,
})
} else {
Err(ForeignSocketError {})
) -> UdpSocket<SpiBus, NetworkImpl, SocketImpl> {
UdpSocket {
w5500,
socket: self.socket,
}
}
}

View file

@ -14,21 +14,25 @@ pub struct IncomingPacket<UdpSocket> {
write_pointer: u16,
}
impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket>
IncomingPacket<UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>>
impl<SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket>
IncomingPacket<UdpSocket<SpiBus, NetworkImpl, SocketImpl>>
{
pub fn new(
mut udp_socket: UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>,
mut udp_socket: UdpSocket<SpiBus, NetworkImpl, SocketImpl>,
) -> Result<Self, SpiBus::Error> {
let receive_size = udp_socket.socket.get_receive_size(&mut udp_socket.bus)?;
let receive_size = udp_socket
.socket
.get_receive_size(&mut udp_socket.w5500.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 --- | .... |
let read_pointer = udp_socket.socket.get_rx_read_pointer(&mut udp_socket.bus)?;
let read_pointer = udp_socket
.socket
.get_rx_read_pointer(&mut udp_socket.w5500.bus)?;
let mut header = [0u8; 8];
block!(udp_socket.bus.transfer_frame(
block!(udp_socket.w5500.bus.transfer_frame(
udp_socket.socket.rx_buffer(),
read_pointer,
false,
@ -53,19 +57,19 @@ impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket>
// TODO add read_all method
pub fn done(mut self) -> Result<UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>, SpiBus::Error> {
pub fn done(mut self) -> Result<UdpSocket<SpiBus, NetworkImpl, SocketImpl>, SpiBus::Error> {
self.udp_socket
.socket
.set_rx_read_pointer(&mut self.udp_socket.bus, self.write_pointer)?;
.set_rx_read_pointer(&mut self.udp_socket.w5500.bus, self.write_pointer)?;
self.udp_socket
.socket
.command(&mut self.udp_socket.bus, socketn::Command::Receive)?;
.command(&mut self.udp_socket.w5500.bus, socketn::Command::Receive)?;
Ok(self.udp_socket)
}
}
impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> Iterator
for IncomingPacket<UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>>
impl<SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> Iterator
for IncomingPacket<UdpSocket<SpiBus, NetworkImpl, SocketImpl>>
{
type Item = Result<u8, SpiBus::Error>;
fn next(&mut self) -> Option<Self::Item> {
@ -73,7 +77,7 @@ impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> Iterator
return None;
}
let mut buffer = [0u8];
let result = block!(self.udp_socket.bus.transfer_frame(
let result = block!(self.udp_socket.w5500.bus.transfer_frame(
self.udp_socket.socket.rx_buffer(),
self.read_pointer,
false,

View file

@ -5,49 +5,40 @@ mod outgoing_packet;
use crate::bus::ActiveBus;
use crate::network::Network;
use crate::register::socketn;
use crate::socket::{OwnedSockets, Socket};
use crate::socket::Socket;
use crate::udp::inactive_udp_socket::InactiveUdpSocket;
use crate::udp::incoming_packet::IncomingPacket;
use crate::udp::outgoing_packet::OutgoingPacket;
use crate::w5500::W5500;
use crate::IpAddress;
pub struct UdpSocket<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> {
bus: SpiBus,
network: NetworkImpl,
sockets: OwnedSockets,
pub struct UdpSocket<SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket> {
w5500: W5500<SpiBus, NetworkImpl>,
socket: &'a mut SocketImpl,
socket: SocketImpl,
}
impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket>
UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>
impl<SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket>
UdpSocket<SpiBus, NetworkImpl, SocketImpl>
{
pub fn new(
port: u16,
mut bus: SpiBus,
network: NetworkImpl,
sockets: OwnedSockets,
socket: &'a mut SocketImpl,
mut w5500: W5500<SpiBus, NetworkImpl>,
socket: SocketImpl,
) -> Result<Self, SpiBus::Error> {
socket.reset_interrupt(&mut bus, socketn::Interrupt::SendOk)?;
socket.set_source_port(&mut bus, port)?;
socket.set_mode(&mut bus, socketn::Protocol::Udp)?;
socket.command(&mut bus, socketn::Command::Open)?;
socket.reset_interrupt(&mut w5500.bus, socketn::Interrupt::SendOk)?;
socket.set_source_port(&mut w5500.bus, port)?;
socket.set_mode(&mut w5500.bus, socketn::Protocol::Udp)?;
socket.command(&mut w5500.bus, socketn::Command::Open)?;
Ok(UdpSocket {
bus,
network,
sockets,
socket,
})
Ok(UdpSocket { w5500, socket })
}
/// Returns a UDP packet if one is available. Will return `None` if no UDP packets are in the socket's buffer
pub fn receive(mut self) -> Result<Option<IncomingPacket<Self>>, SpiBus::Error> {
if !self
.socket
.has_interrupt(&mut self.bus, socketn::Interrupt::Receive)?
.has_interrupt(&mut self.w5500.bus, socketn::Interrupt::Receive)?
{
Ok(None)
} else {
@ -64,15 +55,7 @@ impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket>
Ok(OutgoingPacket::new(self, host, remote_port)?)
}
pub fn deactivate(
self,
) -> (
InactiveUdpSocket<'a, SocketImpl>,
W5500<SpiBus, NetworkImpl>,
) {
(
InactiveUdpSocket::new(self.socket),
W5500::new(self.bus, self.network, self.sockets),
)
pub fn deactivate(self) -> (InactiveUdpSocket<SocketImpl>, W5500<SpiBus, NetworkImpl>) {
(InactiveUdpSocket::new(self.socket), self.w5500)
}
}

View file

@ -10,23 +10,23 @@ pub struct OutgoingPacket<UdpSocket> {
data_length: u16,
}
impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket>
OutgoingPacket<UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>>
impl<SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket>
OutgoingPacket<UdpSocket<SpiBus, NetworkImpl, SocketImpl>>
{
pub fn new(
mut udp_socket: UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>,
mut udp_socket: UdpSocket<SpiBus, NetworkImpl, SocketImpl>,
host: IpAddress,
port: u16,
) -> Result<Self, SpiBus::Error> {
udp_socket
.socket
.set_destination_ip(&mut udp_socket.bus, host)?;
.set_destination_ip(&mut udp_socket.w5500.bus, host)?;
udp_socket
.socket
.set_destination_port(&mut udp_socket.bus, port)?;
.set_destination_port(&mut udp_socket.w5500.bus, port)?;
udp_socket
.socket
.set_tx_read_pointer(&mut udp_socket.bus, 0)?;
.set_tx_read_pointer(&mut udp_socket.w5500.bus, 0)?;
Ok(Self {
udp_socket,
data_length: 0,
@ -34,7 +34,7 @@ impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket>
}
pub fn write(&mut self, mut data: &mut [u8]) -> Result<(), SpiBus::Error> {
block!(self.udp_socket.bus.transfer_frame(
block!(self.udp_socket.w5500.bus.transfer_frame(
self.udp_socket.socket.tx_buffer(),
self.data_length,
true,
@ -44,29 +44,29 @@ impl<'a, SpiBus: ActiveBus, NetworkImpl: Network, SocketImpl: Socket>
Ok(())
}
pub fn send(mut self) -> Result<UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>, SpiBus::Error> {
pub fn send(mut self) -> Result<UdpSocket<SpiBus, NetworkImpl, SocketImpl>, SpiBus::Error> {
self.udp_socket
.socket
.set_tx_write_pointer(&mut self.udp_socket.bus, self.data_length)?;
.set_tx_write_pointer(&mut self.udp_socket.w5500.bus, self.data_length)?;
self.udp_socket
.socket
.command(&mut self.udp_socket.bus, socketn::Command::Send)?;
.command(&mut self.udp_socket.w5500.bus, socketn::Command::Send)?;
loop {
// wait until send is complete
if self
.udp_socket
.socket
.has_interrupt(&mut self.udp_socket.bus, socketn::Interrupt::SendOk)?
.has_interrupt(&mut self.udp_socket.w5500.bus, socketn::Interrupt::SendOk)?
{
self.udp_socket
.socket
.reset_interrupt(&mut self.udp_socket.bus, socketn::Interrupt::SendOk)?;
.reset_interrupt(&mut self.udp_socket.w5500.bus, socketn::Interrupt::SendOk)?;
break;
}
}
self.udp_socket
.socket
.command(&mut self.udp_socket.bus, socketn::Command::Open)?;
.command(&mut self.udp_socket.w5500.bus, socketn::Command::Open)?;
Ok(self.udp_socket)
}
}

View file

@ -4,6 +4,7 @@ use bus::{ActiveBus, ActiveFourWire, ActiveThreeWire};
use embedded_hal::digital::v2::OutputPin;
use embedded_hal::spi::FullDuplex;
use register;
use socket::OwnedSockets;
use socket::{Socket0, Socket1, Socket2, Socket3, Socket4, Socket5, Socket6, Socket7};
use w5500::W5500;
@ -25,7 +26,7 @@ impl<SpiBus: ActiveBus> UninitializedW5500<SpiBus> {
self,
mac: MacAddress,
mode_options: Mode,
) -> Result<W5500<SpiBus, Dhcp>, InitializeError<SpiBus::Error>> {
) -> Result<(W5500<SpiBus, Dhcp>, OwnedSockets), InitializeError<SpiBus::Error>> {
let network = Dhcp::new(mac);
self.initialize_with_network(network, mode_options)
}
@ -35,7 +36,7 @@ impl<SpiBus: ActiveBus> UninitializedW5500<SpiBus> {
mac: MacAddress,
ip: IpAddress,
mode_options: Mode,
) -> Result<W5500<SpiBus, Manual>, InitializeError<SpiBus::Error>> {
) -> Result<(W5500<SpiBus, Manual>, OwnedSockets), InitializeError<SpiBus::Error>> {
let mut gateway = ip;
gateway.address[3] = 1;
let subnet = IpAddress::new(255, 255, 255, 0);
@ -49,7 +50,7 @@ impl<SpiBus: ActiveBus> UninitializedW5500<SpiBus> {
gateway: IpAddress,
subnet: IpAddress,
mode_options: Mode,
) -> Result<W5500<SpiBus, Manual>, InitializeError<SpiBus::Error>> {
) -> Result<(W5500<SpiBus, Manual>, OwnedSockets), InitializeError<SpiBus::Error>> {
let network = Manual::new(mac, ip, gateway, subnet);
self.initialize_with_network(network, mode_options)
}
@ -58,7 +59,7 @@ impl<SpiBus: ActiveBus> UninitializedW5500<SpiBus> {
mut self,
mut network: NetworkImpl,
mode_options: Mode,
) -> Result<W5500<SpiBus, NetworkImpl>, InitializeError<SpiBus::Error>> {
) -> Result<(W5500<SpiBus, NetworkImpl>, OwnedSockets), InitializeError<SpiBus::Error>> {
self.assert_chip_version(0x4)?;
self.set_mode(mode_options)
.map_err(|e| InitializeError::SpiError(e))?;
@ -75,7 +76,7 @@ impl<SpiBus: ActiveBus> UninitializedW5500<SpiBus> {
Socket6 {},
Socket7 {},
);
Ok(W5500::new(self.bus, network, sockets))
Ok((W5500::new(self.bus, network), sockets))
}
fn assert_chip_version(

View file

@ -5,35 +5,17 @@ use embedded_hal::digital::v2::OutputPin;
use embedded_hal::spi::FullDuplex;
use network::Network;
use register;
use socket::{OwnedSockets, Socket, Sockets};
use socket::Socket;
use udp::UdpSocket;
pub struct W5500<SpiBus: ActiveBus, NetworkImpl: Network> {
bus: SpiBus,
pub bus: SpiBus,
network: NetworkImpl,
sockets: OwnedSockets,
}
impl<SpiBus: ActiveBus, NetworkImpl: Network> W5500<SpiBus, NetworkImpl> {
pub fn new(bus: SpiBus, network: NetworkImpl, sockets: OwnedSockets) -> Self {
W5500 {
bus,
network,
sockets,
}
}
pub fn sockets(&mut self) -> Sockets {
(
&mut self.sockets.0,
&mut self.sockets.1,
&mut self.sockets.2,
&mut self.sockets.3,
&mut self.sockets.4,
&mut self.sockets.5,
&mut self.sockets.6,
&mut self.sockets.7,
)
pub fn new(bus: SpiBus, network: NetworkImpl) -> Self {
W5500 { bus, network }
}
pub fn reset(mut self) -> Result<UninitializedW5500<SpiBus>, SpiBus::Error> {
@ -50,22 +32,16 @@ impl<SpiBus: ActiveBus, NetworkImpl: Network> W5500<SpiBus, NetworkImpl> {
Ok(())
}
pub fn open_udp_socket<'a, SocketImpl: Socket>(
pub fn open_udp_socket<SocketImpl: Socket>(
self,
port: u16,
socket: &'a mut SocketImpl,
) -> Result<UdpSocket<'a, SpiBus, NetworkImpl, SocketImpl>, OpenSocketError<SpiBus::Error>>
{
if socket.is_owned_by(&self.sockets) {
UdpSocket::new(port, self.bus, self.network, self.sockets, socket)
.map_err(|e| OpenSocketError::BusError(e))
} else {
Err(OpenSocketError::ForeignSocketError)
}
socket: SocketImpl,
) -> Result<UdpSocket<SpiBus, NetworkImpl, SocketImpl>, SpiBus::Error> {
UdpSocket::new(port, self, socket)
}
pub fn release(self) -> (SpiBus, NetworkImpl, OwnedSockets) {
(self.bus, self.network, self.sockets)
pub fn release(self) -> (SpiBus, NetworkImpl) {
(self.bus, self.network)
}
}
@ -74,20 +50,13 @@ impl<Spi: FullDuplex<u8>, ChipSelect: OutputPin, NetworkImpl: Network>
{
pub fn deactivate(self) -> (InactiveW5500<FourWire<ChipSelect>, NetworkImpl>, Spi) {
let (bus, spi) = self.bus.deactivate();
(InactiveW5500::new(bus, self.network, self.sockets), spi)
(InactiveW5500::new(bus, self.network), spi)
}
}
impl<Spi: FullDuplex<u8>, NetworkImpl: Network> W5500<ActiveThreeWire<Spi>, NetworkImpl> {
pub fn deactivate(self) -> (InactiveW5500<ThreeWire, NetworkImpl>, Spi) {
let (bus, spi) = self.bus.deactivate();
(InactiveW5500::new(bus, self.network, self.sockets), spi)
(InactiveW5500::new(bus, self.network), spi)
}
}
pub enum OpenSocketError<BusError> {
ForeignSocketError,
BusError(BusError),
}
pub struct ForeignSocketError {}