Skip to content

Commit 03578fe

Browse files
authored
Merge pull request #529 from nyurik/dedup
Consolidate identical SPI transaction impl
2 parents a2f7af7 + b39aaed commit 03578fe

File tree

5 files changed

+52
-69
lines changed

5 files changed

+52
-69
lines changed

embedded-hal-bus/src/spi/critical_section.rs

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use embedded_hal::digital::OutputPin;
55
use embedded_hal::spi::{ErrorType, Operation, SpiBus, SpiDevice};
66

77
use super::DeviceError;
8+
use crate::spi::shared::transaction;
89

910
/// `critical-section`-based shared bus [`SpiDevice`] implementation.
1011
///
@@ -66,29 +67,7 @@ where
6667
critical_section::with(|cs| {
6768
let bus = &mut *self.bus.borrow_ref_mut(cs);
6869

69-
self.cs.set_low().map_err(DeviceError::Cs)?;
70-
71-
let op_res = operations.iter_mut().try_for_each(|op| match op {
72-
Operation::Read(buf) => bus.read(buf),
73-
Operation::Write(buf) => bus.write(buf),
74-
Operation::Transfer(read, write) => bus.transfer(read, write),
75-
Operation::TransferInPlace(buf) => bus.transfer_in_place(buf),
76-
Operation::DelayUs(us) => {
77-
bus.flush()?;
78-
self.delay.delay_us(*us);
79-
Ok(())
80-
}
81-
});
82-
83-
// On failure, it's important to still flush and deassert CS.
84-
let flush_res = bus.flush();
85-
let cs_res = self.cs.set_high();
86-
87-
op_res.map_err(DeviceError::Spi)?;
88-
flush_res.map_err(DeviceError::Spi)?;
89-
cs_res.map_err(DeviceError::Cs)?;
90-
91-
Ok(())
70+
transaction(operations, bus, &mut self.delay, &mut self.cs)
9271
})
9372
}
9473
}

embedded-hal-bus/src/spi/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ mod mutex;
1212
#[cfg(feature = "std")]
1313
pub use mutex::*;
1414
mod critical_section;
15+
mod shared;
16+
1517
pub use self::critical_section::*;
1618

1719
#[cfg(feature = "defmt-03")]

embedded-hal-bus/src/spi/mutex.rs

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use embedded_hal::spi::{ErrorType, Operation, SpiBus, SpiDevice};
44
use std::sync::Mutex;
55

66
use super::DeviceError;
7+
use crate::spi::shared::transaction;
78

89
/// `std` `Mutex`-based shared bus [`SpiDevice`] implementation.
910
///
@@ -63,28 +64,6 @@ where
6364
fn transaction(&mut self, operations: &mut [Operation<'_, Word>]) -> Result<(), Self::Error> {
6465
let bus = &mut *self.bus.lock().unwrap();
6566

66-
self.cs.set_low().map_err(DeviceError::Cs)?;
67-
68-
let op_res = operations.iter_mut().try_for_each(|op| match op {
69-
Operation::Read(buf) => bus.read(buf),
70-
Operation::Write(buf) => bus.write(buf),
71-
Operation::Transfer(read, write) => bus.transfer(read, write),
72-
Operation::TransferInPlace(buf) => bus.transfer_in_place(buf),
73-
Operation::DelayUs(us) => {
74-
bus.flush()?;
75-
self.delay.delay_us(*us);
76-
Ok(())
77-
}
78-
});
79-
80-
// On failure, it's important to still flush and deassert CS.
81-
let flush_res = bus.flush();
82-
let cs_res = self.cs.set_high();
83-
84-
op_res.map_err(DeviceError::Spi)?;
85-
flush_res.map_err(DeviceError::Spi)?;
86-
cs_res.map_err(DeviceError::Cs)?;
87-
88-
Ok(())
67+
transaction(operations, bus, &mut self.delay, &mut self.cs)
8968
}
9069
}

embedded-hal-bus/src/spi/refcell.rs

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ use embedded_hal::digital::OutputPin;
44
use embedded_hal::spi::{ErrorType, Operation, SpiBus, SpiDevice};
55

66
use super::DeviceError;
7+
use crate::spi::shared::transaction;
78

89
/// `RefCell`-based shared bus [`SpiDevice`] implementation.
910
///
@@ -62,28 +63,6 @@ where
6263
fn transaction(&mut self, operations: &mut [Operation<'_, Word>]) -> Result<(), Self::Error> {
6364
let bus = &mut *self.bus.borrow_mut();
6465

65-
self.cs.set_low().map_err(DeviceError::Cs)?;
66-
67-
let op_res = operations.iter_mut().try_for_each(|op| match op {
68-
Operation::Read(buf) => bus.read(buf),
69-
Operation::Write(buf) => bus.write(buf),
70-
Operation::Transfer(read, write) => bus.transfer(read, write),
71-
Operation::TransferInPlace(buf) => bus.transfer_in_place(buf),
72-
Operation::DelayUs(us) => {
73-
bus.flush()?;
74-
self.delay.delay_us(*us);
75-
Ok(())
76-
}
77-
});
78-
79-
// On failure, it's important to still flush and deassert CS.
80-
let flush_res = bus.flush();
81-
let cs_res = self.cs.set_high();
82-
83-
op_res.map_err(DeviceError::Spi)?;
84-
flush_res.map_err(DeviceError::Spi)?;
85-
cs_res.map_err(DeviceError::Cs)?;
86-
87-
Ok(())
66+
transaction(operations, bus, &mut self.delay, &mut self.cs)
8867
}
8968
}

embedded-hal-bus/src/spi/shared.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
use embedded_hal::delay::DelayUs;
2+
use embedded_hal::digital::OutputPin;
3+
use embedded_hal::spi::{ErrorType, Operation, SpiBus};
4+
5+
use crate::spi::DeviceError;
6+
7+
/// Common implementation to perform a transaction against the device.
8+
#[inline]
9+
pub fn transaction<Word, BUS, CS, D>(
10+
operations: &mut [Operation<Word>],
11+
bus: &mut BUS,
12+
delay: &mut D,
13+
cs: &mut CS,
14+
) -> Result<(), DeviceError<BUS::Error, CS::Error>>
15+
where
16+
BUS: SpiBus<Word> + ErrorType,
17+
CS: OutputPin,
18+
D: DelayUs,
19+
Word: Copy,
20+
{
21+
cs.set_low().map_err(DeviceError::Cs)?;
22+
23+
let op_res = operations.iter_mut().try_for_each(|op| match op {
24+
Operation::Read(buf) => bus.read(buf),
25+
Operation::Write(buf) => bus.write(buf),
26+
Operation::Transfer(read, write) => bus.transfer(read, write),
27+
Operation::TransferInPlace(buf) => bus.transfer_in_place(buf),
28+
Operation::DelayUs(us) => {
29+
bus.flush()?;
30+
delay.delay_us(*us);
31+
Ok(())
32+
}
33+
});
34+
35+
// On failure, it's important to still flush and deassert CS.
36+
let flush_res = bus.flush();
37+
let cs_res = cs.set_high();
38+
39+
op_res.map_err(DeviceError::Spi)?;
40+
flush_res.map_err(DeviceError::Spi)?;
41+
cs_res.map_err(DeviceError::Cs)?;
42+
43+
Ok(())
44+
}

0 commit comments

Comments
 (0)