@@ -589,7 +589,7 @@ impl<SPI: Instance, const BIDI: bool, W> Spi<SPI, BIDI, W> {
589589 /// Convert the spi to another mode.
590590 fn into_mode < const BIDI2 : bool , W2 : FrameSize > ( self ) -> Spi < SPI , BIDI2 , W2 > {
591591 let mut spi = Spi :: _new ( self . inner . spi , self . pins ) ;
592- spi. enable ( false ) ;
592+ spi. disable ( ) ;
593593 spi. init ( )
594594 }
595595}
@@ -606,7 +606,7 @@ impl<SPI: Instance, const BIDI: bool, W> SpiSlave<SPI, BIDI, W> {
606606 /// Convert the spi to another mode.
607607 fn into_mode < const BIDI2 : bool , W2 : FrameSize > ( self ) -> SpiSlave < SPI , BIDI2 , W2 > {
608608 let mut spi = SpiSlave :: _new ( self . inner . spi , self . pins ) ;
609- spi. enable ( false ) ;
609+ spi. disable ( ) ;
610610 spi. init ( )
611611 }
612612}
@@ -685,12 +685,18 @@ impl<SPI: Instance> Inner<SPI> {
685685 Self { spi }
686686 }
687687
688- /// Enable/disable spi
689- pub fn enable ( & mut self , enable : bool ) {
690- self . spi . cr1 ( ) . modify ( |_, w| {
691- // spe: enable the SPI bus
692- w. spe ( ) . bit ( enable)
693- } ) ;
688+ /// Enable SPI
689+ pub fn enable ( & mut self ) {
690+ // spe: enable the SPI bus
691+ self . spi . cr1 ( ) . modify ( |_, w| w. spe ( ) . set_bit ( ) ) ;
692+ }
693+
694+ /// Disable SPI
695+ pub fn disable ( & mut self ) {
696+ // Wait for !BSY
697+ while self . is_busy ( ) { }
698+ // spe: disable the SPI bus
699+ self . spi . cr1 ( ) . modify ( |_, w| w. spe ( ) . clear_bit ( ) ) ;
694700 }
695701
696702 /// Select which frame format is used for data transfers
@@ -734,6 +740,19 @@ impl<SPI: Instance> Inner<SPI> {
734740 self . spi . sr ( ) . read ( ) . ovr ( ) . bit_is_set ( )
735741 }
736742
743+ fn check_errors ( & self ) -> Result < ( ) , Error > {
744+ let sr = self . spi . sr ( ) . read ( ) ;
745+ if sr. ovr ( ) . bit_is_set ( ) {
746+ Err ( Error :: Overrun )
747+ } else if sr. modf ( ) . bit_is_set ( ) {
748+ Err ( Error :: ModeFault )
749+ } else if sr. crcerr ( ) . bit_is_set ( ) {
750+ Err ( Error :: Crc )
751+ } else {
752+ Ok ( ( ) )
753+ }
754+ }
755+
737756 #[ inline]
738757 fn bidi_output ( & mut self ) {
739758 self . spi . cr1 ( ) . modify ( |_, w| w. bidioe ( ) . set_bit ( ) ) ;
@@ -798,23 +817,38 @@ impl<SPI: Instance> Inner<SPI> {
798817 } )
799818 }
800819
820+ // Implement write as per the "Transmit only procedure"
821+ // RM SPI::3.5. This is more than twice as fast as the
822+ // default Write<> implementation (which reads and drops each
823+ // received value)
801824 fn spi_write < const BIDI : bool , W : FrameSize > (
802825 & mut self ,
803826 words : impl IntoIterator < Item = W > ,
804827 ) -> Result < ( ) , Error > {
805828 if BIDI {
806829 self . bidi_output ( ) ;
807- for word in words. into_iter ( ) {
808- nb:: block!( self . check_send( word) ) ?;
809- }
810- } else {
811- for word in words. into_iter ( ) {
812- nb:: block!( self . check_send( word) ) ?;
813- nb:: block!( self . check_read:: <W >( ) ) ?;
830+ }
831+ // Write each word when the tx buffer is empty
832+ for word in words {
833+ loop {
834+ let sr = self . spi . sr ( ) . read ( ) ;
835+ if sr. txe ( ) . bit_is_set ( ) {
836+ self . write_data_reg ( word) ;
837+ if sr. modf ( ) . bit_is_set ( ) {
838+ return Err ( Error :: ModeFault ) ;
839+ }
840+ break ;
841+ }
814842 }
815843 }
816-
817- Ok ( ( ) )
844+ // Wait for final TXE
845+ while !self . is_tx_empty ( ) { }
846+ if !BIDI {
847+ // Clear OVR set due to dropped received values
848+ let _: W = self . read_data_reg ( ) ;
849+ }
850+ let _ = self . spi . sr ( ) . read ( ) ;
851+ self . check_errors ( )
818852 }
819853
820854 fn listen_event ( & mut self , disable : Option < BitFlags < Event > > , enable : Option < BitFlags < Event > > ) {
0 commit comments