@@ -66,7 +66,6 @@ mod hal_02;
6666mod hal_1;
6767
6868use core:: ops:: { Deref , DerefMut } ;
69- use core:: ptr;
7069
7170use crate :: pac:: { self , RCC } ;
7271
@@ -109,6 +108,36 @@ pub struct Mode {
109108 pub phase : Phase ,
110109}
111110
111+ type SpiRB = pac:: spi1:: RegisterBlock ;
112+
113+ pub trait FrameSize : Copy + Default {
114+ const DFF : bool ;
115+ #[ doc( hidden) ]
116+ fn read_data ( spi : & SpiRB ) -> Self ;
117+ #[ doc( hidden) ]
118+ fn write_data ( self , spi : & SpiRB ) ;
119+ }
120+
121+ impl FrameSize for u8 {
122+ const DFF : bool = false ;
123+ fn read_data ( spi : & SpiRB ) -> Self {
124+ spi. dr8 ( ) . read ( ) . dr ( ) . bits ( )
125+ }
126+ fn write_data ( self , spi : & SpiRB ) {
127+ spi. dr8 ( ) . write ( |w| w. dr ( ) . set ( self ) ) ;
128+ }
129+ }
130+
131+ impl FrameSize for u16 {
132+ const DFF : bool = true ;
133+ fn read_data ( spi : & SpiRB ) -> Self {
134+ spi. dr ( ) . read ( ) . dr ( ) . bits ( )
135+ }
136+ fn write_data ( self , spi : & SpiRB ) {
137+ spi. dr ( ) . write ( |w| w. dr ( ) . set ( self ) ) ;
138+ }
139+ }
140+
112141/// Interrupt event
113142pub enum Event {
114143 /// New data has been received
@@ -519,24 +548,7 @@ impl<SPI: Instance, Otype, PULL> SpiSlave<SPI, u8, Otype, PULL> {
519548 }
520549}
521550
522- pub trait SpiReadWrite < T > {
523- fn read_data_reg ( & mut self ) -> T ;
524- fn write_data_reg ( & mut self , data : T ) ;
525- fn spi_write ( & mut self , words : & [ T ] ) -> Result < ( ) , Error > ;
526- }
527-
528- impl < SPI : Instance , W : Copy > SpiReadWrite < W > for SpiInner < SPI , W > {
529- fn read_data_reg ( & mut self ) -> W {
530- // NOTE(read_volatile) read only 1 byte (the svd2rust API only allows
531- // reading a half-word)
532- unsafe { ptr:: read_volatile ( self . spi . dr ( ) . as_ptr ( ) as * const W ) }
533- }
534-
535- fn write_data_reg ( & mut self , data : W ) {
536- // NOTE(write_volatile) see note above
537- unsafe { ptr:: write_volatile ( self . spi . dr ( ) . as_ptr ( ) as * mut W , data) }
538- }
539-
551+ impl < SPI : Instance , W : FrameSize > SpiInner < SPI , W > {
540552 // Implement write as per the "Transmit only procedure" page 712
541553 // of RM0008 Rev 20. This is more than twice as fast as the
542554 // default Write<> implementation (which reads and drops each
@@ -547,7 +559,7 @@ impl<SPI: Instance, W: Copy> SpiReadWrite<W> for SpiInner<SPI, W> {
547559 loop {
548560 let sr = self . spi . sr ( ) . read ( ) ;
549561 if sr. txe ( ) . bit_is_set ( ) {
550- self . write_data_reg ( * word) ;
562+ ( * word) . write_data ( & self . spi ) ;
551563 if sr. modf ( ) . bit_is_set ( ) {
552564 return Err ( Error :: ModeFault ) ;
553565 }
@@ -560,13 +572,13 @@ impl<SPI: Instance, W: Copy> SpiReadWrite<W> for SpiInner<SPI, W> {
560572 // Wait for final !BSY
561573 while self . is_busy ( ) { }
562574 // Clear OVR set due to dropped received values
563- let _ = self . read_data_reg ( ) ;
575+ let _ = W :: read_data ( & self . spi ) ;
564576 let _ = self . spi . sr ( ) . read ( ) ;
565577 Ok ( ( ) )
566578 }
567579}
568580
569- impl < SPI : Instance , W : Copy > SpiInner < SPI , W > {
581+ impl < SPI : Instance , W > SpiInner < SPI , W > {
570582 /// Select which frame format is used for data transfers
571583 pub fn bit_format ( & mut self , format : SpiBitFormat ) {
572584 self . spi
@@ -676,9 +688,9 @@ impl<SPI: Instance, Otype, PULL> SpiSlave<SPI, u16, Otype, PULL> {
676688impl < SPI , W > SpiInner < SPI , W >
677689where
678690 SPI : Instance ,
679- W : Copy ,
691+ W : FrameSize ,
680692{
681- pub fn read_nonblocking ( & mut self ) -> nb:: Result < W , Error > {
693+ pub ( crate ) fn check_read ( & mut self ) -> nb:: Result < W , Error > {
682694 let sr = self . spi . sr ( ) . read ( ) ;
683695
684696 Err ( if sr. ovr ( ) . bit_is_set ( ) {
@@ -690,12 +702,13 @@ where
690702 } else if sr. rxne ( ) . bit_is_set ( ) {
691703 // NOTE(read_volatile) read only 1 byte (the svd2rust API only allows
692704 // reading a half-word)
693- return Ok ( self . read_data_reg ( ) ) ;
705+ return Ok ( W :: read_data ( & self . spi ) ) ;
694706 } else {
695707 nb:: Error :: WouldBlock
696708 } )
697709 }
698- pub fn write_nonblocking ( & mut self , data : W ) -> nb:: Result < ( ) , Error > {
710+
711+ pub ( crate ) fn check_send ( & mut self , data : W ) -> nb:: Result < ( ) , Error > {
699712 let sr = self . spi . sr ( ) . read ( ) ;
700713
701714 // NOTE: Error::Overrun was deleted in #408. Need check
@@ -705,15 +718,83 @@ where
705718 Error :: Crc . into ( )
706719 } else if sr. txe ( ) . bit_is_set ( ) {
707720 // NOTE(write_volatile) see note above
708- self . write_data_reg ( data ) ;
721+ data . write_data ( & self . spi ) ;
709722 return Ok ( ( ) ) ;
710723 } else {
711724 nb:: Error :: WouldBlock
712725 } )
713726 }
727+
728+ #[ inline( always) ]
729+ pub fn read_nonblocking ( & mut self ) -> nb:: Result < W , Error > {
730+ // TODO: bidimode
731+ self . check_read ( )
732+ }
733+
734+ #[ inline( always) ]
735+ pub fn write_nonblocking ( & mut self , data : W ) -> nb:: Result < ( ) , Error > {
736+ // TODO: bidimode
737+ self . check_send ( data)
738+ }
739+
740+ #[ inline( always) ]
714741 pub fn write ( & mut self , words : & [ W ] ) -> Result < ( ) , Error > {
715742 self . spi_write ( words)
716743 }
744+
745+ pub fn transfer_in_place ( & mut self , words : & mut [ W ] ) -> Result < ( ) , Error > {
746+ for word in words {
747+ nb:: block!( self . write_nonblocking( * word) ) ?;
748+ * word = nb:: block!( self . read_nonblocking( ) ) ?;
749+ }
750+
751+ Ok ( ( ) )
752+ }
753+
754+ pub fn transfer ( & mut self , buff : & mut [ W ] , data : & [ W ] ) -> Result < ( ) , Error > {
755+ if data. len ( ) == buff. len ( ) {
756+ for ( d, b) in data. iter ( ) . cloned ( ) . zip ( buff. iter_mut ( ) ) {
757+ nb:: block!( self . write_nonblocking( d) ) ?;
758+ * b = nb:: block!( self . read_nonblocking( ) ) ?;
759+ }
760+ } else {
761+ let mut iter_r = buff. iter_mut ( ) ;
762+ let mut iter_w = data. iter ( ) . cloned ( ) ;
763+ loop {
764+ match ( iter_r. next ( ) , iter_w. next ( ) ) {
765+ ( Some ( r) , Some ( w) ) => {
766+ nb:: block!( self . write_nonblocking( w) ) ?;
767+ * r = nb:: block!( self . read_nonblocking( ) ) ?;
768+ }
769+ ( Some ( r) , None ) => {
770+ nb:: block!( self . write_nonblocking( W :: default ( ) ) ) ?;
771+ * r = nb:: block!( self . read_nonblocking( ) ) ?;
772+ }
773+ ( None , Some ( w) ) => {
774+ nb:: block!( self . write_nonblocking( w) ) ?;
775+ let _ = nb:: block!( self . read_nonblocking( ) ) ?;
776+ }
777+ ( None , None ) => break ,
778+ }
779+ }
780+ }
781+
782+ Ok ( ( ) )
783+ }
784+
785+ pub fn flush ( & mut self ) -> Result < ( ) , Error > {
786+ Ok ( ( ) )
787+ }
788+
789+ pub fn read ( & mut self , words : & mut [ W ] ) -> Result < ( ) , Error > {
790+ // TODO: bidimode
791+ for word in words {
792+ nb:: block!( self . check_send( W :: default ( ) ) ) ?;
793+ * word = nb:: block!( self . check_read( ) ) ?;
794+ }
795+
796+ Ok ( ( ) )
797+ }
717798}
718799
719800// DMA
0 commit comments