Refactoring bus traits for embedded-hal 1.0

This commit is contained in:
Ryan Summers 2024-07-01 17:54:13 +02:00 committed by kellerkindt
commit b9ba375ca2
10 changed files with 50 additions and 446 deletions

View file

@ -15,7 +15,7 @@ no-chip-version-assertion = []
[dependencies] [dependencies]
byteorder = { version = "1.3.4", default-features = false } byteorder = { version = "1.3.4", default-features = false }
embedded-hal = "0.2" embedded-hal = "1"
embedded-nal = "0.6.0" embedded-nal = "0.6.0"
bit_field = "0.10" bit_field = "0.10"
derive-try-from-primitive = "1" derive-try-from-primitive = "1"
@ -23,4 +23,4 @@ nb = "1.0.0"
defmt = { version = "0.3", optional = true } defmt = { version = "0.3", optional = true }
[dev-dependencies] [dev-dependencies]
embedded-hal-mock = "0.9" embedded-hal-mock = "0.9"

View file

@ -1,8 +1,7 @@
#![allow(clippy::inconsistent_digit_grouping, clippy::unusual_byte_groupings)] #![allow(clippy::inconsistent_digit_grouping, clippy::unusual_byte_groupings)]
use core::fmt; use core::fmt;
use embedded_hal::blocking::spi::{Transfer, Write}; use embedded_hal::spi::{ErrorType, Operation, SpiDevice};
use embedded_hal::digital::v2::OutputPin;
use crate::bus::Bus; use crate::bus::Bus;
@ -11,100 +10,50 @@ const WRITE_MODE_MASK: u8 = 0b00000_1_00;
// TODO This name is not ideal, should be renamed to VDM // TODO This name is not ideal, should be renamed to VDM
#[derive(Debug)] #[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct FourWire<Spi: Transfer<u8> + Write<u8>, ChipSelect: OutputPin> { pub struct FourWire<SPI> {
cs: ChipSelect, spi: SPI,
spi: Spi,
} }
impl<Spi: Transfer<u8> + Write<u8>, ChipSelect: OutputPin> FourWire<Spi, ChipSelect> { impl<SPI> FourWire<SPI> {
pub fn new(spi: Spi, cs: ChipSelect) -> Self { pub fn new(spi: SPI) -> Self {
Self { cs, spi } Self { spi }
} }
pub fn release(self) -> (Spi, ChipSelect) { pub fn release(self) -> SPI {
(self.spi, self.cs) self.spi
} }
} }
impl<Spi: Transfer<u8> + Write<u8>, ChipSelect: OutputPin> Bus for FourWire<Spi, ChipSelect> { impl<SPI: SpiDevice> Bus for FourWire<SPI> {
type Error = type Error = <SPI as ErrorType>::Error;
FourWireError<<Spi as Transfer<u8>>::Error, <Spi as Write<u8>>::Error, ChipSelect::Error>;
fn read_frame(&mut self, block: u8, address: u16, data: &mut [u8]) -> Result<(), Self::Error> { fn read_frame(&mut self, block: u8, address: u16, data: &mut [u8]) -> Result<(), SPI::Error> {
let address_phase = address.to_be_bytes(); let address_phase = address.to_be_bytes();
let control_phase = block << 3; let control_phase = block << 3;
let data_phase = data;
// set Chip select to Low, i.e. prepare to receive data self.spi.transaction(&mut [
self.cs.set_low().map_err(FourWireError::ChipSelectError)?; Operation::Write(&address_phase),
let result = (|| { Operation::Write(&[control_phase]),
self.spi Operation::Write(data),
.write(&address_phase) ])?;
.and_then(|_| self.spi.write(&[control_phase]))
.map_err(FourWireError::WriteError)?;
self.spi
.transfer(data_phase)
.map_err(FourWireError::TransferError)?;
Ok(())
})();
// set Chip select to High, i.e. we've finished listening Ok(())
self.cs.set_high().map_err(FourWireError::ChipSelectError)?;
// then return the result of the transmission
result
} }
fn write_frame(&mut self, block: u8, address: u16, data: &[u8]) -> Result<(), Self::Error> { fn write_frame(&mut self, block: u8, address: u16, data: &[u8]) -> Result<(), SPI::Error> {
let address_phase = address.to_be_bytes();
let control_phase = block << 3 | WRITE_MODE_MASK; let control_phase = block << 3 | WRITE_MODE_MASK;
let data_phase = data;
// set Chip select to Low, i.e. prepare to transmit let address_phase = address.to_be_bytes();
self.cs.set_low().map_err(FourWireError::ChipSelectError)?; self.spi.transaction(&mut [
let result = self Operation::Write(&address_phase),
.spi Operation::Write(&[control_phase]),
.write(&address_phase) Operation::Write(data),
.and_then(|_| self.spi.write(&[control_phase])) ])?;
.and_then(|_| self.spi.write(data_phase))
.map_err(FourWireError::WriteError);
// set Chip select to High, i.e. we've finished transmitting Ok(())
self.cs.set_high().map_err(FourWireError::ChipSelectError)?;
// then return the result of the transmission
result
} }
} }
// Must use map_err, ambiguity prevents From from being implemented
#[repr(u8)]
#[derive(Clone)]
pub enum FourWireError<TransferError, WriteError, ChipSelectError> {
TransferError(TransferError),
WriteError(WriteError),
ChipSelectError(ChipSelectError),
}
impl<TransferError, WriteError, ChipSelectError> fmt::Debug
for FourWireError<TransferError, WriteError, ChipSelectError>
{
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"FourWireError::{}",
match self {
Self::TransferError(_) => "TransferError",
Self::WriteError(_) => "WriteError",
Self::ChipSelectError(_) => "ChipSelectError",
}
)
}
}
// TODO Improved error rendering could be done with specialization.
// https://github.com/rust-lang/rust/issues/31844
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use embedded_hal::digital::v2::OutputPin; use embedded_hal::digital::v2::OutputPin;

