Merge pull request #56 from LechevSpace/chore/four-wire-tests-and-docs
chore: test FourWire with embedded-hal-mock:
This commit is contained in:
commit
f3f0f3e461
3 changed files with 116 additions and 13 deletions
11
Cargo.toml
11
Cargo.toml
|
|
@ -10,14 +10,17 @@ license = "MIT OR Apache-2.0"
|
|||
readme = "README.md"
|
||||
edition = "2018"
|
||||
|
||||
[features]
|
||||
no-chip-version-assertion = []
|
||||
|
||||
[dependencies]
|
||||
byteorder = { version = "1.3.4", default-features = false }
|
||||
embedded-hal = "0.2.4"
|
||||
embedded-hal = "0.2"
|
||||
embedded-nal = "0.6.0"
|
||||
bit_field = "0.10.1"
|
||||
bit_field = "0.10"
|
||||
derive-try-from-primitive = "1"
|
||||
nb = "1.0.0"
|
||||
defmt = { version = "0.3", optional = true }
|
||||
|
||||
[features]
|
||||
no-chip-version-assertion = []
|
||||
[dev-dependencies]
|
||||
embedded-hal-mock = "0.9"
|
||||
|
|
@ -29,10 +29,13 @@ impl<Spi: Transfer<u8> + Write<u8>, ChipSelect: OutputPin> FourWire<Spi, ChipSel
|
|||
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> {
|
||||
let address_phase = address.to_be_bytes();
|
||||
let control_phase = block << 3;
|
||||
let data_phase = data;
|
||||
|
||||
// set Chip select to Low, i.e. prepare to receive data
|
||||
self.cs.set_low().map_err(FourWireError::ChipSelectError)?;
|
||||
let result = (|| {
|
||||
self.spi
|
||||
|
|
@ -44,29 +47,39 @@ impl<Spi: Transfer<u8> + Write<u8>, ChipSelect: OutputPin> Bus for FourWire<Spi,
|
|||
.map_err(FourWireError::TransferError)?;
|
||||
Ok(())
|
||||
})();
|
||||
|
||||
// set Chip select to High, i.e. we've finished listening
|
||||
self.cs.set_high().map_err(FourWireError::ChipSelectError)?;
|
||||
|
||||
// then return the result of the transmission
|
||||
result
|
||||
}
|
||||
|
||||
fn write_frame(&mut self, block: u8, address: u16, data: &[u8]) -> Result<(), Self::Error> {
|
||||
let address_phase = address.to_be_bytes();
|
||||
let control_phase = block << 3 | WRITE_MODE_MASK;
|
||||
let data_phase = data;
|
||||
|
||||
// set Chip select to Low, i.e. prepare to transmit
|
||||
self.cs.set_low().map_err(FourWireError::ChipSelectError)?;
|
||||
let result = (|| {
|
||||
self.spi
|
||||
.write(&address_phase)
|
||||
.and_then(|_| self.spi.write(&[control_phase]))
|
||||
.and_then(|_| self.spi.write(data_phase))
|
||||
.map_err(FourWireError::WriteError)?;
|
||||
Ok(())
|
||||
})();
|
||||
let result = self
|
||||
.spi
|
||||
.write(&address_phase)
|
||||
.and_then(|_| self.spi.write(&[control_phase]))
|
||||
.and_then(|_| self.spi.write(data_phase))
|
||||
.map_err(FourWireError::WriteError);
|
||||
|
||||
// set Chip select to High, i.e. we've finished transmitting
|
||||
self.cs.set_high().map_err(FourWireError::ChipSelectError)?;
|
||||
|
||||
// then return the result of the transmission
|
||||
result
|
||||
}
|
||||
}
|
||||
|
||||
// Must use map_err, ambiguity prevents From from being implemented
|
||||
#[repr(u8)]
|
||||
#[derive(Clone)]
|
||||
pub enum FourWireError<TransferError, WriteError, ChipSelectError> {
|
||||
TransferError(TransferError),
|
||||
WriteError(WriteError),
|
||||
|
|
@ -91,3 +104,90 @@ impl<TransferError, WriteError, ChipSelectError> fmt::Debug
|
|||
|
||||
// TODO Improved error rendering could be done with specialization.
|
||||
// https://github.com/rust-lang/rust/issues/31844
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use embedded_hal::digital::v2::OutputPin;
|
||||
use embedded_hal_mock::{
|
||||
pin::{Mock as PinMock, State as PinState, Transaction as PinTransaction},
|
||||
spi::{Mock as SpiMock, Transaction as SpiTransaction},
|
||||
};
|
||||
|
||||
use crate::{
|
||||
bus::{four_wire::WRITE_MODE_MASK, Bus},
|
||||
register,
|
||||
};
|
||||
|
||||
use super::FourWire;
|
||||
|
||||
#[test]
|
||||
fn test_read_frame() {
|
||||
let mut cs_pin = PinMock::new(&[
|
||||
// we begin with pin HIGH
|
||||
PinTransaction::set(PinState::High),
|
||||
// When reading
|
||||
PinTransaction::set(PinState::Low),
|
||||
// When finished reading
|
||||
PinTransaction::set(PinState::High),
|
||||
]);
|
||||
|
||||
// initiate the pin to high.
|
||||
cs_pin.set_high().expect("Should set pin to high");
|
||||
|
||||
let mut actual_version = [0_u8; 1];
|
||||
let mut expected_version = 5;
|
||||
|
||||
let expectations = [
|
||||
SpiTransaction::write(register::common::VERSION.to_be_bytes().to_vec()),
|
||||
SpiTransaction::write(vec![register::COMMON << 3]),
|
||||
SpiTransaction::transfer(actual_version.to_vec(), vec![expected_version]),
|
||||
];
|
||||
|
||||
let mock_spi = SpiMock::new(&expectations);
|
||||
|
||||
let mut four_wire = FourWire::new(mock_spi, cs_pin);
|
||||
|
||||
four_wire.read_frame(
|
||||
register::COMMON,
|
||||
register::common::VERSION,
|
||||
&mut actual_version,
|
||||
);
|
||||
|
||||
assert_eq!(expected_version, actual_version[0]);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_write_frame() {
|
||||
let mut cs_pin = PinMock::new(&[
|
||||
// we begin with pin HIGH
|
||||
PinTransaction::set(PinState::High),
|
||||
// When reading
|
||||
PinTransaction::set(PinState::Low),
|
||||
// When finished reading
|
||||
PinTransaction::set(PinState::High),
|
||||
]);
|
||||
|
||||
// initiate the pin to high.
|
||||
cs_pin.set_high().expect("Should set pin to high");
|
||||
|
||||
let socket_0_reg = 0x01_u8;
|
||||
let socket_1_reg = 0x05_u8;
|
||||
let source_port = 49849_u16;
|
||||
|
||||
let expectations = [
|
||||
SpiTransaction::write(register::socketn::SOURCE_PORT.to_be_bytes().to_vec()),
|
||||
SpiTransaction::write(vec![socket_1_reg << 3 | WRITE_MODE_MASK]),
|
||||
SpiTransaction::write(source_port.to_be_bytes().to_vec()),
|
||||
];
|
||||
|
||||
let mock_spi = SpiMock::new(&expectations);
|
||||
|
||||
let mut four_wire = FourWire::new(mock_spi, cs_pin);
|
||||
|
||||
four_wire.write_frame(
|
||||
socket_1_reg,
|
||||
register::socketn::SOURCE_PORT,
|
||||
&source_port.to_be_bytes(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#![no_std]
|
||||
#![cfg_attr(not(test), no_std)]
|
||||
#![allow(unused)]
|
||||
#![deny(rustdoc::broken_intra_doc_links)]
|
||||
#![doc = include_str!("../README.md")]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue