#![no_std]
extern crate embedded_hal as hal;
use core::cell::RefCell;
pub struct Spy<T,F>
where F:Fn(DataWord)
{
s: RefCell<T>,
f: RefCell<F>,
}
pub fn new<T,F>(s: T, f: F)-> Spy<T,F>
where F:Fn(DataWord)
{
Spy{s:RefCell::new(s), f:RefCell::new(f)}
}
pub enum DataWord {
None,
Byte(u8),
First,
Last,
Response,
Failed,
Toggle,
}
use hal::spi::FullDuplex;
extern crate nb;
impl<T,F> FullDuplex<u8> for Spy<T,F>
where T:FullDuplex<u8>,
F: Fn(DataWord),
{
type Error = T::Error;
fn read (&mut self) -> Result<u8, nb::Error<Self::Error>>{
let mut s = self.s.borrow_mut();
let ans = s.read();
match &ans {
Ok(w) => {(self.f.borrow_mut())(DataWord::Byte(w.clone()));},
_other => {},
}
ans
}
fn send(&mut self, w: u8) -> Result<(), nb::Error<Self::Error>>{
(self.f.borrow_mut())(DataWord::Byte(w));
let mut s = self.s.borrow_mut();
s.send(w)
}
}
impl<T,F> hal::blocking::spi::Transfer<u8> for Spy<T,F>
where T: hal::blocking::spi::Transfer<u8>,
F:Fn(DataWord)
{
type Error = T::Error;
fn transfer<'w>(&mut self, words: &'w mut [u8]) -> Result<&'w [u8], Self::Error>{
(self.f.borrow_mut())(DataWord::First);
for w in words.iter(){
(self.f.borrow_mut())(DataWord::Byte(*w));
}
(self.f.borrow_mut())(DataWord::Response);
let ans = (self.s.borrow_mut()).transfer(words)?;
for w in ans.iter(){
(self.f.borrow_mut())(DataWord::Byte(*w));
}
(self.f.borrow_mut())(DataWord::Last);
Ok(ans)
}
}
impl<T,F> hal::blocking::spi::Write<u8> for Spy<T,F>
where T: hal::blocking::spi::Write<u8>,
F: Fn(DataWord)
{
type Error = T::Error;
fn write(&mut self, words: &[u8]) -> Result<(), Self::Error>{
for w in words.iter(){
(self.f.borrow_mut())(DataWord::Byte(*w));
}
(self.s.borrow_mut()).write(words)
}
}
#[cfg(feature = "embedded_hal_digital_io_legacy_v1")]
impl<T,F> hal::digital::v1::InputPin for Spy<T,F>
where T: hal::digital::v1::InputPin,
F: Fn(DataWord)
{
fn is_high(&self) -> bool{
let state = (self.s.borrow_mut()).is_high();
(self.f.borrow_mut())(DataWord::Byte(state as u8));
state
}
fn is_low(&self) -> bool{
let state = (self.s.borrow_mut()).is_low();
(self.f.borrow_mut())(DataWord::Byte((!state) as u8));
state
}
}
#[cfg(feature = "embedded_hal_digital_io_legacy_v1")]
impl<T,F> hal::digital::v1::OutputPin for Spy<T,F>
where T: hal::digital::v1::OutputPin,
F: Fn(DataWord)
{
fn set_high(&mut self){
(self.f.borrow_mut())(DataWord::Byte(1));
(self.s.borrow_mut()).set_high()
}
fn set_low(&mut self){
(self.f.borrow_mut())(DataWord::Byte(0));
(self.s.borrow_mut()).set_low()
}
}
#[cfg(feature = "embedded_hal_digital_io_legacy_v1")]
impl<T,F> hal::digital::v1::ToggleableOutputPin for Spy<T,F>
where T: hal::digital::v1::ToggleableOutputPin,
F: Fn(DataWord)
{
fn toggle(&mut self){
(self.f.borrow_mut())(DataWord::Toggle);
(self.s.borrow_mut()).toggle()
}
}
#[cfg(feature = "embedded_hal_digital_io_legacy_v1")]
impl<T,F> hal::digital::v1::StatefulOutputPin for Spy<T,F>
where T: hal::digital::v1::StatefulOutputPin,
F: Fn(DataWord)
{
fn is_set_high(&self) -> bool{
let state = (self.s.borrow_mut()).is_set_high();
(self.f.borrow_mut())(DataWord::Byte(state as u8));
state
}
fn is_set_low(&self) -> bool{
let state = (self.s.borrow_mut()).is_set_low();
(self.f.borrow_mut())(DataWord::Byte((!state) as u8));
state
}
}
#[cfg(not(feature = "embedded_hal_digital_io_legacy_v1"))]
impl<T,F> hal::digital::v2::InputPin for Spy<T,F>
where T: hal::digital::v2::InputPin,
F: Fn(DataWord)
{
type Error = T::Error;
fn is_high(&self) -> Result<bool,Self::Error>{
let state = (self.s.borrow_mut()).is_high()?;
(self.f.borrow_mut())(DataWord::Byte(state as u8));
Ok(state)
}
fn is_low(&self) -> Result<bool,Self::Error>{
let state = (self.s.borrow_mut()).is_low()?;
(self.f.borrow_mut())(DataWord::Byte((!state) as u8));
Ok(state)
}
}
#[cfg(not(feature = "embedded_hal_digital_io_legacy_v1"))]
impl<T,F> hal::digital::v2::OutputPin for Spy<T,F>
where T: hal::digital::v2::OutputPin,
F: Fn(DataWord)
{
type Error = T::Error;
fn set_high(&mut self)->Result<(),T::Error>{
(self.f.borrow_mut())(DataWord::Byte(1));
(self.s.borrow_mut()).set_high()
}
fn set_low(&mut self)->Result<(),T::Error>{
(self.f.borrow_mut())(DataWord::Byte(0));
(self.s.borrow_mut()).set_low()
}
}
#[cfg(not(feature = "embedded_hal_digital_io_legacy_v1"))]
impl<T,F> hal::digital::v2::ToggleableOutputPin for Spy<T,F>
where T: hal::digital::v2::ToggleableOutputPin,
F: Fn(DataWord)
{
type Error = T::Error;
fn toggle(&mut self)->Result<(),T::Error>{
(self.f.borrow_mut())(DataWord::Toggle);
(self.s.borrow_mut()).toggle()
}
}
#[cfg(not(feature = "embedded_hal_digital_io_legacy_v1"))]
impl<T,F> hal::digital::v2::StatefulOutputPin for Spy<T,F>
where T: hal::digital::v2::StatefulOutputPin,
F: Fn(DataWord)
{
fn is_set_high(&self) -> Result<bool,T::Error>{
let state = (self.s.borrow_mut()).is_set_high()?;
(self.f.borrow_mut())(DataWord::Byte(state as u8));
Ok(state)
}
fn is_set_low(&self) -> Result<bool,T::Error>{
let state = (self.s.borrow_mut()).is_set_low()?;
(self.f.borrow_mut())(DataWord::Byte((!state) as u8));
Ok(state)
}
}