diff options
Diffstat (limited to 'embassy-embedded-hal/src/shared_bus')
| -rw-r--r-- | embassy-embedded-hal/src/shared_bus/asynch/spi.rs | 16 |
1 files changed, 14 insertions, 2 deletions
diff --git a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs index 0ba1033f6..78709b7d3 100644 --- a/embassy-embedded-hal/src/shared_bus/asynch/spi.rs +++ b/embassy-embedded-hal/src/shared_bus/asynch/spi.rs | |||
| @@ -72,6 +72,10 @@ where | |||
| 72 | self.cs.set_low().map_err(SpiDeviceError::Cs)?; | 72 | self.cs.set_low().map_err(SpiDeviceError::Cs)?; |
| 73 | 73 | ||
| 74 | let cs_drop = OnDrop::new(|| { | 74 | let cs_drop = OnDrop::new(|| { |
| 75 | // This drop guard deasserts CS pin if the async operation is cancelled. | ||
| 76 | // Errors are ignored in this drop handler, as there's nothing we can do about them. | ||
| 77 | // If the async operation is completed without cancellation, this handler will not | ||
| 78 | // be run, and the CS pin will be deasserted with proper error handling. | ||
| 75 | let _ = self.cs.set_high(); | 79 | let _ = self.cs.set_high(); |
| 76 | }); | 80 | }); |
| 77 | 81 | ||
| @@ -102,10 +106,15 @@ where | |||
| 102 | 106 | ||
| 103 | // On failure, it's important to still flush and deassert CS. | 107 | // On failure, it's important to still flush and deassert CS. |
| 104 | let flush_res = bus.flush().await; | 108 | let flush_res = bus.flush().await; |
| 105 | drop(cs_drop); | 109 | |
| 110 | // Now that all the async operations are done, we defuse the CS guard, | ||
| 111 | // and manually set the CS pin low (to better handle the possible errors). | ||
| 112 | cs_drop.defuse(); | ||
| 113 | let cs_res = self.cs.set_high(); | ||
| 106 | 114 | ||
| 107 | let op_res = op_res.map_err(SpiDeviceError::Spi)?; | 115 | let op_res = op_res.map_err(SpiDeviceError::Spi)?; |
| 108 | flush_res.map_err(SpiDeviceError::Spi)?; | 116 | flush_res.map_err(SpiDeviceError::Spi)?; |
| 117 | cs_res.map_err(SpiDeviceError::Cs)?; | ||
| 109 | 118 | ||
| 110 | Ok(op_res) | 119 | Ok(op_res) |
| 111 | } | 120 | } |
| @@ -160,6 +169,7 @@ where | |||
| 160 | self.cs.set_low().map_err(SpiDeviceError::Cs)?; | 169 | self.cs.set_low().map_err(SpiDeviceError::Cs)?; |
| 161 | 170 | ||
| 162 | let cs_drop = OnDrop::new(|| { | 171 | let cs_drop = OnDrop::new(|| { |
| 172 | // Please see comment in SpiDevice for an explanation of this drop handler. | ||
| 163 | let _ = self.cs.set_high(); | 173 | let _ = self.cs.set_high(); |
| 164 | }); | 174 | }); |
| 165 | 175 | ||
| @@ -190,10 +200,12 @@ where | |||
| 190 | 200 | ||
| 191 | // On failure, it's important to still flush and deassert CS. | 201 | // On failure, it's important to still flush and deassert CS. |
| 192 | let flush_res = bus.flush().await; | 202 | let flush_res = bus.flush().await; |
| 193 | drop(cs_drop); | 203 | cs_drop.defuse(); |
| 204 | let cs_res = self.cs.set_high(); | ||
| 194 | 205 | ||
| 195 | let op_res = op_res.map_err(SpiDeviceError::Spi)?; | 206 | let op_res = op_res.map_err(SpiDeviceError::Spi)?; |
| 196 | flush_res.map_err(SpiDeviceError::Spi)?; | 207 | flush_res.map_err(SpiDeviceError::Spi)?; |
| 208 | cs_res.map_err(SpiDeviceError::Cs)?; | ||
| 197 | 209 | ||
| 198 | Ok(op_res) | 210 | Ok(op_res) |
| 199 | } | 211 | } |
