diff --git a/.github/bors.toml b/.github/bors.toml index 64eb89c..4e5ea50 100644 --- a/.github/bors.toml +++ b/.github/bors.toml @@ -4,5 +4,5 @@ required_approvals = 1 status = [ "CI (stable, x86_64-unknown-linux-gnu)", "CI (stable, armv7-unknown-linux-gnueabihf)", - "CI (1.46.0, x86_64-unknown-linux-gnu)", + "CI (1.54.0, x86_64-unknown-linux-gnu)", ] diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ba91b86..bc4f40e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,7 +21,7 @@ jobs: include: # Test MSRV - - rust: 1.46.0 + - rust: 1.54.0 TARGET: x86_64-unknown-linux-gnu # Test nightly but don't fail diff --git a/CHANGELOG.md b/CHANGELOG.md index 036d328..33ad51f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/). - Added feature flag for `spi` and `i2c` +### Changed + +- Updated to `embedded-hal` `1.0.0-alpha.8` release ([API changes](https://github.com/rust-embedded/embedded-hal/blob/master/CHANGELOG.md#v100-alpha8---2022-04-15)) + ## [v0.4.0-alpha.2] - 2022-02-15 ### Added diff --git a/Cargo.toml b/Cargo.toml index a487645..6a0f994 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ spi = ["spidev"] default = [ "gpio_cdev", "gpio_sysfs", "i2c", "spi" ] [dependencies] -embedded-hal = "=1.0.0-alpha.7" +embedded-hal = "=1.0.0-alpha.8" gpio-cdev = { version = "0.5.1", optional = true } sysfs_gpio = { version = "0.6.1", optional = true } i2cdev = { version = "0.5.1", optional = true } diff --git a/README.md b/README.md index 671688a..82fa45f 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ With `default-features = false` you can enable the features `gpio_cdev`, `gpio_s ## Minimum Supported Rust Version (MSRV) -This crate is guaranteed to compile on stable Rust 1.46.0 and up. It *might* +This crate is guaranteed to compile on stable Rust 1.54.0 and up. It *might* compile with older versions but that may change in any new patch release. ## License diff --git a/src/spi.rs b/src/spi.rs index 7e55e52..123a449 100644 --- a/src/spi.rs +++ b/src/spi.rs @@ -40,71 +40,60 @@ impl ops::DerefMut for Spidev { mod embedded_hal_impl { use super::*; - use embedded_hal::spi::blocking::{ - Operation as SpiOperation, Transactional, Transfer, TransferInplace, Write, - }; + use embedded_hal::spi::blocking::{SpiBus, SpiBusFlush, SpiBusRead, SpiBusWrite, SpiDevice}; use embedded_hal::spi::ErrorType; use spidev::SpidevTransfer; - use std::io::Write as _; + use std::io::{Read, Write}; impl ErrorType for Spidev { type Error = SPIError; } - impl Transfer for Spidev { - fn transfer<'b>(&mut self, read: &'b mut [u8], write: &[u8]) -> Result<(), Self::Error> { - self.0 - .transfer(&mut SpidevTransfer::read_write(&write, read)) - .map_err(|err| SPIError { err }) + impl SpiBusFlush for Spidev { + fn flush(&mut self) -> Result<(), Self::Error> { + self.0.flush().map_err(|err| SPIError { err }) } } - impl TransferInplace for Spidev { - fn transfer_inplace<'b>(&mut self, buffer: &'b mut [u8]) -> Result<(), Self::Error> { - let tx = buffer.to_owned(); - self.0 - .transfer(&mut SpidevTransfer::read_write(&tx, buffer)) - .map_err(|err| SPIError { err }) + impl SpiBusRead for Spidev { + fn read(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { + self.0.read_exact(words).map_err(|err| SPIError { err }) } } - impl Write for Spidev { - fn write(&mut self, buffer: &[u8]) -> Result<(), Self::Error> { - self.0.write_all(buffer).map_err(|err| SPIError { err }) + impl SpiBusWrite for Spidev { + fn write(&mut self, words: &[u8]) -> Result<(), Self::Error> { + self.0.write_all(words).map_err(|err| SPIError { err }) } } - /// Transactional implementation batches SPI operations into a single transaction - impl Transactional for Spidev { - 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::Read(w) => SpidevTransfer::read(w), - SpiOperation::Write(w) => SpidevTransfer::write(w), - SpiOperation::Transfer(r, w) => SpidevTransfer::read_write(w, r), - SpiOperation::TransferInplace(r) => { - // Clone read to write pointer - // SPIdev is okay with having w == r but this is tricky to achieve in safe rust - let w = unsafe { - let p = r.as_ptr(); - std::slice::from_raw_parts(p, r.len()) - }; - - SpidevTransfer::read_write(w, r) - } - } - }) - .collect(); - - // Execute transfer + impl SpiBus for Spidev { + fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { + self.0 + .transfer(&mut SpidevTransfer::read_write(write, read)) + .map_err(|err| SPIError { err }) + } + + fn transfer_in_place(&mut self, words: &mut [u8]) -> Result<(), Self::Error> { + let tx = words.to_owned(); self.0 - .transfer_multiple(&mut messages) + .transfer(&mut SpidevTransfer::read_write(&tx, words)) .map_err(|err| SPIError { err }) } } + + impl SpiDevice for Spidev { + type Bus = Spidev; + + fn transaction( + &mut self, + f: impl FnOnce(&mut Self::Bus) -> Result::Error>, + ) -> Result { + let result = f(self)?; + self.flush()?; + Ok(result) + } + } } /// Error type wrapping [io::Error](io::Error) to implement [embedded_hal::spi::ErrorKind]