@@ -607,7 +607,7 @@ impl<SPI: Instance, const BIDI: bool, W> Spi<SPI, BIDI, W> {
607
607
/// Convert the spi to another mode.
608
608
fn into_mode < const BIDI2 : bool , W2 : FrameSize > ( self ) -> Spi < SPI , BIDI2 , W2 > {
609
609
let mut spi = Spi :: _new ( self . inner . spi , self . pins ) ;
610
- spi. enable ( false ) ;
610
+ spi. disable ( ) ;
611
611
spi. init ( )
612
612
}
613
613
}
@@ -624,7 +624,7 @@ impl<SPI: Instance, const BIDI: bool, W> SpiSlave<SPI, BIDI, W> {
624
624
/// Convert the spi to another mode.
625
625
fn into_mode < const BIDI2 : bool , W2 : FrameSize > ( self ) -> SpiSlave < SPI , BIDI2 , W2 > {
626
626
let mut spi = SpiSlave :: _new ( self . inner . spi , self . pins ) ;
627
- spi. enable ( false ) ;
627
+ spi. disable ( ) ;
628
628
spi. init ( )
629
629
}
630
630
}
@@ -703,12 +703,18 @@ impl<SPI: Instance> Inner<SPI> {
703
703
Self { spi }
704
704
}
705
705
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 ( ) ) ;
712
718
}
713
719
714
720
/// Select which frame format is used for data transfers
@@ -752,6 +758,19 @@ impl<SPI: Instance> Inner<SPI> {
752
758
self . spi . sr ( ) . read ( ) . ovr ( ) . bit_is_set ( )
753
759
}
754
760
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
+
755
774
#[ inline]
756
775
fn bidi_output ( & mut self ) {
757
776
self . spi . cr1 ( ) . modify ( |_, w| w. bidioe ( ) . set_bit ( ) ) ;
@@ -811,23 +830,38 @@ impl<SPI: Instance> Inner<SPI> {
811
830
} )
812
831
}
813
832
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)
814
837
fn spi_write < const BIDI : bool , W : FrameSize > (
815
838
& mut self ,
816
839
words : impl IntoIterator < Item = W > ,
817
840
) -> Result < ( ) , Error > {
818
841
if BIDI {
819
842
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
+ }
827
855
}
828
856
}
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 ( )
831
865
}
832
866
833
867
fn listen_event ( & mut self , disable : Option < BitFlags < Event > > , enable : Option < BitFlags < Event > > ) {
0 commit comments