@@ -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,11 +685,21 @@ 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 ) {
688
+ /// Enable SPI
689
+ pub fn enable ( & mut self ) {
690
690
self . spi . cr1 ( ) . modify ( |_, w| {
691
691
// 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 ( )
693
703
} ) ;
694
704
}
695
705
@@ -734,6 +744,19 @@ impl<SPI: Instance> Inner<SPI> {
734
744
self . spi . sr ( ) . read ( ) . ovr ( ) . bit_is_set ( )
735
745
}
736
746
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
+
737
760
#[ inline]
738
761
fn bidi_output ( & mut self ) {
739
762
self . spi . cr1 ( ) . modify ( |_, w| w. bidioe ( ) . set_bit ( ) ) ;
@@ -798,23 +821,38 @@ impl<SPI: Instance> Inner<SPI> {
798
821
} )
799
822
}
800
823
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)
801
828
fn spi_write < const BIDI : bool , W : FrameSize > (
802
829
& mut self ,
803
830
words : impl IntoIterator < Item = W > ,
804
831
) -> Result < ( ) , Error > {
805
832
if BIDI {
806
833
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
+ }
814
846
}
815
847
}
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 ( )
818
856
}
819
857
820
858
fn listen_event ( & mut self , disable : Option < BitFlags < Event > > , enable : Option < BitFlags < Event > > ) {
0 commit comments