140140//!
141141//! HALs **must not** add infrastructure for sharing at the [`SpiBus`] level. User code owning a [`SpiBus`] must have the guarantee
142142//! of exclusive access.
143+ //!
144+ //! # Flushing
145+ //!
146+ //! To improve performance, Bus implementations are allowed to return before the operation is finished, i.e. when the bus is still not
147+ //! idle. You must call [`flush`](SpiBusFlush::flush) to wait for operations to actually finish, for example before deasserting CS in a
148+ //! [`SpiDevice`] implementation, or before deinitializing the hardware SPI peripheral.
149+ //!
150+ //! For example, for [`write`](SpiBusWrite::write) operations, it is common for hardware SPI peripherals to have a small
151+ //! FIFO buffer, usually 1-4 bytes. Software writes data to the FIFO, and the peripheral sends it on MOSI at its own pace,
152+ //! at the specified SPI frequency. It is allowed for an implementation of [`write`](SpiBusWrite::write) to return as soon
153+ //! as all the data has been written to the FIFO, before it is actually sent. Calling [`flush`](SpiBusFlush::flush) would
154+ //! wait until all the bits have actually been sent, the FIFO is empty, and the bus is idle.
155+ //!
156+ //! This still applies to other operations such as [`read`](SpiBusRead::read) or [`transfer`](SpiBus::transfer). It is less obvious
157+ //! why, because these methods can't return before receiving all the read data. However it's still technically possible
158+ //! for them to return before the bus is idle. For example, assuming SPI mode 0, the last bit is sampled on the first (rising) edge
159+ //! of SCK, at which point a method could return, but the second (falling) SCK edge still has to happen before the bus is idle.
143160
144161use core:: fmt:: Debug ;
145162
@@ -162,6 +179,7 @@ pub trait SpiDevice: ErrorType {
162179 /// - Locks the bus
163180 /// - Asserts the CS (Chip Select) pin.
164181 /// - Calls `f` with an exclusive reference to the bus, which can then be used to do transfers against the device.
182+ /// - [Flushes](SpiBusFlush::flush) the bus.
165183 /// - Deasserts the CS pin.
166184 /// - Unlocks the bus.
167185 ///
@@ -184,12 +202,29 @@ impl<T: SpiDevice> SpiDevice for &mut T {
184202 }
185203}
186204
205+ /// Flush support for SPI bus
206+ pub trait SpiBusFlush : ErrorType {
207+ /// Blocks until all operations have completed and the bus is idle.
208+ ///
209+ /// See the [module-level documentation](self) for important usage information.
210+ fn flush ( & mut self ) -> Result < ( ) , Self :: Error > ;
211+ }
212+
213+ impl < T : SpiBusFlush > SpiBusFlush for & mut T {
214+ fn flush ( & mut self ) -> Result < ( ) , Self :: Error > {
215+ T :: flush ( self )
216+ }
217+ }
218+
187219/// Read-only SPI bus
188- pub trait SpiBusRead < Word : Copy = u8 > : ErrorType {
220+ pub trait SpiBusRead < Word : Copy = u8 > : SpiBusFlush {
189221 /// Reads `words` from the slave.
190222 ///
191223 /// The word value sent on MOSI during reading is implementation-defined,
192224 /// typically `0x00`, `0xFF`, or configurable.
225+ ///
226+ /// Implementations are allowed to return before the operation is
227+ /// complete. See the [module-level documentation](self) for detials.
193228 fn read ( & mut self , words : & mut [ Word ] ) -> Result < ( ) , Self :: Error > ;
194229}
195230
@@ -200,8 +235,11 @@ impl<T: SpiBusRead<Word>, Word: Copy> SpiBusRead<Word> for &mut T {
200235}
201236
202237/// Write-only SPI bus
203- pub trait SpiBusWrite < Word : Copy = u8 > : ErrorType {
238+ pub trait SpiBusWrite < Word : Copy = u8 > : SpiBusFlush {
204239 /// Writes `words` to the slave, ignoring all the incoming words
240+ ///
241+ /// Implementations are allowed to return before the operation is
242+ /// complete. See the [module-level documentation](self) for detials.
205243 fn write ( & mut self , words : & [ Word ] ) -> Result < ( ) , Self :: Error > ;
206244}
207245
@@ -225,11 +263,17 @@ pub trait SpiBus<Word: Copy = u8>: SpiBusRead<Word> + SpiBusWrite<Word> {
225263 /// incoming words after `read` has been filled will be discarded. If `write` is shorter,
226264 /// the value of words sent in MOSI after all `write` has been sent is implementation-defined,
227265 /// typically `0x00`, `0xFF`, or configurable.
266+ ///
267+ /// Implementations are allowed to return before the operation is
268+ /// complete. See the [module-level documentation](self) for detials.
228269 fn transfer ( & mut self , read : & mut [ Word ] , write : & [ Word ] ) -> Result < ( ) , Self :: Error > ;
229270
230271 /// Writes and reads simultaneously. The contents of `words` are
231272 /// written to the slave, and the received words are stored into the same
232273 /// `words` buffer, overwriting it.
274+ ///
275+ /// Implementations are allowed to return before the operation is
276+ /// complete. See the [module-level documentation](self) for detials.
233277 fn transfer_in_place ( & mut self , words : & mut [ Word ] ) -> Result < ( ) , Self :: Error > ;
234278}
235279
@@ -283,15 +327,15 @@ impl<BUS, CS> ExclusiveDevice<BUS, CS> {
283327
284328impl < BUS , CS > ErrorType for ExclusiveDevice < BUS , CS >
285329where
286- BUS : ErrorType ,
330+ BUS : SpiBusFlush ,
287331 CS : OutputPin ,
288332{
289333 type Error = ExclusiveDeviceError < BUS :: Error , CS :: Error > ;
290334}
291335
292336impl < BUS , CS > SpiDevice for ExclusiveDevice < BUS , CS >
293337where
294- BUS : ErrorType ,
338+ BUS : SpiBusFlush ,
295339 CS : OutputPin ,
296340{
297341 type Bus = BUS ;
@@ -304,10 +348,12 @@ where
304348
305349 let f_res = f ( & mut self . bus ) ;
306350
307- // If the closure fails, it's important to still deassert CS.
351+ // On failure, it's important to still flush and deassert CS.
352+ let flush_res = self . bus . flush ( ) ;
308353 let cs_res = self . cs . set_high ( ) ;
309354
310355 let f_res = f_res. map_err ( ExclusiveDeviceError :: Spi ) ?;
356+ flush_res. map_err ( ExclusiveDeviceError :: Spi ) ?;
311357 cs_res. map_err ( ExclusiveDeviceError :: Cs ) ?;
312358
313359 Ok ( f_res)
0 commit comments