@@ -66,7 +66,6 @@ mod hal_02;
66
66
mod hal_1;
67
67
68
68
use core:: ops:: { Deref , DerefMut } ;
69
- use core:: ptr;
70
69
71
70
use crate :: pac:: { self , RCC } ;
72
71
@@ -109,6 +108,36 @@ pub struct Mode {
109
108
pub phase : Phase ,
110
109
}
111
110
111
+ type SpiRB = pac:: spi1:: RegisterBlock ;
112
+
113
+ pub trait FrameSize : Copy + Default {
114
+ const DFF : bool ;
115
+ #[ doc( hidden) ]
116
+ fn read_data ( spi : & SpiRB ) -> Self ;
117
+ #[ doc( hidden) ]
118
+ fn write_data ( self , spi : & SpiRB ) ;
119
+ }
120
+
121
+ impl FrameSize for u8 {
122
+ const DFF : bool = false ;
123
+ fn read_data ( spi : & SpiRB ) -> Self {
124
+ spi. dr8 ( ) . read ( ) . dr ( ) . bits ( )
125
+ }
126
+ fn write_data ( self , spi : & SpiRB ) {
127
+ spi. dr8 ( ) . write ( |w| w. dr ( ) . set ( self ) ) ;
128
+ }
129
+ }
130
+
131
+ impl FrameSize for u16 {
132
+ const DFF : bool = true ;
133
+ fn read_data ( spi : & SpiRB ) -> Self {
134
+ spi. dr ( ) . read ( ) . dr ( ) . bits ( )
135
+ }
136
+ fn write_data ( self , spi : & SpiRB ) {
137
+ spi. dr ( ) . write ( |w| w. dr ( ) . set ( self ) ) ;
138
+ }
139
+ }
140
+
112
141
/// Interrupt event
113
142
pub enum Event {
114
143
/// New data has been received
@@ -519,24 +548,7 @@ impl<SPI: Instance, Otype, PULL> SpiSlave<SPI, u8, Otype, PULL> {
519
548
}
520
549
}
521
550
522
- pub trait SpiReadWrite < T > {
523
- fn read_data_reg ( & mut self ) -> T ;
524
- fn write_data_reg ( & mut self , data : T ) ;
525
- fn spi_write ( & mut self , words : & [ T ] ) -> Result < ( ) , Error > ;
526
- }
527
-
528
- impl < SPI : Instance , W : Copy > SpiReadWrite < W > for SpiInner < SPI , W > {
529
- fn read_data_reg ( & mut self ) -> W {
530
- // NOTE(read_volatile) read only 1 byte (the svd2rust API only allows
531
- // reading a half-word)
532
- unsafe { ptr:: read_volatile ( self . spi . dr ( ) . as_ptr ( ) as * const W ) }
533
- }
534
-
535
- fn write_data_reg ( & mut self , data : W ) {
536
- // NOTE(write_volatile) see note above
537
- unsafe { ptr:: write_volatile ( self . spi . dr ( ) . as_ptr ( ) as * mut W , data) }
538
- }
539
-
551
+ impl < SPI : Instance , W : FrameSize > SpiInner < SPI , W > {
540
552
// Implement write as per the "Transmit only procedure" page 712
541
553
// of RM0008 Rev 20. This is more than twice as fast as the
542
554
// default Write<> implementation (which reads and drops each
@@ -547,7 +559,7 @@ impl<SPI: Instance, W: Copy> SpiReadWrite<W> for SpiInner<SPI, W> {
547
559
loop {
548
560
let sr = self . spi . sr ( ) . read ( ) ;
549
561
if sr. txe ( ) . bit_is_set ( ) {
550
- self . write_data_reg ( * word) ;
562
+ ( * word) . write_data ( & self . spi ) ;
551
563
if sr. modf ( ) . bit_is_set ( ) {
552
564
return Err ( Error :: ModeFault ) ;
553
565
}
@@ -560,13 +572,13 @@ impl<SPI: Instance, W: Copy> SpiReadWrite<W> for SpiInner<SPI, W> {
560
572
// Wait for final !BSY
561
573
while self . is_busy ( ) { }
562
574
// Clear OVR set due to dropped received values
563
- let _ = self . read_data_reg ( ) ;
575
+ let _ = W :: read_data ( & self . spi ) ;
564
576
let _ = self . spi . sr ( ) . read ( ) ;
565
577
Ok ( ( ) )
566
578
}
567
579
}
568
580
569
- impl < SPI : Instance , W : Copy > SpiInner < SPI , W > {
581
+ impl < SPI : Instance , W > SpiInner < SPI , W > {
570
582
/// Select which frame format is used for data transfers
571
583
pub fn bit_format ( & mut self , format : SpiBitFormat ) {
572
584
self . spi
@@ -676,9 +688,9 @@ impl<SPI: Instance, Otype, PULL> SpiSlave<SPI, u16, Otype, PULL> {
676
688
impl < SPI , W > SpiInner < SPI , W >
677
689
where
678
690
SPI : Instance ,
679
- W : Copy ,
691
+ W : FrameSize ,
680
692
{
681
- pub fn read_nonblocking ( & mut self ) -> nb:: Result < W , Error > {
693
+ pub ( crate ) fn check_read ( & mut self ) -> nb:: Result < W , Error > {
682
694
let sr = self . spi . sr ( ) . read ( ) ;
683
695
684
696
Err ( if sr. ovr ( ) . bit_is_set ( ) {
@@ -690,12 +702,13 @@ where
690
702
} else if sr. rxne ( ) . bit_is_set ( ) {
691
703
// NOTE(read_volatile) read only 1 byte (the svd2rust API only allows
692
704
// reading a half-word)
693
- return Ok ( self . read_data_reg ( ) ) ;
705
+ return Ok ( W :: read_data ( & self . spi ) ) ;
694
706
} else {
695
707
nb:: Error :: WouldBlock
696
708
} )
697
709
}
698
- pub fn write_nonblocking ( & mut self , data : W ) -> nb:: Result < ( ) , Error > {
710
+
711
+ pub ( crate ) fn check_send ( & mut self , data : W ) -> nb:: Result < ( ) , Error > {
699
712
let sr = self . spi . sr ( ) . read ( ) ;
700
713
701
714
// NOTE: Error::Overrun was deleted in #408. Need check
@@ -705,15 +718,83 @@ where
705
718
Error :: Crc . into ( )
706
719
} else if sr. txe ( ) . bit_is_set ( ) {
707
720
// NOTE(write_volatile) see note above
708
- self . write_data_reg ( data ) ;
721
+ data . write_data ( & self . spi ) ;
709
722
return Ok ( ( ) ) ;
710
723
} else {
711
724
nb:: Error :: WouldBlock
712
725
} )
713
726
}
727
+
728
+ #[ inline( always) ]
729
+ pub fn read_nonblocking ( & mut self ) -> nb:: Result < W , Error > {
730
+ // TODO: bidimode
731
+ self . check_read ( )
732
+ }
733
+
734
+ #[ inline( always) ]
735
+ pub fn write_nonblocking ( & mut self , data : W ) -> nb:: Result < ( ) , Error > {
736
+ // TODO: bidimode
737
+ self . check_send ( data)
738
+ }
739
+
740
+ #[ inline( always) ]
714
741
pub fn write ( & mut self , words : & [ W ] ) -> Result < ( ) , Error > {
715
742
self . spi_write ( words)
716
743
}
744
+
745
+ pub fn transfer_in_place ( & mut self , words : & mut [ W ] ) -> Result < ( ) , Error > {
746
+ for word in words {
747
+ nb:: block!( self . write_nonblocking( * word) ) ?;
748
+ * word = nb:: block!( self . read_nonblocking( ) ) ?;
749
+ }
750
+
751
+ Ok ( ( ) )
752
+ }
753
+
754
+ pub fn transfer ( & mut self , buff : & mut [ W ] , data : & [ W ] ) -> Result < ( ) , Error > {
755
+ if data. len ( ) == buff. len ( ) {
756
+ for ( d, b) in data. iter ( ) . cloned ( ) . zip ( buff. iter_mut ( ) ) {
757
+ nb:: block!( self . write_nonblocking( d) ) ?;
758
+ * b = nb:: block!( self . read_nonblocking( ) ) ?;
759
+ }
760
+ } else {
761
+ let mut iter_r = buff. iter_mut ( ) ;
762
+ let mut iter_w = data. iter ( ) . cloned ( ) ;
763
+ loop {
764
+ match ( iter_r. next ( ) , iter_w. next ( ) ) {
765
+ ( Some ( r) , Some ( w) ) => {
766
+ nb:: block!( self . write_nonblocking( w) ) ?;
767
+ * r = nb:: block!( self . read_nonblocking( ) ) ?;
768
+ }
769
+ ( Some ( r) , None ) => {
770
+ nb:: block!( self . write_nonblocking( W :: default ( ) ) ) ?;
771
+ * r = nb:: block!( self . read_nonblocking( ) ) ?;
772
+ }
773
+ ( None , Some ( w) ) => {
774
+ nb:: block!( self . write_nonblocking( w) ) ?;
775
+ let _ = nb:: block!( self . read_nonblocking( ) ) ?;
776
+ }
777
+ ( None , None ) => break ,
778
+ }
779
+ }
780
+ }
781
+
782
+ Ok ( ( ) )
783
+ }
784
+
785
+ pub fn flush ( & mut self ) -> Result < ( ) , Error > {
786
+ Ok ( ( ) )
787
+ }
788
+
789
+ pub fn read ( & mut self , words : & mut [ W ] ) -> Result < ( ) , Error > {
790
+ // TODO: bidimode
791
+ for word in words {
792
+ nb:: block!( self . check_send( W :: default ( ) ) ) ?;
793
+ * word = nb:: block!( self . check_read( ) ) ?;
794
+ }
795
+
796
+ Ok ( ( ) )
797
+ }
717
798
}
718
799
719
800
// DMA
0 commit comments