@@ -605,6 +605,19 @@ impl<SPI: Instance, PINS, const BIDI: bool, W, OPERATION> Spi<SPI, PINS, BIDI, W
605
605
pub fn is_overrun ( & self ) -> bool {
606
606
self . spi . sr . read ( ) . ovr ( ) . bit_is_set ( )
607
607
}
608
+
609
+ fn check_errors ( & self ) -> Result < ( ) , Error > {
610
+ let sr = self . spi . sr . read ( ) ;
611
+ if sr. ovr ( ) . bit_is_set ( ) {
612
+ Err ( Error :: Overrun )
613
+ } else if sr. modf ( ) . bit_is_set ( ) {
614
+ Err ( Error :: ModeFault )
615
+ } else if sr. crcerr ( ) . bit_is_set ( ) {
616
+ Err ( Error :: Crc )
617
+ } else {
618
+ Ok ( ( ) )
619
+ }
620
+ }
608
621
}
609
622
610
623
trait ReadWriteReg < W > {
@@ -676,6 +689,42 @@ impl<SPI: Instance, PINS, const BIDI: bool, W: FrameSize, OPERATION>
676
689
nb:: Error :: WouldBlock
677
690
} )
678
691
}
692
+
693
+ // Implement write as per the "Transmit only procedure"
694
+ // RM SPI::3.5. This is more than twice as fast as the
695
+ // default Write<> implementation (which reads and drops each
696
+ // received value)
697
+ fn spi_write < WI > ( & mut self , words : WI ) -> Result < ( ) , Error >
698
+ where
699
+ WI : IntoIterator < Item = W > ,
700
+ {
701
+ if BIDI {
702
+ self . spi . cr1 . modify ( |_, w| w. bidioe ( ) . set_bit ( ) ) ;
703
+ }
704
+ // Write each word when the tx buffer is empty
705
+ for word in words {
706
+ loop {
707
+ let sr = self . spi . sr . read ( ) ;
708
+ if sr. txe ( ) . bit_is_set ( ) {
709
+ self . write_data_reg ( word) ;
710
+ if sr. modf ( ) . bit_is_set ( ) {
711
+ return Err ( Error :: ModeFault ) ;
712
+ }
713
+ break ;
714
+ }
715
+ }
716
+ }
717
+ // Wait for final TXE
718
+ while !self . is_tx_empty ( ) { }
719
+ // Wait for final !BSY
720
+ while self . is_busy ( ) { }
721
+ if !BIDI {
722
+ // Clear OVR set due to dropped received values
723
+ let _ = self . read_data_reg ( ) ;
724
+ }
725
+ let _ = self . spi . sr . read ( ) ;
726
+ self . check_errors ( )
727
+ }
679
728
}
680
729
681
730
// Spi DMA
0 commit comments