@@ -605,6 +605,19 @@ impl<SPI: Instance, PINS, const BIDI: bool, W, OPERATION> Spi<SPI, PINS, BIDI, W
605605 pub fn is_overrun ( & self ) -> bool {
606606 self . spi . sr . read ( ) . ovr ( ) . bit_is_set ( )
607607 }
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+ }
608621}
609622
610623trait ReadWriteReg < W > {
@@ -676,6 +689,42 @@ impl<SPI: Instance, PINS, const BIDI: bool, W: FrameSize, OPERATION>
676689 nb:: Error :: WouldBlock
677690 } )
678691 }
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+ }
679728}
680729
681730// Spi DMA
0 commit comments