@@ -607,7 +607,7 @@ impl<SPI: Instance, const BIDI: bool, W> Spi<SPI, BIDI, W> {
607607 /// Convert the spi to another mode.
608608 fn into_mode < const BIDI2 : bool , W2 : FrameSize > ( self ) -> Spi < SPI , BIDI2 , W2 > {
609609 let mut spi = Spi :: _new ( self . inner . spi , self . pins ) ;
610- spi. enable ( false ) ;
610+ spi. disable ( ) ;
611611 spi. init ( )
612612 }
613613}
@@ -624,7 +624,7 @@ impl<SPI: Instance, const BIDI: bool, W> SpiSlave<SPI, BIDI, W> {
624624 /// Convert the spi to another mode.
625625 fn into_mode < const BIDI2 : bool , W2 : FrameSize > ( self ) -> SpiSlave < SPI , BIDI2 , W2 > {
626626 let mut spi = SpiSlave :: _new ( self . inner . spi , self . pins ) ;
627- spi. enable ( false ) ;
627+ spi. disable ( ) ;
628628 spi. init ( )
629629 }
630630}
@@ -703,12 +703,18 @@ impl<SPI: Instance> Inner<SPI> {
703703 Self { spi }
704704 }
705705
706- /// Enable/disable spi
707- pub fn enable ( & mut self , enable : bool ) {
708- self . spi . cr1 ( ) . modify ( |_, w| {
709- // spe: enable the SPI bus
710- w. spe ( ) . bit ( enable)
711- } ) ;
706+ /// Enable SPI
707+ pub fn enable ( & mut self ) {
708+ // spe: enable the SPI bus
709+ self . spi . cr1 ( ) . modify ( |_, w| w. spe ( ) . set_bit ( ) ) ;
710+ }
711+
712+ /// Disable SPI
713+ pub fn disable ( & mut self ) {
714+ // Wait for !BSY
715+ while self . is_busy ( ) { }
716+ // spe: disable the SPI bus
717+ self . spi . cr1 ( ) . modify ( |_, w| w. spe ( ) . clear_bit ( ) ) ;
712718 }
713719
714720 /// Select which frame format is used for data transfers
@@ -752,6 +758,19 @@ impl<SPI: Instance> Inner<SPI> {
752758 self . spi . sr ( ) . read ( ) . ovr ( ) . bit_is_set ( )
753759 }
754760
761+ fn check_errors ( & self ) -> Result < ( ) , Error > {
762+ let sr = self . spi . sr ( ) . read ( ) ;
763+ if sr. ovr ( ) . bit_is_set ( ) {
764+ Err ( Error :: Overrun )
765+ } else if sr. modf ( ) . bit_is_set ( ) {
766+ Err ( Error :: ModeFault )
767+ } else if sr. crcerr ( ) . bit_is_set ( ) {
768+ Err ( Error :: Crc )
769+ } else {
770+ Ok ( ( ) )
771+ }
772+ }
773+
755774 #[ inline]
756775 fn bidi_output ( & mut self ) {
757776 self . spi . cr1 ( ) . modify ( |_, w| w. bidioe ( ) . set_bit ( ) ) ;
@@ -811,23 +830,38 @@ impl<SPI: Instance> Inner<SPI> {
811830 } )
812831 }
813832
833+ // Implement write as per the "Transmit only procedure"
834+ // RM SPI::3.5. This is more than twice as fast as the
835+ // default Write<> implementation (which reads and drops each
836+ // received value)
814837 fn spi_write < const BIDI : bool , W : FrameSize > (
815838 & mut self ,
816839 words : impl IntoIterator < Item = W > ,
817840 ) -> Result < ( ) , Error > {
818841 if BIDI {
819842 self . bidi_output ( ) ;
820- for word in words. into_iter ( ) {
821- nb:: block!( self . check_send( word) ) ?;
822- }
823- } else {
824- for word in words. into_iter ( ) {
825- nb:: block!( self . check_send( word) ) ?;
826- nb:: block!( self . check_read:: <W >( ) ) ?;
843+ }
844+ // Write each word when the tx buffer is empty
845+ for word in words {
846+ loop {
847+ let sr = self . spi . sr ( ) . read ( ) ;
848+ if sr. txe ( ) . bit_is_set ( ) {
849+ self . write_data_reg ( word) ;
850+ if sr. modf ( ) . bit_is_set ( ) {
851+ return Err ( Error :: ModeFault ) ;
852+ }
853+ break ;
854+ }
827855 }
828856 }
829-
830- Ok ( ( ) )
857+ // Wait for final TXE
858+ while !self . is_tx_empty ( ) { }
859+ if !BIDI {
860+ // Clear OVR set due to dropped received values
861+ let _: W = self . read_data_reg ( ) ;
862+ }
863+ let _ = self . spi . sr ( ) . read ( ) ;
864+ self . check_errors ( )
831865 }
832866
833867 fn listen_event ( & mut self , disable : Option < BitFlags < Event > > , enable : Option < BitFlags < Event > > ) {
0 commit comments