View file

@ -1,85 +0,0 @@
#![allow(clippy::inconsistent_digit_grouping, clippy::unusual_byte_groupings)]
use core::fmt;
use embedded_hal::blocking::spi::{Transfer, Write};
use embedded_hal::digital::v2::OutputPin;
use crate::bus::{Bus, FourWire, FourWireError};
// TODO This name is not ideal, should be renamed to VDM
/// This is just like [crate::bus::FourWire] but takes references instead of ownership
/// for the SPI bus and the ChipSelect pin
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct FourWireRef<'a, Spi: Transfer<u8> + Write<u8>, ChipSelect: OutputPin>(
FourWire<SpiRef<'a, Spi>, OutputPinRef<'a, ChipSelect>>,
);
impl<'a, Spi: Transfer<u8> + Write<u8>, ChipSelect: OutputPin> FourWireRef<'a, Spi, ChipSelect> {
pub fn new(spi: &'a mut Spi, cs: &'a mut ChipSelect) -> Self {
Self(FourWire::new(SpiRef(spi), OutputPinRef(cs)))
}
// this is actually a bit silly, but maybe someday someone finds this useful
pub fn release(self) -> (&'a mut Spi, &'a mut ChipSelect) {
let (spi_ref, cs_ref) = self.0.release();
(spi_ref.0, cs_ref.0)
}
}
impl<Spi: Transfer<u8> + Write<u8>, ChipSelect: OutputPin> Bus
for FourWireRef<'_, Spi, ChipSelect>
{
type Error =
FourWireError<<Spi as Transfer<u8>>::Error, <Spi as Write<u8>>::Error, ChipSelect::Error>;
#[inline]
fn read_frame(&mut self, block: u8, address: u16, data: &mut [u8]) -> Result<(), Self::Error> {
self.0.read_frame(block, address, data)
}
#[inline]
fn write_frame(&mut self, block: u8, address: u16, data: &[u8]) -> Result<(), Self::Error> {
self.0.write_frame(block, address, data)
}
}
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct SpiRef<'a, Spi: Transfer<u8> + Write<u8>>(pub &'a mut Spi);
impl<'a, Spi: Transfer<u8> + Write<u8>> Transfer<u8> for SpiRef<'a, Spi> {
type Error = <Spi as Transfer<u8>>::Error;
#[inline]
fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error> {
self.0.transfer(words)
}
}
impl<'a, Spi: Transfer<u8> + Write<u8>> Write<u8> for SpiRef<'a, Spi> {
type Error = <Spi as Write<u8>>::Error;
#[inline]
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> {
self.0.write(words)
}
}
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct OutputPinRef<'a, P: OutputPin>(pub &'a mut P);
impl<'a, P: OutputPin> OutputPin for OutputPinRef<'a, P> {
type Error = P::Error;
#[inline]
fn set_low(&mut self) -> Result<(), Self::Error> {
self.0.set_low()
}
#[inline]
fn set_high(&mut self) -> Result<(), Self::Error> {
self.0.set_high()
}
}

