From 16e813e45be14816478f084c0609232a7dc6125e Mon Sep 17 00:00:00 2001 From: Jonah Dahlquist Date: Wed, 7 Aug 2019 19:39:28 -0500 Subject: [PATCH] Implemented frame transfer for four-wire bus --- src/bus/four_wire.rs | 19 ++++++++++++++++--- src/bus/mod.rs | 23 ++++++++++++++++++++++- src/bus/three_wire.rs | 3 ++- src/lib.rs | 4 ++-- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/bus/four_wire.rs b/src/bus/four_wire.rs index d94524f..0859a44 100644 --- a/src/bus/four_wire.rs +++ b/src/bus/four_wire.rs @@ -1,3 +1,4 @@ +use byteorder::{BigEndian, ByteOrder}; use embedded_hal::digital::v2::OutputPin; use embedded_hal::spi::FullDuplex; @@ -32,11 +33,23 @@ pub struct ActiveFourWire, ChipSelect: OutputPin> { impl, ChipSelect: OutputPin> ActiveBus for ActiveFourWire { type Error = FourWireError; fn transfer_frame<'a>( - address_phase: [u8; 2], - control_phase: u8, + &mut self, + address_phase: u16, + mut control_phase: u8, data_phase: &'a mut [u8], ) -> Result<&'a mut [u8], nb::Error> { - // TODO implement transfer + let mut address_bytes = [0u8; 2]; + BigEndian::write_u16(&mut address_bytes, address_phase); + self.cs + .set_high() + .map_err(|e| Self::Error::ChipSelectError(e))?; + block!(Self::transfer_bytes(&mut self.spi, &mut address_bytes) + .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))?; + self.cs + .set_low() + .map_err(|e| Self::Error::ChipSelectError(e))?; Ok(data_phase) } } diff --git a/src/bus/mod.rs b/src/bus/mod.rs index 3032b52..dce0f72 100644 --- a/src/bus/mod.rs +++ b/src/bus/mod.rs @@ -1,3 +1,4 @@ +use embedded_hal::spi::FullDuplex; use nb::Result; mod four_wire; @@ -12,9 +13,29 @@ pub trait Bus {} pub trait ActiveBus { type Error; + fn transfer_frame<'a>( - address_phase: [u8; 2], + &mut self, + address_phase: u16, control_phase: u8, data_phase: &'a mut [u8], ) -> Result<&'a mut [u8], Self::Error>; + + fn transfer_bytes<'a, Spi: FullDuplex>( + spi: &mut Spi, + bytes: &'a mut [u8], + ) -> Result<&'a mut [u8], Spi::Error> { + for byte in bytes.iter_mut() { + Self::transfer_byte(spi, byte)?; + } + Ok(bytes) + } + + fn transfer_byte<'a, Spi: FullDuplex>( + spi: &mut Spi, + byte: &'a mut u8, + ) -> Result<&'a mut u8, Spi::Error> { + *byte = spi.send(*byte).and_then(|_| spi.read())?; + Ok(byte) + } } diff --git a/src/bus/three_wire.rs b/src/bus/three_wire.rs index 07db70f..347338b 100644 --- a/src/bus/three_wire.rs +++ b/src/bus/three_wire.rs @@ -25,7 +25,8 @@ pub struct ActiveThreeWire> { impl> ActiveBus for ActiveThreeWire { type Error = Spi::Error; fn transfer_frame<'a>( - address_phase: [u8; 2], + &mut self, + address_phase: u16, control_phase: u8, data_phase: &'a mut [u8], ) -> Result<&'a mut [u8], nb::Error> { diff --git a/src/lib.rs b/src/lib.rs index 44ce24e..548bdf2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -2,10 +2,10 @@ // #![allow(unused)] #![deny(broken_intra_doc_links)] -// extern crate byteorder; +extern crate byteorder; extern crate embedded_hal; -// #[macro_use(block)] +#[macro_use(block)] extern crate nb; // use hal::digital::v2::OutputPin;