From ca8268ab31d67812c86933cc9c754c3589f98b78 Mon Sep 17 00:00:00 2001 From: Jonah Dahlquist Date: Mon, 15 Feb 2021 20:52:26 -0800 Subject: [PATCH] Removed the active/inactive concept, and changed bus to use blocking traits to allow users to use shared-bus --- README.md | 6 ++- src/bus/four_wire.rs | 82 ++++++++++++++++----------------- src/bus/mod.rs | 25 +--------- src/bus/three_wire.rs | 91 ++++++++++++++----------------------- src/device.rs | 27 ++--------- src/host/dhcp.rs | 4 +- src/host/manual.rs | 4 +- src/host/mod.rs | 6 +-- src/inactive_device.rs | 32 ------------- src/lib.rs | 1 - src/socket.rs | 41 +++++++---------- src/udp.rs | 26 +++++------ src/uninitialized_device.rs | 21 ++++----- 13 files changed, 127 insertions(+), 239 deletions(-) delete mode 100644 src/inactive_device.rs diff --git a/README.md b/README.md index 92d12d4..ce3a156 100644 --- a/README.md +++ b/README.md @@ -33,8 +33,10 @@ of the SPI implementation. It must be set up to work as the W5500 chip requires let mut spi = ...; // SPI interface to use let mut cs : OutputPin = ...; // chip select - let interface = Interface::setup(spi, cs, MacAddress::new(0, 1, 2, 3, 4, 5), Ipv4Addr::new(192, 168, 86, 79)).unwrap(); - let socket = interface.connect( + let device = UninitializedDevice::new(FourWire::new(spi, cs)); + let device = device.initialize_manual(MacAddress::new(0, 1, 2, 3, 4, 5), Ipv4Addr::new(192, 168, 86, 79), Mode::default()).unwrap(); + let socket = interface.socket(); + socket.connect( SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 86, 38)), 8000), ).unwrap(); block!(interface.send(&mut socket, &[104, 101, 108, 108, 111, 10])); diff --git a/src/bus/four_wire.rs b/src/bus/four_wire.rs index d7088de..2e19b25 100644 --- a/src/bus/four_wire.rs +++ b/src/bus/four_wire.rs @@ -1,50 +1,43 @@ #![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 embedded_hal::spi::FullDuplex; -use crate::bus::{ActiveBus, Bus}; +use crate::bus::Bus; const WRITE_MODE_MASK: u8 = 0b00000_1_00; -pub struct FourWire { - cs: ChipSelect, -} - -impl FourWire { - pub fn new(cs: ChipSelect) -> Self { - Self { cs } - } - pub fn release(self) -> ChipSelect { - self.cs - } -} - -impl Bus for FourWire {} - -impl FourWire { - pub fn activate>(self, spi: Spi) -> ActiveFourWire { - ActiveFourWire { cs: self.cs, spi } - } -} - -pub struct ActiveFourWire, ChipSelect: OutputPin> { +pub struct FourWire + Write, ChipSelect: OutputPin> { cs: ChipSelect, spi: Spi, } -impl, ChipSelect: OutputPin> ActiveBus for ActiveFourWire { - type Error = FourWireError; +impl + Write, ChipSelect: OutputPin> FourWire { + pub fn new(spi: Spi, cs: ChipSelect) -> Self { + Self { spi, cs } + } + + pub fn release(self) -> (Spi, ChipSelect) { + (self.spi, self.cs) + } +} + +impl + Write, ChipSelect: OutputPin> Bus for FourWire { + type Error = + FourWireError<>::Error, >::Error, ChipSelect::Error>; fn read_frame(&mut self, block: u8, address: u16, data: &mut [u8]) -> Result<(), Self::Error> { let address_phase = address.to_be_bytes(); let control_phase = block << 3; let data_phase = data; self.cs.set_low().map_err(FourWireError::ChipSelectError)?; - Self::write_bytes(&mut self.spi, &address_phase) - .and_then(|_| Self::transfer_byte(&mut self.spi, control_phase)) - .and_then(|_| Self::read_bytes(&mut self.spi, data_phase)) - .map_err(FourWireError::SpiError)?; + self.spi + .write(&address_phase) + .and_then(|_| self.spi.write(&[control_phase])) + .map_err(FourWireError::WriteError)?; + self.spi + .transfer(data_phase) + .map_err(FourWireError::TransferError)?; self.cs.set_high().map_err(FourWireError::ChipSelectError)?; Ok(()) @@ -54,37 +47,40 @@ impl, ChipSelect: OutputPin> ActiveBus for ActiveFourWire, ChipSelect: OutputPin> ActiveFourWire { - pub fn deactivate(self) -> (FourWire, Spi) { - (FourWire::new(self.cs), self.spi) - } -} // Must use map_err, ambiguity prevents From from being implemented #[repr(u8)] -pub enum FourWireError { - SpiError(SpiError), +pub enum FourWireError { + TransferError(TransferError), + WriteError(WriteError), ChipSelectError(ChipSelectError), } -impl fmt::Debug for FourWireError { +impl fmt::Debug + for FourWireError +{ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "FourWireError::{}", match self { - Self::SpiError(_) => "SpiError", + 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 diff --git a/src/bus/mod.rs b/src/bus/mod.rs index e9bd338..a4ffc85 100644 --- a/src/bus/mod.rs +++ b/src/bus/mod.rs @@ -1,38 +1,15 @@ use core::fmt::Debug; -use embedded_hal::spi::FullDuplex; mod four_wire; mod three_wire; -pub use self::four_wire::ActiveFourWire; pub use self::four_wire::FourWire; -pub use self::three_wire::ActiveThreeWire; pub use self::three_wire::ThreeWire; -pub trait Bus {} - -pub trait ActiveBus { +pub trait Bus { type Error: Debug; fn read_frame(&mut self, block: u8, address: u16, data: &mut [u8]) -> Result<(), Self::Error>; fn write_frame(&mut self, block: u8, address: u16, data: &[u8]) -> Result<(), Self::Error>; - - fn read_bytes>(spi: &mut Spi, bytes: &mut [u8]) -> Result<(), Spi::Error> { - for byte in bytes.iter_mut() { - *byte = Self::transfer_byte(spi, *byte)?; - } - Ok(()) - } - - fn write_bytes>(spi: &mut Spi, bytes: &[u8]) -> Result<(), Spi::Error> { - for byte in bytes.iter() { - Self::transfer_byte(spi, *byte)?; - } - Ok(()) - } - - fn transfer_byte>(spi: &mut Spi, byte: u8) -> Result { - block!(spi.send(byte)).and_then(|_| block!(spi.read())) - } } diff --git a/src/bus/three_wire.rs b/src/bus/three_wire.rs index 75bc20f..f7b59bb 100644 --- a/src/bus/three_wire.rs +++ b/src/bus/three_wire.rs @@ -1,9 +1,9 @@ #![allow(clippy::inconsistent_digit_grouping, clippy::unusual_byte_groupings)] use core::fmt; -use embedded_hal::spi::FullDuplex; +use embedded_hal::blocking::spi::{Transfer, Write}; -use crate::bus::{ActiveBus, Bus}; +use crate::bus::Bus; const WRITE_MODE_MASK: u8 = 0b00000_1_0; @@ -11,34 +11,22 @@ const FIXED_DATA_LENGTH_MODE_1: u8 = 0b000000_01; const FIXED_DATA_LENGTH_MODE_2: u8 = 0b000000_10; const FIXED_DATA_LENGTH_MODE_4: u8 = 0b000000_11; -pub struct ThreeWire {} - -impl ThreeWire { - pub fn new() -> Self { - Self {} - } -} - -impl Default for ThreeWire { - fn default() -> Self { - Self::new() - } -} - -impl Bus for ThreeWire {} - -impl ThreeWire { - pub fn activate>(self, spi: Spi) -> ActiveThreeWire { - ActiveThreeWire { spi } - } -} - -pub struct ActiveThreeWire> { +pub struct ThreeWire + Write> { spi: Spi, } -impl> ActiveBus for ActiveThreeWire { - type Error = ThreeWireError; +impl + Write> ThreeWire { + pub fn new(spi: Spi) -> Self { + Self { spi } + } + + pub fn release(self) -> Spi { + self.spi + } +} + +impl + Write> Bus for ThreeWire { + type Error = ThreeWireError<>::Error, >::Error>; /// Transfers a frame with an arbitrary data length in FDM /// @@ -74,20 +62,20 @@ impl> ActiveBus for ActiveThreeWire { } let address_phase = address.to_be_bytes(); - Self::write_bytes(&mut self.spi, &address_phase) - .and_then(|_| Self::transfer_byte(&mut self.spi, control_phase)) - .and_then(|_| { - Self::read_bytes( - &mut self.spi, - &mut data_phase[..last_length_written as usize], - ) - })?; + self.spi + .write(&address_phase) + .and_then(|_| self.spi.write(&[control_phase])) + .map_err(ThreeWireError::WriteError)?; + self.spi + .transfer(&mut data_phase[..last_length_written as usize]) + .map_err(ThreeWireError::TransferError)?; address += last_length_written; data_phase = &mut data_phase[last_length_written as usize..]; } Ok(()) } + fn write_frame(&mut self, block: u8, mut address: u16, data: &[u8]) -> Result<(), Self::Error> { let mut control_phase = block << 3 | WRITE_MODE_MASK; @@ -106,11 +94,11 @@ impl> ActiveBus for ActiveThreeWire { } let address_phase = address.to_be_bytes(); - Self::write_bytes(&mut self.spi, &address_phase) - .and_then(|_| Self::transfer_byte(&mut self.spi, control_phase)) - .and_then(|_| { - Self::write_bytes(&mut self.spi, &data_phase[..last_length_written as usize]) - })?; + self.spi + .write(&address_phase) + .and_then(|_| self.spi.write(&[control_phase])) + .and_then(|_| self.spi.write(&data_phase[..last_length_written as usize])) + .map_err(ThreeWireError::WriteError)?; address += last_length_written; data_phase = &data_phase[last_length_written as usize..]; @@ -119,29 +107,20 @@ impl> ActiveBus for ActiveThreeWire { } } -impl> ActiveThreeWire { - pub fn deactivate(self) -> (ThreeWire, Spi) { - (ThreeWire::new(), self.spi) - } +// Must use map_err, ambiguity prevents From from being implemented +pub enum ThreeWireError { + TransferError(TransferError), + WriteError(WriteError), } -pub enum ThreeWireError { - SpiError(SpiError), -} - -impl From for ThreeWireError { - fn from(error: SpiError) -> ThreeWireError { - ThreeWireError::SpiError(error) - } -} - -impl fmt::Debug for ThreeWireError { +impl fmt::Debug for ThreeWireError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!( f, "ThreeWireError::{}", match self { - Self::SpiError(_) => "SpiError", + Self::TransferError(_) => "TransferError", + Self::WriteError(_) => "WriteError", } ) } diff --git a/src/device.rs b/src/device.rs index f637036..f1629a5 100644 --- a/src/device.rs +++ b/src/device.rs @@ -3,18 +3,14 @@ use crate::uninitialized_device::UninitializedDevice; use bit_field::BitArray; use bus::{ActiveBus, ActiveFourWire, ActiveThreeWire, FourWire, ThreeWire}; use embedded_hal::digital::v2::OutputPin; -use embedded_hal::spi::FullDuplex; -use interface::Interface; -use network::Network; -use crate::bus::{ActiveBus, ActiveFourWire, ActiveThreeWire, FourWire, ThreeWire}; +use crate::bus::{Bus, FourWire, ThreeWire}; use crate::host::Host; -use crate::inactive_device::InactiveDevice; use crate::register; use crate::socket::Socket; use crate::uninitialized_device::UninitializedDevice; -pub struct Device { +pub struct Device { pub bus: SpiBus, host: HostImpl, sockets: [u8; 1], @@ -31,7 +27,7 @@ impl From for ResetError { } } -impl Device { +impl Device { pub fn new(bus: SpiBus, host: HostImpl) -> Self { Device { bus, @@ -58,6 +54,7 @@ impl Device { } pub fn take_socket(&mut self) -> Option { + // TODO maybe return Future that resolves when release_socket invoked for index in 0..8 { if self.sockets.get_bit(index) { self.sockets.set_bit(index, false); @@ -82,19 +79,3 @@ impl Device { (self.bus, self.host) } } - -impl, ChipSelect: OutputPin, HostImpl: Host> - Device, HostImpl> -{ - pub fn deactivate(self) -> (InactiveDevice, HostImpl>, Spi) { - let (bus, spi) = self.bus.deactivate(); - (InactiveDevice::new(bus, self.host), spi) - } -} - -impl, HostImpl: Host> Device, HostImpl> { - pub fn deactivate(self) -> (InactiveDevice, Spi) { - let (bus, spi) = self.bus.deactivate(); - (InactiveDevice::new(bus, self.host), spi) - } -} diff --git a/src/host/dhcp.rs b/src/host/dhcp.rs index dedf226..f792736 100644 --- a/src/host/dhcp.rs +++ b/src/host/dhcp.rs @@ -1,4 +1,4 @@ -use crate::bus::ActiveBus; +use crate::bus::Bus; use crate::host::Host; use crate::MacAddress; @@ -22,7 +22,7 @@ impl Dhcp { impl Host for Dhcp { /// Gets (if necessary) and sets the host settings on the chip - fn refresh(&mut self, _bus: &mut SpiBus) -> Result<(), SpiBus::Error> { + fn refresh(&mut self, _bus: &mut SpiBus) -> Result<(), SpiBus::Error> { // TODO actually negotiate settings from DHCP // TODO figure out how should receive socket for DHCP negotiations Ok(()) diff --git a/src/host/manual.rs b/src/host/manual.rs index ae07216..0f61022 100644 --- a/src/host/manual.rs +++ b/src/host/manual.rs @@ -1,4 +1,4 @@ -use crate::bus::ActiveBus; +use crate::bus::Bus; use crate::host::{Host, HostConfig}; use crate::MacAddress; use embedded_nal::Ipv4Addr; @@ -26,7 +26,7 @@ impl Manual { impl Host for Manual { /// Gets (if necessary) and sets the host settings on the chip - fn refresh(&mut self, bus: &mut SpiBus) -> Result<(), SpiBus::Error> { + fn refresh(&mut self, bus: &mut SpiBus) -> Result<(), SpiBus::Error> { if !self.is_setup { Self::write_settings(bus, &mut self.current, &self.settings)?; self.is_setup = true; diff --git a/src/host/mod.rs b/src/host/mod.rs index 5f50290..206ec91 100644 --- a/src/host/mod.rs +++ b/src/host/mod.rs @@ -3,7 +3,7 @@ mod manual; pub use self::dhcp::Dhcp; pub use self::manual::Manual; -use crate::bus::ActiveBus; +use crate::bus::Bus; use crate::register; use crate::MacAddress; use embedded_nal::Ipv4Addr; @@ -28,13 +28,13 @@ impl Default for HostConfig { pub trait Host { /// Gets (if necessary) and sets the host settings on the chip - fn refresh(&mut self, bus: &mut SpiBus) -> Result<(), SpiBus::Error>; + fn refresh(&mut self, bus: &mut SpiBus) -> Result<(), SpiBus::Error>; /// Write changed settings to chip /// /// Will check all settings and write any new ones to the chip. Will update the settings returned by `current` /// with any changes. - fn write_settings( + fn write_settings( bus: &mut SpiBus, current: &mut HostConfig, settings: &HostConfig, diff --git a/src/inactive_device.rs b/src/inactive_device.rs deleted file mode 100644 index c774598..0000000 --- a/src/inactive_device.rs +++ /dev/null @@ -1,32 +0,0 @@ -use crate::bus::{ActiveFourWire, ActiveThreeWire, Bus, FourWire, ThreeWire}; -use crate::device::Device; -use crate::host::Host; -use embedded_hal::digital::v2::OutputPin; -use embedded_hal::spi::FullDuplex; -use network::Network; - -pub struct InactiveDevice { - bus: SpiBus, - host: HostImpl, -} - -impl InactiveDevice { - pub fn new(bus: SpiBus, host: HostImpl) -> Self { - Self { bus, host } - } -} - -impl InactiveDevice, HostImpl> { - pub fn activate>( - self, - spi: Spi, - ) -> Device, HostImpl> { - Device::new(self.bus.activate(spi), self.host) - } -} - -impl InactiveDevice { - pub fn activate>(self, spi: Spi) -> Device, HostImpl> { - Device::new(self.bus.activate(spi), self.host) - } -} diff --git a/src/lib.rs b/src/lib.rs index d4f0ba3..74267a0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -73,7 +73,6 @@ impl Default for Mode { pub mod bus; mod device; mod host; -mod inactive_device; pub mod net; pub mod register; mod socket; diff --git a/src/socket.rs b/src/socket.rs index 1e97b10..a4e55dd 100644 --- a/src/socket.rs +++ b/src/socket.rs @@ -1,4 +1,4 @@ -use crate::bus::ActiveBus; +use crate::bus::Bus; use crate::register::socketn; use embedded_nal::Ipv4Addr; @@ -40,7 +40,7 @@ impl Socket { self.rx_buffer } - pub fn set_mode( + pub fn set_mode( &self, bus: &mut SpiBus, mode: socketn::Protocol, @@ -50,7 +50,7 @@ impl Socket { Ok(()) } - pub fn reset_interrupt( + pub fn reset_interrupt( &self, bus: &mut SpiBus, code: socketn::Interrupt, @@ -60,7 +60,7 @@ impl Socket { Ok(()) } - pub fn has_interrupt( + pub fn has_interrupt( &self, bus: &mut SpiBus, code: socketn::Interrupt, @@ -70,7 +70,7 @@ impl Socket { Ok(data[0] & code as u8 != 0) } - pub fn set_source_port( + pub fn set_source_port( &self, bus: &mut SpiBus, port: u16, @@ -80,7 +80,7 @@ impl Socket { Ok(()) } - pub fn set_destination_ip( + pub fn set_destination_ip( &self, bus: &mut SpiBus, ip: Ipv4Addr, @@ -90,7 +90,7 @@ impl Socket { Ok(()) } - pub fn set_destination_port( + pub fn set_destination_port( &self, bus: &mut SpiBus, port: u16, @@ -100,16 +100,13 @@ impl Socket { Ok(()) } - pub fn get_tx_read_pointer( - &self, - bus: &mut SpiBus, - ) -> Result { + pub fn get_tx_read_pointer(&self, bus: &mut SpiBus) -> Result { let mut data = [0u8; 2]; bus.read_frame(self.register(), socketn::TX_DATA_READ_POINTER, &mut data)?; Ok(u16::from_be_bytes(data)) } - pub fn set_tx_read_pointer( + pub fn set_tx_read_pointer( &self, bus: &mut SpiBus, pointer: u16, @@ -119,7 +116,7 @@ impl Socket { Ok(()) } - pub fn get_tx_write_pointer( + pub fn get_tx_write_pointer( &self, bus: &mut SpiBus, ) -> Result { @@ -128,7 +125,7 @@ impl Socket { Ok(u16::from_be_bytes(data)) } - pub fn set_tx_write_pointer( + pub fn set_tx_write_pointer( &self, bus: &mut SpiBus, pointer: u16, @@ -138,16 +135,13 @@ impl Socket { Ok(()) } - pub fn get_rx_read_pointer( - &self, - bus: &mut SpiBus, - ) -> Result { + pub fn get_rx_read_pointer(&self, bus: &mut SpiBus) -> Result { let mut data = [0u8; 2]; bus.read_frame(self.register(), socketn::RX_DATA_READ_POINTER, &mut data)?; Ok(u16::from_be_bytes(data)) } - pub fn set_rx_read_pointer( + pub fn set_rx_read_pointer( &self, bus: &mut SpiBus, pointer: u16, @@ -157,7 +151,7 @@ impl Socket { Ok(()) } - pub fn set_interrupt_mask( + pub fn set_interrupt_mask( &self, bus: &mut SpiBus, mask: u8, @@ -167,7 +161,7 @@ impl Socket { Ok(()) } - pub fn command( + pub fn command( &self, bus: &mut SpiBus, command: socketn::Command, @@ -177,10 +171,7 @@ impl Socket { Ok(()) } - pub fn get_receive_size( - &self, - bus: &mut SpiBus, - ) -> Result { + pub 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]; diff --git a/src/udp.rs b/src/udp.rs index 37713c5..345e584 100644 --- a/src/udp.rs +++ b/src/udp.rs @@ -1,4 +1,4 @@ -use crate::bus::ActiveBus; +use crate::bus::Bus; use crate::device::Device; use crate::host::Host; use crate::register::socketn; @@ -15,7 +15,7 @@ impl UdpSocket { UdpSocket { socket } } - pub fn open( + pub fn open( &mut self, bus: &mut SpiBus, local_port: u16, @@ -32,7 +32,7 @@ impl UdpSocket { Ok(()) } - fn set_destination( + fn set_destination( &mut self, bus: &mut SpiBus, remote: SocketAddrV4, @@ -42,7 +42,7 @@ impl UdpSocket { Ok(()) } - fn send( + fn send( &self, bus: &mut SpiBus, send_buffer: &[u8], @@ -74,7 +74,7 @@ impl UdpSocket { } } - fn send_to( + fn send_to( &mut self, bus: &mut SpiBus, remote: SocketAddrV4, @@ -84,7 +84,7 @@ impl UdpSocket { self.send(bus, send_buffer) } - fn receive( + fn receive( &mut self, bus: &mut SpiBus, receive_buffer: &mut [u8], @@ -127,10 +127,7 @@ impl UdpSocket { Ok((packet_size, remote)) } - fn close( - &self, - bus: &mut SpiBus, - ) -> Result<(), UdpSocketError> { + fn close(&self, bus: &mut SpiBus) -> Result<(), UdpSocketError> { self.socket.set_mode(bus, socketn::Protocol::Closed)?; self.socket.command(bus, socketn::Command::Close)?; Ok(()) @@ -180,7 +177,7 @@ impl From> for nb::Error { impl UdpClientStack for Device where - SpiBus: ActiveBus, + SpiBus: Bus, HostImpl: Host, { type UdpSocket = UdpSocket; @@ -200,8 +197,9 @@ where remote: SocketAddr, ) -> Result<(), Self::Error> { if let SocketAddr::V4(remote) = remote { - // TODO find a random port - socket.open(&mut self.bus, 4000)?; + // TODO dynamically select a random port + socket.open(&mut self.bus, 49849)?; // chosen by fair dice roll. + // guaranteed to be random. socket.set_destination(&mut self.bus, remote)?; Ok(()) } else { @@ -228,7 +226,7 @@ where impl UdpFullStack for Device where - SpiBus: ActiveBus, + SpiBus: Bus, HostImpl: Host, { fn bind(&mut self, socket: &mut Self::UdpSocket, local_port: u16) -> Result<(), Self::Error> { diff --git a/src/uninitialized_device.rs b/src/uninitialized_device.rs index 1523561..3774192 100644 --- a/src/uninitialized_device.rs +++ b/src/uninitialized_device.rs @@ -1,16 +1,14 @@ -use crate::bus::{ActiveBus, ActiveFourWire, ActiveThreeWire}; +use crate::bus::{Bus, FourWire, ThreeWire}; use crate::device::Device; use crate::host::{Dhcp, Host, Manual}; use crate::register; use crate::{MacAddress, Mode}; -use bus::{ActiveBus, ActiveFourWire, ActiveThreeWire}; -use device::Device; +use embedded_hal::blocking::spi::{Transfer, Write}; use embedded_hal::digital::v2::OutputPin; -use embedded_hal::spi::FullDuplex; use embedded_nal::Ipv4Addr; use register; -pub struct UninitializedDevice { +pub struct UninitializedDevice { bus: SpiBus, } @@ -26,7 +24,7 @@ impl From for InitializeError { } } -impl UninitializedDevice { +impl UninitializedDevice { pub fn new(bus: SpiBus) -> UninitializedDevice { UninitializedDevice { bus } } @@ -124,17 +122,16 @@ impl UninitializedDevice { } } -impl, ChipSelect: OutputPin> - UninitializedDevice> +impl + Write, ChipSelect: OutputPin> + UninitializedDevice> { pub fn deactivate(self) -> (Spi, ChipSelect) { - let (bus, spi) = self.bus.deactivate(); - (spi, bus.release()) + self.bus.release() } } -impl> UninitializedDevice> { +impl + Write> UninitializedDevice> { pub fn deactivate(self) -> Spi { - self.bus.deactivate().1 + self.bus.release() } }