aboutsummaryrefslogtreecommitdiff
path: root/embassy-embedded-hal/src/shared_bus/blocking/spi.rs
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-embedded-hal/src/shared_bus/blocking/spi.rs')
-rw-r--r--embassy-embedded-hal/src/shared_bus/blocking/spi.rs69
1 files changed, 69 insertions, 0 deletions
diff --git a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs
new file mode 100644
index 000000000..0d01a590b
--- /dev/null
+++ b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs
@@ -0,0 +1,69 @@
1//! Blocking shared SPI bus
2use core::cell::RefCell;
3use core::fmt::Debug;
4
5use embedded_hal_1::digital::blocking::OutputPin;
6use embedded_hal_1::spi;
7use embedded_hal_1::spi::blocking::SpiDevice;
8
9#[derive(Copy, Clone, Eq, PartialEq, Debug)]
10pub enum SpiBusDeviceError<BUS, CS> {
11 Spi(BUS),
12 Cs(CS),
13}
14
15impl<BUS, CS> spi::Error for SpiBusDeviceError<BUS, CS>
16where
17 BUS: spi::Error + Debug,
18 CS: Debug,
19{
20 fn kind(&self) -> spi::ErrorKind {
21 match self {
22 Self::Spi(e) => e.kind(),
23 Self::Cs(_) => spi::ErrorKind::Other,
24 }
25 }
26}
27
28pub struct SpiBusDevice<'a, BUS, CS> {
29 bus: &'a RefCell<BUS>,
30 cs: CS,
31}
32
33impl<'a, BUS, CS> SpiBusDevice<'a, BUS, CS> {
34 pub fn new(bus: &'a RefCell<BUS>, cs: CS) -> Self {
35 Self { bus, cs }
36 }
37}
38
39impl<'a, BUS, CS> spi::ErrorType for SpiBusDevice<'a, BUS, CS>
40where
41 BUS: spi::ErrorType,
42 CS: OutputPin,
43{
44 type Error = SpiBusDeviceError<BUS::Error, CS::Error>;
45}
46
47impl<BUS, CS> spi::SpiDevice for SpiBusDevice<'_, BUS, CS>
48where
49 BUS: spi::SpiBusFlush,
50 CS: OutputPin,
51{
52 type Bus = BUS;
53 fn transaction<R>(&mut self, f: impl FnOnce(&mut Self::Bus) -> Result<R, BUS::Error>) -> Result<R, Self::Error> {
54 let mut bus = self.bus.borrow_mut();
55 self.cs.set_low().map_err(SpiDeviceWithCsError::Cs)?;
56
57 let f_res = f(&mut bus);
58
59 // On failure, it's important to still flush and deassert CS.
60 let flush_res = bus.flush();
61 let cs_res = self.cs.set_high();
62
63 let f_res = f_res.map_err(SpiDeviceWithCsError::Spi)?;
64 flush_res.map_err(SpiDeviceWithCsError::Spi)?;
65 cs_res.map_err(SpiDeviceWithCsError::Cs)?;
66
67 Ok(f_res)
68 }
69}