diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-07-04 19:53:06 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-07-04 19:59:36 +0200 |
| commit | a101d9078deb3ad576a40b6d5f4d6e81dcfd528e (patch) | |
| tree | 98deed296973aa29dc1701f69ecbe342d2a2c7c5 /embassy-embedded-hal/src | |
| parent | b2f843a4ce2dc9114a135f612e1a408a8fe02fab (diff) | |
update embedded-hal crates.
Diffstat (limited to 'embassy-embedded-hal/src')
| -rw-r--r-- | embassy-embedded-hal/src/adapter/blocking_async.rs | 43 | ||||
| -rw-r--r-- | embassy-embedded-hal/src/adapter/yielding_async.rs | 39 | ||||
| -rw-r--r-- | embassy-embedded-hal/src/shared_bus/asynch/spi.rs | 126 | ||||
| -rw-r--r-- | embassy-embedded-hal/src/shared_bus/blocking/spi.rs | 120 | ||||
| -rw-r--r-- | embassy-embedded-hal/src/shared_bus/mod.rs | 4 |
5 files changed, 56 insertions, 276 deletions
diff --git a/embassy-embedded-hal/src/adapter/blocking_async.rs b/embassy-embedded-hal/src/adapter/blocking_async.rs index b996d6a75..98ae2b02c 100644 --- a/embassy-embedded-hal/src/adapter/blocking_async.rs +++ b/embassy-embedded-hal/src/adapter/blocking_async.rs | |||
| @@ -74,47 +74,30 @@ where | |||
| 74 | E: embedded_hal_1::spi::Error + 'static, | 74 | E: embedded_hal_1::spi::Error + 'static, |
| 75 | T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>, | 75 | T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>, |
| 76 | { | 76 | { |
| 77 | async fn transfer<'a>(&'a mut self, read: &'a mut [u8], write: &'a [u8]) -> Result<(), Self::Error> { | 77 | async fn flush(&mut self) -> Result<(), Self::Error> { |
| 78 | // Ensure we write the expected bytes | ||
| 79 | for i in 0..core::cmp::min(read.len(), write.len()) { | ||
| 80 | read[i] = write[i].clone(); | ||
| 81 | } | ||
| 82 | self.wrapped.transfer(read)?; | ||
| 83 | Ok(()) | 78 | Ok(()) |
| 84 | } | 79 | } |
| 85 | 80 | ||
| 86 | async fn transfer_in_place<'a>(&'a mut self, _: &'a mut [u8]) -> Result<(), Self::Error> { | 81 | async fn write(&mut self, data: &[u8]) -> Result<(), Self::Error> { |
| 87 | todo!() | 82 | self.wrapped.write(data)?; |
| 83 | Ok(()) | ||
| 88 | } | 84 | } |
| 89 | } | ||
| 90 | 85 | ||
| 91 | impl<T, E> embedded_hal_async::spi::SpiBusFlush for BlockingAsync<T> | 86 | async fn read(&mut self, data: &mut [u8]) -> Result<(), Self::Error> { |
| 92 | where | 87 | self.wrapped.transfer(data)?; |
| 93 | E: embedded_hal_1::spi::Error + 'static, | ||
| 94 | T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>, | ||
| 95 | { | ||
| 96 | async fn flush(&mut self) -> Result<(), Self::Error> { | ||
| 97 | Ok(()) | 88 | Ok(()) |
| 98 | } | 89 | } |
| 99 | } | ||
| 100 | 90 | ||
| 101 | impl<T, E> embedded_hal_async::spi::SpiBusWrite<u8> for BlockingAsync<T> | 91 | async fn transfer(&mut self, read: &mut [u8], write: &[u8]) -> Result<(), Self::Error> { |
| 102 | where | 92 | // Ensure we write the expected bytes |
| 103 | E: embedded_hal_1::spi::Error + 'static, | 93 | for i in 0..core::cmp::min(read.len(), write.len()) { |
| 104 | T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>, | 94 | read[i] = write[i].clone(); |
| 105 | { | 95 | } |
| 106 | async fn write(&mut self, data: &[u8]) -> Result<(), Self::Error> { | 96 | self.wrapped.transfer(read)?; |
| 107 | self.wrapped.write(data)?; | ||
| 108 | Ok(()) | 97 | Ok(()) |
| 109 | } | 98 | } |
| 110 | } | ||
| 111 | 99 | ||
| 112 | impl<T, E> embedded_hal_async::spi::SpiBusRead<u8> for BlockingAsync<T> | 100 | async fn transfer_in_place(&mut self, data: &mut [u8]) -> Result<(), Self::Error> { |
| 113 | where | ||
| 114 | E: embedded_hal_1::spi::Error + 'static, | ||
| 115 | T: blocking::spi::Transfer<u8, Error = E> + blocking::spi::Write<u8, Error = E>, | ||
| 116 | { | ||
| 117 | async fn read(&mut self, data: &mut [u8]) -> Result<(), Self::Error> { | ||
| 118 | self.wrapped.transfer(data)?; | 101 | self.wrapped.transfer(data)?; |
| 119 | Ok(()) | 102 | Ok(()) |
| 120 | } | 103 | } |
diff --git a/embassy-embedded-hal/src/adapter/yielding_async.rs b/embassy-embedded-hal/src/adapter/yielding_async.rs index f51e4076f..fe9c9c341 100644 --- a/embassy-embedded-hal/src/adapter/yielding_async.rs +++ b/embassy-embedded-hal/src/adapter/yielding_async.rs | |||
| @@ -69,51 +69,36 @@ where | |||
| 69 | type Error = T::Error; | 69 | type Error = T::Error; |
| 70 | } | 70 | } |
| 71 | 71 | ||
| 72 | impl<T> embedded_hal_async::spi::SpiBus<u8> for YieldingAsync<T> | 72 | impl<T, Word: 'static + Copy> embedded_hal_async::spi::SpiBus<Word> for YieldingAsync<T> |
| 73 | where | 73 | where |
| 74 | T: embedded_hal_async::spi::SpiBus, | 74 | T: embedded_hal_async::spi::SpiBus<Word>, |
| 75 | { | 75 | { |
| 76 | async fn transfer<'a>(&'a mut self, read: &'a mut [u8], write: &'a [u8]) -> Result<(), Self::Error> { | 76 | async fn flush(&mut self) -> Result<(), Self::Error> { |
| 77 | self.wrapped.transfer(read, write).await?; | 77 | self.wrapped.flush().await?; |
| 78 | yield_now().await; | 78 | yield_now().await; |
| 79 | Ok(()) | 79 | Ok(()) |
| 80 | } | 80 | } |
| 81 | 81 | ||
| 82 | async fn transfer_in_place<'a>(&'a mut self, words: &'a mut [u8]) -> Result<(), Self::Error> { | 82 | async fn write(&mut self, data: &[Word]) -> Result<(), Self::Error> { |
| 83 | self.wrapped.transfer_in_place(words).await?; | 83 | self.wrapped.write(data).await?; |
| 84 | yield_now().await; | 84 | yield_now().await; |
| 85 | Ok(()) | 85 | Ok(()) |
| 86 | } | 86 | } |
| 87 | } | ||
| 88 | 87 | ||
| 89 | impl<T> embedded_hal_async::spi::SpiBusFlush for YieldingAsync<T> | 88 | async fn read(&mut self, data: &mut [Word]) -> Result<(), Self::Error> { |
| 90 | where | 89 | self.wrapped.read(data).await?; |
| 91 | T: embedded_hal_async::spi::SpiBusFlush, | ||
| 92 | { | ||
| 93 | async fn flush(&mut self) -> Result<(), Self::Error> { | ||
| 94 | self.wrapped.flush().await?; | ||
| 95 | yield_now().await; | 90 | yield_now().await; |
| 96 | Ok(()) | 91 | Ok(()) |
| 97 | } | 92 | } |
| 98 | } | ||
| 99 | 93 | ||
| 100 | impl<T> embedded_hal_async::spi::SpiBusWrite<u8> for YieldingAsync<T> | 94 | async fn transfer(&mut self, read: &mut [Word], write: &[Word]) -> Result<(), Self::Error> { |
| 101 | where | 95 | self.wrapped.transfer(read, write).await?; |
| 102 | T: embedded_hal_async::spi::SpiBusWrite<u8>, | ||
| 103 | { | ||
| 104 | async fn write(&mut self, data: &[u8]) -> Result<(), Self::Error> { | ||
| 105 | self.wrapped.write(data).await?; | ||
| 106 | yield_now().await; | 96 | yield_now().await; |
| 107 | Ok(()) | 97 | Ok(()) |
| 108 | } | 98 | } |
| 109 | } | ||
| 110 | 99 | ||
| 111 | impl<T> embedded_hal_async::spi::SpiBusRead<u8> for YieldingAsync<T> | 100 | async fn transfer_in_place(&mut self, words: &mut [Word]) -> Result<(), Self::Error> { |
| 112 | where | 101 | self.wrapped.transfer_in_place(words).await?; |
| 113 | T: embedded_hal_async::spi::SpiBusRead<u8>, | ||
| 114 | { | ||
| 115 | async fn read(&mut self, data: &mut [u8]) -> Result<(), Self::Error> { | ||
| 116 | self.wrapped.read(data).await?; | ||
| 117 | yield_now().await; | 102 | yield_now().await; |
| 118 | Ok(()) | 103 | Ok(()) |
| 119 | } | 104 | } |
diff --git a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs index b5549a6cd..030392183 100644 --- a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs | |||
| @@ -56,62 +56,6 @@ where | |||
| 56 | type Error = SpiDeviceError<BUS::Error, CS::Error>; | 56 | type Error = SpiDeviceError<BUS::Error, CS::Error>; |
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | impl<M, BUS, CS> spi::SpiDeviceRead for SpiDevice<'_, M, BUS, CS> | ||
| 60 | where | ||
| 61 | M: RawMutex, | ||
| 62 | BUS: spi::SpiBusRead, | ||
| 63 | CS: OutputPin, | ||
| 64 | { | ||
| 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(); | ||
| 78 | |||
| 79 | let op_res = op_res.map_err(SpiDeviceError::Spi)?; | ||
| 80 | flush_res.map_err(SpiDeviceError::Spi)?; | ||
| 81 | cs_res.map_err(SpiDeviceError::Cs)?; | ||
| 82 | |||
| 83 | Ok(op_res) | ||
| 84 | } | ||
| 85 | } | ||
| 86 | |||
| 87 | impl<M, BUS, CS> spi::SpiDeviceWrite for SpiDevice<'_, M, BUS, CS> | ||
| 88 | where | ||
| 89 | M: RawMutex, | ||
| 90 | BUS: spi::SpiBusWrite, | ||
| 91 | CS: OutputPin, | ||
| 92 | { | ||
| 93 | async fn write_transaction(&mut self, operations: &[&[u8]]) -> Result<(), Self::Error> { | ||
| 94 | let mut bus = self.bus.lock().await; | ||
| 95 | self.cs.set_low().map_err(SpiDeviceError::Cs)?; | ||
| 96 | |||
| 97 | let op_res: Result<(), BUS::Error> = try { | ||
| 98 | for buf in operations { | ||
| 99 | bus.write(buf).await?; | ||
| 100 | } | ||
| 101 | }; | ||
| 102 | |||
| 103 | // On failure, it's important to still flush and deassert CS. | ||
| 104 | let flush_res = bus.flush().await; | ||
| 105 | let cs_res = self.cs.set_high(); | ||
| 106 | |||
| 107 | let op_res = op_res.map_err(SpiDeviceError::Spi)?; | ||
| 108 | flush_res.map_err(SpiDeviceError::Spi)?; | ||
| 109 | cs_res.map_err(SpiDeviceError::Cs)?; | ||
| 110 | |||
| 111 | Ok(op_res) | ||
| 112 | } | ||
| 113 | } | ||
| 114 | |||
| 115 | impl<M, BUS, CS> spi::SpiDevice for SpiDevice<'_, M, BUS, CS> | 59 | impl<M, BUS, CS> spi::SpiDevice for SpiDevice<'_, M, BUS, CS> |
| 116 | where | 60 | where |
| 117 | M: RawMutex, | 61 | M: RawMutex, |
| @@ -129,6 +73,12 @@ where | |||
| 129 | Operation::Write(buf) => bus.write(buf).await?, | 73 | Operation::Write(buf) => bus.write(buf).await?, |
| 130 | Operation::Transfer(read, write) => bus.transfer(read, write).await?, | 74 | Operation::Transfer(read, write) => bus.transfer(read, write).await?, |
| 131 | Operation::TransferInPlace(buf) => bus.transfer_in_place(buf).await?, | 75 | Operation::TransferInPlace(buf) => bus.transfer_in_place(buf).await?, |
| 76 | #[cfg(not(feature = "time"))] | ||
| 77 | Operation::DelayUs(_) => return Err(SpiDeviceError::DelayUsNotSupported), | ||
| 78 | #[cfg(feature = "time")] | ||
| 79 | Operation::DelayUs(us) => { | ||
| 80 | embassy_time::Timer::after(embassy_time::Duration::from_micros(*us as _)).await | ||
| 81 | } | ||
| 132 | } | 82 | } |
| 133 | } | 83 | } |
| 134 | }; | 84 | }; |
| @@ -172,64 +122,6 @@ where | |||
| 172 | type Error = SpiDeviceError<BUS::Error, CS::Error>; | 122 | type Error = SpiDeviceError<BUS::Error, CS::Error>; |
| 173 | } | 123 | } |
| 174 | 124 | ||
| 175 | impl<M, BUS, CS> spi::SpiDeviceWrite for SpiDeviceWithConfig<'_, M, BUS, CS> | ||
| 176 | where | ||
| 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 | |||
| 204 | impl<M, BUS, CS> spi::SpiDeviceRead for SpiDeviceWithConfig<'_, M, BUS, CS> | ||
| 205 | where | ||
| 206 | M: RawMutex, | ||
| 207 | BUS: spi::SpiBusRead + SetConfig, | ||
| 208 | CS: OutputPin, | ||
| 209 | { | ||
| 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 | } | ||
| 232 | |||
| 233 | impl<M, BUS, CS> spi::SpiDevice for SpiDeviceWithConfig<'_, M, BUS, CS> | 125 | impl<M, BUS, CS> spi::SpiDevice for SpiDeviceWithConfig<'_, M, BUS, CS> |
| 234 | where | 126 | where |
| 235 | M: RawMutex, | 127 | M: RawMutex, |
| @@ -248,6 +140,12 @@ where | |||
| 248 | Operation::Write(buf) => bus.write(buf).await?, | 140 | Operation::Write(buf) => bus.write(buf).await?, |
| 249 | Operation::Transfer(read, write) => bus.transfer(read, write).await?, | 141 | Operation::Transfer(read, write) => bus.transfer(read, write).await?, |
| 250 | Operation::TransferInPlace(buf) => bus.transfer_in_place(buf).await?, | 142 | Operation::TransferInPlace(buf) => bus.transfer_in_place(buf).await?, |
| 143 | #[cfg(not(feature = "time"))] | ||
| 144 | Operation::DelayUs(_) => return Err(SpiDeviceError::DelayUsNotSupported), | ||
| 145 | #[cfg(feature = "time")] | ||
| 146 | Operation::DelayUs(us) => { | ||
| 147 | embassy_time::Timer::after(embassy_time::Duration::from_micros(*us as _)).await | ||
| 148 | } | ||
| 251 | } | 149 | } |
| 252 | } | 150 | } |
| 253 | }; | 151 | }; |
diff --git a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs index 22e013be9..6d03d6263 100644 --- a/embassy-embedded-hal/src/shared_bus/blocking/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/blocking/spi.rs | |||
| @@ -22,7 +22,7 @@ use core::cell::RefCell; | |||
| 22 | use embassy_sync::blocking_mutex::raw::RawMutex; | 22 | use embassy_sync::blocking_mutex::raw::RawMutex; |
| 23 | use embassy_sync::blocking_mutex::Mutex; | 23 | use embassy_sync::blocking_mutex::Mutex; |
| 24 | use embedded_hal_1::digital::OutputPin; | 24 | use embedded_hal_1::digital::OutputPin; |
| 25 | use embedded_hal_1::spi::{self, Operation, SpiBus, SpiBusRead, SpiBusWrite}; | 25 | use embedded_hal_1::spi::{self, Operation, SpiBus}; |
| 26 | 26 | ||
| 27 | use crate::shared_bus::SpiDeviceError; | 27 | use crate::shared_bus::SpiDeviceError; |
| 28 | use crate::SetConfig; | 28 | use crate::SetConfig; |
| @@ -48,58 +48,6 @@ where | |||
| 48 | type Error = SpiDeviceError<BUS::Error, CS::Error>; | 48 | type Error = SpiDeviceError<BUS::Error, CS::Error>; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | impl<BUS, M, CS> embedded_hal_1::spi::SpiDeviceRead for SpiDevice<'_, M, BUS, CS> | ||
| 52 | where | ||
| 53 | M: RawMutex, | ||
| 54 | BUS: SpiBusRead, | ||
| 55 | CS: OutputPin, | ||
| 56 | { | ||
| 57 | fn read_transaction(&mut self, operations: &mut [&mut [u8]]) -> Result<(), Self::Error> { | ||
| 58 | self.bus.lock(|bus| { | ||
| 59 | let mut bus = bus.borrow_mut(); | ||
| 60 | self.cs.set_low().map_err(SpiDeviceError::Cs)?; | ||
| 61 | |||
| 62 | let op_res = operations.iter_mut().try_for_each(|buf| bus.read(buf)); | ||
| 63 | |||
| 64 | // On failure, it's important to still flush and deassert CS. | ||
| 65 | let flush_res = bus.flush(); | ||
| 66 | let cs_res = self.cs.set_high(); | ||
| 67 | |||
| 68 | let op_res = op_res.map_err(SpiDeviceError::Spi)?; | ||
| 69 | flush_res.map_err(SpiDeviceError::Spi)?; | ||
| 70 | cs_res.map_err(SpiDeviceError::Cs)?; | ||
| 71 | |||
| 72 | Ok(op_res) | ||
| 73 | }) | ||
| 74 | } | ||
| 75 | } | ||
| 76 | |||
| 77 | impl<BUS, M, CS> embedded_hal_1::spi::SpiDeviceWrite for SpiDevice<'_, M, BUS, CS> | ||
| 78 | where | ||
| 79 | M: RawMutex, | ||
| 80 | BUS: SpiBusWrite, | ||
| 81 | CS: OutputPin, | ||
| 82 | { | ||
| 83 | fn write_transaction(&mut self, operations: &[&[u8]]) -> Result<(), Self::Error> { | ||
| 84 | self.bus.lock(|bus| { | ||
| 85 | let mut bus = bus.borrow_mut(); | ||
| 86 | self.cs.set_low().map_err(SpiDeviceError::Cs)?; | ||
| 87 | |||
| 88 | let op_res = operations.iter().try_for_each(|buf| bus.write(buf)); | ||
| 89 | |||
| 90 | // On failure, it's important to still flush and deassert CS. | ||
| 91 | let flush_res = bus.flush(); | ||
| 92 | let cs_res = self.cs.set_high(); | ||
| 93 | |||
| 94 | let op_res = op_res.map_err(SpiDeviceError::Spi)?; | ||
| 95 | flush_res.map_err(SpiDeviceError::Spi)?; | ||
| 96 | cs_res.map_err(SpiDeviceError::Cs)?; | ||
| 97 | |||
| 98 | Ok(op_res) | ||
| 99 | }) | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | impl<BUS, M, CS> embedded_hal_1::spi::SpiDevice for SpiDevice<'_, M, BUS, CS> | 51 | impl<BUS, M, CS> embedded_hal_1::spi::SpiDevice for SpiDevice<'_, M, BUS, CS> |
| 104 | where | 52 | where |
| 105 | M: RawMutex, | 53 | M: RawMutex, |
| @@ -116,6 +64,13 @@ where | |||
| 116 | Operation::Write(buf) => bus.write(buf), | 64 | Operation::Write(buf) => bus.write(buf), |
| 117 | Operation::Transfer(read, write) => bus.transfer(read, write), | 65 | Operation::Transfer(read, write) => bus.transfer(read, write), |
| 118 | Operation::TransferInPlace(buf) => bus.transfer_in_place(buf), | 66 | Operation::TransferInPlace(buf) => bus.transfer_in_place(buf), |
| 67 | #[cfg(not(feature = "time"))] | ||
| 68 | Operation::DelayUs(_) => Err(SpiDeviceError::DelayUsNotSupported), | ||
| 69 | #[cfg(feature = "time")] | ||
| 70 | Operation::DelayUs(us) => { | ||
| 71 | embassy_time::block_for(embassy_time::Duration::from_micros(*us as _)); | ||
| 72 | Ok(()) | ||
| 73 | } | ||
| 119 | }); | 74 | }); |
| 120 | 75 | ||
| 121 | // On failure, it's important to still flush and deassert CS. | 76 | // On failure, it's important to still flush and deassert CS. |
| @@ -199,58 +154,6 @@ where | |||
| 199 | type Error = SpiDeviceError<BUS::Error, CS::Error>; | 154 | type Error = SpiDeviceError<BUS::Error, CS::Error>; |
| 200 | } | 155 | } |
| 201 | 156 | ||
| 202 | impl<BUS, M, CS> embedded_hal_1::spi::SpiDeviceRead for SpiDeviceWithConfig<'_, M, BUS, CS> | ||
| 203 | where | ||
| 204 | M: RawMutex, | ||
| 205 | BUS: SpiBusRead + SetConfig, | ||
| 206 | CS: OutputPin, | ||
| 207 | { | ||
| 208 | fn read_transaction(&mut self, operations: &mut [&mut [u8]]) -> Result<(), Self::Error> { | ||
| 209 | self.bus.lock(|bus| { | ||
| 210 | let mut bus = bus.borrow_mut(); | ||
| 211 | bus.set_config(&self.config); | ||
| 212 | self.cs.set_low().map_err(SpiDeviceError::Cs)?; | ||
| 213 | |||
| 214 | let op_res = operations.iter_mut().try_for_each(|buf| bus.read(buf)); | ||
| 215 | |||
| 216 | // On failure, it's important to still flush and deassert CS. | ||
| 217 | let flush_res = bus.flush(); | ||
| 218 | let cs_res = self.cs.set_high(); | ||
| 219 | |||
| 220 | let op_res = op_res.map_err(SpiDeviceError::Spi)?; | ||
| 221 | flush_res.map_err(SpiDeviceError::Spi)?; | ||
| 222 | cs_res.map_err(SpiDeviceError::Cs)?; | ||
| 223 | Ok(op_res) | ||
| 224 | }) | ||
| 225 | } | ||
| 226 | } | ||
| 227 | |||
| 228 | impl<BUS, M, CS> embedded_hal_1::spi::SpiDeviceWrite for SpiDeviceWithConfig<'_, M, BUS, CS> | ||
| 229 | where | ||
| 230 | M: RawMutex, | ||
| 231 | BUS: SpiBusWrite + SetConfig, | ||
| 232 | CS: OutputPin, | ||
| 233 | { | ||
| 234 | fn write_transaction(&mut self, operations: &[&[u8]]) -> Result<(), Self::Error> { | ||
| 235 | self.bus.lock(|bus| { | ||
| 236 | let mut bus = bus.borrow_mut(); | ||
| 237 | bus.set_config(&self.config); | ||
| 238 | self.cs.set_low().map_err(SpiDeviceError::Cs)?; | ||
| 239 | |||
| 240 | let op_res = operations.iter().try_for_each(|buf| bus.write(buf)); | ||
| 241 | |||
| 242 | // On failure, it's important to still flush and deassert CS. | ||
| 243 | let flush_res = bus.flush(); | ||
| 244 | let cs_res = self.cs.set_high(); | ||
| 245 | |||
| 246 | let op_res = op_res.map_err(SpiDeviceError::Spi)?; | ||
| 247 | flush_res.map_err(SpiDeviceError::Spi)?; | ||
| 248 | cs_res.map_err(SpiDeviceError::Cs)?; | ||
| 249 | Ok(op_res) | ||
| 250 | }) | ||
| 251 | } | ||
| 252 | } | ||
| 253 | |||
| 254 | impl<BUS, M, CS> embedded_hal_1::spi::SpiDevice for SpiDeviceWithConfig<'_, M, BUS, CS> | 157 | impl<BUS, M, CS> embedded_hal_1::spi::SpiDevice for SpiDeviceWithConfig<'_, M, BUS, CS> |
| 255 | where | 158 | where |
| 256 | M: RawMutex, | 159 | M: RawMutex, |
| @@ -268,6 +171,13 @@ where | |||
| 268 | Operation::Write(buf) => bus.write(buf), | 171 | Operation::Write(buf) => bus.write(buf), |
| 269 | Operation::Transfer(read, write) => bus.transfer(read, write), | 172 | Operation::Transfer(read, write) => bus.transfer(read, write), |
| 270 | Operation::TransferInPlace(buf) => bus.transfer_in_place(buf), | 173 | Operation::TransferInPlace(buf) => bus.transfer_in_place(buf), |
| 174 | #[cfg(not(feature = "time"))] | ||
| 175 | Operation::DelayUs(_) => Err(SpiDeviceError::DelayUsNotSupported), | ||
| 176 | #[cfg(feature = "time")] | ||
| 177 | Operation::DelayUs(us) => { | ||
| 178 | embassy_time::block_for(embassy_time::Duration::from_micros(*us as _)); | ||
| 179 | Ok(()) | ||
| 180 | } | ||
| 271 | }); | 181 | }); |
| 272 | 182 | ||
| 273 | // On failure, it's important to still flush and deassert CS. | 183 | // On failure, it's important to still flush and deassert CS. |
diff --git a/embassy-embedded-hal/src/shared_bus/mod.rs b/embassy-embedded-hal/src/shared_bus/mod.rs index 617d921e9..79a90bd52 100644 --- a/embassy-embedded-hal/src/shared_bus/mod.rs +++ b/embassy-embedded-hal/src/shared_bus/mod.rs | |||
| @@ -30,11 +30,14 @@ where | |||
| 30 | /// Error returned by SPI device implementations in this crate. | 30 | /// Error returned by SPI device implementations in this crate. |
| 31 | #[derive(Copy, Clone, Eq, PartialEq, Debug)] | 31 | #[derive(Copy, Clone, Eq, PartialEq, Debug)] |
| 32 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] | 32 | #[cfg_attr(feature = "defmt", derive(defmt::Format))] |
| 33 | #[non_exhaustive] | ||
| 33 | pub enum SpiDeviceError<BUS, CS> { | 34 | pub enum SpiDeviceError<BUS, CS> { |
| 34 | /// An operation on the inner SPI bus failed. | 35 | /// An operation on the inner SPI bus failed. |
| 35 | Spi(BUS), | 36 | Spi(BUS), |
| 36 | /// Setting the value of the Chip Select (CS) pin failed. | 37 | /// Setting the value of the Chip Select (CS) pin failed. |
| 37 | Cs(CS), | 38 | Cs(CS), |
| 39 | /// DelayUs operations are not supported when the `time` Cargo feature is not enabled. | ||
| 40 | DelayUsNotSupported, | ||
| 38 | } | 41 | } |
| 39 | 42 | ||
| 40 | impl<BUS, CS> spi::Error for SpiDeviceError<BUS, CS> | 43 | impl<BUS, CS> spi::Error for SpiDeviceError<BUS, CS> |
| @@ -46,6 +49,7 @@ where | |||
| 46 | match self { | 49 | match self { |
| 47 | Self::Spi(e) => e.kind(), | 50 | Self::Spi(e) => e.kind(), |
| 48 | Self::Cs(_) => spi::ErrorKind::Other, | 51 | Self::Cs(_) => spi::ErrorKind::Other, |
| 52 | Self::DelayUsNotSupported => spi::ErrorKind::Other, | ||
| 49 | } | 53 | } |
| 50 | } | 54 | } |
| 51 | } | 55 | } |
