Removed the active/inactive concept, and changed bus to use blocking traits to allow users to use shared-bus
This commit is contained in:
parent
55097322a0
commit
ca8268ab31
13 changed files with 127 additions and 239 deletions
|
|
@ -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 spi = ...; // SPI interface to use
|
||||||
let mut cs : OutputPin = ...; // chip select
|
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 device = UninitializedDevice::new(FourWire::new(spi, cs));
|
||||||
let socket = interface.connect(
|
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),
|
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(192, 168, 86, 38)), 8000),
|
||||||
).unwrap();
|
).unwrap();
|
||||||
block!(interface.send(&mut socket, &[104, 101, 108, 108, 111, 10]));
|
block!(interface.send(&mut socket, &[104, 101, 108, 108, 111, 10]));
|
||||||
|
|
|
||||||
|
|
@ -1,50 +1,43 @@
|
||||||
#![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::digital::v2::OutputPin;
|
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;
|
const WRITE_MODE_MASK: u8 = 0b00000_1_00;
|
||||||
|
|
||||||
pub struct FourWire<ChipSelect: OutputPin> {
|
pub struct FourWire<Spi: Transfer<u8> + Write<u8>, ChipSelect: OutputPin> {
|
||||||
cs: ChipSelect,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<ChipSelect: OutputPin> FourWire<ChipSelect> {
|
|
||||||
pub fn new(cs: ChipSelect) -> Self {
|
|
||||||
Self { cs }
|
|
||||||
}
|
|
||||||
pub fn release(self) -> ChipSelect {
|
|
||||||
self.cs
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<ChipSelect: OutputPin> Bus for FourWire<ChipSelect> {}
|
|
||||||
|
|
||||||
impl<ChipSelect: OutputPin> FourWire<ChipSelect> {
|
|
||||||
pub fn activate<Spi: FullDuplex<u8>>(self, spi: Spi) -> ActiveFourWire<Spi, ChipSelect> {
|
|
||||||
ActiveFourWire { cs: self.cs, spi }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ActiveFourWire<Spi: FullDuplex<u8>, ChipSelect: OutputPin> {
|
|
||||||
cs: ChipSelect,
|
cs: ChipSelect,
|
||||||
spi: Spi,
|
spi: Spi,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Spi: FullDuplex<u8>, ChipSelect: OutputPin> ActiveBus for ActiveFourWire<Spi, ChipSelect> {
|
impl<Spi: Transfer<u8> + Write<u8>, ChipSelect: OutputPin> FourWire<Spi, ChipSelect> {
|
||||||
type Error = FourWireError<Spi::Error, ChipSelect::Error>;
|
pub fn new(spi: Spi, cs: ChipSelect) -> Self {
|
||||||
|
Self { spi, cs }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn release(self) -> (Spi, ChipSelect) {
|
||||||
|
(self.spi, self.cs)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Spi: Transfer<u8> + Write<u8>, ChipSelect: OutputPin> Bus for FourWire<Spi, ChipSelect> {
|
||||||
|
type 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<(), Self::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;
|
let data_phase = data;
|
||||||
self.cs.set_low().map_err(FourWireError::ChipSelectError)?;
|
self.cs.set_low().map_err(FourWireError::ChipSelectError)?;
|
||||||
Self::write_bytes(&mut self.spi, &address_phase)
|
self.spi
|
||||||
.and_then(|_| Self::transfer_byte(&mut self.spi, control_phase))
|
.write(&address_phase)
|
||||||
.and_then(|_| Self::read_bytes(&mut self.spi, data_phase))
|
.and_then(|_| self.spi.write(&[control_phase]))
|
||||||
.map_err(FourWireError::SpiError)?;
|
.map_err(FourWireError::WriteError)?;
|
||||||
|
self.spi
|
||||||
|
.transfer(data_phase)
|
||||||
|
.map_err(FourWireError::TransferError)?;
|
||||||
self.cs.set_high().map_err(FourWireError::ChipSelectError)?;
|
self.cs.set_high().map_err(FourWireError::ChipSelectError)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -54,37 +47,40 @@ impl<Spi: FullDuplex<u8>, ChipSelect: OutputPin> ActiveBus for ActiveFourWire<Sp
|
||||||
let control_phase = block << 3 | WRITE_MODE_MASK;
|
let control_phase = block << 3 | WRITE_MODE_MASK;
|
||||||
let data_phase = data;
|
let data_phase = data;
|
||||||
self.cs.set_low().map_err(FourWireError::ChipSelectError)?;
|
self.cs.set_low().map_err(FourWireError::ChipSelectError)?;
|
||||||
Self::write_bytes(&mut self.spi, &address_phase)
|
self.spi
|
||||||
.and_then(|_| Self::transfer_byte(&mut self.spi, control_phase))
|
.write(&address_phase)
|
||||||
.and_then(|_| Self::write_bytes(&mut self.spi, data_phase))
|
.and_then(|_| self.spi.write(&[control_phase]))
|
||||||
.map_err(FourWireError::SpiError)?;
|
.and_then(|_| self.spi.write(data_phase))
|
||||||
|
.map_err(FourWireError::WriteError)?;
|
||||||
self.cs.set_high().map_err(FourWireError::ChipSelectError)?;
|
self.cs.set_high().map_err(FourWireError::ChipSelectError)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl<Spi: FullDuplex<u8>, ChipSelect: OutputPin> ActiveFourWire<Spi, ChipSelect> {
|
|
||||||
pub fn deactivate(self) -> (FourWire<ChipSelect>, Spi) {
|
|
||||||
(FourWire::new(self.cs), self.spi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Must use map_err, ambiguity prevents From from being implemented
|
// Must use map_err, ambiguity prevents From from being implemented
|
||||||
#[repr(u8)]
|
#[repr(u8)]
|
||||||
pub enum FourWireError<SpiError, ChipSelectError> {
|
pub enum FourWireError<TransferError, WriteError, ChipSelectError> {
|
||||||
SpiError(SpiError),
|
TransferError(TransferError),
|
||||||
|
WriteError(WriteError),
|
||||||
ChipSelectError(ChipSelectError),
|
ChipSelectError(ChipSelectError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<SpiError, ChipSelectError> fmt::Debug for FourWireError<SpiError, ChipSelectError> {
|
impl<TransferError, WriteError, ChipSelectError> fmt::Debug
|
||||||
|
for FourWireError<TransferError, WriteError, ChipSelectError>
|
||||||
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"FourWireError::{}",
|
"FourWireError::{}",
|
||||||
match self {
|
match self {
|
||||||
Self::SpiError(_) => "SpiError",
|
Self::TransferError(_) => "TransferError",
|
||||||
|
Self::WriteError(_) => "WriteError",
|
||||||
Self::ChipSelectError(_) => "ChipSelectError",
|
Self::ChipSelectError(_) => "ChipSelectError",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO Improved error rendering could be done with specialization.
|
||||||
|
// https://github.com/rust-lang/rust/issues/31844
|
||||||
|
|
|
||||||
|
|
@ -1,38 +1,15 @@
|
||||||
use core::fmt::Debug;
|
use core::fmt::Debug;
|
||||||
use embedded_hal::spi::FullDuplex;
|
|
||||||
|
|
||||||
mod four_wire;
|
mod four_wire;
|
||||||
mod three_wire;
|
mod three_wire;
|
||||||
|
|
||||||
pub use self::four_wire::ActiveFourWire;
|
|
||||||
pub use self::four_wire::FourWire;
|
pub use self::four_wire::FourWire;
|
||||||
pub use self::three_wire::ActiveThreeWire;
|
|
||||||
pub use self::three_wire::ThreeWire;
|
pub use self::three_wire::ThreeWire;
|
||||||
|
|
||||||
pub trait Bus {}
|
pub trait Bus {
|
||||||
|
|
||||||
pub trait ActiveBus {
|
|
||||||
type Error: Debug;
|
type Error: Debug;
|
||||||
|
|
||||||
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<(), Self::Error>;
|
||||||
|
|
||||||
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>;
|
||||||
|
|
||||||
fn read_bytes<Spi: FullDuplex<u8>>(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: FullDuplex<u8>>(spi: &mut Spi, bytes: &[u8]) -> Result<(), Spi::Error> {
|
|
||||||
for byte in bytes.iter() {
|
|
||||||
Self::transfer_byte(spi, *byte)?;
|
|
||||||
}
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn transfer_byte<Spi: FullDuplex<u8>>(spi: &mut Spi, byte: u8) -> Result<u8, Spi::Error> {
|
|
||||||
block!(spi.send(byte)).and_then(|_| block!(spi.read()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
#![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::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;
|
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_2: u8 = 0b000000_10;
|
||||||
const FIXED_DATA_LENGTH_MODE_4: u8 = 0b000000_11;
|
const FIXED_DATA_LENGTH_MODE_4: u8 = 0b000000_11;
|
||||||
|
|
||||||
pub struct ThreeWire {}
|
pub struct ThreeWire<Spi: Transfer<u8> + Write<u8>> {
|
||||||
|
|
||||||
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<Spi: FullDuplex<u8>>(self, spi: Spi) -> ActiveThreeWire<Spi> {
|
|
||||||
ActiveThreeWire { spi }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct ActiveThreeWire<Spi: FullDuplex<u8>> {
|
|
||||||
spi: Spi,
|
spi: Spi,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Spi: FullDuplex<u8>> ActiveBus for ActiveThreeWire<Spi> {
|
impl<Spi: Transfer<u8> + Write<u8>> ThreeWire<Spi> {
|
||||||
type Error = ThreeWireError<Spi::Error>;
|
pub fn new(spi: Spi) -> Self {
|
||||||
|
Self { spi }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn release(self) -> Spi {
|
||||||
|
self.spi
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<Spi: Transfer<u8> + Write<u8>> Bus for ThreeWire<Spi> {
|
||||||
|
type Error = ThreeWireError<<Spi as Transfer<u8>>::Error, <Spi as Write<u8>>::Error>;
|
||||||
|
|
||||||
/// Transfers a frame with an arbitrary data length in FDM
|
/// Transfers a frame with an arbitrary data length in FDM
|
||||||
///
|
///
|
||||||
|
|
@ -74,20 +62,20 @@ impl<Spi: FullDuplex<u8>> ActiveBus for ActiveThreeWire<Spi> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let address_phase = address.to_be_bytes();
|
let address_phase = address.to_be_bytes();
|
||||||
Self::write_bytes(&mut self.spi, &address_phase)
|
self.spi
|
||||||
.and_then(|_| Self::transfer_byte(&mut self.spi, control_phase))
|
.write(&address_phase)
|
||||||
.and_then(|_| {
|
.and_then(|_| self.spi.write(&[control_phase]))
|
||||||
Self::read_bytes(
|
.map_err(ThreeWireError::WriteError)?;
|
||||||
&mut self.spi,
|
self.spi
|
||||||
&mut data_phase[..last_length_written as usize],
|
.transfer(&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..];
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write_frame(&mut self, block: u8, mut address: u16, data: &[u8]) -> Result<(), Self::Error> {
|
fn write_frame(&mut self, block: u8, mut address: u16, data: &[u8]) -> Result<(), Self::Error> {
|
||||||
let mut control_phase = block << 3 | WRITE_MODE_MASK;
|
let mut control_phase = block << 3 | WRITE_MODE_MASK;
|
||||||
|
|
||||||
|
|
@ -106,11 +94,11 @@ impl<Spi: FullDuplex<u8>> ActiveBus for ActiveThreeWire<Spi> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let address_phase = address.to_be_bytes();
|
let address_phase = address.to_be_bytes();
|
||||||
Self::write_bytes(&mut self.spi, &address_phase)
|
self.spi
|
||||||
.and_then(|_| Self::transfer_byte(&mut self.spi, control_phase))
|
.write(&address_phase)
|
||||||
.and_then(|_| {
|
.and_then(|_| self.spi.write(&[control_phase]))
|
||||||
Self::write_bytes(&mut self.spi, &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..];
|
||||||
|
|
@ -119,29 +107,20 @@ impl<Spi: FullDuplex<u8>> ActiveBus for ActiveThreeWire<Spi> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Spi: FullDuplex<u8>> ActiveThreeWire<Spi> {
|
// Must use map_err, ambiguity prevents From from being implemented
|
||||||
pub fn deactivate(self) -> (ThreeWire, Spi) {
|
pub enum ThreeWireError<TransferError, WriteError> {
|
||||||
(ThreeWire::new(), self.spi)
|
TransferError(TransferError),
|
||||||
}
|
WriteError(WriteError),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ThreeWireError<SpiError> {
|
impl<TransferError, WriteError> fmt::Debug for ThreeWireError<TransferError, WriteError> {
|
||||||
SpiError(SpiError),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<SpiError> From<SpiError> for ThreeWireError<SpiError> {
|
|
||||||
fn from(error: SpiError) -> ThreeWireError<SpiError> {
|
|
||||||
ThreeWireError::SpiError(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<SpiError> fmt::Debug for ThreeWireError<SpiError> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(
|
write!(
|
||||||
f,
|
f,
|
||||||
"ThreeWireError::{}",
|
"ThreeWireError::{}",
|
||||||
match self {
|
match self {
|
||||||
Self::SpiError(_) => "SpiError",
|
Self::TransferError(_) => "TransferError",
|
||||||
|
Self::WriteError(_) => "WriteError",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,18 +3,14 @@ use crate::uninitialized_device::UninitializedDevice;
|
||||||
use bit_field::BitArray;
|
use bit_field::BitArray;
|
||||||
use bus::{ActiveBus, ActiveFourWire, ActiveThreeWire, FourWire, ThreeWire};
|
use bus::{ActiveBus, ActiveFourWire, ActiveThreeWire, FourWire, ThreeWire};
|
||||||
use embedded_hal::digital::v2::OutputPin;
|
use embedded_hal::digital::v2::OutputPin;
|
||||||
use embedded_hal::spi::FullDuplex;
|
|
||||||
|
|
||||||
use interface::Interface;
|
use crate::bus::{Bus, FourWire, ThreeWire};
|
||||||
use network::Network;
|
|
||||||
use crate::bus::{ActiveBus, ActiveFourWire, ActiveThreeWire, FourWire, ThreeWire};
|
|
||||||
use crate::host::Host;
|
use crate::host::Host;
|
||||||
use crate::inactive_device::InactiveDevice;
|
|
||||||
use crate::register;
|
use crate::register;
|
||||||
use crate::socket::Socket;
|
use crate::socket::Socket;
|
||||||
use crate::uninitialized_device::UninitializedDevice;
|
use crate::uninitialized_device::UninitializedDevice;
|
||||||
|
|
||||||
pub struct Device<SpiBus: ActiveBus, HostImpl: Host> {
|
pub struct Device<SpiBus: Bus, HostImpl: Host> {
|
||||||
pub bus: SpiBus,
|
pub bus: SpiBus,
|
||||||
host: HostImpl,
|
host: HostImpl,
|
||||||
sockets: [u8; 1],
|
sockets: [u8; 1],
|
||||||
|
|
@ -31,7 +27,7 @@ impl<E> From<E> for ResetError<E> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<SpiBus: ActiveBus, HostImpl: Host> Device<SpiBus, HostImpl> {
|
impl<SpiBus: Bus, HostImpl: Host> Device<SpiBus, HostImpl> {
|
||||||
pub fn new(bus: SpiBus, host: HostImpl) -> Self {
|
pub fn new(bus: SpiBus, host: HostImpl) -> Self {
|
||||||
Device {
|
Device {
|
||||||
bus,
|
bus,
|
||||||
|
|
@ -58,6 +54,7 @@ impl<SpiBus: ActiveBus, HostImpl: Host> Device<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
|
||||||
for index in 0..8 {
|
for index in 0..8 {
|
||||||
if self.sockets.get_bit(index) {
|
if self.sockets.get_bit(index) {
|
||||||
self.sockets.set_bit(index, false);
|
self.sockets.set_bit(index, false);
|
||||||
|
|
@ -82,19 +79,3 @@ impl<SpiBus: ActiveBus, HostImpl: Host> Device<SpiBus, HostImpl> {
|
||||||
(self.bus, self.host)
|
(self.bus, self.host)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Spi: FullDuplex<u8>, ChipSelect: OutputPin, HostImpl: Host>
|
|
||||||
Device<ActiveFourWire<Spi, ChipSelect>, HostImpl>
|
|
||||||
{
|
|
||||||
pub fn deactivate(self) -> (InactiveDevice<FourWire<ChipSelect>, HostImpl>, Spi) {
|
|
||||||
let (bus, spi) = self.bus.deactivate();
|
|
||||||
(InactiveDevice::new(bus, self.host), spi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<Spi: FullDuplex<u8>, HostImpl: Host> Device<ActiveThreeWire<Spi>, HostImpl> {
|
|
||||||
pub fn deactivate(self) -> (InactiveDevice<ThreeWire, HostImpl>, Spi) {
|
|
||||||
let (bus, spi) = self.bus.deactivate();
|
|
||||||
(InactiveDevice::new(bus, self.host), spi)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::bus::ActiveBus;
|
use crate::bus::Bus;
|
||||||
use crate::host::Host;
|
use crate::host::Host;
|
||||||
use crate::MacAddress;
|
use crate::MacAddress;
|
||||||
|
|
||||||
|
|
@ -22,7 +22,7 @@ impl Dhcp {
|
||||||
|
|
||||||
impl Host for Dhcp {
|
impl Host for Dhcp {
|
||||||
/// Gets (if necessary) and sets the host settings on the chip
|
/// Gets (if necessary) and sets the host settings on the chip
|
||||||
fn refresh<SpiBus: ActiveBus>(&mut self, _bus: &mut SpiBus) -> Result<(), SpiBus::Error> {
|
fn refresh<SpiBus: Bus>(&mut self, _bus: &mut SpiBus) -> Result<(), SpiBus::Error> {
|
||||||
// TODO actually negotiate settings from DHCP
|
// TODO actually negotiate settings from DHCP
|
||||||
// TODO figure out how should receive socket for DHCP negotiations
|
// TODO figure out how should receive socket for DHCP negotiations
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::bus::ActiveBus;
|
use crate::bus::Bus;
|
||||||
use crate::host::{Host, HostConfig};
|
use crate::host::{Host, HostConfig};
|
||||||
use crate::MacAddress;
|
use crate::MacAddress;
|
||||||
use embedded_nal::Ipv4Addr;
|
use embedded_nal::Ipv4Addr;
|
||||||
|
|
@ -26,7 +26,7 @@ impl Manual {
|
||||||
|
|
||||||
impl Host for Manual {
|
impl Host for Manual {
|
||||||
/// Gets (if necessary) and sets the host settings on the chip
|
/// Gets (if necessary) and sets the host settings on the chip
|
||||||
fn refresh<SpiBus: ActiveBus>(&mut self, bus: &mut SpiBus) -> Result<(), SpiBus::Error> {
|
fn refresh<SpiBus: Bus>(&mut self, bus: &mut SpiBus) -> Result<(), SpiBus::Error> {
|
||||||
if !self.is_setup {
|
if !self.is_setup {
|
||||||
Self::write_settings(bus, &mut self.current, &self.settings)?;
|
Self::write_settings(bus, &mut self.current, &self.settings)?;
|
||||||
self.is_setup = true;
|
self.is_setup = true;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ mod manual;
|
||||||
|
|
||||||
pub use self::dhcp::Dhcp;
|
pub use self::dhcp::Dhcp;
|
||||||
pub use self::manual::Manual;
|
pub use self::manual::Manual;
|
||||||
use crate::bus::ActiveBus;
|
use crate::bus::Bus;
|
||||||
use crate::register;
|
use crate::register;
|
||||||
use crate::MacAddress;
|
use crate::MacAddress;
|
||||||
use embedded_nal::Ipv4Addr;
|
use embedded_nal::Ipv4Addr;
|
||||||
|
|
@ -28,13 +28,13 @@ impl Default for HostConfig {
|
||||||
|
|
||||||
pub trait Host {
|
pub trait Host {
|
||||||
/// Gets (if necessary) and sets the host settings on the chip
|
/// Gets (if necessary) and sets the host settings on the chip
|
||||||
fn refresh<SpiBus: ActiveBus>(&mut self, bus: &mut SpiBus) -> Result<(), SpiBus::Error>;
|
fn refresh<SpiBus: Bus>(&mut self, bus: &mut SpiBus) -> Result<(), SpiBus::Error>;
|
||||||
|
|
||||||
/// Write changed settings to chip
|
/// Write changed settings to chip
|
||||||
///
|
///
|
||||||
/// Will check all settings and write any new ones to the chip. Will update the settings returned by `current`
|
/// Will check all settings and write any new ones to the chip. Will update the settings returned by `current`
|
||||||
/// with any changes.
|
/// with any changes.
|
||||||
fn write_settings<SpiBus: ActiveBus>(
|
fn write_settings<SpiBus: Bus>(
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
current: &mut HostConfig,
|
current: &mut HostConfig,
|
||||||
settings: &HostConfig,
|
settings: &HostConfig,
|
||||||
|
|
|
||||||
|
|
@ -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<SpiBus: Bus, HostImpl: Host> {
|
|
||||||
bus: SpiBus,
|
|
||||||
host: HostImpl,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<SpiBus: Bus, HostImpl: Host> InactiveDevice<SpiBus, HostImpl> {
|
|
||||||
pub fn new(bus: SpiBus, host: HostImpl) -> Self {
|
|
||||||
Self { bus, host }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<ChipSelect: OutputPin, HostImpl: Host> InactiveDevice<FourWire<ChipSelect>, HostImpl> {
|
|
||||||
pub fn activate<Spi: FullDuplex<u8>>(
|
|
||||||
self,
|
|
||||||
spi: Spi,
|
|
||||||
) -> Device<ActiveFourWire<Spi, ChipSelect>, HostImpl> {
|
|
||||||
Device::new(self.bus.activate(spi), self.host)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<HostImpl: Host> InactiveDevice<ThreeWire, HostImpl> {
|
|
||||||
pub fn activate<Spi: FullDuplex<u8>>(self, spi: Spi) -> Device<ActiveThreeWire<Spi>, HostImpl> {
|
|
||||||
Device::new(self.bus.activate(spi), self.host)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -73,7 +73,6 @@ impl Default for Mode {
|
||||||
pub mod bus;
|
pub mod bus;
|
||||||
mod device;
|
mod device;
|
||||||
mod host;
|
mod host;
|
||||||
mod inactive_device;
|
|
||||||
pub mod net;
|
pub mod net;
|
||||||
pub mod register;
|
pub mod register;
|
||||||
mod socket;
|
mod socket;
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::bus::ActiveBus;
|
use crate::bus::Bus;
|
||||||
use crate::register::socketn;
|
use crate::register::socketn;
|
||||||
use embedded_nal::Ipv4Addr;
|
use embedded_nal::Ipv4Addr;
|
||||||
|
|
||||||
|
|
@ -40,7 +40,7 @@ impl Socket {
|
||||||
self.rx_buffer
|
self.rx_buffer
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_mode<SpiBus: ActiveBus>(
|
pub fn set_mode<SpiBus: Bus>(
|
||||||
&self,
|
&self,
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
mode: socketn::Protocol,
|
mode: socketn::Protocol,
|
||||||
|
|
@ -50,7 +50,7 @@ impl Socket {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reset_interrupt<SpiBus: ActiveBus>(
|
pub fn reset_interrupt<SpiBus: Bus>(
|
||||||
&self,
|
&self,
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
code: socketn::Interrupt,
|
code: socketn::Interrupt,
|
||||||
|
|
@ -60,7 +60,7 @@ impl Socket {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn has_interrupt<SpiBus: ActiveBus>(
|
pub fn has_interrupt<SpiBus: Bus>(
|
||||||
&self,
|
&self,
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
code: socketn::Interrupt,
|
code: socketn::Interrupt,
|
||||||
|
|
@ -70,7 +70,7 @@ impl Socket {
|
||||||
Ok(data[0] & code as u8 != 0)
|
Ok(data[0] & code as u8 != 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_source_port<SpiBus: ActiveBus>(
|
pub fn set_source_port<SpiBus: Bus>(
|
||||||
&self,
|
&self,
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
port: u16,
|
port: u16,
|
||||||
|
|
@ -80,7 +80,7 @@ impl Socket {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_destination_ip<SpiBus: ActiveBus>(
|
pub fn set_destination_ip<SpiBus: Bus>(
|
||||||
&self,
|
&self,
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
ip: Ipv4Addr,
|
ip: Ipv4Addr,
|
||||||
|
|
@ -90,7 +90,7 @@ impl Socket {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_destination_port<SpiBus: ActiveBus>(
|
pub fn set_destination_port<SpiBus: Bus>(
|
||||||
&self,
|
&self,
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
port: u16,
|
port: u16,
|
||||||
|
|
@ -100,16 +100,13 @@ impl Socket {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_tx_read_pointer<SpiBus: ActiveBus>(
|
pub fn get_tx_read_pointer<SpiBus: Bus>(&self, bus: &mut SpiBus) -> Result<u16, SpiBus::Error> {
|
||||||
&self,
|
|
||||||
bus: &mut SpiBus,
|
|
||||||
) -> Result<u16, SpiBus::Error> {
|
|
||||||
let mut data = [0u8; 2];
|
let mut data = [0u8; 2];
|
||||||
bus.read_frame(self.register(), socketn::TX_DATA_READ_POINTER, &mut data)?;
|
bus.read_frame(self.register(), socketn::TX_DATA_READ_POINTER, &mut data)?;
|
||||||
Ok(u16::from_be_bytes(data))
|
Ok(u16::from_be_bytes(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_tx_read_pointer<SpiBus: ActiveBus>(
|
pub fn set_tx_read_pointer<SpiBus: Bus>(
|
||||||
&self,
|
&self,
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
pointer: u16,
|
pointer: u16,
|
||||||
|
|
@ -119,7 +116,7 @@ impl Socket {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_tx_write_pointer<SpiBus: ActiveBus>(
|
pub fn get_tx_write_pointer<SpiBus: Bus>(
|
||||||
&self,
|
&self,
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
) -> Result<u16, SpiBus::Error> {
|
) -> Result<u16, SpiBus::Error> {
|
||||||
|
|
@ -128,7 +125,7 @@ impl Socket {
|
||||||
Ok(u16::from_be_bytes(data))
|
Ok(u16::from_be_bytes(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_tx_write_pointer<SpiBus: ActiveBus>(
|
pub fn set_tx_write_pointer<SpiBus: Bus>(
|
||||||
&self,
|
&self,
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
pointer: u16,
|
pointer: u16,
|
||||||
|
|
@ -138,16 +135,13 @@ impl Socket {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_rx_read_pointer<SpiBus: ActiveBus>(
|
pub fn get_rx_read_pointer<SpiBus: Bus>(&self, bus: &mut SpiBus) -> Result<u16, SpiBus::Error> {
|
||||||
&self,
|
|
||||||
bus: &mut SpiBus,
|
|
||||||
) -> Result<u16, SpiBus::Error> {
|
|
||||||
let mut data = [0u8; 2];
|
let mut data = [0u8; 2];
|
||||||
bus.read_frame(self.register(), socketn::RX_DATA_READ_POINTER, &mut data)?;
|
bus.read_frame(self.register(), socketn::RX_DATA_READ_POINTER, &mut data)?;
|
||||||
Ok(u16::from_be_bytes(data))
|
Ok(u16::from_be_bytes(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_rx_read_pointer<SpiBus: ActiveBus>(
|
pub fn set_rx_read_pointer<SpiBus: Bus>(
|
||||||
&self,
|
&self,
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
pointer: u16,
|
pointer: u16,
|
||||||
|
|
@ -157,7 +151,7 @@ impl Socket {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_interrupt_mask<SpiBus: ActiveBus>(
|
pub fn set_interrupt_mask<SpiBus: Bus>(
|
||||||
&self,
|
&self,
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
mask: u8,
|
mask: u8,
|
||||||
|
|
@ -167,7 +161,7 @@ impl Socket {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn command<SpiBus: ActiveBus>(
|
pub fn command<SpiBus: Bus>(
|
||||||
&self,
|
&self,
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
command: socketn::Command,
|
command: socketn::Command,
|
||||||
|
|
@ -177,10 +171,7 @@ impl Socket {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_receive_size<SpiBus: ActiveBus>(
|
pub fn get_receive_size<SpiBus: Bus>(&self, bus: &mut SpiBus) -> Result<u16, SpiBus::Error> {
|
||||||
&self,
|
|
||||||
bus: &mut SpiBus,
|
|
||||||
) -> Result<u16, SpiBus::Error> {
|
|
||||||
loop {
|
loop {
|
||||||
// Section 4.2 of datasheet, Sn_TX_FSR address docs indicate that read must be repeated until two sequential reads are stable
|
// 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];
|
let mut sample_0 = [0u8; 2];
|
||||||
|
|
|
||||||
26
src/udp.rs
26
src/udp.rs
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::bus::ActiveBus;
|
use crate::bus::Bus;
|
||||||
use crate::device::Device;
|
use crate::device::Device;
|
||||||
use crate::host::Host;
|
use crate::host::Host;
|
||||||
use crate::register::socketn;
|
use crate::register::socketn;
|
||||||
|
|
@ -15,7 +15,7 @@ impl UdpSocket {
|
||||||
UdpSocket { socket }
|
UdpSocket { socket }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open<SpiBus: ActiveBus>(
|
pub fn open<SpiBus: Bus>(
|
||||||
&mut self,
|
&mut self,
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
local_port: u16,
|
local_port: u16,
|
||||||
|
|
@ -32,7 +32,7 @@ impl UdpSocket {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_destination<SpiBus: ActiveBus>(
|
fn set_destination<SpiBus: Bus>(
|
||||||
&mut self,
|
&mut self,
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
remote: SocketAddrV4,
|
remote: SocketAddrV4,
|
||||||
|
|
@ -42,7 +42,7 @@ impl UdpSocket {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send<SpiBus: ActiveBus>(
|
fn send<SpiBus: Bus>(
|
||||||
&self,
|
&self,
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
send_buffer: &[u8],
|
send_buffer: &[u8],
|
||||||
|
|
@ -74,7 +74,7 @@ impl UdpSocket {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn send_to<SpiBus: ActiveBus>(
|
fn send_to<SpiBus: Bus>(
|
||||||
&mut self,
|
&mut self,
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
remote: SocketAddrV4,
|
remote: SocketAddrV4,
|
||||||
|
|
@ -84,7 +84,7 @@ impl UdpSocket {
|
||||||
self.send(bus, send_buffer)
|
self.send(bus, send_buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn receive<SpiBus: ActiveBus>(
|
fn receive<SpiBus: Bus>(
|
||||||
&mut self,
|
&mut self,
|
||||||
bus: &mut SpiBus,
|
bus: &mut SpiBus,
|
||||||
receive_buffer: &mut [u8],
|
receive_buffer: &mut [u8],
|
||||||
|
|
@ -127,10 +127,7 @@ impl UdpSocket {
|
||||||
Ok((packet_size, remote))
|
Ok((packet_size, remote))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn close<SpiBus: ActiveBus>(
|
fn close<SpiBus: Bus>(&self, bus: &mut SpiBus) -> Result<(), UdpSocketError<SpiBus::Error>> {
|
||||||
&self,
|
|
||||||
bus: &mut SpiBus,
|
|
||||||
) -> Result<(), UdpSocketError<SpiBus::Error>> {
|
|
||||||
self.socket.set_mode(bus, socketn::Protocol::Closed)?;
|
self.socket.set_mode(bus, socketn::Protocol::Closed)?;
|
||||||
self.socket.command(bus, socketn::Command::Close)?;
|
self.socket.command(bus, socketn::Command::Close)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
@ -180,7 +177,7 @@ impl<E: Debug> From<NbError<E>> for nb::Error<E> {
|
||||||
|
|
||||||
impl<SpiBus, HostImpl> UdpClientStack for Device<SpiBus, HostImpl>
|
impl<SpiBus, HostImpl> UdpClientStack for Device<SpiBus, HostImpl>
|
||||||
where
|
where
|
||||||
SpiBus: ActiveBus,
|
SpiBus: Bus,
|
||||||
HostImpl: Host,
|
HostImpl: Host,
|
||||||
{
|
{
|
||||||
type UdpSocket = UdpSocket;
|
type UdpSocket = UdpSocket;
|
||||||
|
|
@ -200,8 +197,9 @@ where
|
||||||
remote: SocketAddr,
|
remote: SocketAddr,
|
||||||
) -> Result<(), Self::Error> {
|
) -> Result<(), Self::Error> {
|
||||||
if let SocketAddr::V4(remote) = remote {
|
if let SocketAddr::V4(remote) = remote {
|
||||||
// TODO find a random port
|
// TODO dynamically select a random port
|
||||||
socket.open(&mut self.bus, 4000)?;
|
socket.open(&mut self.bus, 49849)?; // chosen by fair dice roll.
|
||||||
|
// guaranteed to be random.
|
||||||
socket.set_destination(&mut self.bus, remote)?;
|
socket.set_destination(&mut self.bus, remote)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -228,7 +226,7 @@ where
|
||||||
|
|
||||||
impl<SpiBus, HostImpl> UdpFullStack for Device<SpiBus, HostImpl>
|
impl<SpiBus, HostImpl> UdpFullStack for Device<SpiBus, HostImpl>
|
||||||
where
|
where
|
||||||
SpiBus: ActiveBus,
|
SpiBus: Bus,
|
||||||
HostImpl: Host,
|
HostImpl: Host,
|
||||||
{
|
{
|
||||||
fn bind(&mut self, socket: &mut Self::UdpSocket, local_port: u16) -> Result<(), Self::Error> {
|
fn bind(&mut self, socket: &mut Self::UdpSocket, local_port: u16) -> Result<(), Self::Error> {
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,14 @@
|
||||||
use crate::bus::{ActiveBus, ActiveFourWire, ActiveThreeWire};
|
use crate::bus::{Bus, FourWire, ThreeWire};
|
||||||
use crate::device::Device;
|
use crate::device::Device;
|
||||||
use crate::host::{Dhcp, Host, Manual};
|
use crate::host::{Dhcp, Host, Manual};
|
||||||
use crate::register;
|
use crate::register;
|
||||||
use crate::{MacAddress, Mode};
|
use crate::{MacAddress, Mode};
|
||||||
use bus::{ActiveBus, ActiveFourWire, ActiveThreeWire};
|
use embedded_hal::blocking::spi::{Transfer, Write};
|
||||||
use device::Device;
|
|
||||||
use embedded_hal::digital::v2::OutputPin;
|
use embedded_hal::digital::v2::OutputPin;
|
||||||
use embedded_hal::spi::FullDuplex;
|
|
||||||
use embedded_nal::Ipv4Addr;
|
use embedded_nal::Ipv4Addr;
|
||||||
use register;
|
use register;
|
||||||
|
|
||||||
pub struct UninitializedDevice<SpiBus: ActiveBus> {
|
pub struct UninitializedDevice<SpiBus: Bus> {
|
||||||
bus: SpiBus,
|
bus: SpiBus,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -26,7 +24,7 @@ impl<SpiError> From<SpiError> for InitializeError<SpiError> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<SpiBus: ActiveBus> UninitializedDevice<SpiBus> {
|
impl<SpiBus: Bus> UninitializedDevice<SpiBus> {
|
||||||
pub fn new(bus: SpiBus) -> UninitializedDevice<SpiBus> {
|
pub fn new(bus: SpiBus) -> UninitializedDevice<SpiBus> {
|
||||||
UninitializedDevice { bus }
|
UninitializedDevice { bus }
|
||||||
}
|
}
|
||||||
|
|
@ -124,17 +122,16 @@ impl<SpiBus: ActiveBus> UninitializedDevice<SpiBus> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Spi: FullDuplex<u8>, ChipSelect: OutputPin>
|
impl<Spi: Transfer<u8> + Write<u8>, ChipSelect: OutputPin>
|
||||||
UninitializedDevice<ActiveFourWire<Spi, ChipSelect>>
|
UninitializedDevice<FourWire<Spi, ChipSelect>>
|
||||||
{
|
{
|
||||||
pub fn deactivate(self) -> (Spi, ChipSelect) {
|
pub fn deactivate(self) -> (Spi, ChipSelect) {
|
||||||
let (bus, spi) = self.bus.deactivate();
|
self.bus.release()
|
||||||
(spi, bus.release())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Spi: FullDuplex<u8>> UninitializedDevice<ActiveThreeWire<Spi>> {
|
impl<Spi: Transfer<u8> + Write<u8>> UninitializedDevice<ThreeWire<Spi>> {
|
||||||
pub fn deactivate(self) -> Spi {
|
pub fn deactivate(self) -> Spi {
|
||||||
self.bus.deactivate().1
|
self.bus.release()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue