@@ -131,11 +131,32 @@ impl Ms for Master {
131131 const MSTR : bool = true ;
132132}
133133
134+ pub trait FrameSize : Copy + Default {
135+ const DFF : bool ;
136+ }
137+
138+ impl FrameSize for u8 {
139+ const DFF : bool = false ;
140+ }
141+
142+ impl FrameSize for u16 {
143+ const DFF : bool = true ;
144+ }
145+
146+ /// The bit format to send the data in
147+ #[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
148+ pub enum BitFormat {
149+ /// Least significant bit first
150+ LsbFirst ,
151+ /// Most significant bit first
152+ MsbFirst ,
153+ }
154+
134155#[ derive( Debug ) ]
135- pub struct Spi < SPI , PINS , const BIDI : bool = false, OPERATION = Master > {
156+ pub struct Spi < SPI , PINS , const BIDI : bool = false, W = u8 , OPERATION = Master > {
136157 spi : SPI ,
137158 pins : PINS ,
138- _operation : PhantomData < OPERATION > ,
159+ _operation : PhantomData < ( W , OPERATION ) > ,
139160}
140161
141162// Implemented by all SPI instances
@@ -149,8 +170,8 @@ pub trait Instance:
149170// Implemented by all SPI instances
150171macro_rules! spi {
151172 ( $SPI: ty: $Spi: ident) => {
152- pub type $Spi<PINS , const BIDI : bool = false , OPERATION = Master > =
153- Spi <$SPI, PINS , BIDI , OPERATION >;
173+ pub type $Spi<PINS , const BIDI : bool = false , W = u8 , OPERATION = Master > =
174+ Spi <$SPI, PINS , BIDI , W , OPERATION >;
154175
155176 impl Instance for $SPI {
156177 fn ptr( ) -> * const spi1:: RegisterBlock {
@@ -182,7 +203,7 @@ pub trait SpiExt: Sized + Instance {
182203 mode : impl Into < Mode > ,
183204 freq : Hertz ,
184205 clocks : & Clocks ,
185- ) -> Spi < Self , ( SCK , MISO , MOSI ) , false , Master >
206+ ) -> Spi < Self , ( SCK , MISO , MOSI ) , false , u8 , Master >
186207 where
187208 ( SCK , MISO , MOSI ) : Pins < Self > ;
188209 fn spi_bidi < SCK , MISO , MOSI > (
@@ -191,7 +212,7 @@ pub trait SpiExt: Sized + Instance {
191212 mode : impl Into < Mode > ,
192213 freq : Hertz ,
193214 clocks : & Clocks ,
194- ) -> Spi < Self , ( SCK , MISO , MOSI ) , true , Master >
215+ ) -> Spi < Self , ( SCK , MISO , MOSI ) , true , u8 , Master >
195216 where
196217 ( SCK , MISO , MOSI ) : Pins < Self > ;
197218 fn spi_slave < SCK , MISO , MOSI > (
@@ -200,7 +221,7 @@ pub trait SpiExt: Sized + Instance {
200221 mode : impl Into < Mode > ,
201222 freq : Hertz ,
202223 clocks : & Clocks ,
203- ) -> Spi < Self , ( SCK , MISO , MOSI ) , false , Slave >
224+ ) -> Spi < Self , ( SCK , MISO , MOSI ) , false , u8 , Slave >
204225 where
205226 ( SCK , MISO , MOSI ) : Pins < Self > ;
206227 fn spi_bidi_slave < SCK , MISO , MOSI > (
@@ -209,7 +230,7 @@ pub trait SpiExt: Sized + Instance {
209230 mode : impl Into < Mode > ,
210231 freq : Hertz ,
211232 clocks : & Clocks ,
212- ) -> Spi < Self , ( SCK , MISO , MOSI ) , true , Slave >
233+ ) -> Spi < Self , ( SCK , MISO , MOSI ) , true , u8 , Slave >
213234 where
214235 ( SCK , MISO , MOSI ) : Pins < Self > ;
215236}
@@ -221,7 +242,7 @@ impl<SPI: Instance> SpiExt for SPI {
221242 mode : impl Into < Mode > ,
222243 freq : Hertz ,
223244 clocks : & Clocks ,
224- ) -> Spi < Self , ( SCK , MISO , MOSI ) , false , Master >
245+ ) -> Spi < Self , ( SCK , MISO , MOSI ) , false , u8 , Master >
225246 where
226247 ( SCK , MISO , MOSI ) : Pins < Self > ,
227248 {
@@ -233,7 +254,7 @@ impl<SPI: Instance> SpiExt for SPI {
233254 mode : impl Into < Mode > ,
234255 freq : Hertz ,
235256 clocks : & Clocks ,
236- ) -> Spi < Self , ( SCK , MISO , MOSI ) , true , Master >
257+ ) -> Spi < Self , ( SCK , MISO , MOSI ) , true , u8 , Master >
237258 where
238259 ( SCK , MISO , MOSI ) : Pins < Self > ,
239260 {
@@ -245,7 +266,7 @@ impl<SPI: Instance> SpiExt for SPI {
245266 mode : impl Into < Mode > ,
246267 freq : Hertz ,
247268 clocks : & Clocks ,
248- ) -> Spi < Self , ( SCK , MISO , MOSI ) , false , Slave >
269+ ) -> Spi < Self , ( SCK , MISO , MOSI ) , false , u8 , Slave >
249270 where
250271 ( SCK , MISO , MOSI ) : Pins < Self > ,
251272 {
@@ -257,22 +278,26 @@ impl<SPI: Instance> SpiExt for SPI {
257278 mode : impl Into < Mode > ,
258279 freq : Hertz ,
259280 clocks : & Clocks ,
260- ) -> Spi < Self , ( SCK , MISO , MOSI ) , true , Slave >
281+ ) -> Spi < Self , ( SCK , MISO , MOSI ) , true , u8 , Slave >
261282 where
262283 ( SCK , MISO , MOSI ) : Pins < Self > ,
263284 {
264285 Spi :: new_bidi_slave ( self , pins, mode, freq, clocks)
265286 }
266287}
267288
268- impl < SPI : Instance , PINS , const BIDI : bool , OPERATION : Ms > Spi < SPI , PINS , BIDI , OPERATION > {
289+ impl < SPI : Instance , PINS , const BIDI : bool , W : FrameSize , OPERATION : Ms >
290+ Spi < SPI , PINS , BIDI , W , OPERATION >
291+ {
269292 pub fn init ( self ) -> Self {
270293 self . spi . cr1 . modify ( |_, w| {
271294 // bidimode: 2-line or 1-line unidirectional
272295 w. bidimode ( ) . bit ( BIDI ) ;
273296 w. bidioe ( ) . bit ( BIDI ) ;
274297 // master/slave mode
275298 w. mstr ( ) . bit ( OPERATION :: MSTR ) ;
299+ // data frame size
300+ w. dff ( ) . bit ( W :: DFF ) ;
276301 // spe: enable the SPI bus
277302 w. spe ( ) . set_bit ( )
278303 } ) ;
@@ -281,31 +306,51 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION: Ms> Spi<SPI, PINS, BIDI,
281306 }
282307}
283308
284- impl < SPI : Instance , PINS , OPERATION : Ms > Spi < SPI , PINS , false , OPERATION > {
285- pub fn to_bidi_transfer_mode ( self ) -> Spi < SPI , PINS , true , OPERATION > {
309+ impl < SPI : Instance , PINS , W : FrameSize , OPERATION : Ms > Spi < SPI , PINS , false , W , OPERATION > {
310+ pub fn to_bidi_transfer_mode ( self ) -> Spi < SPI , PINS , true , W , OPERATION > {
311+ self . into_mode ( )
312+ }
313+ }
314+
315+ impl < SPI : Instance , PINS , W : FrameSize , OPERATION : Ms > Spi < SPI , PINS , true , W , OPERATION > {
316+ pub fn to_normal_transfer_mode ( self ) -> Spi < SPI , PINS , false , W , OPERATION > {
317+ self . into_mode ( )
318+ }
319+ }
320+
321+ impl < SPI : Instance , PINS , const BIDI : bool , W : FrameSize > Spi < SPI , PINS , BIDI , W , Master > {
322+ pub fn to_slave_operation ( self ) -> Spi < SPI , PINS , BIDI , W , Slave > {
286323 self . into_mode ( )
287324 }
288325}
289326
290- impl < SPI : Instance , PINS , OPERATION : Ms > Spi < SPI , PINS , true , OPERATION > {
291- pub fn to_normal_transfer_mode ( self ) -> Spi < SPI , PINS , false , OPERATION > {
327+ impl < SPI : Instance , PINS , const BIDI : bool , W : FrameSize > Spi < SPI , PINS , BIDI , W , Slave > {
328+ pub fn to_master_operation ( self ) -> Spi < SPI , PINS , BIDI , W , Master > {
292329 self . into_mode ( )
293330 }
294331}
295332
296- impl < SPI : Instance , PINS , const BIDI : bool > Spi < SPI , PINS , BIDI , Master > {
297- pub fn to_slave_operation ( self ) -> Spi < SPI , PINS , BIDI , Slave > {
333+ impl < SPI , PINS , const BIDI : bool , OPERATION : Ms > Spi < SPI , PINS , BIDI , u8 , OPERATION >
334+ where
335+ SPI : Instance ,
336+ {
337+ /// Converts from 8bit dataframe to 16bit.
338+ pub fn frame_size_16bit ( self ) -> Spi < SPI , PINS , BIDI , u16 , OPERATION > {
298339 self . into_mode ( )
299340 }
300341}
301342
302- impl < SPI : Instance , PINS , const BIDI : bool > Spi < SPI , PINS , BIDI , Slave > {
303- pub fn to_master_operation ( self ) -> Spi < SPI , PINS , BIDI , Master > {
343+ impl < SPI , PINS , const BIDI : bool , OPERATION : Ms > Spi < SPI , PINS , BIDI , u16 , OPERATION >
344+ where
345+ SPI : Instance ,
346+ {
347+ /// Converts from 16bit dataframe to 8bit.
348+ pub fn frame_size_8bit ( self ) -> Spi < SPI , PINS , BIDI , u8 , OPERATION > {
304349 self . into_mode ( )
305350 }
306351}
307352
308- impl < SPI : Instance , SCK , MISO , MOSI > Spi < SPI , ( SCK , MISO , MOSI ) , false , Master > {
353+ impl < SPI : Instance , SCK , MISO , MOSI > Spi < SPI , ( SCK , MISO , MOSI ) , false , u8 , Master > {
309354 pub fn new (
310355 spi : SPI ,
311356 mut pins : ( SCK , MISO , MOSI ) ,
@@ -331,7 +376,7 @@ impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), false, Master>
331376 }
332377}
333378
334- impl < SPI : Instance , SCK , MISO , MOSI > Spi < SPI , ( SCK , MISO , MOSI ) , true , Master > {
379+ impl < SPI : Instance , SCK , MISO , MOSI > Spi < SPI , ( SCK , MISO , MOSI ) , true , u8 , Master > {
335380 pub fn new_bidi (
336381 spi : SPI ,
337382 mut pins : ( SCK , MISO , MOSI ) ,
@@ -357,7 +402,7 @@ impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), true, Master> {
357402 }
358403}
359404
360- impl < SPI : Instance , SCK , MISO , MOSI > Spi < SPI , ( SCK , MISO , MOSI ) , false , Slave > {
405+ impl < SPI : Instance , SCK , MISO , MOSI > Spi < SPI , ( SCK , MISO , MOSI ) , false , u8 , Slave > {
361406 pub fn new_slave (
362407 spi : SPI ,
363408 mut pins : ( SCK , MISO , MOSI ) ,
@@ -383,7 +428,7 @@ impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), false, Slave> {
383428 }
384429}
385430
386- impl < SPI : Instance , SCK , MISO , MOSI > Spi < SPI , ( SCK , MISO , MOSI ) , true , Slave > {
431+ impl < SPI : Instance , SCK , MISO , MOSI > Spi < SPI , ( SCK , MISO , MOSI ) , true , u8 , Slave > {
387432 pub fn new_bidi_slave (
388433 spi : SPI ,
389434 mut pins : ( SCK , MISO , MOSI ) ,
@@ -421,7 +466,7 @@ where
421466 }
422467}
423468
424- impl < SPI : Instance , PINS , const BIDI : bool , OPERATION > Spi < SPI , PINS , BIDI , OPERATION > {
469+ impl < SPI : Instance , PINS , const BIDI : bool , W , OPERATION > Spi < SPI , PINS , BIDI , W , OPERATION > {
425470 fn _new ( spi : SPI , pins : PINS ) -> Self {
426471 Self {
427472 spi,
@@ -431,7 +476,9 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
431476 }
432477
433478 /// Convert the spi to another mode.
434- fn into_mode < const BIDI2 : bool , OPERATION2 : Ms > ( self ) -> Spi < SPI , PINS , BIDI2 , OPERATION2 > {
479+ fn into_mode < const BIDI2 : bool , W2 : FrameSize , OPERATION2 : Ms > (
480+ self ,
481+ ) -> Spi < SPI , PINS , BIDI2 , W2 , OPERATION2 > {
435482 let mut spi = Spi :: _new ( self . spi , self . pins ) ;
436483 spi. enable ( false ) ;
437484 spi. init ( )
@@ -482,6 +529,14 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
482529 self
483530 }
484531
532+ /// Select which frame format is used for data transfers
533+ pub fn bit_format ( & mut self , format : BitFormat ) {
534+ match format {
535+ BitFormat :: LsbFirst => self . spi . cr1 . modify ( |_, w| w. lsbfirst ( ) . set_bit ( ) ) ,
536+ BitFormat :: MsbFirst => self . spi . cr1 . modify ( |_, w| w. lsbfirst ( ) . clear_bit ( ) ) ,
537+ }
538+ }
539+
485540 /// Enable interrupts for the given `event`:
486541 /// - Received data ready to be read (RXNE)
487542 /// - Transmit data register empty (TXE)
@@ -550,13 +605,36 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
550605 pub fn is_overrun ( & self ) -> bool {
551606 self . spi . sr . read ( ) . ovr ( ) . bit_is_set ( )
552607 }
608+ }
553609
554- pub fn use_dma ( self ) -> DmaBuilder < SPI > {
555- DmaBuilder { spi : self . spi }
610+ trait ReadWriteReg < W > {
611+ fn read_data_reg ( & mut self ) -> W ;
612+ fn write_data_reg ( & mut self , data : W ) ;
613+ }
614+
615+ impl < SPI , PINS , const BIDI : bool , W , OPERATION > ReadWriteReg < W >
616+ for Spi < SPI , PINS , BIDI , W , OPERATION >
617+ where
618+ SPI : Instance ,
619+ W : FrameSize ,
620+ {
621+ fn read_data_reg ( & mut self ) -> W {
622+ // NOTE(read_volatile) read only 1 byte (the svd2rust API only allows
623+ // reading a half-word)
624+ unsafe { ptr:: read_volatile ( & self . spi . dr as * const _ as * const W ) }
556625 }
557626
627+ fn write_data_reg ( & mut self , data : W ) {
628+ // NOTE(write_volatile) see note above
629+ unsafe { ptr:: write_volatile ( & self . spi . dr as * const _ as * mut W , data) }
630+ }
631+ }
632+
633+ impl < SPI : Instance , PINS , const BIDI : bool , W : FrameSize , OPERATION >
634+ Spi < SPI , PINS , BIDI , W , OPERATION >
635+ {
558636 #[ inline( always) ]
559- fn check_read ( & mut self ) -> nb:: Result < u8 , Error > {
637+ fn check_read ( & mut self ) -> nb:: Result < W , Error > {
560638 let sr = self . spi . sr . read ( ) ;
561639
562640 Err ( if sr. ovr ( ) . bit_is_set ( ) {
@@ -566,14 +644,14 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
566644 } else if sr. crcerr ( ) . bit_is_set ( ) {
567645 Error :: Crc . into ( )
568646 } else if sr. rxne ( ) . bit_is_set ( ) {
569- return Ok ( self . read_u8 ( ) ) ;
647+ return Ok ( self . read_data_reg ( ) ) ;
570648 } else {
571649 nb:: Error :: WouldBlock
572650 } )
573651 }
574652
575653 #[ inline( always) ]
576- fn check_send ( & mut self , byte : u8 ) -> nb:: Result < ( ) , Error > {
654+ fn check_send ( & mut self , byte : W ) -> nb:: Result < ( ) , Error > {
577655 let sr = self . spi . sr . read ( ) ;
578656
579657 Err ( if sr. ovr ( ) . bit_is_set ( ) {
@@ -592,23 +670,19 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
592670 } ) ;
593671 Error :: Crc . into ( )
594672 } else if sr. txe ( ) . bit_is_set ( ) {
595- self . send_u8 ( byte) ;
673+ self . write_data_reg ( byte) ;
596674 return Ok ( ( ) ) ;
597675 } else {
598676 nb:: Error :: WouldBlock
599677 } )
600678 }
679+ }
601680
602- #[ inline( always) ]
603- fn read_u8 ( & mut self ) -> u8 {
604- // NOTE(read_volatile) read only 1 byte (the svd2rust API only allows reading a half-word)
605- unsafe { ptr:: read_volatile ( & self . spi . dr as * const _ as * const u8 ) }
606- }
681+ // Spi DMA
607682
608- #[ inline( always) ]
609- fn send_u8 ( & mut self , byte : u8 ) {
610- // NOTE(write_volatile) see note above
611- unsafe { ptr:: write_volatile ( & self . spi . dr as * const _ as * mut u8 , byte) }
683+ impl < SPI : Instance , PINS , const BIDI : bool > Spi < SPI , PINS , BIDI , u8 , Master > {
684+ pub fn use_dma ( self ) -> DmaBuilder < SPI > {
685+ DmaBuilder { spi : self . spi }
612686 }
613687}
614688
0 commit comments