View file

@ -1,14 +1,9 @@
use core::fmt::Debug; use core::fmt::Debug;
mod four_wire; mod four_wire;
mod four_wire_ref;
mod three_wire; mod three_wire;
pub use self::four_wire::FourWire; pub use self::four_wire::FourWire;
pub use self::four_wire::FourWireError;
pub use self::four_wire_ref::FourWireRef;
pub use self::four_wire_ref::OutputPinRef;
pub use self::four_wire_ref::SpiRef;
pub use self::three_wire::ThreeWire; pub use self::three_wire::ThreeWire;
pub use self::three_wire::ThreeWireError; pub use self::three_wire::ThreeWireError;
@ -19,19 +14,3 @@ pub trait Bus {
fn write_frame(&mut self, block: u8, address: u16, data: &[u8]) -> Result<(), Self::Error>; fn write_frame(&mut self, block: u8, address: u16, data: &[u8]) -> Result<(), Self::Error>;
} }
pub struct BusRef<'a, B: Bus>(pub &'a mut B);
impl<B: Bus> Bus for BusRef<'_, B> {
type Error = B::Error;
#[inline]
fn read_frame(&mut self, block: u8, address: u16, data: &mut [u8]) -> Result<(), Self::Error> {
self.0.read_frame(block, address, data)
}
#[inline]
fn write_frame(&mut self, block: u8, address: u16, data: &[u8]) -> Result<(), Self::Error> {
self.0.write_frame(block, address, data)
}
}

View file

