@@ -131,11 +131,32 @@ impl Ms for Master {
131
131
const MSTR : bool = true ;
132
132
}
133
133
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
+
134
155
#[ 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 > {
136
157
spi : SPI ,
137
158
pins : PINS ,
138
- _operation : PhantomData < OPERATION > ,
159
+ _operation : PhantomData < ( W , OPERATION ) > ,
139
160
}
140
161
141
162
// Implemented by all SPI instances
@@ -149,8 +170,8 @@ pub trait Instance:
149
170
// Implemented by all SPI instances
150
171
macro_rules! spi {
151
172
( $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 >;
154
175
155
176
impl Instance for $SPI {
156
177
fn ptr( ) -> * const spi1:: RegisterBlock {
@@ -182,7 +203,7 @@ pub trait SpiExt: Sized + Instance {
182
203
mode : impl Into < Mode > ,
183
204
freq : Hertz ,
184
205
clocks : & Clocks ,
185
- ) -> Spi < Self , ( SCK , MISO , MOSI ) , false , Master >
206
+ ) -> Spi < Self , ( SCK , MISO , MOSI ) , false , u8 , Master >
186
207
where
187
208
( SCK , MISO , MOSI ) : Pins < Self > ;
188
209
fn spi_bidi < SCK , MISO , MOSI > (
@@ -191,7 +212,7 @@ pub trait SpiExt: Sized + Instance {
191
212
mode : impl Into < Mode > ,
192
213
freq : Hertz ,
193
214
clocks : & Clocks ,
194
- ) -> Spi < Self , ( SCK , MISO , MOSI ) , true , Master >
215
+ ) -> Spi < Self , ( SCK , MISO , MOSI ) , true , u8 , Master >
195
216
where
196
217
( SCK , MISO , MOSI ) : Pins < Self > ;
197
218
fn spi_slave < SCK , MISO , MOSI > (
@@ -200,7 +221,7 @@ pub trait SpiExt: Sized + Instance {
200
221
mode : impl Into < Mode > ,
201
222
freq : Hertz ,
202
223
clocks : & Clocks ,
203
- ) -> Spi < Self , ( SCK , MISO , MOSI ) , false , Slave >
224
+ ) -> Spi < Self , ( SCK , MISO , MOSI ) , false , u8 , Slave >
204
225
where
205
226
( SCK , MISO , MOSI ) : Pins < Self > ;
206
227
fn spi_bidi_slave < SCK , MISO , MOSI > (
@@ -209,7 +230,7 @@ pub trait SpiExt: Sized + Instance {
209
230
mode : impl Into < Mode > ,
210
231
freq : Hertz ,
211
232
clocks : & Clocks ,
212
- ) -> Spi < Self , ( SCK , MISO , MOSI ) , true , Slave >
233
+ ) -> Spi < Self , ( SCK , MISO , MOSI ) , true , u8 , Slave >
213
234
where
214
235
( SCK , MISO , MOSI ) : Pins < Self > ;
215
236
}
@@ -221,7 +242,7 @@ impl<SPI: Instance> SpiExt for SPI {
221
242
mode : impl Into < Mode > ,
222
243
freq : Hertz ,
223
244
clocks : & Clocks ,
224
- ) -> Spi < Self , ( SCK , MISO , MOSI ) , false , Master >
245
+ ) -> Spi < Self , ( SCK , MISO , MOSI ) , false , u8 , Master >
225
246
where
226
247
( SCK , MISO , MOSI ) : Pins < Self > ,
227
248
{
@@ -233,7 +254,7 @@ impl<SPI: Instance> SpiExt for SPI {
233
254
mode : impl Into < Mode > ,
234
255
freq : Hertz ,
235
256
clocks : & Clocks ,
236
- ) -> Spi < Self , ( SCK , MISO , MOSI ) , true , Master >
257
+ ) -> Spi < Self , ( SCK , MISO , MOSI ) , true , u8 , Master >
237
258
where
238
259
( SCK , MISO , MOSI ) : Pins < Self > ,
239
260
{
@@ -245,7 +266,7 @@ impl<SPI: Instance> SpiExt for SPI {
245
266
mode : impl Into < Mode > ,
246
267
freq : Hertz ,
247
268
clocks : & Clocks ,
248
- ) -> Spi < Self , ( SCK , MISO , MOSI ) , false , Slave >
269
+ ) -> Spi < Self , ( SCK , MISO , MOSI ) , false , u8 , Slave >
249
270
where
250
271
( SCK , MISO , MOSI ) : Pins < Self > ,
251
272
{
@@ -257,22 +278,26 @@ impl<SPI: Instance> SpiExt for SPI {
257
278
mode : impl Into < Mode > ,
258
279
freq : Hertz ,
259
280
clocks : & Clocks ,
260
- ) -> Spi < Self , ( SCK , MISO , MOSI ) , true , Slave >
281
+ ) -> Spi < Self , ( SCK , MISO , MOSI ) , true , u8 , Slave >
261
282
where
262
283
( SCK , MISO , MOSI ) : Pins < Self > ,
263
284
{
264
285
Spi :: new_bidi_slave ( self , pins, mode, freq, clocks)
265
286
}
266
287
}
267
288
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
+ {
269
292
pub fn init ( self ) -> Self {
270
293
self . spi . cr1 . modify ( |_, w| {
271
294
// bidimode: 2-line or 1-line unidirectional
272
295
w. bidimode ( ) . bit ( BIDI ) ;
273
296
w. bidioe ( ) . bit ( BIDI ) ;
274
297
// master/slave mode
275
298
w. mstr ( ) . bit ( OPERATION :: MSTR ) ;
299
+ // data frame size
300
+ w. dff ( ) . bit ( W :: DFF ) ;
276
301
// spe: enable the SPI bus
277
302
w. spe ( ) . set_bit ( )
278
303
} ) ;
@@ -281,31 +306,51 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION: Ms> Spi<SPI, PINS, BIDI,
281
306
}
282
307
}
283
308
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 > {
286
323
self . into_mode ( )
287
324
}
288
325
}
289
326
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 > {
292
329
self . into_mode ( )
293
330
}
294
331
}
295
332
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 > {
298
339
self . into_mode ( )
299
340
}
300
341
}
301
342
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 > {
304
349
self . into_mode ( )
305
350
}
306
351
}
307
352
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 > {
309
354
pub fn new (
310
355
spi : SPI ,
311
356
mut pins : ( SCK , MISO , MOSI ) ,
@@ -331,7 +376,7 @@ impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), false, Master>
331
376
}
332
377
}
333
378
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 > {
335
380
pub fn new_bidi (
336
381
spi : SPI ,
337
382
mut pins : ( SCK , MISO , MOSI ) ,
@@ -357,7 +402,7 @@ impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), true, Master> {
357
402
}
358
403
}
359
404
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 > {
361
406
pub fn new_slave (
362
407
spi : SPI ,
363
408
mut pins : ( SCK , MISO , MOSI ) ,
@@ -383,7 +428,7 @@ impl<SPI: Instance, SCK, MISO, MOSI> Spi<SPI, (SCK, MISO, MOSI), false, Slave> {
383
428
}
384
429
}
385
430
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 > {
387
432
pub fn new_bidi_slave (
388
433
spi : SPI ,
389
434
mut pins : ( SCK , MISO , MOSI ) ,
@@ -421,7 +466,7 @@ where
421
466
}
422
467
}
423
468
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 > {
425
470
fn _new ( spi : SPI , pins : PINS ) -> Self {
426
471
Self {
427
472
spi,
@@ -431,7 +476,9 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
431
476
}
432
477
433
478
/// 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 > {
435
482
let mut spi = Spi :: _new ( self . spi , self . pins ) ;
436
483
spi. enable ( false ) ;
437
484
spi. init ( )
@@ -482,6 +529,14 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
482
529
self
483
530
}
484
531
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
+
485
540
/// Enable interrupts for the given `event`:
486
541
/// - Received data ready to be read (RXNE)
487
542
/// - Transmit data register empty (TXE)
@@ -550,13 +605,36 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
550
605
pub fn is_overrun ( & self ) -> bool {
551
606
self . spi . sr . read ( ) . ovr ( ) . bit_is_set ( )
552
607
}
608
+ }
553
609
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 ) }
556
625
}
557
626
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
+ {
558
636
#[ inline( always) ]
559
- fn check_read ( & mut self ) -> nb:: Result < u8 , Error > {
637
+ fn check_read ( & mut self ) -> nb:: Result < W , Error > {
560
638
let sr = self . spi . sr . read ( ) ;
561
639
562
640
Err ( if sr. ovr ( ) . bit_is_set ( ) {
@@ -566,14 +644,14 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
566
644
} else if sr. crcerr ( ) . bit_is_set ( ) {
567
645
Error :: Crc . into ( )
568
646
} else if sr. rxne ( ) . bit_is_set ( ) {
569
- return Ok ( self . read_u8 ( ) ) ;
647
+ return Ok ( self . read_data_reg ( ) ) ;
570
648
} else {
571
649
nb:: Error :: WouldBlock
572
650
} )
573
651
}
574
652
575
653
#[ inline( always) ]
576
- fn check_send ( & mut self , byte : u8 ) -> nb:: Result < ( ) , Error > {
654
+ fn check_send ( & mut self , byte : W ) -> nb:: Result < ( ) , Error > {
577
655
let sr = self . spi . sr . read ( ) ;
578
656
579
657
Err ( if sr. ovr ( ) . bit_is_set ( ) {
@@ -592,23 +670,19 @@ impl<SPI: Instance, PINS, const BIDI: bool, OPERATION> Spi<SPI, PINS, BIDI, OPER
592
670
} ) ;
593
671
Error :: Crc . into ( )
594
672
} else if sr. txe ( ) . bit_is_set ( ) {
595
- self . send_u8 ( byte) ;
673
+ self . write_data_reg ( byte) ;
596
674
return Ok ( ( ) ) ;
597
675
} else {
598
676
nb:: Error :: WouldBlock
599
677
} )
600
678
}
679
+ }
601
680
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
607
682
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 }
612
686
}
613
687
}
614
688
0 commit comments