Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: test FourWire with embedded-hal-mock: #56

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 7 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
116 changes: 108 additions & 8 deletions src/bus/four_wire.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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),
Expand All @@ -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(),
);
}
}
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
@@ -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")]
Expand Down
Loading