@ -1,7 +1,7 @@
#![allow(clippy::inconsistent_digit_grouping, clippy::unusual_byte_groupings)] #![allow(clippy::inconsistent_digit_grouping, clippy::unusual_byte_groupings)]
use core::fmt; use core::fmt;
use embedded_hal::blocking::spi::{Transfer, Write}; use embedded_hal::spi::{ErrorType, Operation, SpiBus};
use crate::bus::Bus; use crate::bus::Bus;
@ -14,22 +14,22 @@ const FIXED_DATA_LENGTH_MODE_4: u8 = 0b000000_11;
// TODO This name is not ideal, should be renamed to FDM // TODO This name is not ideal, should be renamed to FDM
#[derive(Debug)] #[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))] #[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct ThreeWire<Spi: Transfer<u8> + Write<u8>> { pub struct ThreeWire<SPI> {
spi: Spi, spi: SPI,
} }
impl<Spi: Transfer<u8> + Write<u8>> ThreeWire<Spi> { impl<SPI> ThreeWire<SPI> {
pub fn new(spi: Spi) -> Self { pub fn new(spi: SPI) -> Self {
Self { spi } Self { spi }
} }
pub fn release(self) -> Spi { pub fn release(self) -> SPI {
self.spi self.spi
} }
} }
impl<Spi: Transfer<u8> + Write<u8>> Bus for ThreeWire<Spi> { impl<SPI: SpiBus> Bus for ThreeWire<SPI> {
type Error = ThreeWireError<<Spi as Transfer<u8>>::Error, <Spi as Write<u8>>::Error>; type Error = <SPI as ErrorType>::Error;
/// Transfers a frame with an arbitrary data length in FDM /// Transfers a frame with an arbitrary data length in FDM
/// ///
@ -67,11 +67,9 @@ impl<Spi: Transfer<u8> + Write<u8>> Bus for ThreeWire<Spi> {
let address_phase = address.to_be_bytes(); let address_phase = address.to_be_bytes();
self.spi self.spi
.write(&address_phase) .write(&address_phase)
.and_then(|_| self.spi.write(&[control_phase])) .and_then(|_| self.spi.write(&[control_phase]))?;
.map_err(ThreeWireError::WriteError)?;
self.spi self.spi
.transfer(&mut data_phase[..last_length_written as usize]) .transfer_in_place(&mut data_phase[..last_length_written as usize])?;
.map_err(ThreeWireError::TransferError)?;
address += last_length_written; address += last_length_written;
data_phase = &mut data_phase[last_length_written as usize..]; data_phase = &mut data_phase[last_length_written as usize..];
@ -100,8 +98,7 @@ impl<Spi: Transfer<u8> + Write<u8>> Bus for ThreeWire<Spi> {
self.spi self.spi
.write(&address_phase) .write(&address_phase)
.and_then(|_| self.spi.write(&[control_phase])) .and_then(|_| self.spi.write(&[control_phase]))
.and_then(|_| self.spi.write(&data_phase[..last_length_written as usize])) .and_then(|_| self.spi.write(&data_phase[..last_length_written as usize]))?;
.map_err(ThreeWireError::WriteError)?;
address += last_length_written; address += last_length_written;
data_phase = &data_phase[last_length_written as usize..]; data_phase = &data_phase[last_length_written as usize..];

View file

@ -1,7 +1,6 @@
use bit_field::BitArray; use bit_field::BitArray;
use embedded_hal::digital::v2::OutputPin;
use crate::bus::{Bus, BusRef, FourWire, SpiRef, ThreeWire}; use crate::bus::{Bus, FourWire, ThreeWire};
use crate::host::Host; use crate::host::Host;
use crate::net::Ipv4Addr; use crate::net::Ipv4Addr;
use crate::socket::Socket; use crate::socket::Socket;
@ -32,7 +31,7 @@ pub struct DeviceState<HostImpl: Host> {
} }
pub struct Device<SpiBus: Bus, HostImpl: Host> { pub struct Device<SpiBus: Bus, HostImpl: Host> {
bus: SpiBus, pub(crate) bus: SpiBus,
state: DeviceState<HostImpl>, state: DeviceState<HostImpl>,
} }
@ -55,129 +54,15 @@ impl<SpiBus: Bus, HostImpl: Host> Device<SpiBus, HostImpl> {
if self.state.sockets != [0b11111111] { if self.state.sockets != [0b11111111] {
Err(ResetError::SocketsNotReleased) Err(ResetError::SocketsNotReleased)
} else { } else {
self.clear_mode()?; self.reset_device()?;
Ok(UninitializedDevice::new(self.bus)) Ok(UninitializedDevice::new(self.bus))
} }
} }
fn clear_mode(&mut self) -> Result<(), SpiBus::Error> {
// Set RST common register of the w5500
self.as_mut().reset_device()
}
#[inline]
pub fn gateway(&mut self) -> Result<Ipv4Addr, SpiBus::Error> {
self.as_mut().gateway()
}
#[inline]
pub fn subnet_mask(&mut self) -> Result<Ipv4Addr, SpiBus::Error> {
self.as_mut().subnet_mask()
}
#[inline]
pub fn mac(&mut self) -> Result<MacAddress, SpiBus::Error> {
self.as_mut().mac()
}
#[inline]
pub fn ip(&mut self) -> Result<Ipv4Addr, SpiBus::Error> {
self.as_mut().ip()
}
#[inline]
pub fn phy_config(&mut self) -> Result<register::common::PhyConfig, SpiBus::Error> {
self.as_mut().phy_config()
}
#[inline]
pub fn version(&mut self) -> Result<u8, SpiBus::Error> {
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 {
bus: BusRef(&mut self.bus),
state: &mut self.state,
}
}
pub fn release(self) -> (SpiBus, HostImpl) { pub fn release(self) -> (SpiBus, HostImpl) {
(self.bus, self.state.host) (self.bus, self.state.host)
} }
pub fn deactivate(self) -> (SpiBus, InactiveDevice<HostImpl>) {
(self.bus, InactiveDevice(self.state))
}
}
#[derive(Debug)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub struct InactiveDevice<HostImpl: Host>(DeviceState<HostImpl>);
impl<HostImpl: Host> InactiveDevice<HostImpl> {
/// Activates the device by taking ownership
pub fn activate<SpiBus: Bus>(self, bus: SpiBus) -> Device<SpiBus, HostImpl> {
Device { bus, state: self.0 }
}
/// Activates the device by borrowing it
pub fn activate_ref<SpiBus: Bus>(&mut self, bus: SpiBus) -> DeviceRefMut<SpiBus, HostImpl> {
DeviceRefMut {
bus,
state: &mut self.0,
}
}
}
pub struct DeviceRefMut<'a, SpiBus: Bus, HostImpl: Host> {
pub(crate) bus: SpiBus,
state: &'a mut DeviceState<HostImpl>,
}
impl<SpiBus: Bus, HostImpl: Host> DeviceRefMut<'_, SpiBus, HostImpl> {
pub fn take_socket(&mut self) -> Option<Socket> { pub fn take_socket(&mut self) -> Option<Socket> {
// TODO maybe return Future that resolves when release_socket invoked // TODO maybe return Future that resolves when release_socket invoked
for index in 0..8 { for index in 0..8 {
@ -257,6 +142,8 @@ impl<SpiBus: Bus, HostImpl: Host> DeviceRefMut<'_, SpiBus, HostImpl> {
Ok(version_register[0]) Ok(version_register[0])
} }
/// Set a new value for the Retry Time-value Register.
///
/// RTR (Retry Time-value Register) [R/W] [0x0019 0x001A] [0x07D0] /// RTR (Retry Time-value Register) [R/W] [0x0019 0x001A] [0x07D0]
/// ///
/// # Example /// # Example
@ -282,6 +169,8 @@ impl<SpiBus: Bus, HostImpl: Host> DeviceRefMut<'_, SpiBus, HostImpl> {
Ok(()) Ok(())
} }
/// Get the currently set Retry Time-value Register.
///
/// RTR (Retry Time-value Register) [R/W] [0x0019 0x001A] [0x07D0] /// RTR (Retry Time-value Register) [R/W] [0x0019 0x001A] [0x07D0]
/// ///
/// E.g. 4000 = 400ms /// E.g. 4000 = 400ms

View file

@ -17,7 +17,7 @@ mod uninitialized_device;
#[doc(inline)] #[doc(inline)]
pub use self::{ pub use self::{
device::{Device, DeviceRefMut, InactiveDevice}, device::Device,
host::{Dhcp, Host, HostConfig, Manual}, host::{Dhcp, Host, HostConfig, Manual},
net::MacAddress, net::MacAddress,
uninitialized_device::{InitializeError, UninitializedDevice}, uninitialized_device::{InitializeError, UninitializedDevice},

View file

@ -1,10 +1,4 @@
use crate::{ use crate::{bus::Bus, device::Device, host::Host, register::socketn, socket::Socket};
bus::Bus,
device::{Device, DeviceRefMut},
host::Host,
register::socketn,
socket::Socket,
};
use embedded_nal::{nb, IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4, TcpClientStack}; use embedded_nal::{nb, IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4, TcpClientStack};
@ -206,7 +200,7 @@ impl TcpSocket {
} }
} }
impl<SpiBus: Bus, HostImpl: Host> TcpClientStack for DeviceRefMut<'_, SpiBus, HostImpl> { impl<SpiBus: Bus, HostImpl: Host> TcpClientStack for Device<SpiBus, HostImpl> {
type TcpSocket = TcpSocket; type TcpSocket = TcpSocket;
type Error = TcpSocketError<SpiBus::Error>; type Error = TcpSocketError<SpiBus::Error>;
@ -259,44 +253,3 @@ impl<SpiBus: Bus, HostImpl: Host> TcpClientStack for DeviceRefMut<'_, SpiBus, Ho
Ok(()) Ok(())
} }
} }
impl<SpiBus: Bus, HostImpl: Host> TcpClientStack for Device<SpiBus, HostImpl> {
type TcpSocket = TcpSocket;
type Error = TcpSocketError<SpiBus::Error>;
fn socket(&mut self) -> Result<TcpSocket, Self::Error> {
self.as_mut().socket()
}
fn connect(
&mut self,
socket: &mut Self::TcpSocket,
remote: SocketAddr,
) -> nb::Result<(), Self::Error> {
self.as_mut().connect(socket, remote)
}
fn is_connected(&mut self, socket: &Self::TcpSocket) -> Result<bool, Self::Error> {
self.as_mut().is_connected(socket)
}
fn send(
&mut self,
socket: &mut Self::TcpSocket,
buffer: &[u8],
) -> nb::Result<usize, Self::Error> {
self.as_mut().send(socket, buffer)
}
fn receive(
&mut self,
socket: &mut Self::TcpSocket,
buffer: &mut [u8],
) -> nb::Result<usize, Self::Error> {
self.as_mut().receive(socket, buffer)
}
fn close(&mut self, socket: Self::TcpSocket) -> Result<(), Self::Error> {
self.as_mut().close(socket)
}
}

