@@ -352,6 +352,76 @@ impl<SPI: SpiX, PINS> embedded_hal::blocking::spi::WriteIter<u8> for Spi<SPI, PI
352352 }
353353}
354354
355+ #[ cfg( feature = "async-traits" ) ]
356+ mod async_impls {
357+ use core:: convert:: Infallible ;
358+ use core:: future:: Future ;
359+ use core:: pin:: Pin ;
360+ use core:: task:: { Context , Poll } ;
361+ use async_embedded_traits:: spi:: AsyncTransfer ;
362+ use super :: { Spi , SpiX , qspi0:: RegisterBlock } ;
363+
364+ impl < SPI : SpiX , PINS > AsyncTransfer for Spi < SPI , PINS > {
365+ type Error = Infallible ;
366+ type TransferFuture < ' t > = AsyncTransferFuture < ' t > ;
367+
368+ fn async_transfer < ' a > ( & ' a mut self , data : & ' a mut [ u8 ] ) -> Self :: TransferFuture < ' a > {
369+ // Ensure that RX FIFO is empty
370+ while self . spi . rxdata . read ( ) . empty ( ) . bit_is_clear ( ) { }
371+ self . cs_mode_frame ( ) ;
372+
373+ AsyncTransferFuture {
374+ spi : & self . spi ,
375+ data,
376+ iwrite : 0 ,
377+ iread : 0 ,
378+ }
379+ }
380+ }
381+
382+ pub struct AsyncTransferFuture < ' a > {
383+ spi : & ' a RegisterBlock ,
384+ data : & ' a mut [ u8 ] ,
385+ iwrite : usize ,
386+ iread : usize ,
387+ }
388+
389+ impl < ' a > Future for AsyncTransferFuture < ' a > {
390+ type Output = Result < ( ) , Infallible > ;
391+
392+ fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
393+ let data_len = self . data . len ( ) ;
394+
395+ while self . iwrite < data_len || self . iread < data_len {
396+ if self . iwrite < data_len && self . spi . txdata . read ( ) . full ( ) . bit_is_clear ( ) {
397+ let iwrite = self . iwrite ;
398+ let byte = unsafe { * self . data . get_unchecked ( iwrite) } ;
399+ self . iwrite = iwrite + 1 ;
400+ self . spi . txdata . write ( |w| unsafe { w. data ( ) . bits ( byte) } ) ;
401+ }
402+
403+ if self . iread < self . iwrite {
404+ let data = self . spi . rxdata . read ( ) ;
405+ if data. empty ( ) . bit_is_clear ( ) {
406+ let iread = self . iread ;
407+ unsafe { * self . data . get_unchecked_mut ( iread) = data. data ( ) . bits ( ) } ;
408+ self . iread = iread + 1 ;
409+ } else {
410+ cx. waker ( ) . wake_by_ref ( ) ;
411+ return Poll :: Pending ;
412+ }
413+ }
414+ }
415+
416+ // self.cs_mode_word();
417+ if self . spi . csmode . read ( ) . bits ( ) != 3 {
418+ self . spi . csmode . write ( |w| unsafe { w. bits ( 0 ) } ) ;
419+ }
420+
421+ Poll :: Ready ( Ok ( ( ) ) )
422+ }
423+ }
424+ }
355425
356426// Backward compatibility
357427impl < PINS > Spi < QSPI0 , PINS > {
0 commit comments