diff options
Diffstat (limited to 'embassy-embedded-hal/src/shared_bus')
| -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 |
3 files changed, 31 insertions, 219 deletions
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 | } |
