@@ -207,15 +207,13 @@ pub trait SpiExt: Sized + Instance {
207207
208208 fn spi_bidi (
209209 self ,
210- pins : (
211- impl Into < Self :: Sck > ,
212- impl Into < Self :: Miso > ,
213- impl Into < Self :: Mosi > ,
214- ) ,
210+ pins : ( impl Into < Self :: Sck > , impl Into < Self :: Mosi > ) ,
215211 mode : impl Into < Mode > ,
216212 freq : Hertz ,
217213 clocks : & Clocks ,
218- ) -> Spi < Self , true , u8 > ;
214+ ) -> Spi < Self , true , u8 >
215+ where
216+ NoPin : Into < Self :: Miso > ;
219217
220218 fn spi_slave (
221219 self ,
@@ -233,11 +231,12 @@ pub trait SpiExt: Sized + Instance {
233231 pins : (
234232 impl Into < Self :: Sck > ,
235233 impl Into < Self :: Miso > ,
236- impl Into < Self :: Mosi > ,
237234 Option < Self :: Nss > ,
238235 ) ,
239236 mode : impl Into < Mode > ,
240- ) -> SpiSlave < Self , true , u8 > ;
237+ ) -> SpiSlave < Self , true , u8 >
238+ where
239+ NoPin : Into < Self :: Mosi > ;
241240}
242241
243242impl < SPI : Instance > SpiExt for SPI {
@@ -266,15 +265,14 @@ impl<SPI: Instance> SpiExt for SPI {
266265 /// Otherwise it may lead to the 'wrong last bit in every received byte' problem.
267266 fn spi_bidi (
268267 self ,
269- pins : (
270- impl Into < Self :: Sck > ,
271- impl Into < Self :: Miso > ,
272- impl Into < Self :: Mosi > ,
273- ) ,
268+ pins : ( impl Into < Self :: Sck > , impl Into < Self :: Mosi > ) ,
274269 mode : impl Into < Mode > ,
275270 freq : Hertz ,
276271 clocks : & Clocks ,
277- ) -> Spi < Self , true , u8 > {
272+ ) -> Spi < Self , true , u8 >
273+ where
274+ NoPin : Into < Self :: Miso > ,
275+ {
278276 Spi :: new_bidi ( self , pins, mode, freq, clocks)
279277 }
280278 /// Enables the SPI clock, resets the peripheral, sets `Alternate` mode for `pins` and initialize the peripheral as SPI Slave Normal mode.
@@ -304,11 +302,13 @@ impl<SPI: Instance> SpiExt for SPI {
304302 pins : (
305303 impl Into < Self :: Sck > ,
306304 impl Into < Self :: Miso > ,
307- impl Into < Self :: Mosi > ,
308305 Option < Self :: Nss > ,
309306 ) ,
310307 mode : impl Into < Mode > ,
311- ) -> SpiSlave < Self , true , u8 > {
308+ ) -> SpiSlave < Self , true , u8 >
309+ where
310+ NoPin : Into < Self :: Mosi > ,
311+ {
312312 SpiSlave :: new_bidi ( self , pins, mode)
313313 }
314314}
@@ -447,21 +447,20 @@ impl<SPI: Instance> Spi<SPI, true, u8> {
447447 /// Otherwise it may lead to the 'wrong last bit in every received byte' problem.
448448 pub fn new_bidi (
449449 spi : SPI ,
450- pins : (
451- impl Into < SPI :: Sck > ,
452- impl Into < SPI :: Miso > ,
453- impl Into < SPI :: Mosi > ,
454- ) ,
450+ pins : ( impl Into < SPI :: Sck > , impl Into < SPI :: Mosi > ) ,
455451 mode : impl Into < Mode > ,
456452 freq : Hertz ,
457453 clocks : & Clocks ,
458- ) -> Self {
454+ ) -> Self
455+ where
456+ NoPin : Into < SPI :: Miso > ,
457+ {
459458 unsafe {
460459 SPI :: enable_unchecked ( ) ;
461460 SPI :: reset_unchecked ( ) ;
462461 }
463462
464- let pins = ( pins. 0 . into ( ) , pins . 1 . into ( ) , pins. 2 . into ( ) ) ;
463+ let pins = ( pins. 0 . into ( ) , NoPin :: new ( ) . into ( ) , pins. 1 . into ( ) ) ;
465464
466465 Self :: _new ( spi, pins)
467466 . pre_init ( mode. into ( ) , freq, SPI :: clock ( clocks) )
@@ -504,20 +503,18 @@ impl<SPI: Instance> SpiSlave<SPI, true, u8> {
504503 /// Otherwise it may lead to the 'wrong last bit in every received byte' problem.
505504 pub fn new_bidi (
506505 spi : SPI ,
507- pins : (
508- impl Into < SPI :: Sck > ,
509- impl Into < SPI :: Miso > ,
510- impl Into < SPI :: Mosi > ,
511- Option < SPI :: Nss > ,
512- ) ,
506+ pins : ( impl Into < SPI :: Sck > , impl Into < SPI :: Miso > , Option < SPI :: Nss > ) ,
513507 mode : impl Into < Mode > ,
514- ) -> Self {
508+ ) -> Self
509+ where
510+ NoPin : Into < SPI :: Mosi > ,
511+ {
515512 unsafe {
516513 SPI :: enable_unchecked ( ) ;
517514 SPI :: reset_unchecked ( ) ;
518515 }
519516
520- let pins = ( pins. 0 . into ( ) , pins. 1 . into ( ) , pins . 2 . into ( ) , pins. 3 ) ;
517+ let pins = ( pins. 0 . into ( ) , pins. 1 . into ( ) , NoPin :: new ( ) . into ( ) , pins. 2 ) ;
521518
522519 Self :: _new ( spi, pins) . pre_init ( mode. into ( ) ) . init ( )
523520 }
@@ -729,6 +726,16 @@ impl<SPI: Instance> Inner<SPI> {
729726 self . spi . sr . read ( ) . ovr ( ) . bit_is_set ( )
730727 }
731728
729+ #[ inline]
730+ fn bidi_output ( & mut self ) {
731+ self . spi . cr1 . modify ( |_, w| w. bidioe ( ) . set_bit ( ) ) ;
732+ }
733+
734+ #[ inline]
735+ fn bidi_input ( & mut self ) {
736+ self . spi . cr1 . modify ( |_, w| w. bidioe ( ) . set_bit ( ) ) ;
737+ }
738+
732739 fn read_data_reg < W : FrameSize > ( & mut self ) -> W {
733740 // NOTE(read_volatile) read only 1 byte (the svd2rust API only allows
734741 // reading a half-word)
@@ -863,14 +870,14 @@ unsafe impl<SPI, STREAM, const CHANNEL: u8> DMASet<STREAM, CHANNEL, MemoryToPeri
863870impl < SPI : Instance , const BIDI : bool , W : FrameSize > Spi < SPI , BIDI , W > {
864871 pub fn read_nonblocking ( & mut self ) -> nb:: Result < W , Error > {
865872 if BIDI {
866- self . spi . cr1 . modify ( |_ , w| w . bidioe ( ) . clear_bit ( ) ) ;
873+ self . bidi_input ( ) ;
867874 }
868875 self . check_read ( )
869876 }
870877
871878 pub fn write_nonblocking ( & mut self , byte : W ) -> nb:: Result < ( ) , Error > {
872879 if BIDI {
873- self . spi . cr1 . modify ( |_ , w| w . bidioe ( ) . set_bit ( ) ) ;
880+ self . bidi_output ( ) ;
874881 }
875882 self . check_send ( byte)
876883 }
@@ -900,20 +907,48 @@ impl<SPI: Instance, const BIDI: bool, W: FrameSize> Spi<SPI, BIDI, W> {
900907 }
901908
902909 pub fn write ( & mut self , words : & [ W ] ) -> Result < ( ) , Error > {
903- for word in words {
904- nb:: block!( self . write_nonblocking( * word) ) ?;
905- if !BIDI {
906- nb:: block!( self . read_nonblocking( ) ) ?;
910+ if BIDI {
911+ self . bidi_output ( ) ;
912+ for word in words {
913+ nb:: block!( self . check_send( * word) ) ?;
914+ }
915+ } else {
916+ for word in words {
917+ nb:: block!( self . check_send( * word) ) ?;
918+ nb:: block!( self . check_read:: <W >( ) ) ?;
919+ }
920+ }
921+
922+ Ok ( ( ) )
923+ }
924+
925+ pub fn write_iter ( & mut self , words : impl IntoIterator < Item = W > ) -> Result < ( ) , Error > {
926+ if BIDI {
927+ self . bidi_output ( ) ;
928+ for word in words. into_iter ( ) {
929+ nb:: block!( self . check_send( word) ) ?;
930+ }
931+ } else {
932+ for word in words. into_iter ( ) {
933+ nb:: block!( self . check_send( word) ) ?;
934+ nb:: block!( self . check_read:: <W >( ) ) ?;
907935 }
908936 }
909937
910938 Ok ( ( ) )
911939 }
912940
913941 pub fn read ( & mut self , words : & mut [ W ] ) -> Result < ( ) , Error > {
914- for word in words {
915- nb:: block!( self . write_nonblocking( W :: default ( ) ) ) ?;
916- * word = nb:: block!( self . read_nonblocking( ) ) ?;
942+ if BIDI {
943+ self . bidi_input ( ) ;
944+ for word in words {
945+ * word = nb:: block!( self . check_read( ) ) ?;
946+ }
947+ } else {
948+ for word in words {
949+ nb:: block!( self . check_send( W :: default ( ) ) ) ?;
950+ * word = nb:: block!( self . check_read( ) ) ?;
951+ }
917952 }
918953
919954 Ok ( ( ) )
@@ -923,14 +958,14 @@ impl<SPI: Instance, const BIDI: bool, W: FrameSize> Spi<SPI, BIDI, W> {
923958impl < SPI : Instance , const BIDI : bool , W : FrameSize > SpiSlave < SPI , BIDI , W > {
924959 pub fn read_nonblocking ( & mut self ) -> nb:: Result < W , Error > {
925960 if BIDI {
926- self . spi . cr1 . modify ( |_ , w| w . bidioe ( ) . clear_bit ( ) ) ;
961+ self . bidi_input ( ) ;
927962 }
928963 self . check_read ( )
929964 }
930965
931966 pub fn write_nonblocking ( & mut self , byte : W ) -> nb:: Result < ( ) , Error > {
932967 if BIDI {
933- self . spi . cr1 . modify ( |_ , w| w . bidioe ( ) . set_bit ( ) ) ;
968+ self . bidi_output ( ) ;
934969 }
935970 self . check_send ( byte)
936971 }
@@ -960,20 +995,32 @@ impl<SPI: Instance, const BIDI: bool, W: FrameSize> SpiSlave<SPI, BIDI, W> {
960995 }
961996
962997 pub fn write ( & mut self , words : & [ W ] ) -> Result < ( ) , Error > {
963- for word in words {
964- nb:: block!( self . write_nonblocking( * word) ) ?;
965- if !BIDI {
966- nb:: block!( self . read_nonblocking( ) ) ?;
998+ if BIDI {
999+ self . bidi_output ( ) ;
1000+ for word in words {
1001+ nb:: block!( self . check_send( * word) ) ?;
1002+ }
1003+ } else {
1004+ for word in words {
1005+ nb:: block!( self . check_send( * word) ) ?;
1006+ nb:: block!( self . check_read:: <W >( ) ) ?;
9671007 }
9681008 }
9691009
9701010 Ok ( ( ) )
9711011 }
9721012
9731013 pub fn read ( & mut self , words : & mut [ W ] ) -> Result < ( ) , Error > {
974- for word in words {
975- nb:: block!( self . write_nonblocking( W :: default ( ) ) ) ?;
976- * word = nb:: block!( self . read_nonblocking( ) ) ?;
1014+ if BIDI {
1015+ self . bidi_input ( ) ;
1016+ for word in words {
1017+ * word = nb:: block!( self . check_read( ) ) ?;
1018+ }
1019+ } else {
1020+ for word in words {
1021+ nb:: block!( self . check_send( W :: default ( ) ) ) ?;
1022+ * word = nb:: block!( self . check_read( ) ) ?;
1023+ }
9771024 }
9781025
9791026 Ok ( ( ) )
0 commit comments