From 23c0c857ad2ba4ea70ff4b8450f1a4eccc69d626 Mon Sep 17 00:00:00 2001 From: Scott Perkins Date: Fri, 16 Aug 2024 22:54:55 -0600 Subject: [PATCH] Updated the SimpleHalSpiDevice transaction implementation to map the spi operations to segments, so they can all be executed together as a single transaction --- src/spi/hal.rs | 60 +++++++++++++++++++++++++++----------------------- 1 file changed, 32 insertions(+), 28 deletions(-) diff --git a/src/spi/hal.rs b/src/spi/hal.rs index 5c9623b8..a34196cd 100644 --- a/src/spi/hal.rs +++ b/src/spi/hal.rs @@ -1,4 +1,4 @@ -use super::{super::hal::Delay, Error, Spi}; +use super::{Error, Segment, Spi}; #[cfg(feature = "embedded-hal")] impl embedded_hal::spi::ErrorType for Spi { @@ -99,50 +99,54 @@ impl embedded_hal_0::spi::FullDuplex for Spi { /// Slave-select is currently handled at the bus level. /// This no-op device implementation can be used to satisfy the trait. // TODO: The underlying crate::spi::Spi shall be split up to support proper slave-select handling here. -pub struct SimpleHalSpiDevice { - bus: B, +pub struct SimpleHalSpiDevice { + bus: Spi, } #[cfg(feature = "embedded-hal")] -impl> SimpleHalSpiDevice { - pub fn new(bus: B) -> SimpleHalSpiDevice { +impl SimpleHalSpiDevice { + pub fn new(bus: Spi) -> SimpleHalSpiDevice { SimpleHalSpiDevice { bus } } } #[cfg(feature = "embedded-hal")] -impl> embedded_hal::spi::SpiDevice for SimpleHalSpiDevice -where - Error: From<::Error>, -{ +impl embedded_hal::spi::SpiDevice for SimpleHalSpiDevice { fn transaction( &mut self, operations: &mut [embedded_hal::spi::Operation<'_, u8>], ) -> Result<(), Error> { - for op in operations { - match op { - embedded_hal::spi::Operation::Read(read) => { - self.bus.read(read)?; + let clock_speed = self.bus.clock_speed()?; + let bits_per_word = self.bus.bits_per_word()?; + + // Map the hal spi operations to segments, so they all can be executed together as one transaction + let segments = operations + .into_iter() + .map(|op| match op { + embedded_hal::spi::Operation::Read(read_buff) => Segment::with_read(read_buff), + embedded_hal::spi::Operation::Write(write_buff) => Segment::with_write(write_buff), + embedded_hal::spi::Operation::Transfer(read_buff, write_buff) => { + Segment::new(read_buff, write_buff) } - embedded_hal::spi::Operation::Write(write) => { - self.bus.write(write)?; + embedded_hal::spi::Operation::TransferInPlace(buff) => { + Segment::with_settings(Some(buff), None, clock_speed, 0, bits_per_word, false) } - embedded_hal::spi::Operation::Transfer(read, write) => { - self.bus.transfer(read, write)?; - } - embedded_hal::spi::Operation::TransferInPlace(words) => { - self.bus.transfer_in_place(words)?; - } - embedded_hal::spi::Operation::DelayNs(us) => { - embedded_hal::delay::DelayNs::delay_us(&mut Delay::new(), *us); - } - } - } - Ok(()) + // Map a segment with no read or write buffer, just to handle the delay + embedded_hal::spi::Operation::DelayNs(delay_ns) => Segment::with_settings( + None, + None, + clock_speed, + (*delay_ns / 1000) as u16, + bits_per_word, + false, + ), + }) + .collect::>(); + self.bus.transfer_segments(&segments) } } #[cfg(feature = "embedded-hal")] -impl> embedded_hal::spi::ErrorType for SimpleHalSpiDevice { +impl embedded_hal::spi::ErrorType for SimpleHalSpiDevice { type Error = Error; }