From 982d315af9f555e67eead38d69287d1c6b70b178 Mon Sep 17 00:00:00 2001 From: ryan Date: Wed, 22 Jan 2020 09:24:27 +1300 Subject: [PATCH 1/7] Implemented transactional interfaces --- Cargo.toml | 3 +++ src/lib.rs | 44 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/Cargo.toml b/Cargo.toml index 9ddf3b5..3330a2b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,3 +24,6 @@ openpty = "0.1.0" # we don't need the `Error` implementation default-features = false version = "0.2.2" + +[patch.crates-io] +embedded-hal = { path = "../embedded-hal" } diff --git a/src/lib.rs b/src/lib.rs index e999faf..661a4c2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -228,6 +228,27 @@ impl hal::blocking::i2c::WriteRead for I2cdev { } } +use hal::blocking::i2c::{Actions as I2cActions}; + +impl hal::blocking::i2c::Transactional for I2cdev { + type Error = i2cdev::linux::LinuxI2CError; + + fn exec<'a, A>(&mut self, address: u8, mut actions: A) -> Result<(), Self::Error> + where A: AsMut<[I2cActions<'a>]> { + + // Map types from generic to linux objects + let mut messages: Vec<_> = actions.as_mut().iter_mut().map(|a| { + match a { + I2cActions::Write(w) => LinuxI2CMessage::write(w), + I2cActions::Read(r) => LinuxI2CMessage::read(r), + } + }).collect(); + + self.set_address(address)?; + self.inner.transfer(&mut messages).map(drop) + } +} + impl ops::Deref for I2cdev { type Target = i2cdev::linux::LinuxI2CDevice; @@ -278,6 +299,29 @@ impl hal::blocking::spi::Write for Spidev { } } +use hal::blocking::spi::{Actions as SpiActions}; + +impl hal::blocking::spi::Transactional for Spidev { + type Error = io::Error; + + fn exec<'a, A>(&mut self, mut actions: A) -> Result<(), Self::Error> + where A: AsMut<[SpiActions<'a>]> { + + // Map types from generic to linux objects + let mut messages: Vec<_> = actions.as_mut().iter_mut().map(|a| { + match a { + SpiActions::Write(w) => SpidevTransfer::write(w), + SpiActions::WriteRead(w, r) => SpidevTransfer::read_write(w, r), + } + }).collect(); + + // Execute transfer + self.0.transfer_multiple(&mut messages)?; + + Ok(()) + } +} + impl ops::Deref for Spidev { type Target = spidev::Spidev; From e382db3e4612001e11052badc9f4f8d6c6c02bca Mon Sep 17 00:00:00 2001 From: ryan Date: Wed, 22 Jan 2020 09:30:20 +1300 Subject: [PATCH 2/7] Updated transactional impl with new names --- src/lib.rs | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 661a4c2..8174a1b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -228,19 +228,19 @@ impl hal::blocking::i2c::WriteRead for I2cdev { } } -use hal::blocking::i2c::{Actions as I2cActions}; +pub use hal::blocking::i2c::{Transaction as I2cTransaction}; impl hal::blocking::i2c::Transactional for I2cdev { type Error = i2cdev::linux::LinuxI2CError; - fn exec<'a, A>(&mut self, address: u8, mut actions: A) -> Result<(), Self::Error> - where A: AsMut<[I2cActions<'a>]> { + fn exec<'a, T>(&mut self, address: u8, mut transactions: T) -> Result<(), Self::Error> + where T: AsMut<[I2cTransaction<'a>]> { // Map types from generic to linux objects - let mut messages: Vec<_> = actions.as_mut().iter_mut().map(|a| { + let mut messages: Vec<_> = transactions.as_mut().iter_mut().map(|a| { match a { - I2cActions::Write(w) => LinuxI2CMessage::write(w), - I2cActions::Read(r) => LinuxI2CMessage::read(r), + I2cTransaction::Write(w) => LinuxI2CMessage::write(w), + I2cTransaction::Read(r) => LinuxI2CMessage::read(r), } }).collect(); @@ -299,19 +299,19 @@ impl hal::blocking::spi::Write for Spidev { } } -use hal::blocking::spi::{Actions as SpiActions}; +pub use hal::blocking::spi::{Transaction as SpiTransaction}; impl hal::blocking::spi::Transactional for Spidev { type Error = io::Error; - fn exec<'a, A>(&mut self, mut actions: A) -> Result<(), Self::Error> - where A: AsMut<[SpiActions<'a>]> { + fn exec<'a, T>(&mut self, mut transactions: T) -> Result<(), Self::Error> + where T: AsMut<[SpiTransaction<'a>]> { // Map types from generic to linux objects - let mut messages: Vec<_> = actions.as_mut().iter_mut().map(|a| { + let mut messages: Vec<_> = transactions.as_mut().iter_mut().map(|a| { match a { - SpiActions::Write(w) => SpidevTransfer::write(w), - SpiActions::WriteRead(w, r) => SpidevTransfer::read_write(w, r), + SpiTransaction::Write(w) => SpidevTransfer::write(w), + SpiTransaction::WriteRead(w, r) => SpidevTransfer::read_write(w, r), } }).collect(); From 571b9b0fcb30dd60a2ce2fc6d44e05c6b11d139a Mon Sep 17 00:00:00 2001 From: ryan Date: Wed, 22 Jan 2020 09:32:23 +1300 Subject: [PATCH 3/7] updated patch to git --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 3330a2b..65756c3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,4 +26,4 @@ default-features = false version = "0.2.2" [patch.crates-io] -embedded-hal = { path = "../embedded-hal" } +embedded-hal = { git = "https://github.com/ryankurte/embedded-hal", branch = "feature/spi-i2c-transactions" } From 40834bc441aeb62d26adb554588b0bcc921574fc Mon Sep 17 00:00:00 2001 From: ryan Date: Wed, 22 Jan 2020 11:29:40 +1300 Subject: [PATCH 4/7] rename transaction to operation --- src/lib.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 8174a1b..6e75a7b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -228,19 +228,19 @@ impl hal::blocking::i2c::WriteRead for I2cdev { } } -pub use hal::blocking::i2c::{Transaction as I2cTransaction}; +pub use hal::blocking::i2c::{Operation as I2cOperation}; impl hal::blocking::i2c::Transactional for I2cdev { type Error = i2cdev::linux::LinuxI2CError; - fn exec<'a, T>(&mut self, address: u8, mut transactions: T) -> Result<(), Self::Error> - where T: AsMut<[I2cTransaction<'a>]> { + fn exec<'a, O>(&mut self, address: u8, mut operations: O) -> Result<(), Self::Error> + where O: AsMut<[I2cOperation<'a>]> { - // Map types from generic to linux objects - let mut messages: Vec<_> = transactions.as_mut().iter_mut().map(|a| { + // Map operations from generic to linux objects + let mut messages: Vec<_> = operations.as_mut().iter_mut().map(|a| { match a { - I2cTransaction::Write(w) => LinuxI2CMessage::write(w), - I2cTransaction::Read(r) => LinuxI2CMessage::read(r), + I2cOperation::Write(w) => LinuxI2CMessage::write(w), + I2cOperation::Read(r) => LinuxI2CMessage::read(r), } }).collect(); @@ -299,19 +299,19 @@ impl hal::blocking::spi::Write for Spidev { } } -pub use hal::blocking::spi::{Transaction as SpiTransaction}; +pub use hal::blocking::spi::{Operation as SpiOperation}; impl hal::blocking::spi::Transactional for Spidev { type Error = io::Error; - fn exec<'a, T>(&mut self, mut transactions: T) -> Result<(), Self::Error> - where T: AsMut<[SpiTransaction<'a>]> { + fn exec<'a, O>(&mut self, mut operations: O) -> Result<(), Self::Error> + where O: AsMut<[SpiOperation<'a>]> { // Map types from generic to linux objects - let mut messages: Vec<_> = transactions.as_mut().iter_mut().map(|a| { + let mut messages: Vec<_> = operations.as_mut().iter_mut().map(|a| { match a { - SpiTransaction::Write(w) => SpidevTransfer::write(w), - SpiTransaction::WriteRead(w, r) => SpidevTransfer::read_write(w, r), + SpiOperation::Write(w) => SpidevTransfer::write(w), + SpiOperation::WriteRead(w, r) => SpidevTransfer::read_write(w, r), } }).collect(); From 0a12d1ad0437970469ec89010a9d22599d81c20b Mon Sep 17 00:00:00 2001 From: ryan Date: Tue, 28 Jan 2020 10:04:22 +1300 Subject: [PATCH 5/7] updated with spi::Transfer read bounds --- Cargo.toml | 3 ++- src/lib.rs | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 65756c3..771deab 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,4 +26,5 @@ default-features = false version = "0.2.2" [patch.crates-io] -embedded-hal = { git = "https://github.com/ryankurte/embedded-hal", branch = "feature/spi-i2c-transactions" } +#embedded-hal = { git = "https://github.com/ryankurte/embedded-hal", branch = "feature/spi-i2c-transactions" } +embedded-hal = { path = "../embedded-hal" } \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs index 6e75a7b..81343e2 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -301,11 +301,11 @@ impl hal::blocking::spi::Write for Spidev { pub use hal::blocking::spi::{Operation as SpiOperation}; -impl hal::blocking::spi::Transactional for Spidev { +impl hal::blocking::spi::Transactional for Spidev { type Error = io::Error; fn exec<'a, O>(&mut self, mut operations: O) -> Result<(), Self::Error> - where O: AsMut<[SpiOperation<'a>]> { + where O: AsMut<[SpiOperation<'a, u8>]> { // Map types from generic to linux objects let mut messages: Vec<_> = operations.as_mut().iter_mut().map(|a| { From 07410b03e4be39de9ebe7271486020012a95b94b Mon Sep 17 00:00:00 2001 From: ryan Date: Wed, 4 Mar 2020 13:43:28 +1300 Subject: [PATCH 6/7] patch for combined write/read buffer --- src/lib.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 81343e2..bdfa5e1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -311,7 +311,17 @@ impl hal::blocking::spi::Transactional for Spidev { let mut messages: Vec<_> = operations.as_mut().iter_mut().map(|a| { match a { SpiOperation::Write(w) => SpidevTransfer::write(w), - SpiOperation::WriteRead(w, r) => SpidevTransfer::read_write(w, r), + SpiOperation::WriteRead(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(); From 0a933ee8c1965e6c7ba2abab5829490d24dc027f Mon Sep 17 00:00:00 2001 From: ryan Date: Wed, 4 Mar 2020 16:06:55 +1300 Subject: [PATCH 7/7] update to use concrete slice of operations --- Cargo.toml | 4 ++-- src/lib.rs | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 771deab..8b4dbe9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,5 +26,5 @@ default-features = false version = "0.2.2" [patch.crates-io] -#embedded-hal = { git = "https://github.com/ryankurte/embedded-hal", branch = "feature/spi-i2c-transactions" } -embedded-hal = { path = "../embedded-hal" } \ No newline at end of file +embedded-hal = { git = "https://github.com/ryankurte/embedded-hal", branch = "feature/spi-i2c-transactions" } + diff --git a/src/lib.rs b/src/lib.rs index bdfa5e1..cf0ea1b 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -304,11 +304,10 @@ pub use hal::blocking::spi::{Operation as SpiOperation}; impl hal::blocking::spi::Transactional for Spidev { type Error = io::Error; - fn exec<'a, O>(&mut self, mut operations: O) -> Result<(), Self::Error> - where O: AsMut<[SpiOperation<'a, u8>]> { + 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.as_mut().iter_mut().map(|a| { + let mut messages: Vec<_> = operations.iter_mut().map(|a| { match a { SpiOperation::Write(w) => SpidevTransfer::write(w), SpiOperation::WriteRead(r) => {