Removed the active/inactive concept, and changed bus to use blocking traits to allow users to use shared-bus

This commit is contained in:
Jonah Dahlquist 2021-02-15 20:52:26 -08:00
commit ca8268ab31
13 changed files with 127 additions and 239 deletions

View file

@ -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<Spi: FullDuplex<u8>>(self, spi: Spi) -> ActiveThreeWire<Spi> {
ActiveThreeWire { spi }
}
}
pub struct ActiveThreeWire<Spi: FullDuplex<u8>> {
pub struct ThreeWire<Spi: Transfer<u8> + Write<u8>> {
spi: Spi,
}
impl<Spi: FullDuplex<u8>> ActiveBus for ActiveThreeWire<Spi> {
type Error = ThreeWireError<Spi::Error>;
impl<Spi: Transfer<u8> + Write<u8>> ThreeWire<Spi> {
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
///
@ -74,20 +62,20 @@ impl<Spi: FullDuplex<u8>> ActiveBus for ActiveThreeWire<Spi> {
}
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<Spi: FullDuplex<u8>> ActiveBus for ActiveThreeWire<Spi> {
}
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<Spi: FullDuplex<u8>> ActiveBus for ActiveThreeWire<Spi> {
}
}
impl<Spi: FullDuplex<u8>> ActiveThreeWire<Spi> {
pub fn deactivate(self) -> (ThreeWire, Spi) {
(ThreeWire::new(), self.spi)
}
// Must use map_err, ambiguity prevents From from being implemented
pub enum ThreeWireError<TransferError, WriteError> {
TransferError(TransferError),
WriteError(WriteError),
}
pub enum ThreeWireError<SpiError> {
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> {
impl<TransferError, WriteError> fmt::Debug for ThreeWireError<TransferError, WriteError> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"ThreeWireError::{}",
match self {
Self::SpiError(_) => "SpiError",
Self::TransferError(_) => "TransferError",
Self::WriteError(_) => "WriteError",
}
)
}