diff --git a/src/bus/four_wire.rs b/src/bus/four_wire.rs index 684262a..d94524f 100644 --- a/src/bus/four_wire.rs +++ b/src/bus/four_wire.rs @@ -1,15 +1,13 @@ use embedded_hal::digital::v2::OutputPin; use embedded_hal::spi::FullDuplex; -use crate::bus::Bus; +use crate::bus::{ActiveBus, Bus}; pub struct FourWire { - cs: ChipSelect + cs: ChipSelect, } -impl - FourWire -{ +impl FourWire { pub fn new(cs: ChipSelect) -> Self { Self { cs } } @@ -18,12 +16,22 @@ impl } } -impl, ChipSelect: OutputPin> Bus - for FourWire -{ +impl Bus for FourWire {} + +impl FourWire { + pub fn activate>(self, spi: Spi) -> ActiveFourWire { + ActiveFourWire { cs: self.cs, spi } + } +} + +pub struct ActiveFourWire, ChipSelect: OutputPin> { + cs: ChipSelect, + spi: Spi, +} + +impl, ChipSelect: OutputPin> ActiveBus for ActiveFourWire { type Error = FourWireError; - fn transfer_frame<'a, 'b>( - spi: &'b mut Spi, + fn transfer_frame<'a>( address_phase: [u8; 2], control_phase: u8, data_phase: &'a mut [u8], @@ -32,6 +40,11 @@ impl, ChipSelect: OutputPin> Bus Ok(data_phase) } } +impl, ChipSelect: OutputPin> ActiveFourWire { + pub fn deactivate(self) -> (FourWire, Spi) { + (FourWire::new(self.cs), self.spi) + } +} pub enum FourWireError { SpiError(SpiError), diff --git a/src/bus/mod.rs b/src/bus/mod.rs index f962138..3032b52 100644 --- a/src/bus/mod.rs +++ b/src/bus/mod.rs @@ -1,16 +1,18 @@ use nb::Result; -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 Bus {} + +pub trait ActiveBus { type Error; - fn transfer_frame<'a, 'b>( - spi: &'b mut Spi, + fn transfer_frame<'a>( address_phase: [u8; 2], control_phase: u8, data_phase: &'a mut [u8], diff --git a/src/bus/three_wire.rs b/src/bus/three_wire.rs index 787ae0d..07db70f 100644 --- a/src/bus/three_wire.rs +++ b/src/bus/three_wire.rs @@ -1,19 +1,30 @@ use embedded_hal::spi::FullDuplex; -use crate::bus::Bus; +use crate::bus::{ActiveBus, Bus}; pub struct ThreeWire {} impl ThreeWire { pub fn new() -> Self { - Self { } + Self {} } } -impl> Bus for ThreeWire { +impl Bus for ThreeWire {} + +impl ThreeWire { + pub fn activate>(self, spi: Spi) -> ActiveThreeWire { + ActiveThreeWire { spi } + } +} + +pub struct ActiveThreeWire> { + spi: Spi, +} + +impl> ActiveBus for ActiveThreeWire { type Error = Spi::Error; - fn transfer_frame<'a, 'b>( - spi: &'b mut Spi, + fn transfer_frame<'a>( address_phase: [u8; 2], control_phase: u8, data_phase: &'a mut [u8], @@ -22,3 +33,9 @@ impl> Bus for ThreeWire { Ok(data_phase) } } + +impl> ActiveThreeWire { + pub fn deactivate(self) -> (ThreeWire, Spi) { + (ThreeWire::new(), self.spi) + } +} diff --git a/src/inactive_w5500.rs b/src/inactive_w5500.rs new file mode 100644 index 0000000..3bc7f7f --- /dev/null +++ b/src/inactive_w5500.rs @@ -0,0 +1,26 @@ +use bus::{ActiveFourWire, ActiveThreeWire, Bus, FourWire, ThreeWire}; +use embedded_hal::digital::v2::OutputPin; +use embedded_hal::spi::FullDuplex; +use w5500::W5500; + +pub struct InactiveW5500 { + bus: SpiBus, +} + +impl InactiveW5500 { + pub fn new(bus: SpiBus) -> Self { + Self { bus } + } +} + +impl InactiveW5500> { + pub fn activate>(self, spi: Spi) -> W5500> { + W5500::new(self.bus.activate(spi)) + } +} + +impl InactiveW5500 { + pub fn activate>(self, spi: Spi) -> W5500> { + W5500::new(self.bus.activate(spi)) + } +} diff --git a/src/lib.rs b/src/lib.rs index b1f5d90..44ce24e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -901,7 +901,7 @@ extern crate nb; // } // } - -pub mod uninitialized_w5500; pub mod bus; +pub mod inactive_w5500; +pub mod uninitialized_w5500; pub mod w5500; diff --git a/src/uninitialized_w5500.rs b/src/uninitialized_w5500.rs index d4badc8..638c84e 100644 --- a/src/uninitialized_w5500.rs +++ b/src/uninitialized_w5500.rs @@ -1,34 +1,33 @@ -use embedded_hal::spi::FullDuplex; +use bus::{ActiveBus, ActiveFourWire, ActiveThreeWire}; use embedded_hal::digital::v2::OutputPin; -use bus::{Bus, FourWire, ThreeWire}; +use embedded_hal::spi::FullDuplex; use w5500::W5500; -pub struct UninitializedW5500, SpiBus: Bus> { +pub struct UninitializedW5500 { bus: SpiBus, - spi: Spi, } -impl, SpiBus: Bus> UninitializedW5500 { - pub fn initialize() -> W5500 { +impl UninitializedW5500 { + pub fn initialize(self) -> W5500 { // TODO actually initialize chip - W5500 {} + W5500::new(self.bus) + } + pub fn new(bus: SpiBus) -> UninitializedW5500 { + UninitializedW5500 { bus: bus } } } -impl, ChipSelect: OutputPin> UninitializedW5500> { - pub fn new(spi: Spi, cs: ChipSelect) -> Self { - Self { spi, bus: FourWire::new(cs) } - } +impl, ChipSelect: OutputPin> + UninitializedW5500> +{ pub fn deactivate(self) -> (Spi, ChipSelect) { - (self.spi, self.bus.release()) + let (bus, spi) = self.bus.deactivate(); + (spi, bus.release()) } } -impl> UninitializedW5500 { - pub fn new(spi: Spi) -> Self { - Self { spi, bus: ThreeWire::new() } - } +impl> UninitializedW5500> { pub fn deactivate(self) -> Spi { - self.spi + self.bus.deactivate().1 } -} \ No newline at end of file +} diff --git a/src/w5500.rs b/src/w5500.rs index 1650ef6..02acdad 100644 --- a/src/w5500.rs +++ b/src/w5500.rs @@ -1 +1,34 @@ -pub struct W5500 {} \ No newline at end of file +use crate::inactive_w5500::InactiveW5500; +use crate::uninitialized_w5500::UninitializedW5500; +use bus::{ActiveBus, ActiveFourWire, ActiveThreeWire, FourWire, ThreeWire}; +use embedded_hal::digital::v2::OutputPin; +use embedded_hal::spi::FullDuplex; + +pub struct W5500 { + bus: SpiBus, +} + +impl W5500 { + pub fn new(bus: SpiBus) -> Self { + W5500 { bus } + } + pub fn reset(self) -> UninitializedW5500 { + // TODO reset chip + UninitializedW5500::new(self.bus) + } + //TODO open_udp_socket +} + +impl, ChipSelect: OutputPin> W5500> { + pub fn deactivate(self) -> (InactiveW5500>, Spi) { + let (bus, spi) = self.bus.deactivate(); + (InactiveW5500::new(bus), spi) + } +} + +impl> W5500> { + pub fn deactivate(self) -> (InactiveW5500, Spi) { + let (bus, spi) = self.bus.deactivate(); + (InactiveW5500::new(bus), spi) + } +}