aboutsummaryrefslogtreecommitdiff
path: root/embassy-embedded-hal
diff options
context:
space:
mode:
Diffstat (limited to 'embassy-embedded-hal')
-rw-r--r--embassy-embedded-hal/Cargo.toml4
-rw-r--r--embassy-embedded-hal/src/adapter.rs23
-rw-r--r--embassy-embedded-hal/src/lib.rs2
-rw-r--r--embassy-embedded-hal/src/shared_bus/asynch/i2c.rs42
-rw-r--r--embassy-embedded-hal/src/shared_bus/asynch/spi.rs171
-rw-r--r--embassy-embedded-hal/src/shared_bus/blocking/i2c.rs56
-rw-r--r--embassy-embedded-hal/src/shared_bus/blocking/spi.rs153
7 files changed, 307 insertions, 144 deletions
diff --git a/embassy-embedded-hal/Cargo.toml b/embassy-embedded-hal/Cargo.toml
index 45eb0d43d..c509d6ee5 100644
--- a/embassy-embedded-hal/Cargo.toml
+++ b/embassy-embedded-hal/Cargo.toml
@@ -19,8 +19,8 @@ nightly = ["embedded-hal-async", "embedded-storage-async"]
19[dependencies] 19[dependencies]
20embassy-sync = { version = "0.1.0", path = "../embassy-sync" } 20embassy-sync = { version = "0.1.0", path = "../embassy-sync" }
21embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] } 21embedded-hal-02 = { package = "embedded-hal", version = "0.2.6", features = ["unproven"] }
22embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.9" } 22embedded-hal-1 = { package = "embedded-hal", version = "=1.0.0-alpha.10" }
23embedded-hal-async = { version = "=0.2.0-alpha.0", optional = true } 23embedded-hal-async = { version = "=0.2.0-alpha.1", optional = true }
24embedded-storage = "0.3.0" 24embedded-storage = "0.3.0"
25embedded-storage-async = { version = "0.4.0", optional = true } 25embedded-storage-async = { version = "0.4.0", optional = true }
26nb = "1.0.0" 26nb = "1.0.0"
diff --git a/embassy-embedded-hal/src/adapter.rs b/embassy-embedded-hal/src/adapter.rs
index a49f8df4b..ee919bd84 100644
--- a/embassy-embedded-hal/src/adapter.rs
+++ b/embassy-embedded-hal/src/adapter.rs
@@ -36,27 +36,22 @@ where
36 E: embedded_hal_1::i2c::Error + 'static, 36 E: embedded_hal_1::i2c::Error + 'static,
37 T: blocking::i2c::WriteRead<Error = E> + blocking::i2c::Read<Error = E> + blocking::i2c::Write<Error = E>, 37 T: blocking::i2c::WriteRead<Error = E> + blocking::i2c::Read<Error = E> + blocking::i2c::Write<Error = E>,
38{ 38{
39 async fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Result<(), Self::Error> { 39 async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), Self::Error> {
40 self.wrapped.read(address, buffer) 40 self.wrapped.read(address, read)
41 } 41 }
42 42
43 async fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Result<(), Self::Error> { 43 async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), Self::Error> {
44 self.wrapped.write(address, bytes) 44 self.wrapped.write(address, write)
45 } 45 }
46 46
47 async fn write_read<'a>( 47 async fn write_read(&mut self, address: u8, write: &[u8], read: &mut [u8]) -> Result<(), Self::Error> {
48 &'a mut self, 48 self.wrapped.write_read(address, write, read)
49 address: u8,
50 bytes: &'a [u8],
51 buffer: &'a mut [u8],
52 ) -> Result<(), Self::Error> {
53 self.wrapped.write_read(address, bytes, buffer)
54 } 49 }
55 50
56 async fn transaction<'a, 'b>( 51 async fn transaction(
57 &'a mut self, 52 &mut self,
58 address: u8, 53 address: u8,
59 operations: &'a mut [embedded_hal_async::i2c::Operation<'b>], 54 operations: &mut [embedded_hal_1::i2c::Operation<'_>],
60 ) -> Result<(), Self::Error> { 55 ) -> Result<(), Self::Error> {
61 let _ = address; 56 let _ = address;
62 let _ = operations; 57 let _ = operations;
diff --git a/embassy-embedded-hal/src/lib.rs b/embassy-embedded-hal/src/lib.rs
index 8da042228..a23fbdc41 100644
--- a/embassy-embedded-hal/src/lib.rs
+++ b/embassy-embedded-hal/src/lib.rs
@@ -1,7 +1,7 @@
1#![cfg_attr(not(feature = "std"), no_std)] 1#![cfg_attr(not(feature = "std"), no_std)]
2#![cfg_attr( 2#![cfg_attr(
3 feature = "nightly", 3 feature = "nightly",
4 feature(type_alias_impl_trait, async_fn_in_trait, impl_trait_projections) 4 feature(type_alias_impl_trait, async_fn_in_trait, impl_trait_projections, try_blocks)
5)] 5)]
6#![cfg_attr(feature = "nightly", allow(incomplete_features))] 6#![cfg_attr(feature = "nightly", allow(incomplete_features))]
7#![warn(missing_docs)] 7#![warn(missing_docs)]
diff --git a/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs b/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs
index c5e1fd415..829554045 100644
--- a/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs
+++ b/embassy-embedded-hal/src/shared_bus/asynch/i2c.rs
@@ -54,35 +54,35 @@ where
54 M: RawMutex + 'static, 54 M: RawMutex + 'static,
55 BUS: i2c::I2c + 'static, 55 BUS: i2c::I2c + 'static,
56{ 56{
57 async fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Result<(), I2cDeviceError<BUS::Error>> { 57 async fn read(&mut self, address: u8, read: &mut [u8]) -> Result<(), I2cDeviceError<BUS::Error>> {
58 let mut bus = self.bus.lock().await; 58 let mut bus = self.bus.lock().await;
59 bus.read(address, buffer).await.map_err(I2cDeviceError::I2c)?; 59 bus.read(address, read).await.map_err(I2cDeviceError::I2c)?;
60 Ok(()) 60 Ok(())
61 } 61 }
62 62
63 async fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Result<(), I2cDeviceError<BUS::Error>> { 63 async fn write(&mut self, address: u8, write: &[u8]) -> Result<(), I2cDeviceError<BUS::Error>> {
64 let mut bus = self.bus.lock().await; 64 let mut bus = self.bus.lock().await;
65 bus.write(address, bytes).await.map_err(I2cDeviceError::I2c)?; 65 bus.write(address, write).await.map_err(I2cDeviceError::I2c)?;
66 Ok(()) 66 Ok(())
67 } 67 }
68 68
69 async fn write_read<'a>( 69 async fn write_read(
70 &'a mut self, 70 &mut self,
71 address: u8, 71 address: u8,
72 wr_buffer: &'a [u8], 72 write: &[u8],
73 rd_buffer: &'a mut [u8], 73 read: &mut [u8],
74 ) -> Result<(), I2cDeviceError<BUS::Error>> { 74 ) -> Result<(), I2cDeviceError<BUS::Error>> {
75 let mut bus = self.bus.lock().await; 75 let mut bus = self.bus.lock().await;
76 bus.write_read(address, wr_buffer, rd_buffer) 76 bus.write_read(address, write, read)
77 .await 77 .await
78 .map_err(I2cDeviceError::I2c)?; 78 .map_err(I2cDeviceError::I2c)?;
79 Ok(()) 79 Ok(())
80 } 80 }
81 81
82 async fn transaction<'a, 'b>( 82 async fn transaction(
83 &'a mut self, 83 &mut self,
84 address: u8, 84 address: u8,
85 operations: &'a mut [embedded_hal_async::i2c::Operation<'b>], 85 operations: &mut [embedded_hal_async::i2c::Operation<'_>],
86 ) -> Result<(), I2cDeviceError<BUS::Error>> { 86 ) -> Result<(), I2cDeviceError<BUS::Error>> {
87 let _ = address; 87 let _ = address;
88 let _ = operations; 88 let _ = operations;
@@ -121,25 +121,25 @@ where
121 M: RawMutex + 'static, 121 M: RawMutex + 'static,
122 BUS: i2c::I2c + SetConfig + 'static, 122 BUS: i2c::I2c + SetConfig + 'static,
123{ 123{
124 async fn read<'a>(&'a mut self, address: u8, buffer: &'a mut [u8]) -> Result<(), I2cDeviceError<BUS::Error>> { 124 async fn read(&mut self, address: u8, buffer: &mut [u8]) -> Result<(), I2cDeviceError<BUS::Error>> {
125 let mut bus = self.bus.lock().await; 125 let mut bus = self.bus.lock().await;
126 bus.set_config(&self.config); 126 bus.set_config(&self.config);
127 bus.read(address, buffer).await.map_err(I2cDeviceError::I2c)?; 127 bus.read(address, buffer).await.map_err(I2cDeviceError::I2c)?;
128 Ok(()) 128 Ok(())
129 } 129 }
130 130
131 async fn write<'a>(&'a mut self, address: u8, bytes: &'a [u8]) -> Result<(), I2cDeviceError<BUS::Error>> { 131 async fn write(&mut self, address: u8, bytes: &[u8]) -> Result<(), I2cDeviceError<BUS::Error>> {
132 let mut bus = self.bus.lock().await; 132 let mut bus = self.bus.lock().await;
133 bus.set_config(&self.config); 133 bus.set_config(&self.config);
134 bus.write(address, bytes).await.map_err(I2cDeviceError::I2c)?; 134 bus.write(address, bytes).await.map_err(I2cDeviceError::I2c)?;
135 Ok(()) 135 Ok(())
136 } 136 }
137 137
138 async fn write_read<'a>( 138 async fn write_read(
139 &'a mut self, 139 &mut self,
140 address: u8, 140 address: u8,
141 wr_buffer: &'a [u8], 141 wr_buffer: &[u8],
142 rd_buffer: &'a mut [u8], 142 rd_buffer: &mut [u8],
143 ) -> Result<(), I2cDeviceError<BUS::Error>> { 143 ) -> Result<(), I2cDeviceError<BUS::Error>> {
144 let mut bus = self.bus.lock().await; 144 let mut bus = self.bus.lock().await;
145 bus.set_config(&self.config); 145 bus.set_config(&self.config);
@@ -149,11 +149,7 @@ where
149 Ok(()) 149 Ok(())
150 } 150 }
151 151
152 async fn transaction<'a, 'b>( 152 async fn transaction(&mut self, address: u8, operations: &mut [i2c::Operation<'_>]) -> Result<(), Self::Error> {
153 &'a mut self,
154 address: u8,
155 operations: &'a mut [embedded_hal_async::i2c::Operation<'b>],
156 ) -> Result<(), I2cDeviceError<BUS::Error>> {
157 let _ = address; 153 let _ = address;
158 let _ = operations; 154 let _ = operations;
159 todo!() 155 todo!()
diff --git a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs
index d25716655..b5549a6cd 100644
--- a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs
+++ b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs
@@ -25,12 +25,11 @@
25//! let spi_dev2 = SpiDevice::new(spi_bus, cs_pin2); 25//! let spi_dev2 = SpiDevice::new(spi_bus, cs_pin2);
26//! let display2 = ST7735::new(spi_dev2, dc2, rst2, Default::default(), 160, 128); 26//! let display2 = ST7735::new(spi_dev2, dc2, rst2, Default::default(), 160, 128);
27//! ``` 27//! ```
28use core::future::Future;
29 28
30use embassy_sync::blocking_mutex::raw::RawMutex; 29use embassy_sync::blocking_mutex::raw::RawMutex;
31use embassy_sync::mutex::Mutex; 30use embassy_sync::mutex::Mutex;
32use embedded_hal_1::digital::OutputPin; 31use embedded_hal_1::digital::OutputPin;
33use embedded_hal_1::spi::ErrorType; 32use embedded_hal_1::spi::Operation;
34use embedded_hal_async::spi; 33use embedded_hal_async::spi;
35 34
36use crate::shared_bus::SpiDeviceError; 35use crate::shared_bus::SpiDeviceError;
@@ -57,33 +56,92 @@ where
57 type Error = SpiDeviceError<BUS::Error, CS::Error>; 56 type Error = SpiDeviceError<BUS::Error, CS::Error>;
58} 57}
59 58
60unsafe impl<M, BUS, CS> spi::SpiDevice for SpiDevice<'_, M, BUS, CS> 59impl<M, BUS, CS> spi::SpiDeviceRead for SpiDevice<'_, M, BUS, CS>
61where 60where
62 M: RawMutex + 'static, 61 M: RawMutex,
63 BUS: spi::SpiBusFlush + 'static, 62 BUS: spi::SpiBusRead,
64 CS: OutputPin, 63 CS: OutputPin,
65{ 64{
66 type Bus = BUS; 65 async fn read_transaction(&mut self, operations: &mut [&mut [u8]]) -> Result<(), Self::Error> {
66 let mut bus = self.bus.lock().await;
67 self.cs.set_low().map_err(SpiDeviceError::Cs)?;
68
69 let op_res: Result<(), BUS::Error> = try {
70 for buf in operations {
71 bus.read(buf).await?;
72 }
73 };
74
75 // On failure, it's important to still flush and deassert CS.
76 let flush_res = bus.flush().await;
77 let cs_res = self.cs.set_high();
67 78
68 async fn transaction<R, F, Fut>(&mut self, f: F) -> Result<R, Self::Error> 79 let op_res = op_res.map_err(SpiDeviceError::Spi)?;
69 where 80 flush_res.map_err(SpiDeviceError::Spi)?;
70 F: FnOnce(*mut Self::Bus) -> Fut, 81 cs_res.map_err(SpiDeviceError::Cs)?;
71 Fut: Future<Output = Result<R, <Self::Bus as ErrorType>::Error>>, 82
72 { 83 Ok(op_res)
84 }
85}
86
87impl<M, BUS, CS> spi::SpiDeviceWrite for SpiDevice<'_, M, BUS, CS>
88where
89 M: RawMutex,
90 BUS: spi::SpiBusWrite,
91 CS: OutputPin,
92{
93 async fn write_transaction(&mut self, operations: &[&[u8]]) -> Result<(), Self::Error> {
73 let mut bus = self.bus.lock().await; 94 let mut bus = self.bus.lock().await;
74 self.cs.set_low().map_err(SpiDeviceError::Cs)?; 95 self.cs.set_low().map_err(SpiDeviceError::Cs)?;
75 96
76 let f_res = f(&mut *bus).await; 97 let op_res: Result<(), BUS::Error> = try {
98 for buf in operations {
99 bus.write(buf).await?;
100 }
101 };
77 102
78 // On failure, it's important to still flush and deassert CS. 103 // On failure, it's important to still flush and deassert CS.
79 let flush_res = bus.flush().await; 104 let flush_res = bus.flush().await;
80 let cs_res = self.cs.set_high(); 105 let cs_res = self.cs.set_high();
81 106
82 let f_res = f_res.map_err(SpiDeviceError::Spi)?; 107 let op_res = op_res.map_err(SpiDeviceError::Spi)?;
83 flush_res.map_err(SpiDeviceError::Spi)?; 108 flush_res.map_err(SpiDeviceError::Spi)?;
84 cs_res.map_err(SpiDeviceError::Cs)?; 109 cs_res.map_err(SpiDeviceError::Cs)?;
85 110
86 Ok(f_res) 111 Ok(op_res)
112 }
113}
114
115impl<M, BUS, CS> spi::SpiDevice for SpiDevice<'_, M, BUS, CS>
116where
117 M: RawMutex,
118 BUS: spi::SpiBus,
119 CS: OutputPin,
120{
121 async fn transaction(&mut self, operations: &mut [spi::Operation<'_, u8>]) -> Result<(), Self::Error> {
122 let mut bus = self.bus.lock().await;
123 self.cs.set_low().map_err(SpiDeviceError::Cs)?;
124
125 let op_res: Result<(), BUS::Error> = try {
126 for op in operations {
127 match op {
128 Operation::Read(buf) => bus.read(buf).await?,
129 Operation::Write(buf) => bus.write(buf).await?,
130 Operation::Transfer(read, write) => bus.transfer(read, write).await?,
131 Operation::TransferInPlace(buf) => bus.transfer_in_place(buf).await?,
132 }
133 }
134 };
135
136 // On failure, it's important to still flush and deassert CS.
137 let flush_res = bus.flush().await;
138 let cs_res = self.cs.set_high();
139
140 let op_res = op_res.map_err(SpiDeviceError::Spi)?;
141 flush_res.map_err(SpiDeviceError::Spi)?;
142 cs_res.map_err(SpiDeviceError::Cs)?;
143
144 Ok(op_res)
87 } 145 }
88} 146}
89 147
@@ -114,33 +172,94 @@ where
114 type Error = SpiDeviceError<BUS::Error, CS::Error>; 172 type Error = SpiDeviceError<BUS::Error, CS::Error>;
115} 173}
116 174
117unsafe impl<M, BUS, CS> spi::SpiDevice for SpiDeviceWithConfig<'_, M, BUS, CS> 175impl<M, BUS, CS> spi::SpiDeviceWrite for SpiDeviceWithConfig<'_, M, BUS, CS>
176where
177 M: RawMutex,
178 BUS: spi::SpiBusWrite + SetConfig,
179 CS: OutputPin,
180{
181 async fn write_transaction(&mut self, operations: &[&[u8]]) -> Result<(), Self::Error> {
182 let mut bus = self.bus.lock().await;
183 bus.set_config(&self.config);
184 self.cs.set_low().map_err(SpiDeviceError::Cs)?;
185
186 let op_res: Result<(), BUS::Error> = try {
187 for buf in operations {
188 bus.write(buf).await?;
189 }
190 };
191
192 // On failure, it's important to still flush and deassert CS.
193 let flush_res = bus.flush().await;
194 let cs_res = self.cs.set_high();
195
196 let op_res = op_res.map_err(SpiDeviceError::Spi)?;
197 flush_res.map_err(SpiDeviceError::Spi)?;
198 cs_res.map_err(SpiDeviceError::Cs)?;
199
200 Ok(op_res)
201 }
202}
203
204impl<M, BUS, CS> spi::SpiDeviceRead for SpiDeviceWithConfig<'_, M, BUS, CS>
118where 205where
119 M: RawMutex + 'static, 206 M: RawMutex,
120 BUS: spi::SpiBusFlush + SetConfig + 'static, 207 BUS: spi::SpiBusRead + SetConfig,
121 CS: OutputPin, 208 CS: OutputPin,
122{ 209{
123 type Bus = BUS; 210 async fn read_transaction(&mut self, operations: &mut [&mut [u8]]) -> Result<(), Self::Error> {
211 let mut bus = self.bus.lock().await;
212 bus.set_config(&self.config);
213 self.cs.set_low().map_err(SpiDeviceError::Cs)?;
214
215 let op_res: Result<(), BUS::Error> = try {
216 for buf in operations {
217 bus.read(buf).await?;
218 }
219 };
220
221 // On failure, it's important to still flush and deassert CS.
222 let flush_res = bus.flush().await;
223 let cs_res = self.cs.set_high();
224
225 let op_res = op_res.map_err(SpiDeviceError::Spi)?;
226 flush_res.map_err(SpiDeviceError::Spi)?;
227 cs_res.map_err(SpiDeviceError::Cs)?;
228
229 Ok(op_res)
230 }
231}
124 232
125 async fn transaction<R, F, Fut>(&mut self, f: F) -> Result<R, Self::Error> 233impl<M, BUS, CS> spi::SpiDevice for SpiDeviceWithConfig<'_, M, BUS, CS>
126 where 234where
127 F: FnOnce(*mut Self::Bus) -> Fut, 235 M: RawMutex,
128 Fut: Future<Output = Result<R, <Self::Bus as ErrorType>::Error>>, 236 BUS: spi::SpiBus + SetConfig,
129 { 237 CS: OutputPin,
238{
239 async fn transaction(&mut self, operations: &mut [spi::Operation<'_, u8>]) -> Result<(), Self::Error> {
130 let mut bus = self.bus.lock().await; 240 let mut bus = self.bus.lock().await;
131 bus.set_config(&self.config); 241 bus.set_config(&self.config);
132 self.cs.set_low().map_err(SpiDeviceError::Cs)?; 242 self.cs.set_low().map_err(SpiDeviceError::Cs)?;
133 243
134 let f_res = f(&mut *bus).await; 244 let op_res: Result<(), BUS::Error> = try {
245 for op in operations {
246 match op {
247 Operation::Read(buf) => bus.read(buf).await?,
248 Operation::Write(buf) => bus.write(buf).await?,
249 Operation::Transfer(read, write) => bus.transfer(read, write).await?,
250 Operation::TransferInPlace(buf) => bus.transfer_in_place(buf).await?,
251 }
252 }
253 };
135 254
136 // On failure, it's important to still flush and deassert CS. 255 // On failure, it's important to still flush and deassert CS.
137 let flush_res = bus.flush().await; 256 let flush_res = bus.flush().await;
138 let cs_res = self.cs.set_high(); 257 let cs_res = self.cs.set_high();
139 258
140 let f_res = f_res.map_err(SpiDeviceError::Spi)?; 259 let op_res = op_res.map_err(SpiDeviceError::Spi)?;
141 flush_res.map_err(SpiDeviceError::Spi)?; 260 flush_res.map_err(SpiDeviceError::Spi)?;
142 cs_res.map_err(SpiDeviceError::Cs)?; 261 cs_res.map_err(SpiDeviceError::Cs)?;
143 262
144 Ok(f_res) 263 Ok(op_res)
145 } 264 }
146} 265}
diff --git a/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs b/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs
index 892000b26..1fe520e6c 100644
--- a/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs
+++ b/embassy-embedded-hal/src/shared_bus/blocking/i2c.rs
@@ -72,34 +72,6 @@ where
72 let _ = operations; 72 let _ = operations;
73 todo!() 73 todo!()
74 } 74 }
75
76 fn write_iter<B: IntoIterator<Item = u8>>(&mut self, addr: u8, bytes: B) -> Result<(), Self::Error> {
77 let _ = addr;
78 let _ = bytes;
79 todo!()
80 }
81
82 fn write_iter_read<B: IntoIterator<Item = u8>>(
83 &mut self,
84 addr: u8,
85 bytes: B,
86 buffer: &mut [u8],
87 ) -> Result<(), Self::Error> {
88 let _ = addr;
89 let _ = bytes;
90 let _ = buffer;
91 todo!()
92 }
93
94 fn transaction_iter<'a, O: IntoIterator<Item = Operation<'a>>>(
95 &mut self,
96 address: u8,
97 operations: O,
98 ) -> Result<(), Self::Error> {
99 let _ = address;
100 let _ = operations;
101 todo!()
102 }
103} 75}
104 76
105impl<'a, M, BUS, E> embedded_hal_02::blocking::i2c::Write for I2cDevice<'_, M, BUS> 77impl<'a, M, BUS, E> embedded_hal_02::blocking::i2c::Write for I2cDevice<'_, M, BUS>
@@ -204,32 +176,4 @@ where
204 let _ = operations; 176 let _ = operations;
205 todo!() 177 todo!()
206 } 178 }
207
208 fn write_iter<B: IntoIterator<Item = u8>>(&mut self, addr: u8, bytes: B) -> Result<(), Self::Error> {
209 let _ = addr;
210 let _ = bytes;
211 todo!()
212 }
213
214 fn write_iter_read<B: IntoIterator<Item = u8>>(
215 &mut self,
216 addr: u8,
217 bytes: B,
218 buffer: &mut [u8],
219 ) -> Result<(), Self::Error> {
220 let _ = addr;
221 let _ = bytes;
222 let _ = buffer;
223 todo!()
224 }
225
226 fn transaction_iter<'a, O: IntoIterator<Item = Operation<'a>>>(
227 &mut self,
228 address: u8,
229 operations: O,
230 ) -> Result<(), Self::Error> {
231 let _ = address;
232 let _ = operations;
233 todo!()
234 }
235} 179}
diff --git a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs
index 4a08dc36e..7982ffb6e 100644
--- a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs
+++ b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs
@@ -23,8 +23,7 @@ use core::cell::RefCell;
23use embassy_sync::blocking_mutex::raw::RawMutex; 23use embassy_sync::blocking_mutex::raw::RawMutex;
24use embassy_sync::blocking_mutex::Mutex; 24use embassy_sync::blocking_mutex::Mutex;
25use embedded_hal_1::digital::OutputPin; 25use embedded_hal_1::digital::OutputPin;
26use embedded_hal_1::spi; 26use embedded_hal_1::spi::{self, Operation, SpiBus, SpiBusRead, SpiBusWrite};
27use embedded_hal_1::spi::SpiBusFlush;
28 27
29use crate::shared_bus::SpiDeviceError; 28use crate::shared_bus::SpiDeviceError;
30use crate::SetConfig; 29use crate::SetConfig;
@@ -50,30 +49,85 @@ where
50 type Error = SpiDeviceError<BUS::Error, CS::Error>; 49 type Error = SpiDeviceError<BUS::Error, CS::Error>;
51} 50}
52 51
53impl<BUS, M, CS> embedded_hal_1::spi::SpiDevice for SpiDevice<'_, M, BUS, CS> 52impl<BUS, M, CS> embedded_hal_1::spi::SpiDeviceRead for SpiDevice<'_, M, BUS, CS>
54where 53where
55 M: RawMutex, 54 M: RawMutex,
56 BUS: SpiBusFlush, 55 BUS: SpiBusRead,
57 CS: OutputPin, 56 CS: OutputPin,
58{ 57{
59 type Bus = BUS; 58 fn read_transaction(&mut self, operations: &mut [&mut [u8]]) -> Result<(), Self::Error> {
59 self.bus.lock(|bus| {
60 let mut bus = bus.borrow_mut();
61 self.cs.set_low().map_err(SpiDeviceError::Cs)?;
62
63 let op_res = operations.iter_mut().try_for_each(|buf| bus.read(buf));
60 64
61 fn transaction<R>(&mut self, f: impl FnOnce(&mut Self::Bus) -> Result<R, BUS::Error>) -> Result<R, Self::Error> { 65 // On failure, it's important to still flush and deassert CS.
66 let flush_res = bus.flush();
67 let cs_res = self.cs.set_high();
68
69 let op_res = op_res.map_err(SpiDeviceError::Spi)?;
70 flush_res.map_err(SpiDeviceError::Spi)?;
71 cs_res.map_err(SpiDeviceError::Cs)?;
72
73 Ok(op_res)
74 })
75 }
76}
77
78impl<BUS, M, CS> embedded_hal_1::spi::SpiDeviceWrite for SpiDevice<'_, M, BUS, CS>
79where
80 M: RawMutex,
81 BUS: SpiBusWrite,
82 CS: OutputPin,
83{
84 fn write_transaction(&mut self, operations: &[&[u8]]) -> Result<(), Self::Error> {
85 self.bus.lock(|bus| {
86 let mut bus = bus.borrow_mut();
87 self.cs.set_low().map_err(SpiDeviceError::Cs)?;
88
89 let op_res = operations.iter().try_for_each(|buf| bus.write(buf));
90
91 // On failure, it's important to still flush and deassert CS.
92 let flush_res = bus.flush();
93 let cs_res = self.cs.set_high();
94
95 let op_res = op_res.map_err(SpiDeviceError::Spi)?;
96 flush_res.map_err(SpiDeviceError::Spi)?;
97 cs_res.map_err(SpiDeviceError::Cs)?;
98
99 Ok(op_res)
100 })
101 }
102}
103
104impl<BUS, M, CS> embedded_hal_1::spi::SpiDevice for SpiDevice<'_, M, BUS, CS>
105where
106 M: RawMutex,
107 BUS: SpiBus,
108 CS: OutputPin,
109{
110 fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> {
62 self.bus.lock(|bus| { 111 self.bus.lock(|bus| {
63 let mut bus = bus.borrow_mut(); 112 let mut bus = bus.borrow_mut();
64 self.cs.set_low().map_err(SpiDeviceError::Cs)?; 113 self.cs.set_low().map_err(SpiDeviceError::Cs)?;
65 114
66 let f_res = f(&mut bus); 115 let op_res = operations.iter_mut().try_for_each(|op| match op {
116 Operation::Read(buf) => bus.read(buf),
117 Operation::Write(buf) => bus.write(buf),
118 Operation::Transfer(read, write) => bus.transfer(read, write),
119 Operation::TransferInPlace(buf) => bus.transfer_in_place(buf),
120 });
67 121
68 // On failure, it's important to still flush and deassert CS. 122 // On failure, it's important to still flush and deassert CS.
69 let flush_res = bus.flush(); 123 let flush_res = bus.flush();
70 let cs_res = self.cs.set_high(); 124 let cs_res = self.cs.set_high();
71 125
72 let f_res = f_res.map_err(SpiDeviceError::Spi)?; 126 let op_res = op_res.map_err(SpiDeviceError::Spi)?;
73 flush_res.map_err(SpiDeviceError::Spi)?; 127 flush_res.map_err(SpiDeviceError::Spi)?;
74 cs_res.map_err(SpiDeviceError::Cs)?; 128 cs_res.map_err(SpiDeviceError::Cs)?;
75 129
76 Ok(f_res) 130 Ok(op_res)
77 }) 131 })
78 } 132 }
79} 133}
@@ -89,11 +143,11 @@ where
89 self.bus.lock(|bus| { 143 self.bus.lock(|bus| {
90 let mut bus = bus.borrow_mut(); 144 let mut bus = bus.borrow_mut();
91 self.cs.set_low().map_err(SpiDeviceError::Cs)?; 145 self.cs.set_low().map_err(SpiDeviceError::Cs)?;
92 let f_res = bus.transfer(words); 146 let op_res = bus.transfer(words);
93 let cs_res = self.cs.set_high(); 147 let cs_res = self.cs.set_high();
94 let f_res = f_res.map_err(SpiDeviceError::Spi)?; 148 let op_res = op_res.map_err(SpiDeviceError::Spi)?;
95 cs_res.map_err(SpiDeviceError::Cs)?; 149 cs_res.map_err(SpiDeviceError::Cs)?;
96 Ok(f_res) 150 Ok(op_res)
97 }) 151 })
98 } 152 }
99} 153}
@@ -110,11 +164,11 @@ where
110 self.bus.lock(|bus| { 164 self.bus.lock(|bus| {
111 let mut bus = bus.borrow_mut(); 165 let mut bus = bus.borrow_mut();
112 self.cs.set_low().map_err(SpiDeviceError::Cs)?; 166 self.cs.set_low().map_err(SpiDeviceError::Cs)?;
113 let f_res = bus.write(words); 167 let op_res = bus.write(words);
114 let cs_res = self.cs.set_high(); 168 let cs_res = self.cs.set_high();
115 let f_res = f_res.map_err(SpiDeviceError::Spi)?; 169 let op_res = op_res.map_err(SpiDeviceError::Spi)?;
116 cs_res.map_err(SpiDeviceError::Cs)?; 170 cs_res.map_err(SpiDeviceError::Cs)?;
117 Ok(f_res) 171 Ok(op_res)
118 }) 172 })
119 } 173 }
120} 174}
@@ -146,30 +200,85 @@ where
146 type Error = SpiDeviceError<BUS::Error, CS::Error>; 200 type Error = SpiDeviceError<BUS::Error, CS::Error>;
147} 201}
148 202
149impl<BUS, M, CS> embedded_hal_1::spi::SpiDevice for SpiDeviceWithConfig<'_, M, BUS, CS> 203impl<BUS, M, CS> embedded_hal_1::spi::SpiDeviceRead for SpiDeviceWithConfig<'_, M, BUS, CS>
150where 204where
151 M: RawMutex, 205 M: RawMutex,
152 BUS: SpiBusFlush + SetConfig, 206 BUS: SpiBusRead + SetConfig,
153 CS: OutputPin, 207 CS: OutputPin,
154{ 208{
155 type Bus = BUS; 209 fn read_transaction(&mut self, operations: &mut [&mut [u8]]) -> Result<(), Self::Error> {
210 self.bus.lock(|bus| {
211 let mut bus = bus.borrow_mut();
212 bus.set_config(&self.config);
213 self.cs.set_low().map_err(SpiDeviceError::Cs)?;
214
215 let op_res = operations.iter_mut().try_for_each(|buf| bus.read(buf));
156 216
157 fn transaction<R>(&mut self, f: impl FnOnce(&mut Self::Bus) -> Result<R, BUS::Error>) -> Result<R, Self::Error> { 217 // On failure, it's important to still flush and deassert CS.
218 let flush_res = bus.flush();
219 let cs_res = self.cs.set_high();
220
221 let op_res = op_res.map_err(SpiDeviceError::Spi)?;
222 flush_res.map_err(SpiDeviceError::Spi)?;
223 cs_res.map_err(SpiDeviceError::Cs)?;
224 Ok(op_res)
225 })
226 }
227}
228
229impl<BUS, M, CS> embedded_hal_1::spi::SpiDeviceWrite for SpiDeviceWithConfig<'_, M, BUS, CS>
230where
231 M: RawMutex,
232 BUS: SpiBusWrite + SetConfig,
233 CS: OutputPin,
234{
235 fn write_transaction(&mut self, operations: &[&[u8]]) -> Result<(), Self::Error> {
236 self.bus.lock(|bus| {
237 let mut bus = bus.borrow_mut();
238 bus.set_config(&self.config);
239 self.cs.set_low().map_err(SpiDeviceError::Cs)?;
240
241 let op_res = operations.iter().try_for_each(|buf| bus.write(buf));
242
243 // On failure, it's important to still flush and deassert CS.
244 let flush_res = bus.flush();
245 let cs_res = self.cs.set_high();
246
247 let op_res = op_res.map_err(SpiDeviceError::Spi)?;
248 flush_res.map_err(SpiDeviceError::Spi)?;
249 cs_res.map_err(SpiDeviceError::Cs)?;
250 Ok(op_res)
251 })
252 }
253}
254
255impl<BUS, M, CS> embedded_hal_1::spi::SpiDevice for SpiDeviceWithConfig<'_, M, BUS, CS>
256where
257 M: RawMutex,
258 BUS: SpiBus + SetConfig,
259 CS: OutputPin,
260{
261 fn transaction(&mut self, operations: &mut [Operation<'_, u8>]) -> Result<(), Self::Error> {
158 self.bus.lock(|bus| { 262 self.bus.lock(|bus| {
159 let mut bus = bus.borrow_mut(); 263 let mut bus = bus.borrow_mut();
160 bus.set_config(&self.config); 264 bus.set_config(&self.config);
161 self.cs.set_low().map_err(SpiDeviceError::Cs)?; 265 self.cs.set_low().map_err(SpiDeviceError::Cs)?;
162 266
163 let f_res = f(&mut bus); 267 let op_res = operations.iter_mut().try_for_each(|op| match op {
268 Operation::Read(buf) => bus.read(buf),
269 Operation::Write(buf) => bus.write(buf),
270 Operation::Transfer(read, write) => bus.transfer(read, write),
271 Operation::TransferInPlace(buf) => bus.transfer_in_place(buf),
272 });
164 273
165 // On failure, it's important to still flush and deassert CS. 274 // On failure, it's important to still flush and deassert CS.
166 let flush_res = bus.flush(); 275 let flush_res = bus.flush();
167 let cs_res = self.cs.set_high(); 276 let cs_res = self.cs.set_high();
168 277
169 let f_res = f_res.map_err(SpiDeviceError::Spi)?; 278 let op_res = op_res.map_err(SpiDeviceError::Spi)?;
170 flush_res.map_err(SpiDeviceError::Spi)?; 279 flush_res.map_err(SpiDeviceError::Spi)?;
171 cs_res.map_err(SpiDeviceError::Cs)?; 280 cs_res.map_err(SpiDeviceError::Cs)?;
172 Ok(f_res) 281 Ok(op_res)
173 }) 282 })
174 } 283 }
175} 284}