Skip to content

Commit

Permalink
add transactional spi
Browse files Browse the repository at this point in the history
  • Loading branch information
ryankurte committed Mar 10, 2020
1 parent 4d801ed commit 35ff43e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 3 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,6 @@ openpty = "0.1.0"
# we don't need the `Error` implementation
default-features = false
version = "0.2.2"

[patch.crates-io]
embedded-hal = { git = "https://github.com/ryankurte/embedded-hal", branch = "feature/spi-transactions" }
39 changes: 36 additions & 3 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@
#![deny(missing_docs)]

extern crate cast;
extern crate core;
extern crate embedded_hal as hal;
pub extern crate i2cdev;
pub extern crate spidev;
pub extern crate serial_unix;
pub extern crate serial_core;
pub extern crate nb;


#[cfg(feature = "gpio_sysfs")]
pub extern crate sysfs_gpio;

Expand Down Expand Up @@ -194,7 +192,10 @@ impl hal::blocking::i2c::WriteRead for I2cdev {
buffer: &mut [u8],
) -> Result<(), Self::Error> {
self.set_address(address)?;
let mut messages = [LinuxI2CMessage::write(bytes), LinuxI2CMessage::read(buffer)];
let mut messages = [
LinuxI2CMessage::write(bytes),
LinuxI2CMessage::read(buffer),
];
self.inner.transfer(&mut messages).map(drop)
}
}
Expand Down Expand Up @@ -249,6 +250,38 @@ impl hal::blocking::spi::Write<u8> for Spidev {
}
}

pub use hal::blocking::spi::{Operation as SpiOperation};

impl hal::blocking::spi::Transactional<u8> for Spidev {
type Error = io::Error;

fn exec<'a>(&mut self, operations: &mut [SpiOperation<'a, u8>]) -> Result<(), Self::Error> {

// Map types from generic to linux objects
let mut messages: Vec<_> = operations.iter_mut().map(|a| {
match a {
SpiOperation::Write(w) => SpidevTransfer::write(w),
SpiOperation::Transfer(r) => {
// TODO: is spidev okay with the same array pointer
// being used twice? If not, need some kind of vector
// pool that will outlive the transfer
let w = unsafe {
let p = r.as_ptr();
std::slice::from_raw_parts(p, r.len())
};

SpidevTransfer::read_write(w, r)
},
}
}).collect();

// Execute transfer
self.0.transfer_multiple(&mut messages)?;

Ok(())
}
}

impl ops::Deref for Spidev {
type Target = spidev::Spidev;

Expand Down

0 comments on commit 35ff43e

Please sign in to comment.