1use super::Arbiter;
4use embedded_hal::digital::OutputPin;
5use embedded_hal::spi::SpiBus as BlockingSpiBus;
6use embedded_hal_async::{
7 delay::DelayNs,
8 spi::{ErrorType, Operation, SpiBus as AsyncSpiBus, SpiDevice},
9};
10use embedded_hal_bus::spi::DeviceError;
11
12pub struct ArbiterDevice<'a, BUS, CS, D> {
14 bus: &'a Arbiter<BUS>,
15 cs: CS,
16 delay: D,
17}
18
19impl<'a, BUS, CS, D> ArbiterDevice<'a, BUS, CS, D> {
20 pub fn new(bus: &'a Arbiter<BUS>, cs: CS, delay: D) -> Self {
22 Self { bus, cs, delay }
23 }
24}
25
26impl<BUS, CS, D> ErrorType for ArbiterDevice<'_, BUS, CS, D>
27where
28 BUS: ErrorType,
29 CS: OutputPin,
30{
31 type Error = DeviceError<BUS::Error, CS::Error>;
32}
33
34impl<Word, BUS, CS, D> SpiDevice<Word> for ArbiterDevice<'_, BUS, CS, D>
35where
36 Word: Copy + 'static,
37 BUS: AsyncSpiBus<Word>,
38 CS: OutputPin,
39 D: DelayNs,
40{
41 async fn transaction(
42 &mut self,
43 operations: &mut [Operation<'_, Word>],
44 ) -> Result<(), DeviceError<BUS::Error, CS::Error>> {
45 let mut bus = self.bus.access().await;
46
47 self.cs.set_low().map_err(DeviceError::Cs)?;
48
49 let op_res = 'ops: {
50 for op in operations {
51 let res = match op {
52 Operation::Read(buf) => bus.read(buf).await,
53 Operation::Write(buf) => bus.write(buf).await,
54 Operation::Transfer(read, write) => bus.transfer(read, write).await,
55 Operation::TransferInPlace(buf) => bus.transfer_in_place(buf).await,
56 Operation::DelayNs(ns) => match bus.flush().await {
57 Err(e) => Err(e),
58 Ok(()) => {
59 self.delay.delay_ns(*ns).await;
60 Ok(())
61 }
62 },
63 };
64 if let Err(e) = res {
65 break 'ops Err(e);
66 }
67 }
68 Ok(())
69 };
70
71 let flush_res = bus.flush().await;
73 let cs_res = self.cs.set_high();
74
75 op_res.map_err(DeviceError::Spi)?;
76 flush_res.map_err(DeviceError::Spi)?;
77 cs_res.map_err(DeviceError::Cs)?;
78
79 Ok(())
80 }
81}
82
83pub struct BlockingArbiterDevice<'a, BUS, CS, D> {
85 bus: &'a Arbiter<BUS>,
86 cs: CS,
87 delay: D,
88}
89
90impl<'a, BUS, CS, D> BlockingArbiterDevice<'a, BUS, CS, D> {
91 pub fn new(bus: &'a Arbiter<BUS>, cs: CS, delay: D) -> Self {
93 Self { bus, cs, delay }
94 }
95
96 pub fn into_non_blocking(self) -> ArbiterDevice<'a, BUS, CS, D>
98 where
99 BUS: AsyncSpiBus,
100 {
101 ArbiterDevice {
102 bus: self.bus,
103 cs: self.cs,
104 delay: self.delay,
105 }
106 }
107}
108
109impl<'a, BUS, CS, D> ErrorType for BlockingArbiterDevice<'a, BUS, CS, D>
110where
111 BUS: ErrorType,
112 CS: OutputPin,
113{
114 type Error = DeviceError<BUS::Error, CS::Error>;
115}
116
117impl<'a, Word, BUS, CS, D> SpiDevice<Word> for BlockingArbiterDevice<'a, BUS, CS, D>
118where
119 Word: Copy + 'static,
120 BUS: BlockingSpiBus<Word>,
121 CS: OutputPin,
122 D: DelayNs,
123{
124 async fn transaction(
125 &mut self,
126 operations: &mut [Operation<'_, Word>],
127 ) -> Result<(), DeviceError<BUS::Error, CS::Error>> {
128 let mut bus = self.bus.access().await;
129
130 self.cs.set_low().map_err(DeviceError::Cs)?;
131
132 let op_res = 'ops: {
133 for op in operations {
134 let res = match op {
135 Operation::Read(buf) => bus.read(buf),
136 Operation::Write(buf) => bus.write(buf),
137 Operation::Transfer(read, write) => bus.transfer(read, write),
138 Operation::TransferInPlace(buf) => bus.transfer_in_place(buf),
139 Operation::DelayNs(ns) => match bus.flush() {
140 Err(e) => Err(e),
141 Ok(()) => {
142 self.delay.delay_ns(*ns).await;
143 Ok(())
144 }
145 },
146 };
147 if let Err(e) = res {
148 break 'ops Err(e);
149 }
150 }
151 Ok(())
152 };
153
154 let flush_res = bus.flush();
156 let cs_res = self.cs.set_high();
157
158 op_res.map_err(DeviceError::Spi)?;
159 flush_res.map_err(DeviceError::Spi)?;
160 cs_res.map_err(DeviceError::Cs)?;
161
162 Ok(())
163 }
164}