embedded_hal_bus/spi/
exclusive.rs1use embedded_hal::delay::DelayNs;
4use embedded_hal::digital::OutputPin;
5use embedded_hal::spi::{ErrorType, Operation, SpiBus, SpiDevice};
6#[cfg(feature = "async")]
7use embedded_hal_async::{
8 delay::DelayNs as AsyncDelayNs,
9 spi::{SpiBus as AsyncSpiBus, SpiDevice as AsyncSpiDevice},
10};
11
12use super::shared::transaction;
13use super::DeviceError;
14
15pub struct ExclusiveDevice<BUS, CS, D> {
20 bus: BUS,
21 cs: CS,
22 delay: D,
23}
24
25impl<BUS, CS, D> ExclusiveDevice<BUS, CS, D> {
26 #[inline]
28 pub fn new(bus: BUS, cs: CS, delay: D) -> Self {
29 Self { bus, cs, delay }
30 }
31
32 #[inline]
34 pub fn bus(&self) -> &BUS {
35 &self.bus
36 }
37
38 #[inline]
40 pub fn bus_mut(&mut self) -> &mut BUS {
41 &mut self.bus
42 }
43}
44
45impl<BUS, CS> ExclusiveDevice<BUS, CS, super::NoDelay> {
46 #[inline]
63 pub fn new_no_delay(bus: BUS, cs: CS) -> Self {
64 Self {
65 bus,
66 cs,
67 delay: super::NoDelay,
68 }
69 }
70}
71
72impl<BUS, CS, D> ErrorType for ExclusiveDevice<BUS, CS, D>
73where
74 BUS: ErrorType,
75 CS: OutputPin,
76{
77 type Error = DeviceError<BUS::Error, CS::Error>;
78}
79
80impl<Word: Copy + 'static, BUS, CS, D> SpiDevice<Word> for ExclusiveDevice<BUS, CS, D>
81where
82 BUS: SpiBus<Word>,
83 CS: OutputPin,
84 D: DelayNs,
85{
86 #[inline]
87 fn transaction(&mut self, operations: &mut [Operation<'_, Word>]) -> Result<(), Self::Error> {
88 transaction(operations, &mut self.bus, &mut self.delay, &mut self.cs)
89 }
90}
91
92#[cfg(feature = "async")]
93#[cfg_attr(docsrs, doc(cfg(feature = "async")))]
94impl<Word: Copy + 'static, BUS, CS, D> AsyncSpiDevice<Word> for ExclusiveDevice<BUS, CS, D>
95where
96 BUS: AsyncSpiBus<Word>,
97 CS: OutputPin,
98 D: AsyncDelayNs,
99{
100 #[inline]
101 async fn transaction(
102 &mut self,
103 operations: &mut [Operation<'_, Word>],
104 ) -> Result<(), Self::Error> {
105 self.cs.set_low().map_err(DeviceError::Cs)?;
106
107 let op_res = 'ops: {
108 for op in operations {
109 let res = match op {
110 Operation::Read(buf) => self.bus.read(buf).await,
111 Operation::Write(buf) => self.bus.write(buf).await,
112 Operation::Transfer(read, write) => self.bus.transfer(read, write).await,
113 Operation::TransferInPlace(buf) => self.bus.transfer_in_place(buf).await,
114 Operation::DelayNs(ns) => match self.bus.flush().await {
115 Err(e) => Err(e),
116 Ok(()) => {
117 self.delay.delay_ns(*ns).await;
118 Ok(())
119 }
120 },
121 };
122 if let Err(e) = res {
123 break 'ops Err(e);
124 }
125 }
126 Ok(())
127 };
128
129 let flush_res = self.bus.flush().await;
131 let cs_res = self.cs.set_high();
132
133 op_res.map_err(DeviceError::Spi)?;
134 flush_res.map_err(DeviceError::Spi)?;
135 cs_res.map_err(DeviceError::Cs)?;
136
137 Ok(())
138 }
139}