@@ -352,6 +352,77 @@ 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+ use crate :: core:: plic:: Priority :: P0 ;
364+
365+ impl < SPI : SpiX , PINS > AsyncTransfer for Spi < SPI , PINS > {
366+ type Error = Infallible ;
367+ type TransferFuture < ' t > = AsyncTransferFuture < ' t > ;
368+
369+ fn async_transfer < ' a > ( & ' a mut self , data : & ' a mut [ u8 ] ) -> Self :: TransferFuture < ' a > {
370+ // Ensure that RX FIFO is empty
371+ while self . spi . rxdata . read ( ) . empty ( ) . bit_is_clear ( ) { }
372+ self . cs_mode_frame ( ) ;
373+
374+ AsyncTransferFuture {
375+ spi : & self . spi ,
376+ data,
377+ iwrite : 0 ,
378+ iread : 0 ,
379+ }
380+ }
381+ }
382+
383+ pub struct AsyncTransferFuture < ' a > {
384+ spi : & ' a RegisterBlock ,
385+ data : & ' a mut [ u8 ] ,
386+ iwrite : usize ,
387+ iread : usize ,
388+ }
389+
390+ impl < ' a > Future for AsyncTransferFuture < ' a > {
391+ type Output = Result < ( ) , Infallible > ;
392+
393+ fn poll ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self :: Output > {
394+ let data_len = self . data . len ( ) ;
395+
396+ while self . iwrite < data_len || self . iread < data_len {
397+ if self . iwrite < data_len && self . spi . txdata . read ( ) . full ( ) . bit_is_clear ( ) {
398+ let iwrite = self . iwrite ;
399+ let byte = unsafe { * self . data . get_unchecked ( iwrite) } ;
400+ self . iwrite = iwrite + 1 ;
401+ self . spi . txdata . write ( |w| unsafe { w. data ( ) . bits ( byte) } ) ;
402+ }
403+
404+ if self . iread < self . iwrite {
405+ let data = self . spi . rxdata . read ( ) ;
406+ if data. empty ( ) . bit_is_clear ( ) {
407+ let iread = self . iread ;
408+ unsafe { * self . data . get_unchecked_mut ( iread) = data. data ( ) . bits ( ) } ;
409+ self . iread = iread + 1 ;
410+ } else {
411+ cx. waker ( ) . wake_by_ref ( ) ;
412+ return Poll :: Pending ;
413+ }
414+ }
415+ }
416+
417+ // self.cs_mode_word();
418+ if self . spi . csmode . read ( ) . bits ( ) != 3 {
419+ self . spi . csmode . write ( |w| unsafe { w. bits ( 0 ) } ) ;
420+ }
421+
422+ Poll :: Ready ( Ok ( ( ) ) )
423+ }
424+ }
425+ }
355426
356427// Backward compatibility
357428impl < PINS > Spi < QSPI0 , PINS > {
0 commit comments