@@ -99,6 +99,11 @@ pub enum Error {
99
99
_Extensible,
100
100
}
101
101
102
+ /// Enabled SPI peripheral (type state)
103
+ pub struct Enabled ;
104
+ /// Disabled SPI peripheral (type state)
105
+ pub struct Disabled ;
106
+
102
107
pub trait Pins < SPI > { }
103
108
pub trait PinSck < SPI > { }
104
109
pub trait PinMiso < SPI > { }
@@ -333,9 +338,10 @@ pub enum Event {
333
338
}
334
339
335
340
#[ derive( Debug ) ]
336
- pub struct Spi < SPI , WORD = u8 > {
341
+ pub struct Spi < SPI , ED , WORD = u8 > {
337
342
spi : SPI ,
338
343
_word : PhantomData < WORD > ,
344
+ _ed : PhantomData < ED > ,
339
345
}
340
346
341
347
pub trait SpiExt < SPI , WORD > : Sized {
@@ -348,7 +354,7 @@ pub trait SpiExt<SPI, WORD>: Sized {
348
354
freq : T ,
349
355
prec : Self :: Rec ,
350
356
clocks : & CoreClocks ,
351
- ) -> Spi < SPI , WORD >
357
+ ) -> Spi < SPI , Enabled , WORD >
352
358
where
353
359
PINS : Pins < SPI > ,
354
360
T : Into < Hertz > ,
@@ -360,7 +366,7 @@ pub trait SpiExt<SPI, WORD>: Sized {
360
366
freq : T ,
361
367
prec : Self :: Rec ,
362
368
clocks : & CoreClocks ,
363
- ) -> Spi < SPI , WORD >
369
+ ) -> Spi < SPI , Enabled , WORD >
364
370
where
365
371
T : Into < Hertz > ,
366
372
CONFIG : Into < Config > ;
@@ -384,7 +390,7 @@ macro_rules! spi {
384
390
$(
385
391
// For each $TY
386
392
$(
387
- impl Spi <$SPIX, $TY> {
393
+ impl Spi <$SPIX, Enabled , $TY> {
388
394
pub fn $spiX<T , CONFIG >(
389
395
spi: $SPIX,
390
396
config: CONFIG ,
@@ -476,9 +482,49 @@ macro_rules! spi {
476
482
// spe: enable the SPI bus
477
483
spi. cr1. write( |w| w. ssi( ) . slave_not_selected( ) . spe( ) . enabled( ) ) ;
478
484
479
- Spi { spi, _word: PhantomData }
485
+ Spi { spi, _word: PhantomData , _ed: PhantomData }
486
+ }
487
+
488
+ /// Disables the SPI peripheral. Any SPI operation is
489
+ /// stopped and disabled, the internal state machine is
490
+ /// reset, all the FIFOs content is flushed, the MODF
491
+ /// flag is cleared, the SSI flag is cleared, and the
492
+ /// CRC calculation is re-initialized. Clocks are not
493
+ /// disabled.
494
+ pub fn disable( self ) -> Spi <$SPIX, Disabled , $TY> {
495
+ // Master communication must be suspended before the peripheral is disabled
496
+ self . spi. cr1. modify( |_, w| w. csusp( ) . requested( ) ) ;
497
+ while self . spi. sr. read( ) . eot( ) . is_completed( ) { }
498
+ self . spi. cr1. write( |w| w. ssi( ) . slave_not_selected( ) . spe( ) . disabled( ) ) ;
499
+ Spi {
500
+ spi: self . spi,
501
+ _word: PhantomData ,
502
+ _ed: PhantomData ,
503
+ }
504
+ }
505
+ }
506
+
507
+ impl Spi <$SPIX, Disabled , $TY> {
508
+ /// Enables the SPI peripheral.
509
+ /// Clears the MODF flag, the SSI flag, and sets the SPE bit.
510
+ pub fn enable( mut self ) -> Spi <$SPIX, Enabled , $TY> {
511
+ self . clear_modf( ) ; // SPE cannot be set when MODF is set
512
+ self . spi. cr1. write( |w| w. ssi( ) . slave_not_selected( ) . spe( ) . enabled( ) ) ;
513
+ Spi {
514
+ spi: self . spi,
515
+ _word: PhantomData ,
516
+ _ed: PhantomData ,
517
+ }
480
518
}
481
519
520
+ /// Deconstructs the SPI peripheral and returns the component parts.
521
+ pub fn free( self ) -> ( $SPIX, rec:: $Rec) {
522
+ ( self . spi, rec:: $Rec { _marker: PhantomData } )
523
+ }
524
+ }
525
+
526
+ impl <EN > Spi <$SPIX, EN , $TY>
527
+ {
482
528
/// Enable interrupts for the given `event`:
483
529
/// - Received data ready to be read (RXP)
484
530
/// - Transmit data register empty (TXP)
@@ -551,8 +597,10 @@ macro_rules! spi {
551
597
self . spi. sr. read( ) . ovr( ) . is_overrun( )
552
598
}
553
599
554
- pub fn free( self ) -> ( $SPIX, rec:: $Rec) {
555
- ( self . spi, rec:: $Rec { _marker: PhantomData } )
600
+ /// Clears the MODF flag, which indicates that a
601
+ /// mode fault has occurred.
602
+ pub fn clear_modf( & mut self ) {
603
+ self . spi. ifcr. write( |w| w. modfc( ) . clear( ) ) ;
556
604
}
557
605
}
558
606
@@ -564,29 +612,29 @@ macro_rules! spi {
564
612
config: CONFIG ,
565
613
freq: T ,
566
614
prec: rec:: $Rec,
567
- clocks: & CoreClocks ) -> Spi <$SPIX, $TY>
615
+ clocks: & CoreClocks ) -> Spi <$SPIX, Enabled , $TY>
568
616
where
569
617
PINS : Pins <$SPIX>,
570
618
T : Into <Hertz >,
571
619
CONFIG : Into <Config >,
572
620
{
573
- Spi :: <$SPIX, $TY>:: $spiX( self , config, freq, prec, clocks)
621
+ Spi :: <$SPIX, Enabled , $TY>:: $spiX( self , config, freq, prec, clocks)
574
622
}
575
623
576
624
fn spi_unchecked<T , CONFIG >( self ,
577
625
config: CONFIG ,
578
626
freq: T ,
579
627
prec: rec:: $Rec,
580
- clocks: & CoreClocks ) -> Spi <$SPIX, $TY>
628
+ clocks: & CoreClocks ) -> Spi <$SPIX, Enabled , $TY>
581
629
where
582
630
T : Into <Hertz >,
583
631
CONFIG : Into <Config >,
584
632
{
585
- Spi :: <$SPIX, $TY>:: $spiX( self , config, freq, prec, clocks)
633
+ Spi :: <$SPIX, Enabled , $TY>:: $spiX( self , config, freq, prec, clocks)
586
634
}
587
635
}
588
636
589
- impl hal:: spi:: FullDuplex <$TY> for Spi <$SPIX, $TY> {
637
+ impl hal:: spi:: FullDuplex <$TY> for Spi <$SPIX, Enabled , $TY> {
590
638
type Error = Error ;
591
639
592
640
fn read( & mut self ) -> nb:: Result <$TY, Error > {
@@ -641,10 +689,10 @@ macro_rules! spi {
641
689
}
642
690
643
691
impl hal:: blocking:: spi:: transfer:: Default <$TY>
644
- for Spi <$SPIX, $TY> { }
692
+ for Spi <$SPIX, Enabled , $TY> { }
645
693
646
694
impl hal:: blocking:: spi:: write:: Default <$TY>
647
- for Spi <$SPIX, $TY> { }
695
+ for Spi <$SPIX, Enabled , $TY> { }
648
696
) +
649
697
) +
650
698
}
@@ -653,7 +701,7 @@ macro_rules! spi {
653
701
macro_rules! spi123sel {
654
702
( $( $SPIX: ident, ) +) => {
655
703
$(
656
- impl <WORD > Spi <$SPIX, WORD > {
704
+ impl <WORD > Spi <$SPIX, Enabled , WORD > {
657
705
/// Returns the frequency of the current kernel clock
658
706
/// for SPI1, SPI2, SPI3
659
707
fn kernel_clk( clocks: & CoreClocks ) -> Option <Hertz > {
@@ -676,7 +724,7 @@ macro_rules! spi123sel {
676
724
macro_rules! spi45sel {
677
725
( $( $SPIX: ident, ) +) => {
678
726
$(
679
- impl <WORD > Spi <$SPIX, WORD > {
727
+ impl <WORD > Spi <$SPIX, Enabled , WORD > {
680
728
/// Returns the frequency of the current kernel clock
681
729
/// for SPI4, SPI5
682
730
fn kernel_clk( clocks: & CoreClocks ) -> Option <Hertz > {
@@ -699,7 +747,7 @@ macro_rules! spi45sel {
699
747
macro_rules! spi6sel {
700
748
( $( $SPIX: ident, ) +) => {
701
749
$(
702
- impl <WORD > Spi <$SPIX, WORD > {
750
+ impl <WORD > Spi <$SPIX, Enabled , WORD > {
703
751
/// Returns the frequency of the current kernel clock
704
752
/// for SPI6
705
753
fn kernel_clk( clocks: & CoreClocks ) -> Option <Hertz > {
0 commit comments