@@ -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,11 +685,21 @@ impl<SPI: Instance> Inner<SPI> {
685685 Self { spi }
686686 }
687687
688- /// Enable/disable spi
689- pub fn enable ( & mut self , enable : bool ) {
688+ /// Enable SPI
689+ pub fn enable ( & mut self ) {
690690 self . spi . cr1 ( ) . modify ( |_, w| {
691691 // spe: enable the SPI bus
692- w. spe ( ) . bit ( enable)
692+ w. spe ( ) . set_bit ( )
693+ } ) ;
694+ }
695+
696+ /// Disable SPI
697+ pub fn disable ( & mut self ) {
698+ // Wait for !BSY
699+ while self . is_busy ( ) { }
700+ self . spi . cr1 ( ) . modify ( |_, w| {
701+ // spe: enable the SPI bus
702+ w. spe ( ) . clear_bit ( )
693703 } ) ;
694704 }
695705
@@ -734,6 +744,19 @@ impl<SPI: Instance> Inner<SPI> {
734744 self . spi . sr ( ) . read ( ) . ovr ( ) . bit_is_set ( )
735745 }
736746
747+ fn check_errors ( & self ) -> Result < ( ) , Error > {
748+ let sr = self . spi . sr ( ) . read ( ) ;
749+ if sr. ovr ( ) . bit_is_set ( ) {
750+ Err ( Error :: Overrun )
751+ } else if sr. modf ( ) . bit_is_set ( ) {
752+ Err ( Error :: ModeFault )
753+ } else if sr. crcerr ( ) . bit_is_set ( ) {
754+ Err ( Error :: Crc )
755+ } else {
756+ Ok ( ( ) )
757+ }
758+ }
759+
737760 #[ inline]
738761 fn bidi_output ( & mut self ) {
739762 self . spi . cr1 ( ) . modify ( |_, w| w. bidioe ( ) . set_bit ( ) ) ;
@@ -798,23 +821,38 @@ impl<SPI: Instance> Inner<SPI> {
798821 } )
799822 }
800823
824+ // Implement write as per the "Transmit only procedure"
825+ // RM SPI::3.5. This is more than twice as fast as the
826+ // default Write<> implementation (which reads and drops each
827+ // received value)
801828 fn spi_write < const BIDI : bool , W : FrameSize > (
802829 & mut self ,
803830 words : impl IntoIterator < Item = W > ,
804831 ) -> Result < ( ) , Error > {
805832 if BIDI {
806833 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 >( ) ) ?;
834+ }
835+ // Write each word when the tx buffer is empty
836+ for word in words {
837+ loop {
838+ let sr = self . spi . sr ( ) . read ( ) ;
839+ if sr. txe ( ) . bit_is_set ( ) {
840+ self . write_data_reg ( word) ;
841+ if sr. modf ( ) . bit_is_set ( ) {
842+ return Err ( Error :: ModeFault ) ;
843+ }
844+ break ;
845+ }
814846 }
815847 }
816-
817- Ok ( ( ) )
848+ // Wait for final TXE
849+ while !self . is_tx_empty ( ) { }
850+ if !BIDI {
851+ // Clear OVR set due to dropped received values
852+ let _: W = self . read_data_reg ( ) ;
853+ }
854+ let _ = self . spi . sr ( ) . read ( ) ;
855+ self . check_errors ( )
818856 }
819857
820858 fn listen_event ( & mut self , disable : Option < BitFlags < Event > > , enable : Option < BitFlags < Event > > ) {
0 commit comments