diff options
| author | Dario Nieuwenhuis <[email protected]> | 2023-04-06 22:25:24 +0200 |
|---|---|---|
| committer | Dario Nieuwenhuis <[email protected]> | 2023-04-06 22:41:50 +0200 |
| commit | be37eee13dbd7833e0d74ea57d31d3e5c58cd47f (patch) | |
| tree | 3e1d5a59409ea06fe34d97fdaf45642683332638 /embassy-embedded-hal/src/shared_bus/blocking/spi.rs | |
| parent | f3ec6080bf9a39d9819195861e7b41e8a2081600 (diff) | |
Update embedded-hal crates.
Diffstat (limited to 'embassy-embedded-hal/src/shared_bus/blocking/spi.rs')
| -rw-r--r-- | embassy-embedded-hal/src/shared_bus/blocking/spi.rs | 153 |
1 files changed, 131 insertions, 22 deletions
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; | |||
| 23 | use embassy_sync::blocking_mutex::raw::RawMutex; | 23 | use embassy_sync::blocking_mutex::raw::RawMutex; |
| 24 | use embassy_sync::blocking_mutex::Mutex; | 24 | use embassy_sync::blocking_mutex::Mutex; |
| 25 | use embedded_hal_1::digital::OutputPin; | 25 | use embedded_hal_1::digital::OutputPin; |
| 26 | use embedded_hal_1::spi; | 26 | use embedded_hal_1::spi::{self, Operation, SpiBus, SpiBusRead, SpiBusWrite}; |
| 27 | use embedded_hal_1::spi::SpiBusFlush; | ||
| 28 | 27 | ||
| 29 | use crate::shared_bus::SpiDeviceError; | 28 | use crate::shared_bus::SpiDeviceError; |
| 30 | use crate::SetConfig; | 29 | use 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 | ||
| 53 | impl<BUS, M, CS> embedded_hal_1::spi::SpiDevice for SpiDevice<'_, M, BUS, CS> | 52 | impl<BUS, M, CS> embedded_hal_1::spi::SpiDeviceRead for SpiDevice<'_, M, BUS, CS> |
| 54 | where | 53 | where |
| 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 | |||
| 78 | impl<BUS, M, CS> embedded_hal_1::spi::SpiDeviceWrite for SpiDevice<'_, M, BUS, CS> | ||
| 79 | where | ||
| 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 | |||
| 104 | impl<BUS, M, CS> embedded_hal_1::spi::SpiDevice for SpiDevice<'_, M, BUS, CS> | ||
| 105 | where | ||
| 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 | ||
| 149 | impl<BUS, M, CS> embedded_hal_1::spi::SpiDevice for SpiDeviceWithConfig<'_, M, BUS, CS> | 203 | impl<BUS, M, CS> embedded_hal_1::spi::SpiDeviceRead for SpiDeviceWithConfig<'_, M, BUS, CS> |
| 150 | where | 204 | where |
| 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 | |||
| 229 | impl<BUS, M, CS> embedded_hal_1::spi::SpiDeviceWrite for SpiDeviceWithConfig<'_, M, BUS, CS> | ||
| 230 | where | ||
| 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 | |||
| 255 | impl<BUS, M, CS> embedded_hal_1::spi::SpiDevice for SpiDeviceWithConfig<'_, M, BUS, CS> | ||
| 256 | where | ||
| 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 | } |
