@@ -589,7 +589,7 @@ impl<SPI: Instance, const BIDI: bool, W> Spi<SPI, BIDI, W> {
589
589
/// Convert the spi to another mode.
590
590
fn into_mode < const BIDI2 : bool , W2 : FrameSize > ( self ) -> Spi < SPI , BIDI2 , W2 > {
591
591
let mut spi = Spi :: _new ( self . inner . spi , self . pins ) ;
592
- spi. enable ( false ) ;
592
+ spi. disable ( ) ;
593
593
spi. init ( )
594
594
}
595
595
}
@@ -606,7 +606,7 @@ impl<SPI: Instance, const BIDI: bool, W> SpiSlave<SPI, BIDI, W> {
606
606
/// Convert the spi to another mode.
607
607
fn into_mode < const BIDI2 : bool , W2 : FrameSize > ( self ) -> SpiSlave < SPI , BIDI2 , W2 > {
608
608
let mut spi = SpiSlave :: _new ( self . inner . spi , self . pins ) ;
609
- spi. enable ( false ) ;
609
+ spi. disable ( ) ;
610
610
spi. init ( )
611
611
}
612
612
}
@@ -685,12 +685,18 @@ impl<SPI: Instance> Inner<SPI> {
685
685
Self { spi }
686
686
}
687
687
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 ( ) ) ;
694
700
}
695
701
696
702
/// Select which frame format is used for data transfers
@@ -734,6 +740,19 @@ impl<SPI: Instance> Inner<SPI> {
734
740
self . spi . sr ( ) . read ( ) . ovr ( ) . bit_is_set ( )
735
741
}
736
742
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
+
737
756
#[ inline]
738
757
fn bidi_output ( & mut self ) {
739
758
self . spi . cr1 ( ) . modify ( |_, w| w. bidioe ( ) . set_bit ( ) ) ;
@@ -798,23 +817,38 @@ impl<SPI: Instance> Inner<SPI> {
798
817
} )
799
818
}
800
819
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)
801
824
fn spi_write < const BIDI : bool , W : FrameSize > (
802
825
& mut self ,
803
826
words : impl IntoIterator < Item = W > ,
804
827
) -> Result < ( ) , Error > {
805
828
if BIDI {
806
829
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
+ }
814
842
}
815
843
}
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 ( )
818
852
}
819
853
820
854
fn listen_event ( & mut self , disable : Option < BitFlags < Event > > , enable : Option < BitFlags < Event > > ) {
0 commit comments