View file

@ -4,7 +4,7 @@ use embedded_nal::{nb, IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4, UdpClientStac
use crate::{ use crate::{
bus::Bus, bus::Bus,
device::{Device, DeviceRefMut}, device::Device,
host::Host, host::Host,
register::socketn::{self, Status}, register::socketn::{self, Status},
socket::Socket, socket::Socket,
@ -478,48 +478,6 @@ where
type UdpSocket = UdpSocket; type UdpSocket = UdpSocket;
type Error = UdpSocketError<SpiBus::Error>; type Error = UdpSocketError<SpiBus::Error>;
#[inline]
fn socket(&mut self) -> Result<Self::UdpSocket, Self::Error> {
self.as_mut().socket()
}
#[inline]
fn connect(
&mut self,
socket: &mut Self::UdpSocket,
remote: SocketAddr,
) -> Result<(), Self::Error> {
self.as_mut().connect(socket, remote)
}
#[inline]
fn send(&mut self, socket: &mut Self::UdpSocket, buffer: &[u8]) -> nb::Result<(), Self::Error> {
self.as_mut().send(socket, buffer)
}
#[inline]
fn receive(
&mut self,
socket: &mut Self::UdpSocket,
buffer: &mut [u8],
) -> nb::Result<(usize, SocketAddr), Self::Error> {
self.as_mut().receive(socket, buffer)
}
#[inline]
fn close(&mut self, socket: Self::UdpSocket) -> Result<(), Self::Error> {
self.as_mut().close(socket)
}
}
impl<SpiBus, HostImpl> UdpClientStack for DeviceRefMut<'_, SpiBus, HostImpl>
where
SpiBus: Bus,
HostImpl: Host,
{
type UdpSocket = UdpSocket;
type Error = UdpSocketError<SpiBus::Error>;
fn socket(&mut self) -> Result<Self::UdpSocket, Self::Error> { fn socket(&mut self) -> Result<Self::UdpSocket, Self::Error> {
if let Some(socket) = self.take_socket() { if let Some(socket) = self.take_socket() {
Ok(UdpSocket::new(socket)) Ok(UdpSocket::new(socket))
@ -564,27 +522,6 @@ where
} }
impl<SpiBus, HostImpl> UdpFullStack for Device<SpiBus, HostImpl> impl<SpiBus, HostImpl> UdpFullStack for Device<SpiBus, HostImpl>
where
SpiBus: Bus,
HostImpl: Host,
{
#[inline]
fn bind(&mut self, socket: &mut Self::UdpSocket, local_port: u16) -> Result<(), Self::Error> {
self.as_mut().bind(socket, local_port)
}
#[inline]
fn send_to(
&mut self,
socket: &mut Self::UdpSocket,
remote: SocketAddr,
buffer: &[u8],
) -> nb::Result<(), Self::Error> {
self.as_mut().send_to(socket, remote, buffer)
}
}
impl<SpiBus, HostImpl> UdpFullStack for DeviceRefMut<'_, SpiBus, HostImpl>
where where
SpiBus: Bus, SpiBus: Bus,
HostImpl: Host, HostImpl: Host,

View file

@ -1,5 +1,4 @@
use embedded_hal::blocking::spi::{Transfer, Write}; use embedded_hal::spi::SpiDevice;
use embedded_hal::digital::v2::OutputPin;
use embedded_nal::Ipv4Addr; use embedded_nal::Ipv4Addr;
use crate::bus::{Bus, FourWire, ThreeWire}; use crate::bus::{Bus, FourWire, ThreeWire};
@ -244,17 +243,3 @@ impl<SpiBus: Bus> UninitializedDevice<SpiBus> {
} }
} }
} }
impl<Spi: Transfer<u8> + Write<u8>, ChipSelect: OutputPin>
UninitializedDevice<FourWire<Spi, ChipSelect>>
{
pub fn deactivate(self) -> (Spi, ChipSelect) {
self.bus.release()
}
}
impl<Spi: Transfer<u8> + Write<u8>> UninitializedDevice<ThreeWire<Spi>> {
pub fn deactivate(self) -> Spi {
self.bus.release()
}
}